aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/dtemplate.d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2024-01-18 02:39:20 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2024-02-03 00:49:46 +0100
commitf204359931866b917856fc959c70dbf55f28c14d (patch)
treeba1c671045e384fa49a6381f79abf7c1b84a55ea /gcc/d/dmd/dtemplate.d
parent5470a9b176c2b3030ff3891c7e9403db2b0685b8 (diff)
downloadgcc-f204359931866b917856fc959c70dbf55f28c14d.zip
gcc-f204359931866b917856fc959c70dbf55f28c14d.tar.gz
gcc-f204359931866b917856fc959c70dbf55f28c14d.tar.bz2
d: Merge dmd, druntime bce5c1f7b5, phobos e4d0dd513.
D front-end changes: - Import latest changes from dmd v2.107.0-beta.1. - Keywords like `__FILE__' are now always evaluated at the callsite. D runtime changes: - Import latest changes from druntime v2.107.0-beta.1. - Added `nameSig' field to TypeInfo_Class in object.d. Phobos changes: - Import latest changes from phobos v2.107.0-beta.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd bce5c1f7b5. * d-attribs.cc (build_attributes): Update for new front-end interface. * d-lang.cc (d_parse_file): Likewise. * decl.cc (DeclVisitor::visit (VarDeclaration *)): Likewise. * expr.cc (build_lambda_tree): New function. (ExprVisitor::visit (FuncExp *)): Use build_lambda_tree. (ExprVisitor::visit (SymOffExp *)): Likewise. (ExprVisitor::visit (VarExp *)): Likewise. * typeinfo.cc (create_tinfo_types): Add two ulong fields to internal TypeInfo representation. (TypeInfoVisitor::visit (TypeInfoClassDeclaration *)): Emit stub data for TypeInfo_Class.nameSig. (TypeInfoVisitor::visit (TypeInfoStructDeclaration *)): Update for new front-end interface. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime bce5c1f7b5. * src/MERGE: Merge upstream phobos e4d0dd513.
Diffstat (limited to 'gcc/d/dmd/dtemplate.d')
-rw-r--r--gcc/d/dmd/dtemplate.d964
1 files changed, 495 insertions, 469 deletions
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 1d84ccd..13cc32f 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -56,6 +56,7 @@ import dmd.dscope;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.errors;
+import dmd.errorsink;
import dmd.expression;
import dmd.expressionsem;
import dmd.func;
@@ -150,7 +151,7 @@ extern (C++) bool isError(const RootObject o)
if (const e = isExpression(o))
return (e.op == EXP.error || !e.type || e.type.ty == Terror);
if (const v = isTuple(o))
- return arrayObjectIsError(&v.objects);
+ return arrayObjectIsError(v.objects);
const s = isDsymbol(o);
assert(s);
if (s.errors)
@@ -161,9 +162,9 @@ extern (C++) bool isError(const RootObject o)
/**************************************
* Are any of the Objects an error?
*/
-bool arrayObjectIsError(const Objects* args)
+bool arrayObjectIsError(const ref Objects args)
{
- foreach (const o; *args)
+ foreach (const o; args)
{
if (isError(o))
return true;
@@ -187,6 +188,13 @@ inout(Type) getType(inout RootObject o)
}
+/***********************************
+ * If oarg represents a Dsymbol, return that Dsymbol
+ * Params:
+ * oarg = argument to check
+ * Returns:
+ * Dsymbol if a symbol, null if not
+ */
Dsymbol getDsymbol(RootObject oarg)
{
//printf("getDsymbol()\n");
@@ -256,8 +264,11 @@ private Expression getExpression(RootObject o)
}
/******************************
- * If o1 matches o2, return true.
- * Else, return false.
+ * See if two objects match
+ * Params:
+ * o1 = first object
+ * o2 = second object
+ * Returns: true if they match
*/
private bool match(RootObject o1, RootObject o2)
{
@@ -343,7 +354,7 @@ private bool match(RootObject o1, RootObject o2)
printf("\tu1 = %s\n", u1.toChars());
printf("\tu2 = %s\n", u2.toChars());
}
- if (!arrayObjectMatch(&u1.objects, &u2.objects))
+ if (!arrayObjectMatch(u1.objects, u2.objects))
goto Lnomatch;
goto Lmatch;
@@ -362,15 +373,15 @@ Lnomatch:
/************************************
* Match an array of them.
*/
-private bool arrayObjectMatch(Objects* oa1, Objects* oa2)
+private bool arrayObjectMatch(ref Objects oa1, ref Objects oa2)
{
- if (oa1 == oa2)
+ if (&oa1 == &oa2)
return true;
if (oa1.length != oa2.length)
return false;
immutable oa1dim = oa1.length;
- auto oa1d = (*oa1)[].ptr;
- auto oa2d = (*oa2)[].ptr;
+ auto oa1d = oa1[].ptr;
+ auto oa2d = oa2[].ptr;
foreach (j; 0 .. oa1dim)
{
RootObject o1 = oa1d[j];
@@ -386,12 +397,12 @@ private bool arrayObjectMatch(Objects* oa1, Objects* oa2)
/************************************
* Return hash of Objects.
*/
-private size_t arrayObjectHash(Objects* oa1)
+private size_t arrayObjectHash(ref Objects oa1)
{
import dmd.root.hash : mixHash;
size_t hash = 0;
- foreach (o1; *oa1)
+ foreach (o1; oa1)
{
/* Must follow the logic of match()
*/
@@ -407,7 +418,7 @@ private size_t arrayObjectHash(Objects* oa1)
hash = mixHash(hash, mixHash(cast(size_t)cast(void*)s1.getIdent(), cast(size_t)cast(void*)s1.parent));
}
else if (auto u1 = isTuple(o1))
- hash = mixHash(hash, arrayObjectHash(&u1.objects));
+ hash = mixHash(hash, arrayObjectHash(u1.objects));
}
return hash;
}
@@ -672,7 +683,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
/**********************************
* Overload existing TemplateDeclaration 'this' with the new one 's'.
- * Return true if successful; i.e. no conflict.
+ * Params:
+ * s = symbol to be inserted
+ * Return: true if successful; i.e. no conflict.
*/
override bool overloadInsert(Dsymbol s)
{
@@ -741,6 +754,8 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
return toCharsMaybeConstraints(false);
}
+ // Note: this function is not actually `const`, because iterating the
+ // function parameter list may run dsymbolsemantic on enum types
const(char)* toCharsMaybeConstraints(bool includeConstraints) const
{
OutBuffer buf;
@@ -758,15 +773,17 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (onemember)
{
- const FuncDeclaration fd = onemember.isFuncDeclaration();
- if (fd && fd.type)
+ if (const fd = onemember.isFuncDeclaration())
{
- TypeFunction tf = cast(TypeFunction)fd.type;
- buf.writestring(parametersTypeToChars(tf.parameterList));
- if (tf.mod)
+ if (TypeFunction tf = cast(TypeFunction)fd.type.isTypeFunction())
{
- buf.writeByte(' ');
- buf.MODtoBuffer(tf.mod);
+ // !! Casted away const
+ buf.writestring(parametersTypeToChars(tf.parameterList));
+ if (tf.mod)
+ {
+ buf.writeByte(' ');
+ buf.MODtoBuffer(tf.mod);
+ }
}
}
}
@@ -790,7 +807,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
/****************************
* Check to see if constraint is satisfied.
*/
- extern (D) bool evaluateConstraint(TemplateInstance ti, Scope* sc, Scope* paramscope, Objects* dedargs, FuncDeclaration fd)
+ private bool evaluateConstraint(TemplateInstance ti, Scope* sc, Scope* paramscope, Objects* dedargs, FuncDeclaration fd)
{
/* Detect recursive attempts to instantiate this template declaration,
* https://issues.dlang.org/show_bug.cgi?id=4072
@@ -807,7 +824,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
for (TemplatePrevious* p = previous; p; p = p.prev)
{
- if (!arrayObjectMatch(p.dedargs, dedargs))
+ if (!arrayObjectMatch(*p.dedargs, *dedargs))
continue;
//printf("recursive, no match p.sc=%p %p %s\n", p.sc, this, this.toChars());
/* It must be a subscope of p.sc, other scope chains are not recursive
@@ -1055,7 +1072,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* dedtypes deduced arguments
* Return match level.
*/
- extern (D) MATCH matchWithInstance(Scope* sc, TemplateInstance ti, Objects* dedtypes, ArgumentList argumentList, int flag)
+ private MATCH matchWithInstance(Scope* sc, TemplateInstance ti, ref Objects dedtypes, ArgumentList argumentList, int flag)
{
enum LOGM = 0;
static if (LOGM)
@@ -1151,7 +1168,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
/* Any parameter left without a type gets the type of
* its corresponding arg
*/
- foreach (i, ref dedtype; *dedtypes)
+ foreach (i, ref dedtype; dedtypes)
{
if (!dedtype)
{
@@ -1202,7 +1219,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
// TODO: dedtypes => ti.tiargs ?
- if (!evaluateConstraint(ti, sc, paramscope, dedtypes, fd))
+ if (!evaluateConstraint(ti, sc, paramscope, &dedtypes, fd))
return nomatch();
}
@@ -1283,7 +1300,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
Objects dedtypes = Objects(td2.parameters.length);
// Attempt a type deduction
- MATCH m = td2.matchWithInstance(sc, ti, &dedtypes, argumentList, 1);
+ MATCH m = td2.matchWithInstance(sc, ti, dedtypes, argumentList, 1);
if (m > MATCH.nomatch)
{
/* A non-variadic template is more specialized than a
@@ -1425,7 +1442,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
assert(i < parameters.length);
Declaration sparam = null;
- MATCH m = (*parameters)[i].matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, &sparam);
+ MATCH m = (*parameters)[i].matchArg(instLoc, paramscope, dedargs, i, parameters, *dedtypes, &sparam);
//printf("\tdeduceType m = %d\n", m);
if (m == MATCH.nomatch)
return nomatch();
@@ -1458,10 +1475,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
ParameterList fparameters = fd.getParameterList(); // function parameter list
const nfparams = fparameters.length; // number of function parameters
- const nfargs = argumentList.length; // number of function arguments
if (argumentList.hasNames)
return matcherror(); // TODO: resolve named args
- Expressions* fargs = argumentList.arguments; // TODO: resolve named args
+ Expression[] fargs = argumentList.arguments ? (*argumentList.arguments)[] : null;
/* Check for match of function arguments with variadic template
* parameter, such as:
@@ -1475,7 +1491,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
// TemplateTupleParameter always makes most lesser matching.
matchTiargs = MATCH.convert;
- if (nfparams == 0 && nfargs != 0) // if no function parameters
+ if (nfparams == 0 && argumentList.length != 0) // if no function parameters
{
if (!declaredTuple)
{
@@ -1498,7 +1514,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
auto fparam = (*fparameters.parameters)[fptupindex]; // fparameters[fptupindex] ?
if (fparam.type.ty != Tident)
continue;
- TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
+ TypeIdentifier tid = fparam.type.isTypeIdentifier();
if (!tp.ident.equals(tid.ident) || tid.idents.length)
continue;
@@ -1527,7 +1543,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
hasttp = true;
Type t = new TypeIdentifier(Loc.initial, ttp.ident);
- MATCH m = deduceType(tthis, paramscope, t, parameters, dedtypes);
+ MATCH m = deduceType(tthis, paramscope, t, *parameters, *dedtypes);
if (m == MATCH.nomatch)
return nomatch();
if (m < match)
@@ -1576,7 +1592,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
//printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple.objects.length : 0);
//printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple.toChars() : NULL);
size_t argi = 0;
- size_t nfargs2 = nfargs; // nfargs + supplied defaultArgs
+ size_t nfargs2 = fargs.length; // nfargs + supplied defaultArgs
uint inoutMatch = 0; // for debugging only
for (size_t parami = 0; parami < nfparams; parami++)
{
@@ -1592,8 +1608,8 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
*/
if (fptupindex != IDX_NOTFOUND && parami == fptupindex)
{
- assert(prmtype.ty == Tident);
- TypeIdentifier tid = cast(TypeIdentifier)prmtype;
+ TypeIdentifier tid = prmtype.isTypeIdentifier();
+ assert(tid);
if (!declaredTuple)
{
/* The types of the function arguments
@@ -1606,7 +1622,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* void foo(U, T...)(int y, T, U, double, int bar = 0) {} // rem == 2 (U, double)
*/
size_t rem = 0;
- for (size_t j = parami + 1; j < nfparams; j++)
+ foreach (j; parami + 1 .. nfparams)
{
Parameter p = fparameters[j];
if (p.defaultArg)
@@ -1616,7 +1632,10 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (!reliesOnTemplateParameters(p.type, (*parameters)[inferStart .. parameters.length]))
{
Type pt = p.type.syntaxCopy().typeSemantic(fd.loc, paramscope);
- rem += pt.ty == Ttuple ? (cast(TypeTuple)pt).arguments.length : 1;
+ if (auto ptt = pt.isTypeTuple())
+ rem += ptt.arguments.length;
+ else
+ rem += 1;
}
else
{
@@ -1627,9 +1646,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (nfargs2 - argi < rem)
return nomatch();
declaredTuple.objects.setDim(nfargs2 - argi - rem);
- for (size_t i = 0; i < declaredTuple.objects.length; i++)
+ foreach (i; 0 .. declaredTuple.objects.length)
{
- farg = (*fargs)[argi + i];
+ farg = fargs[argi + i];
// Check invalid arguments to detect errors early.
if (farg.op == EXP.error || farg.type.ty == Terror)
@@ -1647,7 +1666,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
else
{
- m = deduceTypeHelper(farg.type, &tt, tid);
+ m = deduceTypeHelper(farg.type, tt, tid);
}
if (m == MATCH.nomatch)
return nomatch();
@@ -1687,20 +1706,19 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
// should copy prmtype to avoid affecting semantic result
prmtype = prmtype.syntaxCopy().typeSemantic(fd.loc, paramscope);
- if (prmtype.ty == Ttuple)
+ if (TypeTuple tt = prmtype.isTypeTuple())
{
- TypeTuple tt = cast(TypeTuple)prmtype;
- size_t tt_dim = tt.arguments.length;
+ const tt_dim = tt.arguments.length;
for (size_t j = 0; j < tt_dim; j++, ++argi)
{
Parameter p = (*tt.arguments)[j];
if (j == tt_dim - 1 && fparameters.varargs == VarArg.typesafe &&
- parami + 1 == nfparams && argi < nfargs)
+ parami + 1 == nfparams && argi < fargs.length)
{
prmtype = p.type;
goto Lvarargs;
}
- if (argi >= nfargs)
+ if (argi >= fargs.length)
{
if (p.defaultArg)
continue;
@@ -1711,7 +1729,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
return nomatch();
}
- farg = (*fargs)[argi];
+ farg = fargs[argi];
if (!farg.implicitConvTo(p.type))
return nomatch();
}
@@ -1719,7 +1737,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
}
- if (argi >= nfargs) // if not enough arguments
+ if (argi >= fargs.length) // if not enough arguments
{
if (!fparam.defaultArg)
goto Lvarargs;
@@ -1741,7 +1759,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* // at fparam `N start = 0`, N should be 'size_t' before
* // the deduction result from fparam.defaultArg.
*/
- if (argi == nfargs)
+ if (argi == fargs.length)
{
foreach (ref dedtype; *dedtypes)
{
@@ -1769,7 +1787,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* the oded == oarg
*/
(*dedargs)[i] = oded;
- MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, null);
+ MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, *dedtypes, null);
//printf("m2 = %d\n", m2);
if (m2 == MATCH.nomatch)
return nomatch();
@@ -1822,7 +1840,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
else
{
- farg = (*fargs)[argi];
+ farg = fargs[argi];
}
{
// Check invalid arguments to detect errors early.
@@ -1851,8 +1869,15 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
/* Allow expressions that have CT-known boundaries and type [] to match with [dim]
*/
- Type taai;
- if (argtype.ty == Tarray && (prmtype.ty == Tsarray || prmtype.ty == Taarray && (taai = (cast(TypeAArray)prmtype).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
+ bool inferIndexType = (argtype.ty == Tarray) && (prmtype.ty == Tsarray || prmtype.ty == Taarray);
+ if (auto aaType = prmtype.isTypeAArray())
+ {
+ if (auto indexType = aaType.index.isTypeIdentifier())
+ {
+ inferIndexType = indexType.idents.length == 0;
+ }
+ }
+ if (inferIndexType)
{
if (StringExp se = farg.isStringExp())
{
@@ -1871,7 +1896,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
oarg = argtype;
}
- else if ((fparam.storageClass & STC.out_) == 0 && (argtype.ty == Tarray || argtype.ty == Tpointer) && templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND && (cast(TypeIdentifier)prmtype).idents.length == 0)
+ else if ((fparam.storageClass & STC.out_) == 0 && (argtype.ty == Tarray || argtype.ty == Tpointer) && templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND && prmtype.isTypeIdentifier().idents.length == 0)
{
/* The farg passing to the prmtype always make a copy. Therefore,
* we can shrink the set of the deduced type arguments for prmtype
@@ -1892,11 +1917,11 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
}
- if (fparameters.varargs == VarArg.typesafe && parami + 1 == nfparams && argi + 1 < nfargs)
+ if (fparameters.varargs == VarArg.typesafe && parami + 1 == nfparams && argi + 1 < fargs.length)
goto Lvarargs;
uint im = 0;
- MATCH m = deduceType(oarg, paramscope, prmtype, parameters, dedtypes, &im, inferStart);
+ MATCH m = deduceType(oarg, paramscope, prmtype, *parameters, *dedtypes, &im, inferStart);
//printf("\tL%d deduceType m = %d, im = x%x, inoutMatch = x%x\n", __LINE__, m, im, inoutMatch);
inoutMatch |= im;
@@ -1984,17 +2009,15 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
case Taarray:
{
// Perhaps we can do better with this, see TypeFunction.callMatch()
- if (tb.ty == Tsarray)
+ if (TypeSArray tsa = tb.isTypeSArray())
{
- TypeSArray tsa = cast(TypeSArray)tb;
dinteger_t sz = tsa.dim.toInteger();
- if (sz != nfargs - argi)
+ if (sz != fargs.length - argi)
return nomatch();
}
- else if (tb.ty == Taarray)
+ else if (TypeAArray taa = tb.isTypeAArray())
{
- TypeAArray taa = cast(TypeAArray)tb;
- Expression dim = new IntegerExp(instLoc, nfargs - argi, Type.tsize_t);
+ Expression dim = new IntegerExp(instLoc, fargs.length - argi, Type.tsize_t);
size_t i = templateParameterLookup(taa.index, parameters);
if (i == IDX_NOTFOUND)
@@ -2057,9 +2080,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
TypeArray ta = cast(TypeArray)tb;
Type tret = fparam.isLazyArray();
- for (; argi < nfargs; argi++)
+ for (; argi < fargs.length; argi++)
{
- Expression arg = (*fargs)[argi];
+ Expression arg = fargs[argi];
assert(arg);
MATCH m;
@@ -2085,7 +2108,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
else
{
uint wm = 0;
- m = deduceType(arg, paramscope, ta.next, parameters, dedtypes, &wm, inferStart);
+ m = deduceType(arg, paramscope, ta.next, *parameters, *dedtypes, &wm, inferStart);
inoutMatch |= wm;
}
if (m == MATCH.nomatch)
@@ -2112,8 +2135,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
Lmatch:
foreach (ref dedtype; *dedtypes)
{
- Type at = isType(dedtype);
- if (at)
+ if (Type at = isType(dedtype))
{
if (at.ty == Tnone)
{
@@ -2147,7 +2169,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* the oded == oarg
*/
(*dedargs)[i] = oded;
- MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, null);
+ MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, *dedtypes, null);
//printf("m2 = %d\n", m2);
if (m2 == MATCH.nomatch)
return nomatch();
@@ -2194,7 +2216,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (tparam.specialization())
{
(*dedargs)[i] = oded;
- MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, null);
+ MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, parameters, *dedtypes, null);
//printf("m2 = %d\n", m2);
if (m2 == MATCH.nomatch)
return nomatch();
@@ -2233,7 +2255,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
sc2.minst = sc.minst;
sc2.stc |= fd.storage_class & STC.deprecated_;
- fd = doHeaderInstantiation(ti, sc2, fd, tthis, fargs);
+ fd = doHeaderInstantiation(ti, sc2, fd, tthis, argumentList.arguments);
sc2 = sc2.pop();
sc2 = sc2.pop();
@@ -2396,7 +2418,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
if (hasttp)
{
- tf = cast(TypeFunction)tf.addSTC(ModToStc(tthis.mod));
+ tf = tf.addSTC(ModToStc(tthis.mod)).isTypeFunction();
assert(!tf.deco);
}
}
@@ -2602,10 +2624,10 @@ extern (C++) final class TypeDeduced : Type
* tiargs = initial list of template arguments
* tthis = if !NULL, the 'this' pointer argument
* argumentList= arguments to function
- * pMessage = address to store error message, or null
+ * errorHelper = delegate to send error message to if not null
*/
void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiargs,
- Type tthis, ArgumentList argumentList, const(char)** pMessage = null)
+ Type tthis, ArgumentList argumentList, void delegate(const(char)*) scope errorHelper = null)
{
version (none)
{
@@ -2662,7 +2684,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
return 1;
}
//printf("fd = %s %s, fargs = %s\n", fd.toChars(), fd.type.toChars(), fargs.toChars());
- auto tf = cast(TypeFunction)fd.type;
+ auto tf = fd.type.isTypeFunction();
int prop = tf.isproperty ? 1 : 2;
if (property == 0)
@@ -2711,8 +2733,12 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
else if (shared_this && !shared_dtor && tthis_fd !is null)
tf.mod = tthis_fd.mod;
}
- MATCH mfa = tf.callMatch(tthis_fd, argumentList, 0, pMessage, sc);
+ const(char)* failMessage;
+ const(char)** pMessage = errorHelper ? &failMessage : null;
+ MATCH mfa = tf.callMatch(tthis_fd, argumentList, 0, errorHelper, sc);
//printf("test1: mfa = %d\n", mfa);
+ if (failMessage)
+ errorHelper(failMessage);
if (mfa == MATCH.nomatch)
return 0;
@@ -2850,7 +2876,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
auto ti = new TemplateInstance(loc, td, tiargs);
Objects dedtypes = Objects(td.parameters.length);
assert(td.semanticRun != PASS.initial);
- MATCH mta = td.matchWithInstance(sc, ti, &dedtypes, argumentList, 0);
+ MATCH mta = td.matchWithInstance(sc, ti, dedtypes, argumentList, 0);
//printf("matchWithInstance = %d\n", mta);
if (mta == MATCH.nomatch || mta < ta_last) // no match or less match
return 0;
@@ -2869,7 +2895,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
// Check for recursive instantiation of tdx.
for (TemplatePrevious* p = tdx.previous; p; p = p.prev)
{
- if (arrayObjectMatch(p.dedargs, &dedtypesX))
+ if (arrayObjectMatch(*p.dedargs, dedtypesX))
{
//printf("recursive, no match p.sc=%p %p %s\n", p.sc, this, this.toChars());
/* It must be a subscope of p.sc, other scope chains are not recursive
@@ -2918,7 +2944,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
Type tthis_fd = fd.needThis() && !fd.isCtorDeclaration() ? tthis : null;
- auto tf = cast(TypeFunction)fd.type;
+ auto tf = fd.type.isTypeFunction();
MATCH mfa = tf.callMatch(tthis_fd, argumentList, 0, null, sc);
if (mfa < m.last)
return 0;
@@ -2979,7 +3005,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
if (isCtorCall)
{
// Constructor call requires additional check.
- auto tf = cast(TypeFunction)fd.type;
+ auto tf = fd.type.isTypeFunction();
assert(tf.next);
if (MODimplicitConv(tf.mod, tthis_fd.mod) ||
tf.isWild() && tf.isShared() == tthis_fd.isShared() ||
@@ -3175,9 +3201,8 @@ private size_t templateIdentifierLookup(Identifier id, TemplateParameters* param
private size_t templateParameterLookup(Type tparam, TemplateParameters* parameters)
{
- if (tparam.ty == Tident)
+ if (TypeIdentifier tident = tparam.isTypeIdentifier())
{
- TypeIdentifier tident = cast(TypeIdentifier)tparam;
//printf("\ttident = '%s'\n", tident.toChars());
return templateIdentifierLookup(tident.ident, parameters);
}
@@ -3267,7 +3292,7 @@ private Type rawTypeMerge(Type t1, Type t2)
return null;
}
-private MATCH deduceTypeHelper(Type t, Type* at, Type tparam)
+private MATCH deduceTypeHelper(Type t, out Type at, Type tparam)
{
// 9*9 == 81 cases
@@ -3297,7 +3322,7 @@ private MATCH deduceTypeHelper(Type t, Type* at, Type tparam)
// foo(U) shared(inout(const(T))) => shared(inout(const(T)))
// foo(U) immutable(T) => immutable(T)
{
- *at = t;
+ at = t;
return MATCH.exact;
}
case X(MODFlags.const_, MODFlags.const_):
@@ -3317,7 +3342,7 @@ private MATCH deduceTypeHelper(Type t, Type* at, Type tparam)
// foo(shared(inout(const(U)))) shared(inout(const(T))) => T
// foo(immutable(U)) immutable(T) => T
{
- *at = t.mutableOf().unSharedOf();
+ at = t.mutableOf().unSharedOf();
return MATCH.exact;
}
case X(MODFlags.const_, MODFlags.shared_ | MODFlags.const_):
@@ -3327,7 +3352,7 @@ private MATCH deduceTypeHelper(Type t, Type* at, Type tparam)
// foo(inout(U)) shared(inout(T)) => shared(T)
// foo(inout(const(U))) shared(inout(const(T))) => shared(T)
{
- *at = t.mutableOf();
+ at = t.mutableOf();
return MATCH.exact;
}
case X(MODFlags.const_, 0):
@@ -3345,13 +3370,13 @@ private MATCH deduceTypeHelper(Type t, Type* at, Type tparam)
// foo(const(U)) immutable(T) => T
// foo(shared(const(U))) immutable(T) => T
{
- *at = t.mutableOf();
+ at = t.mutableOf();
return MATCH.constant;
}
case X(MODFlags.const_, MODFlags.shared_):
// foo(const(U)) shared(T) => shared(T)
{
- *at = t;
+ at = t;
return MATCH.constant;
}
case X(MODFlags.shared_, MODFlags.shared_ | MODFlags.const_):
@@ -3361,13 +3386,13 @@ private MATCH deduceTypeHelper(Type t, Type* at, Type tparam)
// foo(shared(U)) shared(inout(T)) => inout(T)
// foo(shared(U)) shared(inout(const(T))) => inout(const(T))
{
- *at = t.unSharedOf();
+ at = t.unSharedOf();
return MATCH.exact;
}
case X(MODFlags.shared_ | MODFlags.const_, MODFlags.shared_):
// foo(shared(const(U))) shared(T) => T
{
- *at = t.unSharedOf();
+ at = t.unSharedOf();
return MATCH.constant;
}
case X(MODFlags.wildconst, MODFlags.immutable_):
@@ -3379,13 +3404,13 @@ private MATCH deduceTypeHelper(Type t, Type* at, Type tparam)
// foo(shared(inout(const(U)))) immutable(T) => T
// foo(shared(inout(const(U)))) shared(inout(T)) => T
{
- *at = t.unSharedOf().mutableOf();
+ at = t.unSharedOf().mutableOf();
return MATCH.constant;
}
case X(MODFlags.shared_ | MODFlags.const_, MODFlags.shared_ | MODFlags.wild):
// foo(shared(const(U))) shared(inout(T)) => T
{
- *at = t.unSharedOf().mutableOf();
+ at = t.unSharedOf().mutableOf();
return MATCH.constant;
}
case X(MODFlags.wild, 0):
@@ -3499,30 +3524,16 @@ __gshared Expression emptyArrayElement = null;
* Output:
* dedtypes = [ int ] // Array of Expression/Type's
*/
-MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* parameters, Objects* dedtypes, uint* wm = null, size_t inferStart = 0, bool ignoreAliasThis = false)
+MATCH deduceType(RootObject o, Scope* sc, Type tparam, ref TemplateParameters parameters, ref Objects dedtypes, uint* wm = null, size_t inferStart = 0, bool ignoreAliasThis = false)
{
extern (C++) final class DeduceType : Visitor
{
alias visit = Visitor.visit;
public:
- Scope* sc;
- Type tparam;
- TemplateParameters* parameters;
- Objects* dedtypes;
- uint* wm;
- size_t inferStart;
- bool ignoreAliasThis;
MATCH result;
- extern (D) this(Scope* sc, Type tparam, TemplateParameters* parameters, Objects* dedtypes, uint* wm, size_t inferStart, bool ignoreAliasThis) @safe
+ extern (D) this() @safe
{
- this.sc = sc;
- this.tparam = tparam;
- this.parameters = parameters;
- this.dedtypes = dedtypes;
- this.wm = wm;
- this.inferStart = inferStart;
- this.ignoreAliasThis = ignoreAliasThis;
result = MATCH.nomatch;
}
@@ -3537,7 +3548,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (tparam.ty == Tident)
{
// Determine which parameter tparam is
- size_t i = templateParameterLookup(tparam, parameters);
+ size_t i = templateParameterLookup(tparam, &parameters);
if (i == IDX_NOTFOUND)
{
if (!sc)
@@ -3548,7 +3559,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
Loc loc;
if (parameters.length)
{
- TemplateParameter tp = (*parameters)[0];
+ TemplateParameter tp = parameters[0];
loc = tp.loc;
}
@@ -3561,9 +3572,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
return;
}
- TemplateParameter tp = (*parameters)[i];
+ TemplateParameter tp = parameters[i];
- TypeIdentifier tident = cast(TypeIdentifier)tparam;
+ TypeIdentifier tident = tparam.isTypeIdentifier();
if (tident.idents.length > 0)
{
//printf("matching %s to %s\n", tparam.toChars(), t.toChars());
@@ -3601,21 +3612,21 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
Type tt = s.getType();
if (!tt)
goto Lnomatch;
- Type at = cast(Type)(*dedtypes)[i];
+ Type at = cast(Type)dedtypes[i];
if (at && at.ty == Tnone)
at = (cast(TypeDeduced)at).tded;
if (!at || tt.equals(at))
{
- (*dedtypes)[i] = tt;
+ dedtypes[i] = tt;
goto Lexact;
}
}
if (tp.isTemplateAliasParameter())
{
- Dsymbol s2 = cast(Dsymbol)(*dedtypes)[i];
+ Dsymbol s2 = cast(Dsymbol)dedtypes[i];
if (!s2 || s == s2)
{
- (*dedtypes)[i] = s;
+ dedtypes[i] = s;
goto Lexact;
}
}
@@ -3637,7 +3648,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
+/
if (auto ta = tp.isTemplateAliasParameter())
{
- (*dedtypes)[i] = t;
+ dedtypes[i] = t;
goto Lexact;
}
// (23578) - ensure previous behaviour for non-alias template params
@@ -3646,14 +3657,14 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
goto Lnomatch;
}
- Type at = cast(Type)(*dedtypes)[i];
+ Type at = cast(Type)dedtypes[i];
Type tt;
if (ubyte wx = wm ? deduceWildHelper(t, &tt, tparam) : 0)
{
// type vs (none)
if (!at)
{
- (*dedtypes)[i] = tt;
+ dedtypes[i] = tt;
*wm |= wx;
result = MATCH.constant;
return;
@@ -3662,11 +3673,11 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// type vs expressions
if (at.ty == Tnone)
{
- TypeDeduced xt = cast(TypeDeduced)at;
+ auto xt = cast(TypeDeduced)at;
result = xt.matchAll(tt);
if (result > MATCH.nomatch)
{
- (*dedtypes)[i] = tt;
+ dedtypes[i] = tt;
if (result > MATCH.constant)
result = MATCH.constant; // limit level for inout matches
}
@@ -3676,29 +3687,29 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// type vs type
if (tt.equals(at))
{
- (*dedtypes)[i] = tt; // Prefer current type match
+ dedtypes[i] = tt; // Prefer current type match
goto Lconst;
}
if (tt.implicitConvTo(at.constOf()))
{
- (*dedtypes)[i] = at.constOf().mutableOf();
+ dedtypes[i] = at.constOf().mutableOf();
*wm |= MODFlags.const_;
goto Lconst;
}
if (at.implicitConvTo(tt.constOf()))
{
- (*dedtypes)[i] = tt.constOf().mutableOf();
+ dedtypes[i] = tt.constOf().mutableOf();
*wm |= MODFlags.const_;
goto Lconst;
}
goto Lnomatch;
}
- else if (MATCH m = deduceTypeHelper(t, &tt, tparam))
+ else if (MATCH m = deduceTypeHelper(t, tt, tparam))
{
// type vs (none)
if (!at)
{
- (*dedtypes)[i] = tt;
+ dedtypes[i] = tt;
result = m;
return;
}
@@ -3706,11 +3717,11 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// type vs expressions
if (at.ty == Tnone)
{
- TypeDeduced xt = cast(TypeDeduced)at;
+ auto xt = cast(TypeDeduced)at;
result = xt.matchAll(tt);
if (result > MATCH.nomatch)
{
- (*dedtypes)[i] = tt;
+ dedtypes[i] = tt;
}
return;
}
@@ -3740,7 +3751,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
Loc loc;
if (parameters.length)
{
- TemplateParameter tp = (*parameters)[0];
+ TemplateParameter tp = parameters[0];
loc = tp.loc;
}
@@ -3757,9 +3768,8 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
MATCH m = t.implicitConvTo(tparam);
if (m == MATCH.nomatch && !ignoreAliasThis)
{
- if (t.ty == Tclass)
+ if (auto tc = t.isTypeClass())
{
- TypeClass tc = cast(TypeClass)t;
if (tc.sym.aliasthis && !(tc.att & AliasThisRec.tracingDT))
{
if (auto ato = t.aliasthisOf())
@@ -3770,9 +3780,8 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
}
}
}
- else if (t.ty == Tstruct)
+ else if (auto ts = t.isTypeStruct())
{
- TypeStruct ts = cast(TypeStruct)t;
if (ts.sym.aliasthis && !(ts.att & AliasThisRec.tracingDT))
{
if (auto ato = t.aliasthisOf())
@@ -3822,9 +3831,8 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
override void visit(TypeVector t)
{
- if (tparam.ty == Tvector)
+ if (auto tp = tparam.isTypeVector())
{
- TypeVector tp = cast(TypeVector)tparam;
result = deduceType(t.basetype, sc, tp.basetype, parameters, dedtypes, wm);
return;
}
@@ -3851,25 +3859,23 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
TemplateParameter tp = null;
Expression edim = null;
size_t i;
- if (tparam.ty == Tsarray)
+ if (auto tsa = tparam.isTypeSArray())
{
- TypeSArray tsa = cast(TypeSArray)tparam;
if (tsa.dim.isVarExp() && tsa.dim.isVarExp().var.storage_class & STC.templateparameter)
{
Identifier id = tsa.dim.isVarExp().var.ident;
- i = templateIdentifierLookup(id, parameters);
+ i = templateIdentifierLookup(id, &parameters);
assert(i != IDX_NOTFOUND);
- tp = (*parameters)[i];
+ tp = parameters[i];
}
else
edim = tsa.dim;
}
- else if (tparam.ty == Taarray)
+ else if (auto taa = tparam.isTypeAArray())
{
- TypeAArray taa = cast(TypeAArray)tparam;
- i = templateParameterLookup(taa.index, parameters);
+ i = templateParameterLookup(taa.index, &parameters);
if (i != IDX_NOTFOUND)
- tp = (*parameters)[i];
+ tp = parameters[i];
else
{
Loc loc;
@@ -3878,7 +3884,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// so we use that for the resolution (better error message).
if (inferStart < parameters.length)
{
- TemplateParameter loctp = (*parameters)[inferStart];
+ TemplateParameter loctp = parameters[inferStart];
loc = loctp.loc;
}
@@ -3889,7 +3895,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
edim = s ? getValue(s) : getValue(e);
}
}
- if (tp && tp.matchArg(sc, t.dim, i, parameters, dedtypes, null) || edim && edim.toInteger() == t.dim.toInteger())
+ if (tp && tp.matchArg(sc, t.dim, i, &parameters, dedtypes, null) || edim && edim.toInteger() == t.dim.toInteger())
{
result = deduceType(t.next, sc, tparam.nextOf(), parameters, dedtypes, wm);
return;
@@ -3903,7 +3909,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// Extra check that index type must match
if (tparam && tparam.ty == Taarray)
{
- TypeAArray tp = cast(TypeAArray)tparam;
+ TypeAArray tp = tparam.isTypeAArray();
if (!deduceType(t.index, sc, tp.index, parameters, dedtypes))
{
result = MATCH.nomatch;
@@ -3936,7 +3942,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// https://issues.dlang.org/show_bug.cgi?id=15243
// Resolve parameter type if it's not related with template parameters
- if (!reliesOnTemplateParameters(fparam.type, (*parameters)[inferStart .. parameters.length]))
+ if (!reliesOnTemplateParameters(fparam.type, parameters[inferStart .. parameters.length]))
{
auto tx = fparam.type.typeSemantic(Loc.initial, sc);
if (tx.ty == Terror)
@@ -3948,7 +3954,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
}
}
- size_t nfargs = t.parameterList.length;
+ const size_t nfargs = t.parameterList.length;
size_t nfparams = tp.parameterList.length;
/* See if tuple match
@@ -3963,7 +3969,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
assert(fparam.type);
if (fparam.type.ty != Tident)
goto L1;
- TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
+ TypeIdentifier tid = fparam.type.isTypeIdentifier();
if (tid.idents.length)
goto L1;
@@ -3974,7 +3980,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
{
if (tupi == parameters.length)
goto L1;
- TemplateParameter tx = (*parameters)[tupi];
+ TemplateParameter tx = parameters[tupi];
TemplateTupleParameter tup = tx.isTemplateTupleParameter();
if (tup && tup.ident.equals(tid.ident))
break;
@@ -3987,7 +3993,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
/* See if existing tuple, and whether it matches or not
*/
- RootObject o = (*dedtypes)[tupi];
+ RootObject o = dedtypes[tupi];
if (o)
{
// Existing deduced argument must be a tuple, and must match
@@ -4016,7 +4022,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
Parameter arg = t.parameterList[nfparams - 1 + i];
tup.objects[i] = arg.type;
}
- (*dedtypes)[tupi] = tup;
+ dedtypes[tupi] = tup;
}
nfparams--; // don't consider the last parameter for type deduction
goto L2;
@@ -4053,7 +4059,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// Extra check
if (tparam && tparam.ty == Tident)
{
- TypeIdentifier tp = cast(TypeIdentifier)tparam;
+ TypeIdentifier tp = tparam.isTypeIdentifier();
for (size_t i = 0; i < t.idents.length; i++)
{
RootObject id1 = t.idents[i];
@@ -4076,7 +4082,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
TemplateDeclaration tempdecl = t.tempinst.tempdecl.isTemplateDeclaration();
assert(tempdecl);
- TypeInstance tp = cast(TypeInstance)tparam;
+ TypeInstance tp = tparam.isTypeInstance();
//printf("tempinst.tempdecl = %p\n", tempdecl);
//printf("tp.tempinst.tempdecl = %p\n", tp.tempinst.tempdecl);
@@ -4087,7 +4093,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
/* Handle case of:
* template Foo(T : sa!(T), alias sa)
*/
- size_t i = templateIdentifierLookup(tp.tempinst.name, parameters);
+ size_t i = templateIdentifierLookup(tp.tempinst.name, &parameters);
if (i == IDX_NOTFOUND)
{
/* Didn't find it as a parameter identifier. Try looking
@@ -4132,15 +4138,15 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
goto Lnomatch;
}
- TemplateParameter tpx = (*parameters)[i];
- if (!tpx.matchArg(sc, tempdecl, i, parameters, dedtypes, null))
+ TemplateParameter tpx = parameters[i];
+ if (!tpx.matchArg(sc, tempdecl, i, &parameters, dedtypes, null))
goto Lnomatch;
}
else if (tempdecl != tp.tempinst.tempdecl)
goto Lnomatch;
L2:
- if (!resolveTemplateInstantiation(t.tempinst.tiargs, &t.tempinst.tdtypes, tempdecl, tp, dedtypes))
+ if (!resolveTemplateInstantiation(sc, &parameters, t.tempinst.tiargs, &t.tempinst.tdtypes, tempdecl, tp, &dedtypes))
goto Lnomatch;
}
visit(cast(Type)t);
@@ -4151,198 +4157,6 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
result = MATCH.nomatch;
}
- /********************
- * Match template `parameters` to the target template instance.
- * Example:
- * struct Temp(U, int Z) {}
- * void foo(T)(Temp!(T, 3));
- * foo(Temp!(int, 3)());
- * Input:
- * this.parameters = template params of foo -> [T]
- * tiargs = <Temp!(int, 3)>.tiargs -> [int, 3]
- * tdtypes = <Temp!(int, 3)>.tdtypes -> [int, 3]
- * tempdecl = <struct Temp!(T, int Z)> -> [T, Z]
- * tp = <Temp!(T, 3)>
- * Output:
- * dedtypes = deduced params of `foo(Temp!(int, 3)())` -> [int]
- */
- private bool resolveTemplateInstantiation(Objects* tiargs, Objects* tdtypes, TemplateDeclaration tempdecl, TypeInstance tp, Objects* dedtypes)
- {
- for (size_t i = 0; 1; i++)
- {
- //printf("\ttest: tempinst.tiargs[%zu]\n", i);
- RootObject o1 = null;
- if (i < tiargs.length)
- o1 = (*tiargs)[i];
- else if (i < tdtypes.length && i < tp.tempinst.tiargs.length)
- {
- // Pick up default arg
- o1 = (*tdtypes)[i];
- }
- else if (i >= tp.tempinst.tiargs.length)
- break;
- //printf("\ttest: o1 = %s\n", o1.toChars());
- if (i >= tp.tempinst.tiargs.length)
- {
- size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
- while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
- {
- i++;
- }
- if (i >= dim)
- break; // match if all remained parameters are dependent
- return false;
- }
-
- RootObject o2 = (*tp.tempinst.tiargs)[i];
- Type t2 = isType(o2);
- //printf("\ttest: o2 = %s\n", o2.toChars());
- size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
- ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
- if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
- (*parameters)[j].isTemplateTupleParameter())
- {
- /* Given:
- * struct A(B...) {}
- * alias A!(int, float) X;
- * static if (is(X Y == A!(Z), Z...)) {}
- * deduce that Z is a tuple(int, float)
- */
-
- /* Create tuple from remaining args
- */
- size_t vtdim = (tempdecl.isVariadic() ? tiargs.length : tdtypes.length) - i;
- auto vt = new Tuple(vtdim);
- for (size_t k = 0; k < vtdim; k++)
- {
- RootObject o;
- if (k < tiargs.length)
- o = (*tiargs)[i + k];
- else // Pick up default arg
- o = (*tdtypes)[i + k];
- vt.objects[k] = o;
- }
-
- Tuple v = cast(Tuple)(*dedtypes)[j];
- if (v)
- {
- if (!match(v, vt))
- return false;
- }
- else
- (*dedtypes)[j] = vt;
- break;
- }
- else if (!o1)
- break;
-
- Type t1 = isType(o1);
- Dsymbol s1 = isDsymbol(o1);
- Dsymbol s2 = isDsymbol(o2);
- Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
- Expression e2 = isExpression(o2);
- version (none)
- {
- Tuple v1 = isTuple(o1);
- Tuple v2 = isTuple(o2);
- if (t1)
- printf("t1 = %s\n", t1.toChars());
- if (t2)
- printf("t2 = %s\n", t2.toChars());
- if (e1)
- printf("e1 = %s\n", e1.toChars());
- if (e2)
- printf("e2 = %s\n", e2.toChars());
- if (s1)
- printf("s1 = %s\n", s1.toChars());
- if (s2)
- printf("s2 = %s\n", s2.toChars());
- if (v1)
- printf("v1 = %s\n", v1.toChars());
- if (v2)
- printf("v2 = %s\n", v2.toChars());
- }
-
- if (t1 && t2)
- {
- if (!deduceType(t1, sc, t2, parameters, dedtypes))
- return false;
- }
- else if (e1 && e2)
- {
- Le:
- e1 = e1.ctfeInterpret();
-
- /* If it is one of the template parameters for this template,
- * we should not attempt to interpret it. It already has a value.
- */
- if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter))
- {
- /*
- * (T:Number!(e2), int e2)
- */
- j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters);
- if (j != IDX_NOTFOUND)
- goto L1;
- // The template parameter was not from this template
- // (it may be from a parent template, for example)
- }
-
- e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417
- e2 = e2.ctfeInterpret();
-
- //printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty);
- //printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty);
- if (!e1.equals(e2))
- {
- if (!e2.implicitConvTo(e1.type))
- return false;
-
- e2 = e2.implicitCastTo(sc, e1.type);
- e2 = e2.ctfeInterpret();
- if (!e1.equals(e2))
- return false;
- }
- }
- else if (e1 && t2 && t2.ty == Tident)
- {
- j = templateParameterLookup(t2, parameters);
- L1:
- if (j == IDX_NOTFOUND)
- {
- t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
- if (e2)
- goto Le;
- return false;
- }
- if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null))
- return false;
- }
- else if (s1 && s2)
- {
- Ls:
- if (!s1.equals(s2))
- return false;
- }
- else if (s1 && t2 && t2.ty == Tident)
- {
- j = templateParameterLookup(t2, parameters);
- if (j == IDX_NOTFOUND)
- {
- t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
- if (s2)
- goto Ls;
- return false;
- }
- if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null))
- return false;
- }
- else
- return false;
- }
- return true;
- }
-
override void visit(TypeStruct t)
{
/* If this struct is a template struct, and we're matching
@@ -4368,7 +4182,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
/* Match things like:
* S!(T).foo
*/
- TypeInstance tpi = cast(TypeInstance)tparam;
+ TypeInstance tpi = tparam.isTypeInstance();
if (tpi.idents.length)
{
RootObject id = tpi.idents[tpi.idents.length - 1];
@@ -4391,7 +4205,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// Extra check
if (tparam && tparam.ty == Tstruct)
{
- TypeStruct tp = cast(TypeStruct)tparam;
+ TypeStruct tp = tparam.isTypeStruct();
//printf("\t%d\n", cast(MATCH) t.implicitConvTo(tp));
if (wm && t.deduceWild(tparam, false))
@@ -4410,7 +4224,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// Extra check
if (tparam && tparam.ty == Tenum)
{
- TypeEnum tp = cast(TypeEnum)tparam;
+ TypeEnum tp = tparam.isTypeEnum();
if (t.sym == tp.sym)
visit(cast(Type)t);
else
@@ -4428,59 +4242,6 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
visit(cast(Type)t);
}
- /* Helper for TypeClass.deduceType().
- * Classes can match with implicit conversion to a base class or interface.
- * This is complicated, because there may be more than one base class which
- * matches. In such cases, one or more parameters remain ambiguous.
- * For example,
- *
- * interface I(X, Y) {}
- * class C : I(uint, double), I(char, double) {}
- * C x;
- * foo(T, U)( I!(T, U) x)
- *
- * deduces that U is double, but T remains ambiguous (could be char or uint).
- *
- * Given a baseclass b, and initial deduced types 'dedtypes', this function
- * tries to match tparam with b, and also tries all base interfaces of b.
- * If a match occurs, numBaseClassMatches is incremented, and the new deduced
- * types are ANDed with the current 'best' estimate for dedtypes.
- */
- static void deduceBaseClassParameters(ref BaseClass b, Scope* sc, Type tparam, TemplateParameters* parameters, Objects* dedtypes, Objects* best, ref int numBaseClassMatches)
- {
- TemplateInstance parti = b.sym ? b.sym.parent.isTemplateInstance() : null;
- if (parti)
- {
- // Make a temporary copy of dedtypes so we don't destroy it
- auto tmpdedtypes = new Objects(dedtypes.length);
- memcpy(tmpdedtypes.tdata(), dedtypes.tdata(), dedtypes.length * (void*).sizeof);
-
- auto t = new TypeInstance(Loc.initial, parti);
- MATCH m = deduceType(t, sc, tparam, parameters, tmpdedtypes);
- if (m > MATCH.nomatch)
- {
- // If this is the first ever match, it becomes our best estimate
- if (numBaseClassMatches == 0)
- memcpy(best.tdata(), tmpdedtypes.tdata(), tmpdedtypes.length * (void*).sizeof);
- else
- for (size_t k = 0; k < tmpdedtypes.length; ++k)
- {
- // If we've found more than one possible type for a parameter,
- // mark it as unknown.
- if ((*tmpdedtypes)[k] != (*best)[k])
- (*best)[k] = (*dedtypes)[k];
- }
- ++numBaseClassMatches;
- }
- }
-
- // Now recursively test the inherited interfaces
- foreach (ref bi; b.baseInterfaces)
- {
- deduceBaseClassParameters(bi, sc, tparam, parameters, dedtypes, best, numBaseClassMatches);
- }
- }
-
override void visit(TypeClass t)
{
//printf("TypeClass.deduceType(this = %s)\n", t.toChars());
@@ -4509,7 +4270,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
/* Match things like:
* S!(T).foo
*/
- TypeInstance tpi = cast(TypeInstance)tparam;
+ TypeInstance tpi = tparam.isTypeInstance();
if (tpi.idents.length)
{
RootObject id = tpi.idents[tpi.idents.length - 1];
@@ -4547,12 +4308,12 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
while (s && s.baseclasses.length > 0)
{
// Test the base class
- deduceBaseClassParameters(*(*s.baseclasses)[0], sc, tparam, parameters, dedtypes, best, numBaseClassMatches);
+ deduceBaseClassParameters(*(*s.baseclasses)[0], sc, tparam, parameters, dedtypes, *best, numBaseClassMatches);
// Test the interfaces inherited by the base class
foreach (b; s.interfaces)
{
- deduceBaseClassParameters(*b, sc, tparam, parameters, dedtypes, best, numBaseClassMatches);
+ deduceBaseClassParameters(*b, sc, tparam, parameters, dedtypes, *best, numBaseClassMatches);
}
s = (*s.baseclasses)[0].sym;
}
@@ -4572,7 +4333,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// Extra check
if (tparam && tparam.ty == Tclass)
{
- TypeClass tp = cast(TypeClass)tparam;
+ TypeClass tp = tparam.isTypeClass();
//printf("\t%d\n", cast(MATCH) t.implicitConvTo(tp));
if (wm && t.deduceWild(tparam, false))
@@ -4589,8 +4350,8 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
override void visit(Expression e)
{
//printf("Expression.deduceType(e = %s)\n", e.toChars());
- size_t i = templateParameterLookup(tparam, parameters);
- if (i == IDX_NOTFOUND || (cast(TypeIdentifier)tparam).idents.length > 0)
+ size_t i = templateParameterLookup(tparam, &parameters);
+ if (i == IDX_NOTFOUND || tparam.isTypeIdentifier().idents.length > 0)
{
if (e == emptyArrayElement && tparam.ty == Tarray)
{
@@ -4602,13 +4363,13 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
return;
}
- TemplateTypeParameter tp = (*parameters)[i].isTemplateTypeParameter();
+ TemplateTypeParameter tp = parameters[i].isTemplateTypeParameter();
if (!tp)
return; // nomatch
if (e == emptyArrayElement)
{
- if ((*dedtypes)[i])
+ if (dedtypes[i])
{
result = MATCH.exact;
return;
@@ -4630,14 +4391,14 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
tb.ty == Tstruct && tb.hasPointers();
}
- Type at = cast(Type)(*dedtypes)[i];
+ Type at = cast(Type)dedtypes[i];
Type tt;
if (ubyte wx = deduceWildHelper(e.type, &tt, tparam))
{
*wm |= wx;
result = MATCH.constant;
}
- else if (MATCH m = deduceTypeHelper(e.type, &tt, tparam))
+ else if (MATCH m = deduceTypeHelper(e.type, tt, tparam))
{
result = m;
}
@@ -4658,7 +4419,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// expression vs (none)
if (!at)
{
- (*dedtypes)[i] = new TypeDeduced(tt, e, tparam);
+ dedtypes[i] = new TypeDeduced(tt, e, tparam);
return;
}
@@ -4716,7 +4477,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (xt)
xt.update(tt, e, tparam);
else
- (*dedtypes)[i] = tt;
+ dedtypes[i] = tt;
result = match1;
return;
}
@@ -4736,7 +4497,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (xt)
xt.update(t, e, tparam);
else
- (*dedtypes)[i] = t;
+ dedtypes[i] = t;
pt = tt.addMod(tparam.mod);
if (*wm)
@@ -4870,7 +4631,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// Parameter types inference from 'tof'
assert(e.td._scope);
- TypeFunction tf = cast(TypeFunction)e.fd.type;
+ TypeFunction tf = e.fd.type.isTypeFunction();
//printf("\ttof = %s\n", tof.toChars());
//printf("\ttf = %s\n", tf.toChars());
const dim = tf.parameterList.length;
@@ -4895,7 +4656,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (!pto)
break;
Type t = pto.type.syntaxCopy(); // https://issues.dlang.org/show_bug.cgi?id=11774
- if (reliesOnTemplateParameters(t, (*parameters)[inferStart .. parameters.length]))
+ if (reliesOnTemplateParameters(t, parameters[inferStart .. parameters.length]))
return;
t = t.typeSemantic(e.loc, sc);
if (t.ty == Terror)
@@ -4929,7 +4690,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// Allow conversion from implicit function pointer to delegate
if (e.tok == TOK.reserved && t.ty == Tpointer && tparam.ty == Tdelegate)
{
- TypeFunction tf = cast(TypeFunction)t.nextOf();
+ TypeFunction tf = t.nextOf().isTypeFunction();
t = (new TypeDelegate(tf)).merge();
}
//printf("tparam = %s <= e.type = %s, t = %s\n", tparam.toChars(), e.type.toChars(), t.toChars());
@@ -4959,7 +4720,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
}
}
- scope DeduceType v = new DeduceType(sc, tparam, parameters, dedtypes, wm, inferStart, ignoreAliasThis);
+ scope DeduceType v = new DeduceType();
if (Type t = isType(o))
t.accept(v);
else if (Expression e = isExpression(o))
@@ -4972,6 +4733,254 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
return v.result;
}
+
+/* Helper for TypeClass.deduceType().
+ * Classes can match with implicit conversion to a base class or interface.
+ * This is complicated, because there may be more than one base class which
+ * matches. In such cases, one or more parameters remain ambiguous.
+ * For example,
+ *
+ * interface I(X, Y) {}
+ * class C : I(uint, double), I(char, double) {}
+ * C x;
+ * foo(T, U)( I!(T, U) x)
+ *
+ * deduces that U is double, but T remains ambiguous (could be char or uint).
+ *
+ * Given a baseclass b, and initial deduced types 'dedtypes', this function
+ * tries to match tparam with b, and also tries all base interfaces of b.
+ * If a match occurs, numBaseClassMatches is incremented, and the new deduced
+ * types are ANDed with the current 'best' estimate for dedtypes.
+ */
+private void deduceBaseClassParameters(ref BaseClass b, Scope* sc, Type tparam, ref TemplateParameters parameters, ref Objects dedtypes, ref Objects best, ref int numBaseClassMatches)
+{
+ TemplateInstance parti = b.sym ? b.sym.parent.isTemplateInstance() : null;
+ if (parti)
+ {
+ // Make a temporary copy of dedtypes so we don't destroy it
+ auto tmpdedtypes = new Objects(dedtypes.length);
+ memcpy(tmpdedtypes.tdata(), dedtypes.tdata(), dedtypes.length * (void*).sizeof);
+
+ auto t = new TypeInstance(Loc.initial, parti);
+ MATCH m = deduceType(t, sc, tparam, parameters, *tmpdedtypes);
+ if (m > MATCH.nomatch)
+ {
+ // If this is the first ever match, it becomes our best estimate
+ if (numBaseClassMatches == 0)
+ memcpy(best.tdata(), tmpdedtypes.tdata(), tmpdedtypes.length * (void*).sizeof);
+ else
+ for (size_t k = 0; k < tmpdedtypes.length; ++k)
+ {
+ // If we've found more than one possible type for a parameter,
+ // mark it as unknown.
+ if ((*tmpdedtypes)[k] != best[k])
+ best[k] = dedtypes[k];
+ }
+ ++numBaseClassMatches;
+ }
+ }
+
+ // Now recursively test the inherited interfaces
+ foreach (ref bi; b.baseInterfaces)
+ {
+ deduceBaseClassParameters(bi, sc, tparam, parameters, dedtypes, best, numBaseClassMatches);
+ }
+}
+
+/********************
+ * Match template `parameters` to the target template instance.
+ * Example:
+ * struct Temp(U, int Z) {}
+ * void foo(T)(Temp!(T, 3));
+ * foo(Temp!(int, 3)());
+ * Input:
+ * sc = context
+ * parameters = template params of foo -> [T]
+ * tiargs = <Temp!(int, 3)>.tiargs -> [int, 3]
+ * tdtypes = <Temp!(int, 3)>.tdtypes -> [int, 3]
+ * tempdecl = <struct Temp!(T, int Z)> -> [T, Z]
+ * tp = <Temp!(T, 3)>
+ * Output:
+ * dedtypes = deduced params of `foo(Temp!(int, 3)())` -> [int]
+ */
+private bool resolveTemplateInstantiation(Scope* sc, TemplateParameters* parameters, Objects* tiargs, Objects* tdtypes, TemplateDeclaration tempdecl, TypeInstance tp, Objects* dedtypes)
+{
+ for (size_t i = 0; 1; i++)
+ {
+ //printf("\ttest: tempinst.tiargs[%zu]\n", i);
+ RootObject o1 = null;
+ if (i < tiargs.length)
+ o1 = (*tiargs)[i];
+ else if (i < tdtypes.length && i < tp.tempinst.tiargs.length)
+ {
+ // Pick up default arg
+ o1 = (*tdtypes)[i];
+ }
+ else if (i >= tp.tempinst.tiargs.length)
+ break;
+ //printf("\ttest: o1 = %s\n", o1.toChars());
+ if (i >= tp.tempinst.tiargs.length)
+ {
+ size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
+ while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
+ {
+ i++;
+ }
+ if (i >= dim)
+ break; // match if all remained parameters are dependent
+ return false;
+ }
+
+ RootObject o2 = (*tp.tempinst.tiargs)[i];
+ Type t2 = isType(o2);
+ //printf("\ttest: o2 = %s\n", o2.toChars());
+ size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
+ ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
+ if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
+ (*parameters)[j].isTemplateTupleParameter())
+ {
+ /* Given:
+ * struct A(B...) {}
+ * alias A!(int, float) X;
+ * static if (is(X Y == A!(Z), Z...)) {}
+ * deduce that Z is a tuple(int, float)
+ */
+
+ /* Create tuple from remaining args
+ */
+ size_t vtdim = (tempdecl.isVariadic() ? tiargs.length : tdtypes.length) - i;
+ auto vt = new Tuple(vtdim);
+ for (size_t k = 0; k < vtdim; k++)
+ {
+ RootObject o;
+ if (k < tiargs.length)
+ o = (*tiargs)[i + k];
+ else // Pick up default arg
+ o = (*tdtypes)[i + k];
+ vt.objects[k] = o;
+ }
+
+ Tuple v = cast(Tuple)(*dedtypes)[j];
+ if (v)
+ {
+ if (!match(v, vt))
+ return false;
+ }
+ else
+ (*dedtypes)[j] = vt;
+ break;
+ }
+ else if (!o1)
+ break;
+
+ Type t1 = isType(o1);
+ Dsymbol s1 = isDsymbol(o1);
+ Dsymbol s2 = isDsymbol(o2);
+ Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
+ Expression e2 = isExpression(o2);
+ version (none)
+ {
+ Tuple v1 = isTuple(o1);
+ Tuple v2 = isTuple(o2);
+ if (t1)
+ printf("t1 = %s\n", t1.toChars());
+ if (t2)
+ printf("t2 = %s\n", t2.toChars());
+ if (e1)
+ printf("e1 = %s\n", e1.toChars());
+ if (e2)
+ printf("e2 = %s\n", e2.toChars());
+ if (s1)
+ printf("s1 = %s\n", s1.toChars());
+ if (s2)
+ printf("s2 = %s\n", s2.toChars());
+ if (v1)
+ printf("v1 = %s\n", v1.toChars());
+ if (v2)
+ printf("v2 = %s\n", v2.toChars());
+ }
+
+ if (t1 && t2)
+ {
+ if (!deduceType(t1, sc, t2, *parameters, *dedtypes))
+ return false;
+ }
+ else if (e1 && e2)
+ {
+ Le:
+ e1 = e1.ctfeInterpret();
+
+ /* If it is one of the template parameters for this template,
+ * we should not attempt to interpret it. It already has a value.
+ */
+ if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter))
+ {
+ /*
+ * (T:Number!(e2), int e2)
+ */
+ j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters);
+ if (j != IDX_NOTFOUND)
+ goto L1;
+ // The template parameter was not from this template
+ // (it may be from a parent template, for example)
+ }
+
+ e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417
+ e2 = e2.ctfeInterpret();
+
+ //printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty);
+ //printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty);
+ if (!e1.equals(e2))
+ {
+ if (!e2.implicitConvTo(e1.type))
+ return false;
+
+ e2 = e2.implicitCastTo(sc, e1.type);
+ e2 = e2.ctfeInterpret();
+ if (!e1.equals(e2))
+ return false;
+ }
+ }
+ else if (e1 && t2 && t2.ty == Tident)
+ {
+ j = templateParameterLookup(t2, parameters);
+ L1:
+ if (j == IDX_NOTFOUND)
+ {
+ t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
+ if (e2)
+ goto Le;
+ return false;
+ }
+ if (!(*parameters)[j].matchArg(sc, e1, j, parameters, *dedtypes, null))
+ return false;
+ }
+ else if (s1 && s2)
+ {
+ Ls:
+ if (!s1.equals(s2))
+ return false;
+ }
+ else if (s1 && t2 && t2.ty == Tident)
+ {
+ j = templateParameterLookup(t2, parameters);
+ if (j == IDX_NOTFOUND)
+ {
+ t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
+ if (s2)
+ goto Ls;
+ return false;
+ }
+ if (!(*parameters)[j].matchArg(sc, s1, j, parameters, *dedtypes, null))
+ return false;
+ }
+ else
+ return false;
+ }
+ return true;
+}
+
+
/***********************************************************
* Check whether the type t representation relies on one or more the template parameters.
* Params:
@@ -5625,7 +5634,11 @@ extern (C++) final class TemplateValueParameter : TemplateParameter
if (e)
{
e = e.syntaxCopy();
- if ((e = e.expressionSemantic(sc)) is null)
+ Scope* sc2 = sc.push();
+ sc2.inDefaultArg = true;
+ e = e.expressionSemantic(sc2);
+ sc2.pop();
+ if (e is null)
return null;
if (auto te = e.isTemplateExp())
{
@@ -6176,7 +6189,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
}
//printf("parent = %s, ti.parent = %s\n", parent.toPrettyChars(), ti.parent.toPrettyChars());
- if (!arrayObjectMatch(&tdtypes, &ti.tdtypes))
+ if (!arrayObjectMatch(tdtypes, ti.tdtypes))
goto Lnotequals;
/* Template functions may have different instantiations based on
@@ -6221,7 +6234,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if (!hash)
{
hash = cast(size_t)cast(void*)enclosing;
- hash += arrayObjectHash(&tdtypes);
+ hash += arrayObjectHash(tdtypes);
hash += hash == 0;
}
return hash;
@@ -6691,6 +6704,12 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if (!tiargs)
return true;
bool err = false;
+
+ // The arguments are not treated as part of a default argument,
+ // because they are evaluated at compile time.
+ sc = sc.push();
+ sc.inDefaultArg = false;
+
for (size_t j = 0; j < tiargs.length; j++)
{
RootObject o = (*tiargs)[j];
@@ -6716,10 +6735,9 @@ extern (C++) class TemplateInstance : ScopeDsymbol
}
Ltype:
- if (ta.ty == Ttuple)
+ if (TypeTuple tt = ta.isTypeTuple())
{
// Expand tuple
- TypeTuple tt = cast(TypeTuple)ta;
size_t dim = tt.arguments.length;
tiargs.remove(j);
if (dim)
@@ -6923,6 +6941,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
}
//printf("1: (*tiargs)[%d] = %p\n", j, (*tiargs)[j]);
}
+ sc.pop();
version (none)
{
printf("-TemplateInstance.semanticTiargs()\n");
@@ -6982,7 +7001,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
assert(tempdecl._scope);
// Deduce tdtypes
tdtypes.setDim(tempdecl.parameters.length);
- if (!tempdecl.matchWithInstance(sc, this, &tdtypes, argumentList, 2))
+ if (!tempdecl.matchWithInstance(sc, this, tdtypes, argumentList, 2))
{
.error(loc, "%s `%s` incompatible arguments for template instantiation", kind, toPrettyChars);
return false;
@@ -7032,7 +7051,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
dedtypes.zero();
assert(td.semanticRun != PASS.initial);
- MATCH m = td.matchWithInstance(sc, this, &dedtypes, argumentList, 0);
+ MATCH m = td.matchWithInstance(sc, this, dedtypes, argumentList, 0);
//printf("matchWithInstance = %d\n", m);
if (m == MATCH.nomatch) // no match at all
return 0;
@@ -7158,7 +7177,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
// print additional information, e.g. `foo` is not a type
foreach (i, param; *tdecl.parameters)
{
- MATCH match = param.matchArg(loc, sc, tiargs, i, tdecl.parameters, &dedtypes, null);
+ MATCH match = param.matchArg(loc, sc, tiargs, i, tdecl.parameters, dedtypes, null);
auto arg = (*tiargs)[i];
auto sym = arg.isDsymbol;
auto exp = arg.isExpression;
@@ -7262,7 +7281,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
* to instantiate the template.
*/
//printf("tp = %p, td.parameters.length = %d, tiargs.length = %d\n", tp, td.parameters.length, tiargs.length);
- auto tf = cast(TypeFunction)fd.type;
+ auto tf = fd.type.isTypeFunction();
if (tf.parameterList.length)
{
auto tp = td.isVariadic();
@@ -7308,7 +7327,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
return 1;
}
}
- MATCH m = td.matchWithInstance(sc, this, &dedtypes, ArgumentList(), 0);
+ MATCH m = td.matchWithInstance(sc, this, dedtypes, ArgumentList(), 0);
if (m == MATCH.nomatch)
return 0;
}
@@ -7992,7 +8011,7 @@ struct TemplateInstanceBox
* dedtypes[] deduced arguments to template instance
* *psparam set to symbol declared and initialized to dedtypes[i]
*/
-MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam)
+MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, size_t i, TemplateParameters* parameters, ref Objects dedtypes, Declaration* psparam)
{
MATCH matchArgNoMatch()
{
@@ -8015,7 +8034,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
{
assert(i < dedtypes.length);
// It might have already been deduced
- oarg = (*dedtypes)[i];
+ oarg = dedtypes[i];
if (!oarg)
return matchArgNoMatch();
}
@@ -8031,7 +8050,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
assert(i + 1 == dedtypes.length); // must be the last one
Tuple ovar;
- if (Tuple u = isTuple((*dedtypes)[i]))
+ if (Tuple u = isTuple(dedtypes[i]))
{
// It has already been deduced
ovar = u;
@@ -8059,7 +8078,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
return matchArgParameter();
}
-MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam)
+MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, TemplateParameters* parameters, ref Objects dedtypes, Declaration* psparam)
{
MATCH matchArgNoMatch()
{
@@ -8087,7 +8106,7 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ
return matchArgNoMatch();
//printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta.toChars(), ttp.specType.toChars());
- MATCH m2 = deduceType(ta, sc, ttp.specType, parameters, dedtypes);
+ MATCH m2 = deduceType(ta, sc, ttp.specType, *parameters, dedtypes);
if (m2 == MATCH.nomatch)
{
//printf("\tfailed deduceType\n");
@@ -8096,9 +8115,9 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ
if (m2 < m)
m = m2;
- if ((*dedtypes)[i])
+ if (dedtypes[i])
{
- Type t = cast(Type)(*dedtypes)[i];
+ Type t = cast(Type)dedtypes[i];
if (ttp.dependent && !t.equals(ta)) // https://issues.dlang.org/show_bug.cgi?id=14357
return matchArgNoMatch();
@@ -8113,10 +8132,10 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ
}
else
{
- if ((*dedtypes)[i])
+ if (dedtypes[i])
{
// Must match already deduced type
- Type t = cast(Type)(*dedtypes)[i];
+ Type t = cast(Type)dedtypes[i];
if (!t.equals(ta))
{
@@ -8130,7 +8149,7 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ
m = MATCH.convert;
}
}
- (*dedtypes)[i] = ta;
+ dedtypes[i] = ta;
if (psparam)
*psparam = new AliasDeclaration(ttp.loc, ttp.ident, ta);
@@ -8235,15 +8254,15 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ
}
else
{
- if ((*dedtypes)[i])
+ if (dedtypes[i])
{
// Must match already deduced value
- Expression e = cast(Expression)(*dedtypes)[i];
+ Expression e = cast(Expression)dedtypes[i];
if (!ei || !ei.equals(e))
return matchArgNoMatch();
}
}
- (*dedtypes)[i] = ei;
+ dedtypes[i] = ei;
if (psparam)
{
@@ -8354,7 +8373,7 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ
return matchArgNoMatch();
Type t = new TypeInstance(Loc.initial, ti);
- MATCH m2 = deduceType(t, sc, talias, parameters, dedtypes);
+ MATCH m2 = deduceType(t, sc, talias, *parameters, dedtypes);
if (m2 == MATCH.nomatch)
return matchArgNoMatch();
}
@@ -8375,14 +8394,14 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ
}
}
}
- else if ((*dedtypes)[i])
+ else if (dedtypes[i])
{
// Must match already deduced symbol
- RootObject si = (*dedtypes)[i];
+ RootObject si = dedtypes[i];
if (!sa || si != sa)
return matchArgNoMatch();
}
- (*dedtypes)[i] = sa;
+ dedtypes[i] = sa;
if (psparam)
{
@@ -8415,15 +8434,15 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ
Tuple ovar = isTuple(oarg);
if (!ovar)
return MATCH.nomatch;
- if ((*dedtypes)[i])
+ if (dedtypes[i])
{
- Tuple tup = isTuple((*dedtypes)[i]);
+ Tuple tup = isTuple(dedtypes[i]);
if (!tup)
return MATCH.nomatch;
if (!match(tup, ovar))
return MATCH.nomatch;
}
- (*dedtypes)[i] = ovar;
+ dedtypes[i] = ovar;
if (psparam)
*psparam = new TupleDeclaration(ttp.loc, ttp.ident, &ovar.objects);
@@ -8457,21 +8476,24 @@ struct TemplateStats
/*******************************
* Add this instance
+ * Params:
+ * td = template declaration
+ * ti = instance of td
+ * listInstances = keep track of instances of templates
*/
static void incInstance(const TemplateDeclaration td,
- const TemplateInstance ti)
+ const TemplateInstance ti,
+ bool listInstances)
{
void log(ref TemplateStats ts)
{
if (ts.allInstances is null)
ts.allInstances = new TemplateInstances();
- if (global.params.v.templatesListInstances)
+ if (listInstances)
ts.allInstances.push(cast() ti);
}
- // message(ti.loc, "incInstance %p %p", td, ti);
- if (!global.params.v.templates)
- return;
+ // message(ti.loc, "incInstance %p %p", td, ti);
if (!td)
return;
assert(ti);
@@ -8494,8 +8516,6 @@ struct TemplateStats
const TemplateInstance ti)
{
// message(ti.loc, "incUnique %p %p", td, ti);
- if (!global.params.v.templates)
- return;
if (!td)
return;
assert(ti);
@@ -8506,7 +8526,13 @@ struct TemplateStats
}
}
-extern (C++) void printTemplateStats()
+/********************************
+ * Print informational statistics on template instantiations.
+ * Params:
+ * listInstances = list instances of templates
+ * eSink = where the print is sent
+ */
+extern (C++) void printTemplateStats(bool listInstances, ErrorSink eSink)
{
static struct TemplateDeclarationStats
{
@@ -8523,11 +8549,12 @@ extern (C++) void printTemplateStats()
}
}
- if (!global.params.v.templates)
- return;
+ const stats_length = TemplateStats.stats.length;
+ if (!stats_length)
+ return; // nothing to report
Array!(TemplateDeclarationStats) sortedStats;
- sortedStats.reserve(TemplateStats.stats.length);
+ sortedStats.reserve(stats_length);
foreach (td_, ref ts; TemplateStats.stats)
{
sortedStats.push(TemplateDeclarationStats(cast(TemplateDeclaration) td_, ts));
@@ -8537,10 +8564,9 @@ extern (C++) void printTemplateStats()
foreach (const ref ss; sortedStats[])
{
- if (global.params.v.templatesListInstances &&
- ss.ts.allInstances)
+ if (listInstances && ss.ts.allInstances)
{
- message(ss.td.loc,
+ eSink.message(ss.td.loc,
"vtemplate: %u (%u distinct) instantiation(s) of template `%s` found, they are:",
ss.ts.numInstantiations,
ss.ts.uniqueInstantiations,
@@ -8548,14 +8574,14 @@ extern (C++) void printTemplateStats()
foreach (const ti; (*ss.ts.allInstances)[])
{
if (ti.tinst) // if has enclosing instance
- message(ti.loc, "vtemplate: implicit instance `%s`", ti.toChars());
+ eSink.message(ti.loc, "vtemplate: implicit instance `%s`", ti.toChars());
else
- message(ti.loc, "vtemplate: explicit instance `%s`", ti.toChars());
+ eSink.message(ti.loc, "vtemplate: explicit instance `%s`", ti.toChars());
}
}
else
{
- message(ss.td.loc,
+ eSink.message(ss.td.loc,
"vtemplate: %u (%u distinct) instantiation(s) of template `%s` found",
ss.ts.numInstantiations,
ss.ts.uniqueInstantiations,