diff --git a/changelog/deprecate_this_super_as_types.dd b/changelog/deprecate_this_super_as_types.dd new file mode 100644 index 000000000000..a55ecc5a0127 --- /dev/null +++ b/changelog/deprecate_this_super_as_types.dd @@ -0,0 +1,33 @@ +Deprecate usage of `this` and `super` as types + +Prior to this release, `this` and `super` could be used as both data or types +depending on the context. Starting with this release using `this` or `super` +as a type will result in a compiler error. + +--- +class C +{ + shared(this) x; // Deprecation: Using `this` as a type is deprecated. Use `typeof(this)` instead +} + +class D : C +{ + shared(super) a; // Deprecation: Using `super` as a type is deprecated. Use `typeof(super)` instead + super b; // Deprecation: Using `super` as a type is deprecated. Use `typeof(super)` instead +} +--- + +Use `typeof(super)` or `typeof(this)` instead. + +--- +class C +{ + shared(typeof(this)) x; +} + +class D : C +{ + shared(typeof(super)) a; + typeof(super) b; +} +--- diff --git a/src/dmd/apply.d b/src/dmd/apply.d index 5a19ef18edd8..0dd76b7d23f7 100644 --- a/src/dmd/apply.d +++ b/src/dmd/apply.d @@ -29,7 +29,7 @@ import dmd.visitor; */ private extern (C++) final class PostorderExpressionVisitor : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: StoppableVisitor v; diff --git a/src/dmd/canthrow.d b/src/dmd/canthrow.d index b5003336cadc..55d95b3d452c 100644 --- a/src/dmd/canthrow.d +++ b/src/dmd/canthrow.d @@ -39,7 +39,7 @@ extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow // stop walking if we determine this expression can throw extern (C++) final class CanThrow : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; FuncDeclaration func; bool mustNotThrow; diff --git a/src/dmd/delegatize.d b/src/dmd/delegatize.d index a4945dac6fec..ddf96304f5d3 100644 --- a/src/dmd/delegatize.d +++ b/src/dmd/delegatize.d @@ -82,7 +82,7 @@ private void lambdaSetParent(Expression e, FuncDeclaration fd) { extern (C++) final class LambdaSetParent : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; FuncDeclaration fd; public: @@ -137,7 +137,7 @@ extern (C++) bool lambdaCheckForNestedRef(Expression e, Scope* sc) { extern (C++) final class LambdaCheckForNestedRef : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: Scope* sc; bool result; diff --git a/src/dmd/dinterpret.d b/src/dmd/dinterpret.d index c6d62e2d0a31..9f46100bcaf0 100644 --- a/src/dmd/dinterpret.d +++ b/src/dmd/dinterpret.d @@ -261,7 +261,7 @@ struct CompiledCtfeFunction { extern (C++) final class VarWalker : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: CompiledCtfeFunction* ccf; diff --git a/src/dmd/expression.d b/src/dmd/expression.d index 185e6a112c17..2b095d76222d 100644 --- a/src/dmd/expression.d +++ b/src/dmd/expression.d @@ -7061,7 +7061,7 @@ extern (C++) final class CondExp : BinExp { extern (C++) final class DtorVisitor : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: Scope* sc; CondExp ce; diff --git a/src/dmd/func.d b/src/dmd/func.d index 86a740a91a78..c5194db1f81c 100644 --- a/src/dmd/func.d +++ b/src/dmd/func.d @@ -68,7 +68,7 @@ enum BUILTIN : int */ extern (C++) final class NrvoWalker : StatementRewriteWalker { - alias visit = super.visit; + alias visit = typeof(super).visit; public: FuncDeclaration fd; Scope* sc; @@ -3174,7 +3174,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration extern (C++) final class RetWalker : StatementRewriteWalker { - alias visit = super.visit; + alias visit = typeof(super).visit; public: Scope* sc; Type tret; diff --git a/src/dmd/inlinecost.d b/src/dmd/inlinecost.d index c993ecc39f62..78569cc0ba12 100644 --- a/src/dmd/inlinecost.d +++ b/src/dmd/inlinecost.d @@ -287,7 +287,7 @@ public: { extern (C++) final class LambdaInlineCost : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; InlineCostVisitor icv; public: diff --git a/src/dmd/nogc.d b/src/dmd/nogc.d index 503bc1f14907..2bc8bdae41ab 100644 --- a/src/dmd/nogc.d +++ b/src/dmd/nogc.d @@ -29,7 +29,7 @@ import dmd.visitor; */ extern (C++) final class NOGCVisitor : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: FuncDeclaration f; bool err; diff --git a/src/dmd/parse.d b/src/dmd/parse.d index 64788b4f1fa9..7f9de91628d0 100644 --- a/src/dmd/parse.d +++ b/src/dmd/parse.d @@ -2872,11 +2872,6 @@ final class Parser(AST) : Lexer } default: { - // Deprecated in 2018-04. - // Change to error in 2019-04. - // @@@DEPRECATED_2019-04@@@. - if (token.value == TOK.this_) - deprecation("`this` cannot be used as a parameter type. Use `typeof(this)` instead"); stc = storageClass & (AST.STC.in_ | AST.STC.out_ | AST.STC.ref_ | AST.STC.lazy_); // if stc is not a power of 2 if (stc & (stc - 1) && !(stc == (AST.STC.in_ | AST.STC.ref_))) diff --git a/src/dmd/sapply.d b/src/dmd/sapply.d index 1bccc0bc6fb7..8cc7e90100ff 100644 --- a/src/dmd/sapply.d +++ b/src/dmd/sapply.d @@ -27,7 +27,7 @@ import dmd.visitor; */ extern (C++) final class PostorderStatementVisitor : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: StoppableVisitor v; diff --git a/src/dmd/sideeffect.d b/src/dmd/sideeffect.d index 27b7e9a26f0e..17906e8d188b 100644 --- a/src/dmd/sideeffect.d +++ b/src/dmd/sideeffect.d @@ -35,7 +35,7 @@ extern (C++) bool isTrivialExp(Expression e) { extern (C++) final class IsTrivialExp : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: extern (D) this() { @@ -68,7 +68,7 @@ extern (C++) bool hasSideEffect(Expression e) { extern (C++) final class LambdaHasSideEffect : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: extern (D) this() { diff --git a/src/dmd/statement.d b/src/dmd/statement.d index d3660e90eccd..abf2eb19066b 100644 --- a/src/dmd/statement.d +++ b/src/dmd/statement.d @@ -176,7 +176,7 @@ extern (C++) abstract class Statement : RootObject { extern (C++) final class UsesEH : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: override void visit(Statement s) { @@ -215,7 +215,7 @@ extern (C++) abstract class Statement : RootObject { extern (C++) final class ComeFrom : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: override void visit(Statement s) { @@ -254,7 +254,7 @@ extern (C++) abstract class Statement : RootObject { extern (C++) final class HasCode : StoppableVisitor { - alias visit = super.visit; + alias visit = typeof(super).visit; public: override void visit(Statement s) { diff --git a/src/dmd/typesem.d b/src/dmd/typesem.d index a839c1425c78..5853e1bee695 100644 --- a/src/dmd/typesem.d +++ b/src/dmd/typesem.d @@ -1510,7 +1510,7 @@ extern(C++) Expression getProperty(Type t, const ref Loc loc, Identifier ident, private extern (C++) final class GetPropertyVisitor : Visitor { - alias visit = super.visit; + alias visit = typeof(super).visit; Loc loc; Identifier ident; int flag; @@ -2056,7 +2056,7 @@ extern(C++) void resolve(Type mt, const ref Loc loc, Scope* sc, Expression* pe, private extern(C++) final class ResolveVisitor : Visitor { - alias visit = super.visit; + alias visit = typeof(super).visit; Loc loc; Scope* sc; Expression* pe; @@ -2238,6 +2238,16 @@ private extern(C++) final class ResolveVisitor : Visitor //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, mt.toChars()); if ((mt.ident.equals(Id._super) || mt.ident.equals(Id.This)) && !hasThis(sc)) { + // @@@DEPRECATED_v2.086@@@. + if (mt.ident.equals(Id._super)) + { + deprecation(mt.loc, "Using `super` as a type is deprecated. Use `typeof(super)` instead"); + } + // @@@DEPRECATED_v2.086@@@. + if (mt.ident.equals(Id.This)) + { + deprecation(mt.loc, "Using `this` as a type is deprecated. Use `typeof(this)` instead"); + } AggregateDeclaration ad = sc.getStructClassScope(); if (ad) { @@ -2549,7 +2559,7 @@ extern(C++) Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident private extern(C++) final class DotExpVisitor : Visitor { - alias visit = super.visit; + alias visit = typeof(super).visit; Scope *sc; Expression e; Identifier ident; diff --git a/test/compilable/test15785.d b/test/compilable/test15785.d index c8ad24096e85..d4e6c0b28287 100644 --- a/test/compilable/test15785.d +++ b/test/compilable/test15785.d @@ -18,5 +18,5 @@ class Derived : Base, IBase2 // IBase2.faz(); // doesn't work yet due to a bug in checkAccess } - super.T t; + typeof(super).T t; } diff --git a/test/fail_compilation/fail18228.d b/test/fail_compilation/fail18228.d index bc5839a86422..ca3dc239d06f 100644 --- a/test/fail_compilation/fail18228.d +++ b/test/fail_compilation/fail18228.d @@ -2,8 +2,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail18228.d(12): Deprecation: `this` cannot be used as a parameter type. Use `typeof(this)` instead -fail_compilation/fail18228.d(13): Deprecation: `this` cannot be used as a parameter type. Use `typeof(this)` instead +fail_compilation/fail18228.d(12): Deprecation: Using `this` as a type is deprecated. Use `typeof(this)` instead +fail_compilation/fail18228.d(13): Deprecation: Using `this` as a type is deprecated. Use `typeof(this)` instead --- */ diff --git a/test/fail_compilation/test12228.d b/test/fail_compilation/test12228.d new file mode 100644 index 000000000000..f9800f0d75e9 --- /dev/null +++ b/test/fail_compilation/test12228.d @@ -0,0 +1,22 @@ +/* +REQUIRED_ARGS: -de +TEST_OUTPUT: +--- +fail_compilation/test12228.d(14): Deprecation: Using `this` as a type is deprecated. Use `typeof(this)` instead +fail_compilation/test12228.d(19): Error: no property `x` for type `object.Object` +fail_compilation/test12228.d(20): Deprecation: Using `super` as a type is deprecated. Use `typeof(super)` instead +fail_compilation/test12228.d(21): Deprecation: Using `super` as a type is deprecated. Use `typeof(super)` instead +--- +*/ + +class C +{ + shared(this) x; +} + +class D : C +{ + alias x = typeof(super).x; + shared(super) a; + super b; +} diff --git a/test/fail_compilation/test13867.d b/test/fail_compilation/test13867.d index 7559b55c66af..36543f92ebe9 100644 --- a/test/fail_compilation/test13867.d +++ b/test/fail_compilation/test13867.d @@ -15,14 +15,14 @@ extern (C++) class Y : Base { override void blah(){} } class Z : Base { - alias blah = super.blah; + alias blah = typeof(super).blah; override void blah(){}//Error } class O : Base { extern (C++) override void blah(){} } extern (C++) class OK : Base { - alias blah = super.blah; + alias blah = typeof(super).blah; override void blah(){} } diff --git a/test/fail_compilation/test15785b.d b/test/fail_compilation/test15785b.d index 809d5d10f934..2531945a9432 100644 --- a/test/fail_compilation/test15785b.d +++ b/test/fail_compilation/test15785b.d @@ -12,7 +12,7 @@ import imports.test15785; class Derived : Base, IBase2 { - super.T t; + typeof(super).T t; Base.T t2; IBase2.T t3; }