Skip to content

Commit

Permalink
fix Issue 9022 - IFTI should support enclosing type/scope deduction
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Jun 24, 2013
1 parent 9d298c0 commit d5b412b
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 12 deletions.
11 changes: 4 additions & 7 deletions src/mtype.c
Expand Up @@ -6656,14 +6656,11 @@ Type *TypeIdentifier::reliesOnTident(TemplateParameters *tparams)
{
if (tparams)
{
if (idents.dim == 0)
for (size_t i = 0; i < tparams->dim; i++)
{
for (size_t i = 0; i < tparams->dim; i++)
{ TemplateParameter *tp = (*tparams)[i];

if (tp->ident->equals(ident))
return this;
}
TemplateParameter *tp = (*tparams)[i];
if (tp->ident->equals(ident))
return this;
}
return NULL;
}
Expand Down
62 changes: 58 additions & 4 deletions src/template.c
Expand Up @@ -2798,10 +2798,7 @@ size_t templateParameterLookup(Type *tparam, TemplateParameters *parameters)
{
TypeIdentifier *tident = (TypeIdentifier *)tparam;
//printf("\ttident = '%s'\n", tident->toChars());
if (tident->idents.dim == 0)
{
return templateIdentifierLookup(tident->ident, parameters);
}
return templateIdentifierLookup(tident->ident, parameters);
}
return IDX_NOTFOUND;
}
Expand Down Expand Up @@ -2863,6 +2860,63 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,

TemplateParameter *tp = (*parameters)[i];

TypeIdentifier *tident = (TypeIdentifier *)tparam;
if (tident->idents.dim > 0)
{
//printf("matching %s to %s\n", tparam->toChars(), toChars());
Dsymbol *s = this->toDsymbol(sc);
for (size_t i = tident->idents.dim; i-- > 0; )
{
RootObject *id = tident->idents[i];
if (id->dyncast() == DYNCAST_IDENTIFIER)
{
if (!s || !s->parent)
goto Lnomatch;
Dsymbol *s2 = s->parent->searchX(Loc(), sc, id);
if (!s2)
goto Lnomatch;
s2 = s2->toAlias();
//printf("[%d] s = %s %s, s2 = %s %s\n", i, s->kind(), s->toChars(), s2->kind(), s2->toChars());
if (s != s2)
{
if (Type *t = s2->getType())
{
if (s != t->toDsymbol(sc))
goto Lnomatch;
}
else
goto Lnomatch;
}
s = s->parent;
}
else
goto Lnomatch;
}
//printf("[e] s = %s\n", s?s->toChars():"(null)");
if (TemplateTypeParameter *ttp = tp->isTemplateTypeParameter())
{
Type *tt = s->getType();
if (!tt)
goto Lnomatch;
Type *at = (Type *)(*dedtypes)[i];
if (!at || tt->equals(at))
{
(*dedtypes)[i] = tt;
goto Lexact;
}
}
if (TemplateAliasParameter *tap = tp->isTemplateAliasParameter())
{
Dsymbol *s2 = (Dsymbol *)(*dedtypes)[i];
if (!s2 || s == s2)
{
(*dedtypes)[i] = s;
goto Lexact;
}
}
goto Lnomatch;
}

// Found the corresponding parameter tp
if (!tp->isTemplateTypeParameter())
goto Lnomatch;
Expand Down
1 change: 0 additions & 1 deletion test/fail_compilation/diag9004.d
@@ -1,7 +1,6 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag9004.d(4): Error: undefined identifier FooT.T
fail_compilation/diag9004.d(8): Error: template diag9004.bar does not match any function template declaration. Candidates are:
fail_compilation/diag9004.d(4): diag9004.bar(FooT)(FooT foo, FooT.T x)
fail_compilation/diag9004.d(8): Error: template diag9004.bar(FooT)(FooT foo, FooT.T x) cannot deduce template function from argument types !()(Foo!int, int)
Expand Down
46 changes: 46 additions & 0 deletions test/runnable/template9.d
Expand Up @@ -1771,6 +1771,51 @@ template Template9018(T)
static assert(!__traits(compiles, Inst9018!(Template9018, int))); // Assert passes
static assert(!__traits(compiles, Inst9018!(Template9018, int))); // Assert fails

/**********************************/
// 9022

class C9022
{
struct X {}

alias B = X;
}
class D9022
{
struct X {}
}

void test9022()
{
auto c = new C9022();
auto d = new D9022();
auto cx = C9022.X();
auto dx = D9022.X();

void foo1(T)(T, T.X) { static assert(is(T == C9022)); }
void foo2(T)(T.X, T) { static assert(is(T == C9022)); }
foo1(c, cx);
foo2(cx, c);

void hoo1(T)(T, T.B) { static assert(is(T == C9022)); }
void hoo2(T)(T.B, T) { static assert(is(T == C9022)); }
hoo1(c, cx);
hoo1(c, cx);

void bar1(alias A)(A.C9022, A.D9022) { static assert(A.stringof == "module breaker"); }
void bar2(alias A)(A.D9022, A.C9022) { static assert(A.stringof == "module breaker"); }
bar1(c, d);
bar2(d, c);

void var1(alias A)(A.C9022, A.D9022.X) { static assert(A.stringof == "module breaker"); }
void var2(alias A)(A.D9022.X, A.C9022) { static assert(A.stringof == "module breaker"); }
var1(c, dx);
var2(dx, c);

void baz(T)(T.X t, T.X u) { }
static assert(!__traits(compiles, baz(cx, dx)));
}

/**********************************/
// 9026

Expand Down Expand Up @@ -2507,6 +2552,7 @@ int main()
test8833();
test8976();
test8940();
test9022();
test9026();
test9038();
test9076();
Expand Down

0 comments on commit d5b412b

Please sign in to comment.