bitint: Fix up lowering of COMPLEX_EXPR [PR115544]
[official-gcc.git] / gcc / d / dmd / templatesem.d
blobbd3cd89588f7b902872bdf91fb95459ad41e0b7b
1 /**
2 * Template semantics.
4 * Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
5 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
6 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/templatesem.d, _templatesem.d)
8 * Documentation: https://dlang.org/phobos/dmd_templatesem.html
9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/templatesem.d
12 module dmd.templatesem;
14 import core.stdc.stdio;
15 import core.stdc.string;
16 import dmd.aggregate;
17 import dmd.aliasthis;
18 import dmd.arraytypes;
19 import dmd.astenums;
20 import dmd.ast_node;
21 import dmd.attrib;
22 import dmd.dcast;
23 import dmd.dclass;
24 import dmd.declaration;
25 import dmd.dinterpret;
26 import dmd.dmangle;
27 import dmd.dmodule;
28 import dmd.dscope;
29 import dmd.dsymbol;
30 import dmd.dsymbolsem;
31 import dmd.dtemplate;
32 import dmd.errors;
33 import dmd.errorsink;
34 import dmd.expression;
35 import dmd.expressionsem;
36 import dmd.func;
37 import dmd.funcsem;
38 import dmd.globals;
39 import dmd.hdrgen;
40 import dmd.id;
41 import dmd.identifier;
42 import dmd.impcnvtab;
43 import dmd.init;
44 import dmd.initsem;
45 import dmd.location;
46 import dmd.mtype;
47 import dmd.opover;
48 import dmd.optimize;
49 import dmd.root.array;
50 import dmd.common.outbuffer;
51 import dmd.rootobject;
52 import dmd.semantic2;
53 import dmd.semantic3;
54 import dmd.templateparamsem;
55 import dmd.tokens;
56 import dmd.typesem;
57 import dmd.visitor;
59 /************************************
60 * Perform semantic analysis on template.
61 * Params:
62 * sc = context
63 * tempdecl = template declaration
65 void templateDeclarationSemantic(Scope* sc, TemplateDeclaration tempdecl)
67 enum log = false;
68 static if (log)
70 printf("TemplateDeclaration.dsymbolSemantic(this = %p, id = '%s')\n", this, tempdecl.ident.toChars());
71 printf("sc.stc = %llx\n", sc.stc);
72 printf("sc.module = %s\n", sc._module.toChars());
74 if (tempdecl.semanticRun != PASS.initial)
75 return; // semantic() already run
77 if (tempdecl._scope)
79 sc = tempdecl._scope;
80 tempdecl._scope = null;
82 if (!sc)
83 return;
85 // Remember templates defined in module object that we need to know about
86 if (sc._module && sc._module.ident == Id.object)
88 if (tempdecl.ident == Id.RTInfo)
89 Type.rtinfo = tempdecl;
92 /* Remember Scope for later instantiations, but make
93 * a copy since attributes can change.
95 if (!tempdecl._scope)
97 tempdecl._scope = sc.copy();
98 tempdecl._scope.setNoFree();
101 tempdecl.semanticRun = PASS.semantic;
103 tempdecl.parent = sc.parent;
104 tempdecl.visibility = sc.visibility;
105 tempdecl.userAttribDecl = sc.userAttribDecl;
106 tempdecl.cppnamespace = sc.namespace;
107 tempdecl.isstatic = tempdecl.toParent().isModule() || (tempdecl._scope.stc & STC.static_);
108 tempdecl.deprecated_ = !!(sc.stc & STC.deprecated_);
110 UserAttributeDeclaration.checkGNUABITag(tempdecl, sc.linkage);
112 if (!tempdecl.isstatic)
114 if (auto ad = tempdecl.parent.pastMixin().isAggregateDeclaration())
115 ad.makeNested();
118 // Set up scope for parameters
119 auto paramsym = new ScopeDsymbol();
120 paramsym.parent = tempdecl.parent;
121 Scope* paramscope = sc.push(paramsym);
122 paramscope.stc = 0;
124 if (global.params.ddoc.doOutput)
126 tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.length);
127 for (size_t i = 0; i < tempdecl.parameters.length; i++)
129 TemplateParameter tp = (*tempdecl.parameters)[i];
130 (*tempdecl.origParameters)[i] = tp.syntaxCopy();
134 for (size_t i = 0; i < tempdecl.parameters.length; i++)
136 TemplateParameter tp = (*tempdecl.parameters)[i];
137 if (!tp.declareParameter(paramscope))
139 error(tp.loc, "parameter `%s` multiply defined", tp.ident.toChars());
140 tempdecl.errors = true;
142 if (!tp.tpsemantic(paramscope, tempdecl.parameters))
144 tempdecl.errors = true;
146 if (i + 1 != tempdecl.parameters.length && tp.isTemplateTupleParameter())
148 .error(tempdecl.loc, "%s `%s` template sequence parameter must be the last one", tempdecl.kind, tempdecl.toPrettyChars);
149 tempdecl.errors = true;
153 /* Calculate TemplateParameter.dependent
155 TemplateParameters tparams = TemplateParameters(1);
156 for (size_t i = 0; i < tempdecl.parameters.length; i++)
158 TemplateParameter tp = (*tempdecl.parameters)[i];
159 tparams[0] = tp;
161 for (size_t j = 0; j < tempdecl.parameters.length; j++)
163 // Skip cases like: X(T : T)
164 if (i == j)
165 continue;
167 if (TemplateTypeParameter ttp = (*tempdecl.parameters)[j].isTemplateTypeParameter())
169 if (reliesOnTident(ttp.specType, &tparams))
170 tp.dependent = true;
172 else if (TemplateAliasParameter tap = (*tempdecl.parameters)[j].isTemplateAliasParameter())
174 if (reliesOnTident(tap.specType, &tparams) ||
175 reliesOnTident(isType(tap.specAlias), &tparams))
177 tp.dependent = true;
183 paramscope.pop();
185 // Compute again
186 tempdecl.onemember = null;
187 if (tempdecl.members)
189 Dsymbol s;
190 if (Dsymbol.oneMembers(tempdecl.members, s, tempdecl.ident) && s)
192 tempdecl.onemember = s;
193 s.parent = tempdecl;
197 /* BUG: should check:
198 * 1. template functions must not introduce virtual functions, as they
199 * cannot be accomodated in the vtbl[]
200 * 2. templates cannot introduce non-static data members (i.e. fields)
201 * as they would change the instance size of the aggregate.
204 tempdecl.semanticRun = PASS.semanticdone;
208 /***************************************
209 * Given that ti is an instance of this TemplateDeclaration,
210 * deduce the types of the parameters to this, and store
211 * those deduced types in dedtypes[].
212 * Params:
213 * sc = context
214 * td = template
215 * ti = instance of td
216 * dedtypes = fill in with deduced types
217 * argumentList = arguments to template instance
218 * flag = 1 - don't do semantic() because of dummy types
219 * 2 - don't change types in matchArg()
220 * Returns: match level.
222 public
223 MATCH matchWithInstance(Scope* sc, TemplateDeclaration td, TemplateInstance ti, ref Objects dedtypes, ArgumentList argumentList, int flag)
225 enum LOGM = 0;
226 static if (LOGM)
228 printf("\n+TemplateDeclaration.matchWithInstance(td = %s, ti = %s, flag = %d)\n", td.toChars(), ti.toChars(), flag);
230 version (none)
232 printf("dedtypes.length = %d, parameters.length = %d\n", dedtypes.length, parameters.length);
233 if (ti.tiargs.length)
234 printf("ti.tiargs.length = %d, [0] = %p\n", ti.tiargs.length, (*ti.tiargs)[0]);
236 MATCH nomatch()
238 static if (LOGM)
240 printf(" no match\n");
242 return MATCH.nomatch;
244 MATCH m;
245 size_t dedtypes_dim = dedtypes.length;
247 dedtypes.zero();
249 if (td.errors)
250 return MATCH.nomatch;
252 size_t parameters_dim = td.parameters.length;
253 const bool variadic = td.isVariadic() !is null;
255 // If more arguments than parameters, no match
256 if (ti.tiargs.length > parameters_dim && !variadic)
258 static if (LOGM)
260 printf(" no match: more arguments than parameters\n");
262 return MATCH.nomatch;
265 assert(dedtypes_dim == parameters_dim);
266 assert(dedtypes_dim >= ti.tiargs.length || variadic);
268 assert(td._scope);
270 // Set up scope for template parameters
271 Scope* paramscope = createScopeForTemplateParameters(td, ti, sc);
273 // Attempt type deduction
274 m = MATCH.exact;
275 for (size_t i = 0; i < dedtypes_dim; i++)
277 MATCH m2;
278 TemplateParameter tp = (*td.parameters)[i];
279 Declaration sparam;
281 //printf("\targument [%d]\n", i);
282 static if (LOGM)
284 //printf("\targument [%d] is %s\n", i, oarg ? oarg.toChars() : "null");
285 TemplateTypeParameter ttp = tp.isTemplateTypeParameter();
286 if (ttp)
287 printf("\tparameter[%d] is %s : %s\n", i, tp.ident.toChars(), ttp.specType ? ttp.specType.toChars() : "");
290 m2 = tp.matchArg(ti.loc, paramscope, ti.tiargs, i, td.parameters, dedtypes, &sparam);
291 //printf("\tm2 = %d\n", m2);
292 if (m2 == MATCH.nomatch)
294 version (none)
296 printf("\tmatchArg() for parameter %i failed\n", i);
298 return nomatch();
301 if (m2 < m)
302 m = m2;
304 if (!flag)
305 sparam.dsymbolSemantic(paramscope);
306 if (!paramscope.insert(sparam)) // TODO: This check can make more early
308 // in TemplateDeclaration.semantic, and
309 // then we don't need to make sparam if flags == 0
310 return nomatch();
314 if (!flag)
316 /* Any parameter left without a type gets the type of
317 * its corresponding arg
319 foreach (i, ref dedtype; dedtypes)
321 if (!dedtype)
323 assert(i < ti.tiargs.length);
324 dedtype = cast(Type)(*ti.tiargs)[i];
329 if (m > MATCH.nomatch && td.constraint && !flag)
331 if (ti.hasNestedArgs(ti.tiargs, td.isstatic)) // TODO: should gag error
332 ti.parent = ti.enclosing;
333 else
334 ti.parent = td.parent;
336 // Similar to doHeaderInstantiation
337 FuncDeclaration fd = td.onemember ? td.onemember.isFuncDeclaration() : null;
338 if (fd)
340 TypeFunction tf = fd.type.isTypeFunction().syntaxCopy();
342 fd = new FuncDeclaration(fd.loc, fd.endloc, fd.ident, fd.storage_class, tf);
343 fd.parent = ti;
344 fd.inferRetType = true;
346 // Shouldn't run semantic on default arguments and return type.
347 foreach (ref param; *tf.parameterList.parameters)
348 param.defaultArg = null;
350 tf.next = null;
351 tf.incomplete = true;
353 // Resolve parameter types and 'auto ref's.
354 tf.inferenceArguments = argumentList;
355 uint olderrors = global.startGagging();
356 fd.type = tf.typeSemantic(td.loc, paramscope);
357 global.endGagging(olderrors);
358 if (fd.type.ty != Tfunction)
359 return nomatch();
360 fd.originalType = fd.type; // for mangling
363 // TODO: dedtypes => ti.tiargs ?
364 if (!evaluateConstraint(td, ti, sc, paramscope, &dedtypes, fd))
365 return nomatch();
368 static if (LOGM)
370 // Print out the results
371 printf("--------------------------\n");
372 printf("template %s\n", toChars());
373 printf("instance %s\n", ti.toChars());
374 if (m > MATCH.nomatch)
376 for (size_t i = 0; i < dedtypes_dim; i++)
378 TemplateParameter tp = (*parameters)[i];
379 RootObject oarg;
380 printf(" [%d]", i);
381 if (i < ti.tiargs.length)
382 oarg = (*ti.tiargs)[i];
383 else
384 oarg = null;
385 tp.print(oarg, (*dedtypes)[i]);
388 else
389 return nomatch();
391 static if (LOGM)
393 printf(" match = %d\n", m);
396 paramscope.pop();
397 static if (LOGM)
399 printf("-TemplateDeclaration.matchWithInstance(td = %s, ti = %s) = %d\n", td.toChars(), ti.toChars(), m);
401 return m;
404 /****************************
405 * Check to see if constraint is satisfied.
407 bool evaluateConstraint(TemplateDeclaration td, TemplateInstance ti, Scope* sc, Scope* paramscope, Objects* dedargs, FuncDeclaration fd)
409 /* Detect recursive attempts to instantiate this template declaration,
410 * https://issues.dlang.org/show_bug.cgi?id=4072
411 * void foo(T)(T x) if (is(typeof(foo(x)))) { }
412 * static assert(!is(typeof(foo(7))));
413 * Recursive attempts are regarded as a constraint failure.
415 /* There's a chicken-and-egg problem here. We don't know yet if this template
416 * instantiation will be a local one (enclosing is set), and we won't know until
417 * after selecting the correct template. Thus, function we're nesting inside
418 * is not on the sc scope chain, and this can cause errors in FuncDeclaration.getLevel().
419 * Workaround the problem by setting a flag to relax the checking on frame errors.
422 for (TemplatePrevious* p = td.previous; p; p = p.prev)
424 if (!arrayObjectMatch(*p.dedargs, *dedargs))
425 continue;
426 //printf("recursive, no match p.sc=%p %p %s\n", p.sc, this, this.toChars());
427 /* It must be a subscope of p.sc, other scope chains are not recursive
428 * instantiations.
429 * the chain of enclosing scopes is broken by paramscope (its enclosing
430 * scope is _scope, but paramscope.callsc is the instantiating scope). So
431 * it's good enough to check the chain of callsc
433 for (Scope* scx = paramscope.callsc; scx; scx = scx.callsc)
435 // The first scx might be identical for nested eponymeous templates, e.g.
436 // template foo() { void foo()() {...} }
437 if (scx == p.sc && scx !is paramscope.callsc)
438 return false;
440 /* BUG: should also check for ref param differences
444 TemplatePrevious pr;
445 pr.prev = td.previous;
446 pr.sc = paramscope.callsc;
447 pr.dedargs = dedargs;
448 td.previous = &pr; // add this to threaded list
450 Scope* scx = paramscope.push(ti);
451 scx.parent = ti;
452 scx.tinst = null;
453 scx.minst = null;
454 // Set SCOPE.constraint before declaring function parameters for the static condition
455 // (previously, this was immediately before calling evalStaticCondition), so the
456 // semantic pass knows not to issue deprecation warnings for these throw-away decls.
457 // https://issues.dlang.org/show_bug.cgi?id=21831
458 scx.flags |= SCOPE.constraint;
460 assert(!ti.symtab);
461 if (fd)
463 /* Declare all the function parameters as variables and add them to the scope
464 * Making parameters is similar to FuncDeclaration.semantic3
466 auto tf = fd.type.isTypeFunction();
468 scx.parent = fd;
470 Parameters* fparameters = tf.parameterList.parameters;
471 const nfparams = tf.parameterList.length;
472 foreach (i, fparam; tf.parameterList)
474 fparam.storageClass &= (STC.IOR | STC.lazy_ | STC.final_ | STC.TYPECTOR | STC.nodtor);
475 fparam.storageClass |= STC.parameter;
476 if (tf.parameterList.varargs == VarArg.typesafe && i + 1 == nfparams)
478 fparam.storageClass |= STC.variadic;
479 /* Don't need to set STC.scope_ because this will only
480 * be evaluated at compile time
484 foreach (fparam; *fparameters)
486 if (!fparam.ident)
487 continue;
488 // don't add it, if it has no name
489 auto v = new VarDeclaration(fparam.loc, fparam.type, fparam.ident, null);
490 fparam.storageClass |= STC.parameter;
491 v.storage_class = fparam.storageClass;
492 v.dsymbolSemantic(scx);
493 if (!ti.symtab)
494 ti.symtab = new DsymbolTable();
495 if (!scx.insert(v))
496 .error(td.loc, "%s `%s` parameter `%s.%s` is already defined", td.kind, td.toPrettyChars, td.toChars(), v.toChars());
497 else
498 v.parent = fd;
500 if (td.isstatic)
501 fd.storage_class |= STC.static_;
502 declareThis(fd, scx);
505 td.lastConstraint = td.constraint.syntaxCopy();
506 td.lastConstraintTiargs = ti.tiargs;
507 td.lastConstraintNegs.setDim(0);
509 import dmd.staticcond;
511 assert(ti.inst is null);
512 ti.inst = ti; // temporary instantiation to enable genIdent()
513 bool errors;
514 const bool result = evalStaticCondition(scx, td.constraint, td.lastConstraint, errors, &td.lastConstraintNegs);
515 if (result || errors)
517 td.lastConstraint = null;
518 td.lastConstraintTiargs = null;
519 td.lastConstraintNegs.setDim(0);
521 ti.inst = null;
522 ti.symtab = null;
523 scx = scx.pop();
524 td.previous = pr.prev; // unlink from threaded list
525 if (errors)
526 return false;
527 return result;
530 /*******************************************
531 * Append to buf a textual representation of template parameters with their arguments.
532 * Params:
533 * parameters = the template parameters
534 * tiargs = the correspondeing template arguments
535 * variadic = if it's a variadic argument list
536 * buf = where the text output goes
538 void formatParamsWithTiargs(ref TemplateParameters parameters, ref Objects tiargs, bool variadic, ref OutBuffer buf)
540 buf.writestring(" with `");
542 // write usual arguments line-by-line
543 // skips trailing default ones - they are not present in `tiargs`
544 const end = parameters.length - (variadic ? 1 : 0);
545 size_t i;
546 for (; i < tiargs.length && i < end; i++)
548 if (i)
550 buf.writeByte(',');
551 buf.writenl();
552 buf.writestring(" ");
554 write(buf, parameters[i]);
555 buf.writestring(" = ");
556 write(buf, tiargs[i]);
558 // write remaining variadic arguments on the last line
559 if (variadic)
561 if (i)
563 buf.writeByte(',');
564 buf.writenl();
565 buf.writestring(" ");
567 write(buf, parameters[end]);
568 buf.writestring(" = ");
569 buf.writeByte('(');
570 if (end < tiargs.length)
572 write(buf, tiargs[end]);
573 foreach (j; parameters.length .. tiargs.length)
575 buf.writestring(", ");
576 write(buf, tiargs[j]);
579 buf.writeByte(')');
581 buf.writeByte('`');
584 /******************************
585 * Create a scope for the parameters of the TemplateInstance
586 * `ti` in the parent scope sc from the ScopeDsymbol paramsym.
588 * If paramsym is null a new ScopeDsymbol is used in place of
589 * paramsym.
590 * Params:
591 * td = template that ti is an instance of
592 * ti = the TemplateInstance whose parameters to generate the scope for.
593 * sc = the parent scope of ti
594 * Returns:
595 * new scope for the parameters of ti
597 Scope* createScopeForTemplateParameters(TemplateDeclaration td, TemplateInstance ti, Scope* sc)
599 ScopeDsymbol paramsym = new ScopeDsymbol();
600 paramsym.parent = td._scope.parent;
601 Scope* paramscope = td._scope.push(paramsym);
602 paramscope.tinst = ti;
603 paramscope.minst = sc.minst;
604 paramscope.callsc = sc;
605 paramscope.stc = 0;
606 return paramscope;
609 /********************************************
610 * Determine partial specialization order of `td` vs `td2`.
611 * Params:
612 * sc = context
613 * td = first template
614 * td2 = second template
615 * argumentList = arguments to template
616 * Returns:
617 * MATCH - td is at least as specialized as td2
618 * MATCH.nomatch - td2 is more specialized than td
620 MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration td, TemplateDeclaration td2, ArgumentList argumentList)
622 enum LOG_LEASTAS = 0;
623 static if (LOG_LEASTAS)
625 printf("%s.leastAsSpecialized(%s)\n", toChars(), td2.toChars());
628 /* This works by taking the template parameters to this template
629 * declaration and feeding them to td2 as if it were a template
630 * instance.
631 * If it works, then this template is at least as specialized
632 * as td2.
635 // Set type arguments to dummy template instance to be types
636 // generated from the parameters to this template declaration
637 auto tiargs = new Objects();
638 tiargs.reserve(td.parameters.length);
639 foreach (tp; *td.parameters)
641 if (tp.dependent)
642 break;
643 RootObject p = tp.dummyArg();
644 if (!p) //TemplateTupleParameter
645 break;
647 tiargs.push(p);
649 scope TemplateInstance ti = new TemplateInstance(Loc.initial, td.ident, tiargs); // create dummy template instance
651 // Temporary Array to hold deduced types
652 Objects dedtypes = Objects(td2.parameters.length);
654 // Attempt a type deduction
655 MATCH m = matchWithInstance(sc, td2, ti, dedtypes, argumentList, 1);
656 if (m > MATCH.nomatch)
658 /* A non-variadic template is more specialized than a
659 * variadic one.
661 TemplateTupleParameter tp = td.isVariadic();
662 if (tp && !tp.dependent && !td2.isVariadic())
663 goto L1;
665 static if (LOG_LEASTAS)
667 printf(" matches %d, so is least as specialized\n", m);
669 return m;
672 static if (LOG_LEASTAS)
674 printf(" doesn't match, so is not as specialized\n");
676 return MATCH.nomatch;
679 /*************************************************
680 * Match function arguments against a specific template function.
682 * Params:
683 * td = template declaration for template instance
684 * ti = template instance. `ti.tdtypes` will be set to Expression/Type deduced template arguments
685 * sc = instantiation scope
686 * fd = Partially instantiated function declaration, which is set to an instantiated function declaration
687 * tthis = 'this' argument if !NULL
688 * argumentList = arguments to function
690 * Returns:
691 * match pair of initial and inferred template arguments
693 extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, TemplateInstance ti, Scope* sc, ref FuncDeclaration fd, Type tthis, ArgumentList argumentList)
695 version (none)
697 printf("\nTemplateDeclaration.deduceFunctionTemplateMatch() %s\n", td.toChars());
698 for (size_t i = 0; i < (fargs ? fargs.length : 0); i++)
700 Expression e = (*fargs)[i];
701 printf("\tfarg[%d] is %s, type is %s\n", cast(int) i, e.toChars(), e.type.toChars());
703 printf("fd = %s\n", fd.toChars());
704 printf("fd.type = %s\n", fd.type.toChars());
705 if (tthis)
706 printf("tthis = %s\n", tthis.toChars());
709 assert(td._scope);
711 auto dedargs = new Objects(td.parameters.length);
712 dedargs.zero();
714 Objects* dedtypes = &ti.tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
715 dedtypes.setDim(td.parameters.length);
716 dedtypes.zero();
718 if (td.errors || fd.errors)
719 return MATCHpair(MATCH.nomatch, MATCH.nomatch);
721 // Set up scope for parameters
722 Scope* paramscope = createScopeForTemplateParameters(td, ti,sc);
724 MATCHpair nomatch()
726 paramscope.pop();
727 //printf("\tnomatch\n");
728 return MATCHpair(MATCH.nomatch, MATCH.nomatch);
731 MATCHpair matcherror()
733 // todo: for the future improvement
734 paramscope.pop();
735 //printf("\terror\n");
736 return MATCHpair(MATCH.nomatch, MATCH.nomatch);
738 // Mark the parameter scope as deprecated if the templated
739 // function is deprecated (since paramscope.enclosing is the
740 // calling scope already)
741 paramscope.stc |= fd.storage_class & STC.deprecated_;
743 TemplateTupleParameter tp = td.isVariadic();
744 Tuple declaredTuple = null;
746 version (none)
748 for (size_t i = 0; i < dedargs.length; i++)
750 printf("\tdedarg[%d] = ", i);
751 RootObject oarg = (*dedargs)[i];
752 if (oarg)
753 printf("%s", oarg.toChars());
754 printf("\n");
758 size_t ntargs = 0; // array size of tiargs
759 size_t inferStart = 0; // index of first template parameter to infer from function argument
760 const Loc instLoc = ti.loc;
761 MATCH matchTiargs = MATCH.exact;
763 if (auto tiargs = ti.tiargs)
765 // Set initial template arguments
766 ntargs = tiargs.length;
767 size_t n = td.parameters.length;
768 if (tp)
769 n--;
770 if (ntargs > n)
772 if (!tp)
773 return nomatch();
775 /* The extra initial template arguments
776 * now form the tuple argument.
778 auto t = new Tuple(ntargs - n);
779 assert(td.parameters.length);
780 (*dedargs)[td.parameters.length - 1] = t;
782 for (size_t i = 0; i < t.objects.length; i++)
784 t.objects[i] = (*tiargs)[n + i];
786 td.declareParameter(paramscope, tp, t);
787 declaredTuple = t;
789 else
790 n = ntargs;
792 memcpy(dedargs.tdata(), tiargs.tdata(), n * (*dedargs.tdata()).sizeof);
794 for (size_t i = 0; i < n; i++)
796 assert(i < td.parameters.length);
797 Declaration sparam = null;
798 MATCH m = (*td.parameters)[i].matchArg(instLoc, paramscope, dedargs, i, td.parameters, *dedtypes, &sparam);
799 //printf("\tdeduceType m = %d\n", m);
800 if (m == MATCH.nomatch)
801 return nomatch();
802 if (m < matchTiargs)
803 matchTiargs = m;
805 sparam.dsymbolSemantic(paramscope);
806 if (!paramscope.insert(sparam))
807 return nomatch();
809 if (n < td.parameters.length && !declaredTuple)
811 inferStart = n;
813 else
814 inferStart = td.parameters.length;
815 //printf("tiargs matchTiargs = %d\n", matchTiargs);
817 version (none)
819 for (size_t i = 0; i < dedargs.length; i++)
821 printf("\tdedarg[%d] = ", i);
822 RootObject oarg = (*dedargs)[i];
823 if (oarg)
824 printf("%s", oarg.toChars());
825 printf("\n");
829 ParameterList fparameters = fd.getParameterList(); // function parameter list
830 const nfparams = fparameters.length; // number of function parameters
832 /* Check for match of function arguments with variadic template
833 * parameter, such as:
835 * void foo(T, A...)(T t, A a);
836 * void main() { foo(1,2,3); }
838 size_t fptupindex = IDX_NOTFOUND;
839 if (tp) // if variadic
841 // TemplateTupleParameter always makes most lesser matching.
842 matchTiargs = MATCH.convert;
844 if (nfparams == 0 && argumentList.length != 0) // if no function parameters
846 if (!declaredTuple)
848 auto t = new Tuple();
849 //printf("t = %p\n", t);
850 (*dedargs)[td.parameters.length - 1] = t;
851 td.declareParameter(paramscope, tp, t);
852 declaredTuple = t;
855 else
857 /* Figure out which of the function parameters matches
858 * the tuple template parameter. Do this by matching
859 * type identifiers.
860 * Set the index of this function parameter to fptupindex.
862 for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
864 auto fparam = (*fparameters.parameters)[fptupindex]; // fparameters[fptupindex] ?
865 if (fparam.type.ty != Tident)
866 continue;
867 TypeIdentifier tid = fparam.type.isTypeIdentifier();
868 if (!tp.ident.equals(tid.ident) || tid.idents.length)
869 continue;
871 if (fparameters.varargs != VarArg.none) // variadic function doesn't
872 return nomatch(); // go with variadic template
874 goto L1;
876 fptupindex = IDX_NOTFOUND;
881 MATCH match = MATCH.exact;
882 if (td.toParent().isModule())
883 tthis = null;
884 if (tthis)
886 bool hasttp = false;
888 // Match 'tthis' to any TemplateThisParameter's
889 foreach (param; *td.parameters)
891 if (auto ttp = param.isTemplateThisParameter())
893 hasttp = true;
895 Type t = new TypeIdentifier(Loc.initial, ttp.ident);
896 MATCH m = deduceType(tthis, paramscope, t, *td.parameters, *dedtypes);
897 if (m == MATCH.nomatch)
898 return nomatch();
899 if (m < match)
900 match = m; // pick worst match
904 // Match attributes of tthis against attributes of fd
905 if (fd.type && !fd.isCtorDeclaration() && !(td._scope.stc & STC.static_))
907 StorageClass stc = td._scope.stc | fd.storage_class2;
908 // Propagate parent storage class, https://issues.dlang.org/show_bug.cgi?id=5504
909 Dsymbol p = td.parent;
910 while (p.isTemplateDeclaration() || p.isTemplateInstance())
911 p = p.parent;
912 AggregateDeclaration ad = p.isAggregateDeclaration();
913 if (ad)
914 stc |= ad.storage_class;
916 ubyte mod = fd.type.mod;
917 if (stc & STC.immutable_)
918 mod = MODFlags.immutable_;
919 else
921 if (stc & (STC.shared_ | STC.synchronized_))
922 mod |= MODFlags.shared_;
923 if (stc & STC.const_)
924 mod |= MODFlags.const_;
925 if (stc & STC.wild)
926 mod |= MODFlags.wild;
929 ubyte thismod = tthis.mod;
930 if (hasttp)
931 mod = MODmerge(thismod, mod);
932 MATCH m = MODmethodConv(thismod, mod);
933 if (m == MATCH.nomatch)
934 return nomatch();
935 if (m < match)
936 match = m;
940 // Loop through the function parameters
942 //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple.objects.length : 0);
943 //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple.toChars() : NULL);
944 enum DEFAULT_ARGI = size_t.max - 10; // pseudo index signifying the parameter is expected to be assigned its default argument
945 size_t argi = 0; // current argument index
946 size_t argsConsumed = 0; // to ensure no excess arguments
947 size_t nfargs2 = argumentList.length; // total number of arguments including applied defaultArgs
948 uint inoutMatch = 0; // for debugging only
949 Expression[] fargs = argumentList.arguments ? (*argumentList.arguments)[] : null;
950 Identifier[] fnames = argumentList.names ? (*argumentList.names)[] : null;
952 for (size_t parami = 0; parami < nfparams; parami++)
954 Parameter fparam = fparameters[parami];
956 // Apply function parameter storage classes to parameter types
957 Type prmtype = fparam.type.addStorageClass(fparam.storageClass);
959 Expression farg;
960 Identifier fname = argi < fnames.length ? fnames[argi] : null;
961 bool foundName = false;
962 if (fparam.ident)
964 foreach (i; 0 .. fnames.length)
966 if (fparam.ident == fnames[i])
968 argi = i;
969 foundName = true;
973 if (fname && !foundName)
975 argi = DEFAULT_ARGI;
978 /* See function parameters which wound up
979 * as part of a template tuple parameter.
981 if (fptupindex != IDX_NOTFOUND && parami == fptupindex && argi != DEFAULT_ARGI)
983 TypeIdentifier tid = prmtype.isTypeIdentifier();
984 assert(tid);
985 if (!declaredTuple)
987 /* The types of the function arguments
988 * now form the tuple argument.
990 declaredTuple = new Tuple();
991 (*dedargs)[td.parameters.length - 1] = declaredTuple;
993 /* Count function parameters with no defaults following a tuple parameter.
994 * void foo(U, T...)(int y, T, U, double, int bar = 0) {} // rem == 2 (U, double)
996 size_t rem = 0;
997 foreach (j; parami + 1 .. nfparams)
999 Parameter p = fparameters[j];
1000 if (p.defaultArg)
1002 break;
1004 foreach(name; fnames)
1006 if (p.ident == name)
1007 break;
1009 if (!reliesOnTemplateParameters(p.type, (*td.parameters)[inferStart .. td.parameters.length]))
1011 Type pt = p.type.syntaxCopy().typeSemantic(fd.loc, paramscope);
1012 if (auto ptt = pt.isTypeTuple())
1013 rem += ptt.arguments.length;
1014 else
1015 rem += 1;
1017 else
1019 ++rem;
1023 if (nfargs2 - argi < rem)
1024 return nomatch();
1025 declaredTuple.objects.setDim(nfargs2 - argi - rem);
1026 foreach (i; 0 .. declaredTuple.objects.length)
1028 farg = fargs[argi + i];
1030 // Check invalid arguments to detect errors early.
1031 if (farg.op == EXP.error || farg.type.ty == Terror)
1032 return nomatch();
1034 if (!fparam.isLazy() && farg.type.ty == Tvoid)
1035 return nomatch();
1037 Type tt;
1038 MATCH m;
1039 if (ubyte wm = deduceWildHelper(farg.type, &tt, tid))
1041 inoutMatch |= wm;
1042 m = MATCH.constant;
1044 else
1046 m = deduceTypeHelper(farg.type, tt, tid);
1048 if (m == MATCH.nomatch)
1049 return nomatch();
1050 if (m < match)
1051 match = m;
1053 /* Remove top const for dynamic array types and pointer types
1055 if ((tt.ty == Tarray || tt.ty == Tpointer) && !tt.isMutable() && (!(fparam.storageClass & STC.ref_) || (fparam.storageClass & STC.auto_) && !farg.isLvalue()))
1057 tt = tt.mutableOf();
1059 declaredTuple.objects[i] = tt;
1061 td.declareParameter(paramscope, tp, declaredTuple);
1063 else
1065 // https://issues.dlang.org/show_bug.cgi?id=6810
1066 // If declared tuple is not a type tuple,
1067 // it cannot be function parameter types.
1068 for (size_t i = 0; i < declaredTuple.objects.length; i++)
1070 if (!isType(declaredTuple.objects[i]))
1071 return nomatch();
1074 assert(declaredTuple);
1075 argi += declaredTuple.objects.length;
1076 argsConsumed += declaredTuple.objects.length;
1077 continue;
1080 // If parameter type doesn't depend on inferred template parameters,
1081 // semantic it to get actual type.
1082 if (!reliesOnTemplateParameters(prmtype, (*td.parameters)[inferStart .. td.parameters.length]))
1084 // should copy prmtype to avoid affecting semantic result
1085 prmtype = prmtype.syntaxCopy().typeSemantic(fd.loc, paramscope);
1087 if (TypeTuple tt = prmtype.isTypeTuple())
1089 const tt_dim = tt.arguments.length;
1090 for (size_t j = 0; j < tt_dim; j++, ++argi, ++argsConsumed)
1092 Parameter p = (*tt.arguments)[j];
1093 if (j == tt_dim - 1 && fparameters.varargs == VarArg.typesafe &&
1094 parami + 1 == nfparams && argi < fargs.length)
1096 prmtype = p.type;
1097 goto Lvarargs;
1099 if (argi >= fargs.length)
1101 if (p.defaultArg)
1102 continue;
1104 // https://issues.dlang.org/show_bug.cgi?id=19888
1105 if (fparam.defaultArg)
1106 break;
1108 return nomatch();
1110 farg = fargs[argi];
1111 if (!farg.implicitConvTo(p.type))
1112 return nomatch();
1114 continue;
1118 if (argi >= fargs.length) // if not enough arguments
1120 if (!fparam.defaultArg)
1121 goto Lvarargs;
1123 /* https://issues.dlang.org/show_bug.cgi?id=2803
1124 * Before the starting of type deduction from the function
1125 * default arguments, set the already deduced parameters into paramscope.
1126 * It's necessary to avoid breaking existing acceptable code. Cases:
1128 * 1. Already deduced template parameters can appear in fparam.defaultArg:
1129 * auto foo(A, B)(A a, B b = A.stringof);
1130 * foo(1);
1131 * // at fparam == 'B b = A.string', A is equivalent with the deduced type 'int'
1133 * 2. If prmtype depends on default-specified template parameter, the
1134 * default type should be preferred.
1135 * auto foo(N = size_t, R)(R r, N start = 0)
1136 * foo([1,2,3]);
1137 * // at fparam `N start = 0`, N should be 'size_t' before
1138 * // the deduction result from fparam.defaultArg.
1140 if (argi == fargs.length)
1142 foreach (ref dedtype; *dedtypes)
1144 Type at = isType(dedtype);
1145 if (at && at.ty == Tnone)
1147 TypeDeduced xt = cast(TypeDeduced)at;
1148 dedtype = xt.tded; // 'unbox'
1151 for (size_t i = ntargs; i < dedargs.length; i++)
1153 TemplateParameter tparam = (*td.parameters)[i];
1155 RootObject oarg = (*dedargs)[i];
1156 RootObject oded = (*dedtypes)[i];
1157 if (oarg)
1158 continue;
1160 if (oded)
1162 if (tparam.specialization() || !tparam.isTemplateTypeParameter())
1164 /* The specialization can work as long as afterwards
1165 * the oded == oarg
1167 (*dedargs)[i] = oded;
1168 MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, td.parameters, *dedtypes, null);
1169 //printf("m2 = %d\n", m2);
1170 if (m2 == MATCH.nomatch)
1171 return nomatch();
1172 if (m2 < matchTiargs)
1173 matchTiargs = m2; // pick worst match
1174 if (!(*dedtypes)[i].equals(oded))
1175 .error(td.loc, "%s `%s` specialization not allowed for deduced parameter `%s`",
1176 td.kind, td.toPrettyChars, td.kind, td.toPrettyChars, tparam.ident.toChars());
1178 else
1180 if (MATCH.convert < matchTiargs)
1181 matchTiargs = MATCH.convert;
1183 (*dedargs)[i] = td.declareParameter(paramscope, tparam, oded);
1185 else
1187 oded = tparam.defaultArg(instLoc, paramscope);
1188 if (oded)
1189 (*dedargs)[i] = td.declareParameter(paramscope, tparam, oded);
1194 if (argi != DEFAULT_ARGI)
1195 nfargs2 = argi + 1;
1197 /* If prmtype does not depend on any template parameters:
1199 * auto foo(T)(T v, double x = 0);
1200 * foo("str");
1201 * // at fparam == 'double x = 0'
1203 * or, if all template parameters in the prmtype are already deduced:
1205 * auto foo(R)(R range, ElementType!R sum = 0);
1206 * foo([1,2,3]);
1207 * // at fparam == 'ElementType!R sum = 0'
1209 * Deducing prmtype from fparam.defaultArg is not necessary.
1211 if (prmtype.deco || prmtype.syntaxCopy().trySemantic(td.loc, paramscope))
1213 if (argi != DEFAULT_ARGI)
1215 ++argi;
1216 ++argsConsumed;
1218 continue;
1221 // Deduce prmtype from the defaultArg.
1222 farg = fparam.defaultArg.syntaxCopy();
1223 farg = farg.expressionSemantic(paramscope);
1224 farg = resolveProperties(paramscope, farg);
1226 else
1228 farg = fargs[argi];
1231 assert(farg);
1232 // Check invalid arguments to detect errors early.
1233 if (farg.op == EXP.error || farg.type.ty == Terror)
1234 return nomatch();
1236 Type att = null;
1237 Lretry:
1238 version (none)
1240 printf("\tfarg.type = %s\n", farg.type.toChars());
1241 printf("\tfparam.type = %s\n", prmtype.toChars());
1243 Type argtype = farg.type;
1245 if (!fparam.isLazy() && argtype.ty == Tvoid && farg.op != EXP.function_)
1246 return nomatch();
1248 // https://issues.dlang.org/show_bug.cgi?id=12876
1249 // Optimize argument to allow CT-known length matching
1250 farg = farg.optimize(WANTvalue, fparam.isReference());
1251 //printf("farg = %s %s\n", farg.type.toChars(), farg.toChars());
1253 RootObject oarg = farg;
1254 if ((fparam.storageClass & STC.ref_) && (!(fparam.storageClass & STC.auto_) || farg.isLvalue()))
1256 /* Allow expressions that have CT-known boundaries and type [] to match with [dim]
1258 bool inferIndexType = (argtype.ty == Tarray) && (prmtype.ty == Tsarray || prmtype.ty == Taarray);
1259 if (auto aaType = prmtype.isTypeAArray())
1261 if (auto indexType = aaType.index.isTypeIdentifier())
1263 inferIndexType = indexType.idents.length == 0;
1266 if (inferIndexType)
1268 if (StringExp se = farg.isStringExp())
1270 argtype = se.type.nextOf().sarrayOf(se.len);
1272 else if (ArrayLiteralExp ae = farg.isArrayLiteralExp())
1274 argtype = ae.type.nextOf().sarrayOf(ae.elements.length);
1276 else if (SliceExp se = farg.isSliceExp())
1278 if (Type tsa = toStaticArrayType(se))
1279 argtype = tsa;
1283 oarg = argtype;
1285 else if ((fparam.storageClass & STC.out_) == 0 &&
1286 (argtype.ty == Tarray || argtype.ty == Tpointer) &&
1287 templateParameterLookup(prmtype, td.parameters) != IDX_NOTFOUND &&
1288 prmtype.isTypeIdentifier().idents.length == 0)
1290 /* The farg passing to the prmtype always make a copy. Therefore,
1291 * we can shrink the set of the deduced type arguments for prmtype
1292 * by adjusting top-qualifier of the argtype.
1294 * prmtype argtype ta
1295 * T <- const(E)[] const(E)[]
1296 * T <- const(E[]) const(E)[]
1297 * qualifier(T) <- const(E)[] const(E[])
1298 * qualifier(T) <- const(E[]) const(E[])
1300 Type ta = argtype.castMod(prmtype.mod ? argtype.nextOf().mod : 0);
1301 if (ta != argtype)
1303 Expression ea = farg.copy();
1304 ea.type = ta;
1305 oarg = ea;
1309 if (fparameters.varargs == VarArg.typesafe && parami + 1 == nfparams && argi + 1 < fargs.length)
1310 goto Lvarargs;
1312 uint im = 0;
1313 MATCH m = deduceType(oarg, paramscope, prmtype, *td.parameters, *dedtypes, &im, inferStart);
1314 //printf("\tL%d deduceType m = %d, im = x%x, inoutMatch = x%x\n", __LINE__, m, im, inoutMatch);
1315 inoutMatch |= im;
1317 /* If no match, see if the argument can be matched by using
1318 * implicit conversions.
1320 if (m == MATCH.nomatch && prmtype.deco)
1321 m = farg.implicitConvTo(prmtype);
1323 if (m == MATCH.nomatch)
1325 AggregateDeclaration ad = isAggregate(farg.type);
1326 if (ad && ad.aliasthis && !isRecursiveAliasThis(att, argtype))
1328 // https://issues.dlang.org/show_bug.cgi?id=12537
1329 // The isRecursiveAliasThis() call above
1331 /* If a semantic error occurs while doing alias this,
1332 * eg purity(https://issues.dlang.org/show_bug.cgi?id=7295),
1333 * just regard it as not a match.
1335 * We also save/restore sc.func.flags to avoid messing up
1336 * attribute inference in the evaluation.
1338 const oldflags = sc.func ? sc.func.flags : 0;
1339 auto e = resolveAliasThis(sc, farg, true);
1340 if (sc.func)
1341 sc.func.flags = oldflags;
1342 if (e)
1344 farg = e;
1345 goto Lretry;
1350 if (m > MATCH.nomatch && (fparam.storageClass & (STC.ref_ | STC.auto_)) == STC.ref_)
1352 if (!farg.isLvalue())
1354 if ((farg.op == EXP.string_ || farg.op == EXP.slice) && (prmtype.ty == Tsarray || prmtype.ty == Taarray))
1356 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
1358 else if (global.params.rvalueRefParam == FeatureState.enabled)
1360 // Allow implicit conversion to ref
1362 else
1363 return nomatch();
1366 if (m > MATCH.nomatch && (fparam.storageClass & STC.out_))
1368 if (!farg.isLvalue())
1369 return nomatch();
1370 if (!farg.type.isMutable()) // https://issues.dlang.org/show_bug.cgi?id=11916
1371 return nomatch();
1373 if (m == MATCH.nomatch && fparam.isLazy() && prmtype.ty == Tvoid && farg.type.ty != Tvoid)
1374 m = MATCH.convert;
1375 if (m != MATCH.nomatch)
1377 if (m < match)
1378 match = m; // pick worst match
1379 if (argi != DEFAULT_ARGI)
1381 argi++;
1382 argsConsumed++;
1384 continue;
1388 Lvarargs:
1389 /* The following code for variadic arguments closely
1390 * matches TypeFunction.callMatch()
1392 if (!(fparameters.varargs == VarArg.typesafe && parami + 1 == nfparams))
1393 return nomatch();
1395 /* Check for match with function parameter T...
1397 Type tb = prmtype.toBasetype();
1398 switch (tb.ty)
1400 // 6764 fix - TypeAArray may be TypeSArray have not yet run semantic().
1401 case Tsarray:
1402 case Taarray:
1404 // Perhaps we can do better with this, see TypeFunction.callMatch()
1405 if (TypeSArray tsa = tb.isTypeSArray())
1407 dinteger_t sz = tsa.dim.toInteger();
1408 if (sz != fargs.length - argi)
1409 return nomatch();
1411 else if (TypeAArray taa = tb.isTypeAArray())
1413 Expression dim = new IntegerExp(instLoc, fargs.length - argi, Type.tsize_t);
1415 size_t i = templateParameterLookup(taa.index, td.parameters);
1416 if (i == IDX_NOTFOUND)
1418 Expression e;
1419 Type t;
1420 Dsymbol s;
1421 Scope *sco;
1423 uint errors = global.startGagging();
1424 /* ref: https://issues.dlang.org/show_bug.cgi?id=11118
1425 * The parameter isn't part of the template
1426 * ones, let's try to find it in the
1427 * instantiation scope 'sc' and the one
1428 * belonging to the template itself. */
1429 sco = sc;
1430 taa.index.resolve(instLoc, sco, e, t, s);
1431 if (!e)
1433 sco = paramscope;
1434 taa.index.resolve(instLoc, sco, e, t, s);
1436 global.endGagging(errors);
1438 if (!e)
1439 return nomatch();
1441 e = e.ctfeInterpret();
1442 e = e.implicitCastTo(sco, Type.tsize_t);
1443 e = e.optimize(WANTvalue);
1444 if (!dim.equals(e))
1445 return nomatch();
1447 else
1449 // This code matches code in TypeInstance.deduceType()
1450 TemplateParameter tprm = (*td.parameters)[i];
1451 TemplateValueParameter tvp = tprm.isTemplateValueParameter();
1452 if (!tvp)
1453 return nomatch();
1454 Expression e = cast(Expression)(*dedtypes)[i];
1455 if (e)
1457 if (!dim.equals(e))
1458 return nomatch();
1460 else
1462 Type vt = tvp.valType.typeSemantic(Loc.initial, sc);
1463 MATCH m = dim.implicitConvTo(vt);
1464 if (m == MATCH.nomatch)
1465 return nomatch();
1466 (*dedtypes)[i] = dim;
1470 goto case Tarray;
1472 case Tarray:
1474 TypeArray ta = cast(TypeArray)tb;
1475 Type tret = fparam.isLazyArray();
1476 for (; argi < fargs.length; argi++)
1478 Expression arg = fargs[argi];
1479 assert(arg);
1481 MATCH m;
1482 /* If lazy array of delegates,
1483 * convert arg(s) to delegate(s)
1485 if (tret)
1487 if (ta.next.equals(arg.type))
1489 m = MATCH.exact;
1491 else
1493 m = arg.implicitConvTo(tret);
1494 if (m == MATCH.nomatch)
1496 if (tret.toBasetype().ty == Tvoid)
1497 m = MATCH.convert;
1501 else
1503 uint wm = 0;
1504 m = deduceType(arg, paramscope, ta.next, *td.parameters, *dedtypes, &wm, inferStart);
1505 inoutMatch |= wm;
1507 if (m == MATCH.nomatch)
1508 return nomatch();
1509 if (m < match)
1510 match = m;
1512 goto Lmatch;
1514 case Tclass:
1515 case Tident:
1516 goto Lmatch;
1518 default:
1519 return nomatch();
1521 assert(0);
1523 // printf(". argi = %d, nfargs = %d, nfargs2 = %d, argsConsumed = %d\n", cast(int) argi, cast(int) nfargs, cast(int) nfargs2, cast(int) argsConsumed);
1524 if (argsConsumed != nfargs2 && fparameters.varargs == VarArg.none)
1525 return nomatch();
1528 Lmatch:
1529 foreach (ref dedtype; *dedtypes)
1531 if (Type at = isType(dedtype))
1533 if (at.ty == Tnone)
1535 TypeDeduced xt = cast(TypeDeduced)at;
1536 at = xt.tded; // 'unbox'
1538 dedtype = at.merge2();
1541 for (size_t i = ntargs; i < dedargs.length; i++)
1543 TemplateParameter tparam = (*td.parameters)[i];
1544 //printf("tparam[%d] = %s\n", i, tparam.ident.toChars());
1546 /* For T:T*, the dedargs is the T*, dedtypes is the T
1547 * But for function templates, we really need them to match
1549 RootObject oarg = (*dedargs)[i];
1550 RootObject oded = (*dedtypes)[i];
1551 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
1552 //if (oarg) printf("oarg: %s\n", oarg.toChars());
1553 //if (oded) printf("oded: %s\n", oded.toChars());
1554 if (oarg)
1555 continue;
1557 if (oded)
1559 if (tparam.specialization() || !tparam.isTemplateTypeParameter())
1561 /* The specialization can work as long as afterwards
1562 * the oded == oarg
1564 (*dedargs)[i] = oded;
1565 MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, td.parameters, *dedtypes, null);
1566 //printf("m2 = %d\n", m2);
1567 if (m2 == MATCH.nomatch)
1568 return nomatch();
1569 if (m2 < matchTiargs)
1570 matchTiargs = m2; // pick worst match
1571 if (!(*dedtypes)[i].equals(oded))
1572 .error(td.loc, "%s `%s` specialization not allowed for deduced parameter `%s`", td.kind, td.toPrettyChars, tparam.ident.toChars());
1574 else
1576 // Discussion: https://issues.dlang.org/show_bug.cgi?id=16484
1577 if (MATCH.convert < matchTiargs)
1578 matchTiargs = MATCH.convert;
1581 else
1583 oded = tparam.defaultArg(instLoc, paramscope);
1584 if (!oded)
1586 // if tuple parameter and
1587 // tuple parameter was not in function parameter list and
1588 // we're one or more arguments short (i.e. no tuple argument)
1589 if (tparam == tp &&
1590 fptupindex == IDX_NOTFOUND &&
1591 ntargs <= dedargs.length - 1)
1593 // make tuple argument an empty tuple
1594 oded = new Tuple();
1596 else
1597 return nomatch();
1599 if (isError(oded))
1600 return matcherror();
1601 ntargs++;
1603 /* At the template parameter T, the picked default template argument
1604 * X!int should be matched to T in order to deduce dependent
1605 * template parameter A.
1606 * auto foo(T : X!A = X!int, A...)() { ... }
1607 * foo(); // T <-- X!int, A <-- (int)
1609 if (tparam.specialization())
1611 (*dedargs)[i] = oded;
1612 MATCH m2 = tparam.matchArg(instLoc, paramscope, dedargs, i, td.parameters, *dedtypes, null);
1613 //printf("m2 = %d\n", m2);
1614 if (m2 == MATCH.nomatch)
1615 return nomatch();
1616 if (m2 < matchTiargs)
1617 matchTiargs = m2; // pick worst match
1618 if (!(*dedtypes)[i].equals(oded))
1619 .error(td.loc, "%s `%s` specialization not allowed for deduced parameter `%s`", td.kind, td.toPrettyChars, tparam.ident.toChars());
1622 oded = td.declareParameter(paramscope, tparam, oded);
1623 (*dedargs)[i] = oded;
1626 /* https://issues.dlang.org/show_bug.cgi?id=7469
1627 * As same as the code for 7469 in findBestMatch,
1628 * expand a Tuple in dedargs to normalize template arguments.
1630 if (auto d = dedargs.length)
1632 if (auto va = isTuple((*dedargs)[d - 1]))
1634 dedargs.setDim(d - 1);
1635 dedargs.insert(d - 1, &va.objects);
1638 ti.tiargs = dedargs; // update to the normalized template arguments.
1640 // Partially instantiate function for constraint and fd.leastAsSpecialized()
1642 assert(paramscope.scopesym);
1643 Scope* sc2 = td._scope;
1644 sc2 = sc2.push(paramscope.scopesym);
1645 sc2 = sc2.push(ti);
1646 sc2.parent = ti;
1647 sc2.tinst = ti;
1648 sc2.minst = sc.minst;
1649 sc2.stc |= fd.storage_class & STC.deprecated_;
1651 fd = doHeaderInstantiation(td, ti, sc2, fd, tthis, argumentList);
1652 sc2 = sc2.pop();
1653 sc2 = sc2.pop();
1655 if (!fd)
1656 return nomatch();
1659 if (td.constraint)
1661 if (!evaluateConstraint(td, ti, sc, paramscope, dedargs, fd))
1662 return nomatch();
1665 version (none)
1667 for (size_t i = 0; i < dedargs.length; i++)
1669 RootObject o = (*dedargs)[i];
1670 printf("\tdedargs[%d] = %d, %s\n", i, o.dyncast(), o.toChars());
1674 paramscope.pop();
1675 //printf("\tmatch %d\n", match);
1676 return MATCHpair(matchTiargs, match);
1679 /*************************************************
1680 * Limited function template instantiation for using fd.leastAsSpecialized()
1682 private
1683 FuncDeclaration doHeaderInstantiation(TemplateDeclaration td, TemplateInstance ti, Scope* sc2, FuncDeclaration fd, Type tthis, ArgumentList inferenceArguments)
1685 assert(fd);
1686 version (none)
1688 printf("doHeaderInstantiation this = %s\n", toChars());
1691 // function body and contracts are not need
1692 if (fd.isCtorDeclaration())
1693 fd = new CtorDeclaration(fd.loc, fd.endloc, fd.storage_class, fd.type.syntaxCopy());
1694 else
1695 fd = new FuncDeclaration(fd.loc, fd.endloc, fd.ident, fd.storage_class, fd.type.syntaxCopy());
1696 fd.parent = ti;
1698 assert(fd.type.ty == Tfunction);
1699 auto tf = fd.type.isTypeFunction();
1700 tf.inferenceArguments = inferenceArguments;
1702 if (tthis)
1704 // Match 'tthis' to any TemplateThisParameter's
1705 bool hasttp = false;
1706 foreach (tp; *td.parameters)
1708 TemplateThisParameter ttp = tp.isTemplateThisParameter();
1709 if (ttp)
1710 hasttp = true;
1712 if (hasttp)
1714 tf = tf.addSTC(ModToStc(tthis.mod)).isTypeFunction();
1715 assert(!tf.deco);
1719 Scope* scx = sc2.push();
1721 // Shouldn't run semantic on default arguments and return type.
1722 foreach (ref params; *tf.parameterList.parameters)
1723 params.defaultArg = null;
1724 tf.incomplete = true;
1726 if (fd.isCtorDeclaration())
1728 // For constructors, emitting return type is necessary for
1729 // isReturnIsolated() in functionResolve.
1730 tf.isctor = true;
1732 Dsymbol parent = td.toParentDecl();
1733 Type tret;
1734 AggregateDeclaration ad = parent.isAggregateDeclaration();
1735 if (!ad || parent.isUnionDeclaration())
1737 tret = Type.tvoid;
1739 else
1741 tret = ad.handleType();
1742 assert(tret);
1743 tret = tret.addStorageClass(fd.storage_class | scx.stc);
1744 tret = tret.addMod(tf.mod);
1746 tf.next = tret;
1747 if (ad && ad.isStructDeclaration())
1748 tf.isref = 1;
1749 //printf("tf = %s\n", tf.toChars());
1751 else
1752 tf.next = null;
1753 fd.type = tf;
1754 fd.type = fd.type.addSTC(scx.stc);
1755 fd.type = fd.type.typeSemantic(fd.loc, scx);
1756 scx = scx.pop();
1758 if (fd.type.ty != Tfunction)
1759 return null;
1761 fd.originalType = fd.type; // for mangling
1762 //printf("\t[%s] fd.type = %s, mod = %x, ", loc.toChars(), fd.type.toChars(), fd.type.mod);
1763 //printf("fd.needThis() = %d\n", fd.needThis());
1765 return fd;
1768 /**************************************************
1769 * Declare template parameter tp with value o, and install it in the scope sc.
1771 extern (D) RootObject declareParameter(TemplateDeclaration td, Scope* sc, TemplateParameter tp, RootObject o)
1773 //printf("TemplateDeclaration.declareParameter('%s', o = %p)\n", tp.ident.toChars(), o);
1774 Type ta = isType(o);
1775 Expression ea = isExpression(o);
1776 Dsymbol sa = isDsymbol(o);
1777 Tuple va = isTuple(o);
1779 Declaration d;
1780 VarDeclaration v = null;
1782 if (ea)
1784 if (ea.op == EXP.type)
1785 ta = ea.type;
1786 else if (auto se = ea.isScopeExp())
1787 sa = se.sds;
1788 else if (auto te = ea.isThisExp())
1789 sa = te.var;
1790 else if (auto se = ea.isSuperExp())
1791 sa = se.var;
1792 else if (auto fe = ea.isFuncExp())
1794 if (fe.td)
1795 sa = fe.td;
1796 else
1797 sa = fe.fd;
1801 if (ta)
1803 //printf("type %s\n", ta.toChars());
1804 auto ad = new AliasDeclaration(Loc.initial, tp.ident, ta);
1805 ad.storage_class |= STC.templateparameter;
1806 d = ad;
1808 else if (sa)
1810 //printf("Alias %s %s;\n", sa.ident.toChars(), tp.ident.toChars());
1811 auto ad = new AliasDeclaration(Loc.initial, tp.ident, sa);
1812 ad.storage_class |= STC.templateparameter;
1813 d = ad;
1815 else if (ea)
1817 // tdtypes.data[i] always matches ea here
1818 Initializer _init = new ExpInitializer(td.loc, ea);
1819 TemplateValueParameter tvp = tp.isTemplateValueParameter();
1820 Type t = tvp ? tvp.valType : null;
1821 v = new VarDeclaration(td.loc, t, tp.ident, _init);
1822 v.storage_class = STC.manifest | STC.templateparameter;
1823 d = v;
1825 else if (va)
1827 //printf("\ttuple\n");
1828 d = new TupleDeclaration(td.loc, tp.ident, &va.objects);
1830 else
1832 assert(0);
1834 d.storage_class |= STC.templateparameter;
1836 if (ta)
1838 Type t = ta;
1839 // consistent with Type.checkDeprecated()
1840 while (t.ty != Tenum)
1842 if (!t.nextOf())
1843 break;
1844 t = (cast(TypeNext)t).next;
1846 if (Dsymbol s = t.toDsymbol(sc))
1848 if (s.isDeprecated())
1849 d.storage_class |= STC.deprecated_;
1852 else if (sa)
1854 if (sa.isDeprecated())
1855 d.storage_class |= STC.deprecated_;
1858 if (!sc.insert(d))
1859 .error(td.loc, "%s `%s` declaration `%s` is already defined", td.kind, td.toPrettyChars, tp.ident.toChars());
1860 d.dsymbolSemantic(sc);
1861 /* So the caller's o gets updated with the result of semantic() being run on o
1863 if (v)
1864 o = v._init.initializerToExpression();
1865 return o;
1868 /*************************************************
1869 * Given function arguments, figure out which template function
1870 * to expand, and return matching result.
1871 * Params:
1872 * m = matching result
1873 * dstart = the root of overloaded function templates
1874 * loc = instantiation location
1875 * sc = instantiation scope
1876 * tiargs = initial list of template arguments
1877 * tthis = if !NULL, the 'this' pointer argument
1878 * argumentList= arguments to function
1879 * errorHelper = delegate to send error message to if not null
1881 void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiargs,
1882 Type tthis, ArgumentList argumentList, void delegate(const(char)*) scope errorHelper = null)
1884 version (none)
1886 printf("functionResolve() dstart = %s\n", dstart.toChars());
1887 printf(" tiargs:\n");
1888 if (tiargs)
1890 for (size_t i = 0; i < tiargs.length; i++)
1892 RootObject arg = (*tiargs)[i];
1893 printf("\t%s\n", arg.toChars());
1896 printf(" fargs:\n");
1897 for (size_t i = 0; i < (fargs ? fargs.length : 0); i++)
1899 Expression arg = (*fargs)[i];
1900 printf("\t%s %s\n", arg.type.toChars(), arg.toChars());
1901 //printf("\tty = %d\n", arg.type.ty);
1903 //printf("stc = %llx\n", dstart._scope.stc);
1904 //printf("match:t/f = %d/%d\n", ta_last, m.last);
1907 // results
1908 int property = 0; // 0: uninitialized
1909 // 1: seen @property
1910 // 2: not @property
1911 size_t ov_index = 0;
1912 TemplateDeclaration td_best;
1913 TemplateInstance ti_best;
1914 MATCH ta_last = m.last != MATCH.nomatch ? MATCH.exact : MATCH.nomatch;
1915 Type tthis_best;
1917 int applyFunction(FuncDeclaration fd)
1919 // skip duplicates
1920 if (fd == m.lastf)
1921 return 0;
1922 // explicitly specified tiargs never match to non template function
1923 if (tiargs && tiargs.length > 0)
1924 return 0;
1926 // constructors need a valid scope in order to detect semantic errors
1927 if (!fd.isCtorDeclaration &&
1928 fd.semanticRun < PASS.semanticdone)
1930 fd.ungagSpeculative();
1931 fd.dsymbolSemantic(null);
1933 if (fd.semanticRun < PASS.semanticdone)
1935 .error(loc, "forward reference to template `%s`", fd.toChars());
1936 return 1;
1938 //printf("fd = %s %s, fargs = %s\n", fd.toChars(), fd.type.toChars(), fargs.toChars());
1939 auto tf = fd.type.isTypeFunction();
1941 int prop = tf.isproperty ? 1 : 2;
1942 if (property == 0)
1943 property = prop;
1944 else if (property != prop)
1945 error(fd.loc, "cannot overload both property and non-property functions");
1947 /* For constructors, qualifier check will be opposite direction.
1948 * Qualified constructor always makes qualified object, then will be checked
1949 * that it is implicitly convertible to tthis.
1951 Type tthis_fd = fd.needThis() ? tthis : null;
1952 bool isCtorCall = tthis_fd && fd.isCtorDeclaration();
1953 if (isCtorCall)
1955 //printf("%s tf.mod = x%x tthis_fd.mod = x%x %d\n", tf.toChars(),
1956 // tf.mod, tthis_fd.mod, fd.isReturnIsolated());
1957 if (MODimplicitConv(tf.mod, tthis_fd.mod) ||
1958 tf.isWild() && tf.isShared() == tthis_fd.isShared() ||
1959 fd.isReturnIsolated())
1961 /* && tf.isShared() == tthis_fd.isShared()*/
1962 // Uniquely constructed object can ignore shared qualifier.
1963 // TODO: Is this appropriate?
1964 tthis_fd = null;
1966 else
1967 return 0; // MATCH.nomatch
1969 /* Fix Issue 17970:
1970 If a struct is declared as shared the dtor is automatically
1971 considered to be shared, but when the struct is instantiated
1972 the instance is no longer considered to be shared when the
1973 function call matching is done. The fix makes it so that if a
1974 struct declaration is shared, when the destructor is called,
1975 the instantiated struct is also considered shared.
1977 if (auto dt = fd.isDtorDeclaration())
1979 auto dtmod = dt.type.toTypeFunction();
1980 auto shared_dtor = dtmod.mod & MODFlags.shared_;
1981 auto shared_this = tthis_fd !is null ?
1982 tthis_fd.mod & MODFlags.shared_ : 0;
1983 if (shared_dtor && !shared_this)
1984 tthis_fd = dtmod;
1985 else if (shared_this && !shared_dtor && tthis_fd !is null)
1986 tf.mod = tthis_fd.mod;
1988 const(char)* failMessage;
1989 MATCH mfa = tf.callMatch(tthis_fd, argumentList, 0, errorHelper, sc);
1990 //printf("test1: mfa = %d\n", mfa);
1991 if (failMessage)
1992 errorHelper(failMessage);
1993 if (mfa == MATCH.nomatch)
1994 return 0;
1996 int firstIsBetter()
1998 td_best = null;
1999 ti_best = null;
2000 ta_last = MATCH.exact;
2001 m.last = mfa;
2002 m.lastf = fd;
2003 tthis_best = tthis_fd;
2004 ov_index = 0;
2005 m.count = 1;
2006 return 0;
2009 if (mfa > m.last) return firstIsBetter();
2010 if (mfa < m.last) return 0;
2012 /* See if one of the matches overrides the other.
2014 assert(m.lastf);
2015 if (m.lastf.overrides(fd)) return 0;
2016 if (fd.overrides(m.lastf)) return firstIsBetter();
2018 /* Try to disambiguate using template-style partial ordering rules.
2019 * In essence, if f() and g() are ambiguous, if f() can call g(),
2020 * but g() cannot call f(), then pick f().
2021 * This is because f() is "more specialized."
2024 MATCH c1 = FuncDeclaration.leastAsSpecialized(fd, m.lastf, argumentList.names);
2025 MATCH c2 = FuncDeclaration.leastAsSpecialized(m.lastf, fd, argumentList.names);
2026 //printf("c1 = %d, c2 = %d\n", c1, c2);
2027 if (c1 > c2) return firstIsBetter();
2028 if (c1 < c2) return 0;
2031 /* The 'overrides' check above does covariant checking only
2032 * for virtual member functions. It should do it for all functions,
2033 * but in order to not risk breaking code we put it after
2034 * the 'leastAsSpecialized' check.
2035 * In the future try moving it before.
2036 * I.e. a not-the-same-but-covariant match is preferred,
2037 * as it is more restrictive.
2039 if (!m.lastf.type.equals(fd.type))
2041 //printf("cov: %d %d\n", m.lastf.type.covariant(fd.type), fd.type.covariant(m.lastf.type));
2042 const lastCovariant = m.lastf.type.covariant(fd.type);
2043 const firstCovariant = fd.type.covariant(m.lastf.type);
2045 if (lastCovariant == Covariant.yes || lastCovariant == Covariant.no)
2047 if (firstCovariant != Covariant.yes && firstCovariant != Covariant.no)
2049 return 0;
2052 else if (firstCovariant == Covariant.yes || firstCovariant == Covariant.no)
2054 return firstIsBetter();
2058 /* If the two functions are the same function, like:
2059 * int foo(int);
2060 * int foo(int x) { ... }
2061 * then pick the one with the body.
2063 * If none has a body then don't care because the same
2064 * real function would be linked to the decl (e.g from object file)
2066 if (tf.equals(m.lastf.type) &&
2067 fd.storage_class == m.lastf.storage_class &&
2068 fd.parent == m.lastf.parent &&
2069 fd.visibility == m.lastf.visibility &&
2070 fd._linkage == m.lastf._linkage)
2072 if (fd.fbody && !m.lastf.fbody)
2073 return firstIsBetter();
2074 if (!fd.fbody)
2075 return 0;
2078 // https://issues.dlang.org/show_bug.cgi?id=14450
2079 // Prefer exact qualified constructor for the creating object type
2080 if (isCtorCall && tf.mod != m.lastf.type.mod)
2082 if (tthis.mod == tf.mod) return firstIsBetter();
2083 if (tthis.mod == m.lastf.type.mod) return 0;
2086 m.nextf = fd;
2087 m.count++;
2088 return 0;
2091 int applyTemplate(TemplateDeclaration td)
2093 //printf("applyTemplate(): td = %s\n", td.toChars());
2094 if (td == td_best) // skip duplicates
2095 return 0;
2097 if (!sc)
2098 sc = td._scope; // workaround for Type.aliasthisOf
2100 if (td.semanticRun == PASS.initial && td._scope)
2102 // Try to fix forward reference. Ungag errors while doing so.
2103 td.ungagSpeculative();
2104 td.dsymbolSemantic(td._scope);
2106 if (td.semanticRun == PASS.initial)
2108 .error(loc, "forward reference to template `%s`", td.toChars());
2109 Lerror:
2110 m.lastf = null;
2111 m.count = 0;
2112 m.last = MATCH.nomatch;
2113 return 1;
2115 //printf("td = %s\n", td.toChars());
2117 auto f = td.onemember ? td.onemember.isFuncDeclaration() : null;
2118 if (!f)
2120 if (!tiargs)
2121 tiargs = new Objects();
2122 auto ti = new TemplateInstance(loc, td, tiargs);
2123 Objects dedtypes = Objects(td.parameters.length);
2124 assert(td.semanticRun != PASS.initial);
2125 MATCH mta = matchWithInstance(sc, td, ti, dedtypes, argumentList, 0);
2126 //printf("matchWithInstance = %d\n", mta);
2127 if (mta == MATCH.nomatch || mta < ta_last) // no match or less match
2128 return 0;
2130 ti.templateInstanceSemantic(sc, argumentList);
2131 if (!ti.inst) // if template failed to expand
2132 return 0;
2134 Dsymbol s = ti.inst.toAlias();
2135 FuncDeclaration fd;
2136 if (auto tdx = s.isTemplateDeclaration())
2138 Objects dedtypesX; // empty tiargs
2140 // https://issues.dlang.org/show_bug.cgi?id=11553
2141 // Check for recursive instantiation of tdx.
2142 for (TemplatePrevious* p = tdx.previous; p; p = p.prev)
2144 if (arrayObjectMatch(*p.dedargs, dedtypesX))
2146 //printf("recursive, no match p.sc=%p %p %s\n", p.sc, this, this.toChars());
2147 /* It must be a subscope of p.sc, other scope chains are not recursive
2148 * instantiations.
2150 for (Scope* scx = sc; scx; scx = scx.enclosing)
2152 if (scx == p.sc)
2154 error(loc, "recursive template expansion while looking for `%s.%s`", ti.toChars(), tdx.toChars());
2155 goto Lerror;
2159 /* BUG: should also check for ref param differences
2163 TemplatePrevious pr;
2164 pr.prev = tdx.previous;
2165 pr.sc = sc;
2166 pr.dedargs = &dedtypesX;
2167 tdx.previous = &pr; // add this to threaded list
2169 fd = resolveFuncCall(loc, sc, s, null, tthis, argumentList, FuncResolveFlag.quiet);
2171 tdx.previous = pr.prev; // unlink from threaded list
2173 else if (s.isFuncDeclaration())
2175 fd = resolveFuncCall(loc, sc, s, null, tthis, argumentList, FuncResolveFlag.quiet);
2177 else
2178 goto Lerror;
2180 if (!fd)
2181 return 0;
2183 if (fd.type.ty != Tfunction)
2185 m.lastf = fd; // to propagate "error match"
2186 m.count = 1;
2187 m.last = MATCH.nomatch;
2188 return 1;
2191 Type tthis_fd = fd.needThis() && !fd.isCtorDeclaration() ? tthis : null;
2193 auto tf = fd.type.isTypeFunction();
2194 MATCH mfa = tf.callMatch(tthis_fd, argumentList, 0, null, sc);
2195 if (mfa < m.last)
2196 return 0;
2198 if (mta < ta_last) goto Ltd_best2;
2199 if (mta > ta_last) goto Ltd2;
2201 if (mfa < m.last) goto Ltd_best2;
2202 if (mfa > m.last) goto Ltd2;
2204 // td_best and td are ambiguous
2205 //printf("Lambig2\n");
2206 m.nextf = fd;
2207 m.count++;
2208 return 0;
2210 Ltd_best2:
2211 return 0;
2213 Ltd2:
2214 // td is the new best match
2215 assert(td._scope);
2216 td_best = td;
2217 ti_best = null;
2218 property = 0; // (backward compatibility)
2219 ta_last = mta;
2220 m.last = mfa;
2221 m.lastf = fd;
2222 tthis_best = tthis_fd;
2223 ov_index = 0;
2224 m.nextf = null;
2225 m.count = 1;
2226 return 0;
2229 //printf("td = %s\n", td.toChars());
2230 for (size_t ovi = 0; f; f = f.overnext0, ovi++)
2232 if (f.type.ty != Tfunction || f.errors)
2233 goto Lerror;
2235 /* This is a 'dummy' instance to evaluate constraint properly.
2237 auto ti = new TemplateInstance(loc, td, tiargs);
2238 ti.parent = td.parent; // Maybe calculating valid 'enclosing' is unnecessary.
2240 auto fd = f;
2241 MATCHpair x = td.deduceFunctionTemplateMatch(ti, sc, fd, tthis, argumentList);
2242 MATCH mta = x.mta;
2243 MATCH mfa = x.mfa;
2244 //printf("match:t/f = %d/%d\n", mta, mfa);
2245 if (!fd || mfa == MATCH.nomatch)
2246 continue;
2248 Type tthis_fd = fd.needThis() ? tthis : null;
2250 bool isCtorCall = tthis_fd && fd.isCtorDeclaration();
2251 if (isCtorCall)
2253 // Constructor call requires additional check.
2254 auto tf = fd.type.isTypeFunction();
2255 assert(tf.next);
2256 if (MODimplicitConv(tf.mod, tthis_fd.mod) ||
2257 tf.isWild() && tf.isShared() == tthis_fd.isShared() ||
2258 fd.isReturnIsolated())
2260 tthis_fd = null;
2262 else
2263 continue; // MATCH.nomatch
2265 // need to check here whether the constructor is the member of a struct
2266 // declaration that defines a copy constructor. This is already checked
2267 // in the semantic of CtorDeclaration, however, when matching functions,
2268 // the template instance is not expanded.
2269 // https://issues.dlang.org/show_bug.cgi?id=21613
2270 auto ad = fd.isThis();
2271 auto sd = ad.isStructDeclaration();
2272 if (checkHasBothRvalueAndCpCtor(sd, fd.isCtorDeclaration(), ti))
2273 continue;
2276 if (mta < ta_last) goto Ltd_best;
2277 if (mta > ta_last) goto Ltd;
2279 if (mfa < m.last) goto Ltd_best;
2280 if (mfa > m.last) goto Ltd;
2282 if (td_best)
2284 // Disambiguate by picking the most specialized TemplateDeclaration
2285 MATCH c1 = leastAsSpecialized(sc, td, td_best, argumentList);
2286 MATCH c2 = leastAsSpecialized(sc, td_best, td, argumentList);
2287 //printf("1: c1 = %d, c2 = %d\n", c1, c2);
2288 if (c1 > c2) goto Ltd;
2289 if (c1 < c2) goto Ltd_best;
2291 assert(fd && m.lastf);
2293 // Disambiguate by tf.callMatch
2294 auto tf1 = fd.type.isTypeFunction();
2295 auto tf2 = m.lastf.type.isTypeFunction();
2296 MATCH c1 = tf1.callMatch(tthis_fd, argumentList, 0, null, sc);
2297 MATCH c2 = tf2.callMatch(tthis_best, argumentList, 0, null, sc);
2298 //printf("2: c1 = %d, c2 = %d\n", c1, c2);
2299 if (c1 > c2) goto Ltd;
2300 if (c1 < c2) goto Ltd_best;
2303 // Disambiguate by picking the most specialized FunctionDeclaration
2304 MATCH c1 = FuncDeclaration.leastAsSpecialized(fd, m.lastf, argumentList.names);
2305 MATCH c2 = FuncDeclaration.leastAsSpecialized(m.lastf, fd, argumentList.names);
2306 //printf("3: c1 = %d, c2 = %d\n", c1, c2);
2307 if (c1 > c2) goto Ltd;
2308 if (c1 < c2) goto Ltd_best;
2311 // https://issues.dlang.org/show_bug.cgi?id=14450
2312 // Prefer exact qualified constructor for the creating object type
2313 if (isCtorCall && fd.type.mod != m.lastf.type.mod)
2315 if (tthis.mod == fd.type.mod) goto Ltd;
2316 if (tthis.mod == m.lastf.type.mod) goto Ltd_best;
2319 m.nextf = fd;
2320 m.count++;
2321 continue;
2323 Ltd_best: // td_best is the best match so far
2324 //printf("Ltd_best\n");
2325 continue;
2327 Ltd: // td is the new best match
2328 //printf("Ltd\n");
2329 assert(td._scope);
2330 td_best = td;
2331 ti_best = ti;
2332 property = 0; // (backward compatibility)
2333 ta_last = mta;
2334 m.last = mfa;
2335 m.lastf = fd;
2336 tthis_best = tthis_fd;
2337 ov_index = ovi;
2338 m.nextf = null;
2339 m.count = 1;
2340 continue;
2342 return 0;
2345 auto td = dstart.isTemplateDeclaration();
2346 if (td && td.funcroot)
2347 dstart = td.funcroot;
2348 overloadApply(dstart, (Dsymbol s)
2350 if (s.errors)
2351 return 0;
2352 if (auto fd = s.isFuncDeclaration())
2353 return applyFunction(fd);
2354 if (auto td = s.isTemplateDeclaration())
2355 return applyTemplate(td);
2356 return 0;
2357 }, sc);
2359 //printf("td_best = %p, m.lastf = %p\n", td_best, m.lastf);
2360 if (td_best && ti_best && m.count == 1)
2362 // Matches to template function
2363 assert(td_best.onemember && td_best.onemember.isFuncDeclaration());
2364 /* The best match is td_best with arguments tdargs.
2365 * Now instantiate the template.
2367 assert(td_best._scope);
2368 if (!sc)
2369 sc = td_best._scope; // workaround for Type.aliasthisOf
2371 auto ti = new TemplateInstance(loc, td_best, ti_best.tiargs);
2372 ti.templateInstanceSemantic(sc, argumentList);
2374 m.lastf = ti.toAlias().isFuncDeclaration();
2375 if (!m.lastf)
2376 goto Lnomatch;
2377 if (ti.errors)
2379 Lerror:
2380 m.count = 1;
2381 assert(m.lastf);
2382 m.last = MATCH.nomatch;
2383 return;
2386 // look forward instantiated overload function
2387 // Dsymbol.oneMembers is alredy called in TemplateInstance.semantic.
2388 // it has filled overnext0d
2389 while (ov_index--)
2391 m.lastf = m.lastf.overnext0;
2392 assert(m.lastf);
2395 tthis_best = m.lastf.needThis() && !m.lastf.isCtorDeclaration() ? tthis : null;
2397 if (m.lastf.type.ty == Terror)
2398 goto Lerror;
2399 auto tf = m.lastf.type.isTypeFunction();
2400 if (!tf.callMatch(tthis_best, argumentList, 0, null, sc))
2401 goto Lnomatch;
2403 /* As https://issues.dlang.org/show_bug.cgi?id=3682 shows,
2404 * a template instance can be matched while instantiating
2405 * that same template. Thus, the function type can be incomplete. Complete it.
2407 * https://issues.dlang.org/show_bug.cgi?id=9208
2408 * For auto function, completion should be deferred to the end of
2409 * its semantic3. Should not complete it in here.
2411 if (tf.next && !m.lastf.inferRetType)
2413 m.lastf.type = tf.typeSemantic(loc, sc);
2416 else if (m.lastf)
2418 // Matches to non template function,
2419 // or found matches were ambiguous.
2420 assert(m.count >= 1);
2422 else
2424 Lnomatch:
2425 m.count = 0;
2426 m.lastf = null;
2427 m.last = MATCH.nomatch;