Skip to content

Instantly share code, notes, and snippets.

@FeepingCreature
Created September 28, 2022 12:54
Show Gist options
  • Save FeepingCreature/61ccf09d6e70e266aaa49a345dc76d23 to your computer and use it in GitHub Desktop.
Save FeepingCreature/61ccf09d6e70e266aaa49a345dc76d23 to your computer and use it in GitHub Desktop.
diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d
index 701f06aade..b033376fe6 100644
--- a/compiler/src/dmd/dsymbolsem.d
+++ b/compiler/src/dmd/dsymbolsem.d
@@ -6136,8 +6136,31 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
* resolve any "auto ref" storage classes.
*/
if (fd.type)
+ {
if (auto tf = fd.type.isTypeFunction())
+ {
+ auto fparameters = tf.parameterList;
+ outer:for (size_t i = 0; i < fparameters.length; i++)
+ {
+ auto fparam = fparameters[i];
+ if (auto ident = fparam.isPlainIdentifier)
+ {
+ bool pmatch = false;
+ auto parameters = tempdecl.parameters;
+ for (size_t k = 0; k < parameters.length; k++)
+ {
+ TemplateParameter tparam = (*parameters)[i];
+ if (tparam.ident != ident)
+ continue;
+ tf.parameterList = tf.parameterList.syntaxCopy;
+ tf.parameterList.parameters.remove(i);
+ break outer;
+ }
+ }
+ }
tf.fargs = fargs;
+ }
+ }
}
}
diff --git a/compiler/src/dmd/dtemplate.d b/compiler/src/dmd/dtemplate.d
index 13efc1cba3..25805bb0b6 100644
--- a/compiler/src/dmd/dtemplate.d
+++ b/compiler/src/dmd/dtemplate.d
@@ -1578,6 +1578,36 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
Parameter fparam = fparameters[parami];
+ if (auto ident = fparam.isPlainIdentifier)
+ {
+ bool tvpmatch = false;
+ for (size_t i = ntargs; i < dedargs.dim; i++)
+ {
+ TemplateParameter tparam = (*parameters)[i];
+ if (tparam.ident != ident)
+ continue;
+ TemplateValueParameter tvp = tparam.isTemplateValueParameter();
+ if (!tvp)
+ return nomatch();
+ Expression e = (*fargs)[parami];
+ if (!e)
+ return nomatch();
+ Type vt = tvp.valType.typeSemantic(Loc.initial, sc);
+ MATCH m = e.implicitConvTo(vt);
+ if (m == MATCH.nomatch)
+ return nomatch();
+ (*dedargs)[i] = e;
+ ++argi;
+ tvpmatch = true;
+ auto newTf = fd.type.isTypeFunction().syntaxCopy();
+ newTf.parameterList.parameters.remove(parami);
+ fargs.remove(parami);
+ fd = new FuncDeclaration(fd.loc, fd.endloc, fd.ident, fd.storage_class, newTf);
+ break;
+ }
+ if (!tvpmatch) return nomatch();
+ continue;
+ }
// Apply function parameter storage classes to parameter types
Type prmtype = fparam.type.addStorageClass(fparam.storageClass);
@@ -3088,6 +3118,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
auto ti = new TemplateInstance(loc, td_best, ti_best.tiargs);
ti.templateInstanceSemantic(sc, fargs);
+ fargs_ = fargs.peekSlice();
m.lastf = ti.toAlias().isFuncDeclaration();
if (!m.lastf)
diff --git a/compiler/src/dmd/mtype.d b/compiler/src/dmd/mtype.d
index 1240f5a8a9..858a4c9112 100644
--- a/compiler/src/dmd/mtype.d
+++ b/compiler/src/dmd/mtype.d
@@ -6574,6 +6574,18 @@ extern (C++) final class Parameter : ASTNode
return (this.storageClass & (STC.ref_ | STC.out_)) != 0;
}
+ const(Identifier) isPlainIdentifier() const @safe pure nothrow @nogc
+ {
+ if (!this.ident && !this.defaultArg && this.type)
+ {
+ if (auto ident = this.type.isTypeIdentifier)
+ {
+ return ident.ident;
+ }
+ }
+ return null;
+ }
+
// kludge for template.isType()
override DYNCAST dyncast() const
{
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment