Showing with 31 additions and 42 deletions.
  1. +3 −0 src/declaration.d
  2. +1 −0 src/dsymbol.d
  3. +22 −33 src/expression.d
  4. +5 −0 test/compilable/ice11300.d
  5. 0 test/{fail_compilation → compilable}/imports/ice11300a.d
  6. +0 −9 test/fail_compilation/ice11300.d
3 changes: 3 additions & 0 deletions src/declaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -2275,6 +2275,9 @@ public:
override final Dsymbol toAlias()
{
//printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
if ((!type || !type.deco) && _scope)
semantic(_scope);

assert(this != aliassym);
Dsymbol s = aliassym ? aliassym.toAlias() : this;
return s;
Expand Down
1 change: 1 addition & 0 deletions src/dsymbol.d
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ public:
/*********************************
* If this symbol is really an alias for another,
* return that other.
* If needed, semantic() is invoked due to resolve forward reference.
*/
Dsymbol toAlias()
{
Expand Down
55 changes: 22 additions & 33 deletions src/expression.d
Original file line number Diff line number Diff line change
Expand Up @@ -3715,36 +3715,15 @@ public:
{
if (!s.isFuncDeclaration()) // functions are checked after overloading
s.checkDeprecated(loc, sc);

// Bugzilla 12023: if 's' is a tuple variable, the tuple is returned.
s = s.toAlias();

//printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis());
if (s != olds && !s.isFuncDeclaration())
s.checkDeprecated(loc, sc);
}
if (VarDeclaration v = s.isVarDeclaration())
{
/* Bugzilla 12023: forward reference should be resolved
* before 's->needThis()' is called.
*/
if ((!v.type || !v.type.deco) && v._scope)
{
v.semantic(v._scope);
s = v.toAlias(); // Need this if 'v' is a tuple variable
}
// Change the ancestor lambdas to delegate before hasThis(sc) call.
if (v.checkNestedReference(sc, loc))
return new ErrorExp();
}
if (s.needThis() && hasThis(sc))
{
// For functions, this should happen after overload resolution
if (!s.isFuncDeclaration())
{
// Supply an implicit 'this', as in
// this.ident
auto de = new DotVarExp(loc, new ThisExp(loc), s.isDeclaration());
return de.semantic(sc);
}
}

if (EnumMember em = s.isEnumMember())
{
return em.getVarExp(loc, sc);
Expand All @@ -3770,10 +3749,17 @@ public:
v.inuse--;
return e;
}
e = new VarExp(loc, v);
e.type = v.type;

// Change the ancestor lambdas to delegate before hasThis(sc) call.
if (v.checkNestedReference(sc, loc))
return new ErrorExp();

if (v.needThis() && hasThis(sc))
e = new DotVarExp(loc, new ThisExp(loc), v);
else
e = new VarExp(loc, v);
e = e.semantic(sc);
return e.deref();
return e;
}
if (FuncLiteralDeclaration fld = s.isFuncLiteralDeclaration())
{
Expand Down Expand Up @@ -3839,7 +3825,10 @@ public:
}
if (TupleDeclaration tup = s.isTupleDeclaration())
{
e = new TupleExp(loc, tup);
if (tup.needThis() && hasThis(sc))
e = new DotVarExp(loc, new ThisExp(loc), tup);
else
e = new TupleExp(loc, tup);
e = e.semantic(sc);
return e;
}
Expand Down Expand Up @@ -5275,9 +5264,6 @@ public:

if (auto v = s.isVarDeclaration())
{
if ((!v.type || !v.type.deco) && v._scope)
v.semantic(v._scope);

if (!v.type)
{
error("forward reference of %s %s", v.kind(), v.toChars());
Expand Down Expand Up @@ -7950,8 +7936,12 @@ public:
*/
if (Declaration d = s.isDeclaration())
checkAccess(loc, sc, null, d);

// if 's' is a tuple variable, the tuple is returned.
s = s.toAlias();

checkDeprecated(sc, s);

EnumMember em = s.isEnumMember();
if (em)
{
Expand All @@ -7966,7 +7956,6 @@ public:
error("circular reference to '%s'", v.toChars());
return new ErrorExp();
}
type = v.type;
if (v.needThis())
{
if (!eleft)
Expand Down
5 changes: 5 additions & 0 deletions test/compilable/ice11300.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// PERMUTE_ARGS:

module ice11300;
import imports.ice11300a;
enum value = 42;
File renamed without changes.
9 changes: 0 additions & 9 deletions test/fail_compilation/ice11300.d

This file was deleted.