1
/**
2
 * Semantic analysis for D types.
3
 *
4
 * Copyright:   Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
5
 * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
6
 * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/typesem.d, _typesem.d)
8
 * Documentation:  https://dlang.org/phobos/dmd_typesem.html
9
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/typesem.d
10
 */
11

12
module dmd.typesem;
13

14
import core.checkedint;
15
import core.stdc.string;
16
import core.stdc.stdio;
17

18
import dmd.access;
19
import dmd.aggregate;
20
import dmd.aliasthis;
21
import dmd.arrayop;
22
import dmd.arraytypes;
23
import dmd.astcodegen;
24
import dmd.complex;
25
import dmd.dcast;
26
import dmd.dclass;
27
import dmd.declaration;
28
import dmd.denum;
29
import dmd.dimport;
30
import dmd.dmangle;
31
import dmd.dmodule : Module;
32
import dmd.dscope;
33
import dmd.dstruct;
34
import dmd.dsymbol;
35
import dmd.dsymbolsem;
36
import dmd.dtemplate;
37
import dmd.errors;
38
import dmd.expression;
39
import dmd.expressionsem;
40
import dmd.func;
41
import dmd.globals;
42
import dmd.hdrgen;
43
import dmd.id;
44
import dmd.identifier;
45
import dmd.imphint;
46
import dmd.init;
47
import dmd.initsem;
48
import dmd.visitor;
49
import dmd.mtype;
50
import dmd.objc;
51
import dmd.opover;
52
import dmd.parse;
53
import dmd.root.ctfloat;
54
import dmd.root.rmem;
55
import dmd.root.outbuffer;
56
import dmd.root.rootobject;
57
import dmd.root.string;
58
import dmd.root.stringtable;
59
import dmd.semantic3;
60
import dmd.sideeffect;
61
import dmd.target;
62
import dmd.tokens;
63
import dmd.typesem;
64

65
/**************************
66
 * This evaluates exp while setting length to be the number
67
 * of elements in the tuple t.
68
 */
69
private Expression semanticLength(Scope* sc, Type t, Expression exp)
70
{
71 1
    if (auto tt = t.isTypeTuple())
72
    {
73 1
        ScopeDsymbol sym = new ArrayScopeSymbol(sc, tt);
74 1
        sym.parent = sc.scopesym;
75 1
        sc = sc.push(sym);
76 1
        sc = sc.startCTFE();
77 1
        exp = exp.expressionSemantic(sc);
78 1
        sc = sc.endCTFE();
79 1
        sc.pop();
80
    }
81
    else
82
    {
83 1
        sc = sc.startCTFE();
84 1
        exp = exp.expressionSemantic(sc);
85 1
        sc = sc.endCTFE();
86
    }
87 1
    return exp;
88
}
89

90
private Expression semanticLength(Scope* sc, TupleDeclaration tup, Expression exp)
91
{
92 1
    ScopeDsymbol sym = new ArrayScopeSymbol(sc, tup);
93 1
    sym.parent = sc.scopesym;
94

95 1
    sc = sc.push(sym);
96 1
    sc = sc.startCTFE();
97 1
    exp = exp.expressionSemantic(sc);
98 1
    sc = sc.endCTFE();
99 1
    sc.pop();
100

101 1
    return exp;
102
}
103

104
/*************************************
105
 * Resolve a tuple index.
106
 */
107
private void resolveTupleIndex(const ref Loc loc, Scope* sc, Dsymbol s, Expression* pe, Type* pt, Dsymbol* ps, RootObject oindex)
108
{
109 1
    *pt = null;
110 1
    *ps = null;
111 1
    *pe = null;
112

113 1
    auto tup = s.isTupleDeclaration();
114

115 1
    auto eindex = isExpression(oindex);
116 1
    auto tindex = isType(oindex);
117 1
    auto sindex = isDsymbol(oindex);
118

119 1
    if (!tup)
120
    {
121
        // It's really an index expression
122 1
        if (tindex)
123 0
            eindex = new TypeExp(loc, tindex);
124 1
        else if (sindex)
125 0
            eindex = symbolToExp(sindex, loc, sc, false);
126 1
        Expression e = new IndexExp(loc, symbolToExp(s, loc, sc, false), eindex);
127 1
        e = e.expressionSemantic(sc);
128 1
        resolveExp(e, pt, pe, ps);
129 1
        return;
130
    }
131

132
    // Convert oindex to Expression, then try to resolve to constant.
133 1
    if (tindex)
134 1
        tindex.resolve(loc, sc, &eindex, &tindex, &sindex);
135 1
    if (sindex)
136 0
        eindex = symbolToExp(sindex, loc, sc, false);
137 1
    if (!eindex)
138
    {
139 0
        .error(loc, "index `%s` is not an expression", oindex.toChars());
140 0
        *pt = Type.terror;
141 0
        return;
142
    }
143

144 1
    eindex = semanticLength(sc, tup, eindex);
145 1
    eindex = eindex.ctfeInterpret();
146 1
    if (eindex.op == TOK.error)
147
    {
148 0
        *pt = Type.terror;
149 0
        return;
150
    }
151 1
    const(uinteger_t) d = eindex.toUInteger();
152 1
    if (d >= tup.objects.dim)
153
    {
154 0
        .error(loc, "tuple index `%llu` exceeds length %llu", d, cast(ulong) tup.objects.dim);
155 0
        *pt = Type.terror;
156 0
        return;
157
    }
158

159 1
    RootObject o = (*tup.objects)[cast(size_t)d];
160 1
    *pt = isType(o);
161 1
    *ps = isDsymbol(o);
162 1
    *pe = isExpression(o);
163 1
    if (*pt)
164 1
        *pt = (*pt).typeSemantic(loc, sc);
165 1
    if (*pe)
166 1
        resolveExp(*pe, pt, pe, ps);
167
}
168

169
/*************************************
170
 * Takes an array of Identifiers and figures out if
171
 * it represents a Type, Expression, or Dsymbol.
172
 * Params:
173
 *      mt = array of identifiers
174
 *      loc = location for error messages
175
 *      sc = context
176
 *      s = symbol to start search at
177
 *      scopesym = unused
178
 *      pe = set if expression
179
 *      pt = set if type
180
 *      ps = set if symbol
181
 *      typeid = set if in TypeidExpression https://dlang.org/spec/expression.html#TypeidExpression
182
 */
183
private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymbol s, Dsymbol scopesym,
184
    Expression* pe, Type* pt, Dsymbol* ps, bool intypeid = false)
185
{
186
    version (none)
187
    {
188
        printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, mt.toChars());
189
        if (scopesym)
190
            printf("\tscopesym = '%s'\n", scopesym.toChars());
191
    }
192 1
    *pe = null;
193 1
    *pt = null;
194 1
    *ps = null;
195

196 1
    if (!s)
197
    {
198
        /* Look for what user might have intended
199
         */
200 1
        const p = mt.mutableOf().unSharedOf().toChars();
201 1
        auto id = Identifier.idPool(p, cast(uint)strlen(p));
202 1
        if (const n = importHint(id.toString()))
203 1
            error(loc, "`%s` is not defined, perhaps `import %.*s;` ?", p, cast(int)n.length, n.ptr);
204 1
        else if (auto s2 = sc.search_correct(id))
205 1
            error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2.kind(), s2.toChars());
206 1
        else if (const q = Scope.search_correct_C(id))
207 1
            error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
208
        else
209 1
            error(loc, "undefined identifier `%s`", p);
210

211 1
        *pt = Type.terror;
212 1
        return;
213
    }
214

215
    //printf("\t1: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
216 1
    Declaration d = s.isDeclaration();
217 1
    if (d && (d.storage_class & STC.templateparameter))
218 1
        s = s.toAlias();
219
    else
220
    {
221
        // check for deprecated or disabled aliases
222 1
        s.checkDeprecated(loc, sc);
223 1
        if (d)
224 1
            d.checkDisabled(loc, sc, true);
225
    }
226 1
    s = s.toAlias();
227
    //printf("\t2: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
228 1
    for (size_t i = 0; i < mt.idents.dim; i++)
229
    {
230 1
        RootObject id = mt.idents[i];
231 1
        if (id.dyncast() == DYNCAST.expression ||
232 1
            id.dyncast() == DYNCAST.type)
233
        {
234 1
            Type tx;
235 1
            Expression ex;
236 1
            Dsymbol sx;
237 1
            resolveTupleIndex(loc, sc, s, &ex, &tx, &sx, id);
238 1
            if (sx)
239
            {
240 1
                s = sx.toAlias();
241 1
                continue;
242
            }
243 1
            if (tx)
244 1
                ex = new TypeExp(loc, tx);
245 1
            assert(ex);
246

247 1
            ex = typeToExpressionHelper(mt, ex, i + 1);
248 1
            ex = ex.expressionSemantic(sc);
249 1
            resolveExp(ex, pt, pe, ps);
250 1
            return;
251
        }
252

253 1
        Type t = s.getType(); // type symbol, type alias, or type tuple?
254 1
        uint errorsave = global.errors;
255 1
        int flags = t is null ? SearchLocalsOnly : IgnorePrivateImports;
256

257 1
        Dsymbol sm = s.searchX(loc, sc, id, flags);
258 1
        if (sm && !(sc.flags & SCOPE.ignoresymbolvisibility) && !symbolIsVisible(sc, sm))
259
        {
260 1
            .error(loc, "`%s` is not visible from module `%s`", sm.toPrettyChars(), sc._module.toChars());
261 1
            sm = null;
262
        }
263 1
        if (global.errors != errorsave)
264
        {
265 1
            *pt = Type.terror;
266 1
            return;
267
        }
268

269
        void helper3()
270
        {
271 1
            Expression e;
272 1
            VarDeclaration v = s.isVarDeclaration();
273 1
            FuncDeclaration f = s.isFuncDeclaration();
274 1
            if (intypeid || !v && !f)
275 1
                e = symbolToExp(s, loc, sc, true);
276
            else
277 1
                e = new VarExp(loc, s.isDeclaration(), true);
278

279 1
            e = typeToExpressionHelper(mt, e, i);
280 1
            e = e.expressionSemantic(sc);
281 1
            resolveExp(e, pt, pe, ps);
282
        }
283

284
        //printf("\t3: s = %p %s %s, sm = %p\n", s, s.kind(), s.toChars(), sm);
285 1
        if (intypeid && !t && sm && sm.needThis())
286 1
            return helper3();
287

288 1
        if (VarDeclaration v = s.isVarDeclaration())
289
        {
290
            // https://issues.dlang.org/show_bug.cgi?id=19913
291
            // v.type would be null if it is a forward referenced member.
292 1
            if (v.type is null)
293 1
                v.dsymbolSemantic(sc);
294 1
            if (v.storage_class & (STC.const_ | STC.immutable_ | STC.manifest) ||
295 1
                v.type.isConst() || v.type.isImmutable())
296
            {
297
                // https://issues.dlang.org/show_bug.cgi?id=13087
298
                // this.field is not constant always
299 1
                if (!v.isThisDeclaration())
300 1
                    return helper3();
301
            }
302
        }
303 1
        if (!sm)
304
        {
305 1
            if (!t)
306
            {
307 1
                if (s.isDeclaration()) // var, func, or tuple declaration?
308
                {
309 1
                    t = s.isDeclaration().type;
310 1
                    if (!t && s.isTupleDeclaration()) // expression tuple?
311 1
                        return helper3();
312
                }
313 1
                else if (s.isTemplateInstance() ||
314 1
                         s.isImport() || s.isPackage() || s.isModule())
315
                {
316 1
                    return helper3();
317
                }
318
            }
319 1
            if (t)
320
            {
321 1
                sm = t.toDsymbol(sc);
322 1
                if (sm && id.dyncast() == DYNCAST.identifier)
323
                {
324 1
                    sm = sm.search(loc, cast(Identifier)id, IgnorePrivateImports);
325 1
                    if (!sm)
326 1
                        return helper3();
327
                }
328
                else
329 1
                    return helper3();
330
            }
331
            else
332
            {
333 1
                if (id.dyncast() == DYNCAST.dsymbol)
334
                {
335
                    // searchX already handles errors for template instances
336 0
                    assert(global.errors);
337
                }
338
                else
339
                {
340 1
                    assert(id.dyncast() == DYNCAST.identifier);
341 1
                    sm = s.search_correct(cast(Identifier)id);
342 1
                    if (sm)
343 0
                        error(loc, "identifier `%s` of `%s` is not defined, did you mean %s `%s`?", id.toChars(), mt.toChars(), sm.kind(), sm.toChars());
344
                    else
345 1
                        error(loc, "identifier `%s` of `%s` is not defined", id.toChars(), mt.toChars());
346
                }
347 1
                *pe = ErrorExp.get();
348 1
                return;
349
            }
350
        }
351 1
        s = sm.toAlias();
352
    }
353

354 1
    if (auto em = s.isEnumMember())
355
    {
356
        // It's not a type, it's an expression
357 1
        *pe = em.getVarExp(loc, sc);
358 1
        return;
359
    }
360 1
    if (auto v = s.isVarDeclaration())
361
    {
362
        /* This is mostly same with DsymbolExp::semantic(), but we cannot use it
363
         * because some variables used in type context need to prevent lowering
364
         * to a literal or contextful expression. For example:
365
         *
366
         *  enum a = 1; alias b = a;
367
         *  template X(alias e){ alias v = e; }  alias x = X!(1);
368
         *  struct S { int v; alias w = v; }
369
         *      // TypeIdentifier 'a', 'e', and 'v' should be TOK.variable,
370
         *      // because getDsymbol() need to work in AliasDeclaration::semantic().
371
         */
372 1
        if (!v.type ||
373 1
            !v.type.deco && v.inuse)
374
        {
375 1
            if (v.inuse) // https://issues.dlang.org/show_bug.cgi?id=9494
376 1
                error(loc, "circular reference to %s `%s`", v.kind(), v.toPrettyChars());
377
            else
378 0
                error(loc, "forward reference to %s `%s`", v.kind(), v.toPrettyChars());
379 1
            *pt = Type.terror;
380 1
            return;
381
        }
382 1
        if (v.type.ty == Terror)
383 1
            *pt = Type.terror;
384
        else
385 1
            *pe = new VarExp(loc, v);
386 1
        return;
387
    }
388 1
    if (auto fld = s.isFuncLiteralDeclaration())
389
    {
390
        //printf("'%s' is a function literal\n", fld.toChars());
391 1
        *pe = new FuncExp(loc, fld);
392 1
        *pe = (*pe).expressionSemantic(sc);
393 1
        return;
394
    }
395
    version (none)
396
    {
397
        if (FuncDeclaration fd = s.isFuncDeclaration())
398
        {
399
            *pe = new DsymbolExp(loc, fd);
400
            return;
401
        }
402
    }
403

404 1
    Type t;
405 1
    while (1)
406
    {
407 1
        t = s.getType();
408 1
        if (t)
409 1
            break;
410
        // If the symbol is an import, try looking inside the import
411 1
        if (Import si = s.isImport())
412
        {
413 1
            s = si.search(loc, s.ident);
414 1
            if (s && s != si)
415 1
                continue;
416 1
            s = si;
417
        }
418 1
        *ps = s;
419 1
        return;
420
    }
421

422 1
    if (auto ti = t.isTypeInstance())
423 1
        if (ti != mt && !ti.deco)
424
        {
425 1
            if (!ti.tempinst.errors)
426 0
                error(loc, "forward reference to `%s`", ti.toChars());
427 1
            *pt = Type.terror;
428 1
            return;
429
        }
430

431 1
    if (t.ty == Ttuple)
432 1
        *pt = t;
433
    else
434 1
        *pt = t.merge();
435
}
436

437
/************************************
438
 * Transitively search a type for all function types.
439
 * If any function types with parameters are found that have parameter identifiers
440
 * or default arguments, remove those and create a new type stripped of those.
441
 * This is used to determine the "canonical" version of a type which is useful for
442
 * comparisons.
443
 * Params:
444
 *      t = type to scan
445
 * Returns:
446
 *      `t` if no parameter identifiers or default arguments found, otherwise a new type that is
447
 *      the same as t but with no parameter identifiers or default arguments.
448
 */
449
private Type stripDefaultArgs(Type t)
450
{
451
    static Parameters* stripParams(Parameters* parameters)
452
    {
453
        static Parameter stripParameter(Parameter p)
454
        {
455 1
            Type t = stripDefaultArgs(p.type);
456 1
            return (t != p.type || p.defaultArg || p.ident || p.userAttribDecl)
457 1
                ? new Parameter(p.storageClass, t, null, null, null)
458 1
                : null;
459
        }
460

461 1
        if (parameters)
462
        {
463 1
            foreach (i, p; *parameters)
464
            {
465 1
                Parameter ps = stripParameter(p);
466 1
                if (ps)
467
                {
468
                    // Replace params with a copy we can modify
469 1
                    Parameters* nparams = new Parameters(parameters.dim);
470

471 1
                    foreach (j, ref np; *nparams)
472
                    {
473 1
                        Parameter pj = (*parameters)[j];
474 1
                        if (j < i)
475 1
                            np = pj;
476 1
                        else if (j == i)
477 1
                            np = ps;
478
                        else
479
                        {
480 1
                            Parameter nps = stripParameter(pj);
481 1
                            np = nps ? nps : pj;
482
                        }
483
                    }
484 1
                    return nparams;
485
                }
486
            }
487
        }
488 1
        return parameters;
489
    }
490

491 1
    if (t is null)
492 1
        return t;
493

494 1
    if (auto tf = t.isTypeFunction())
495
    {
496 1
        Type tret = stripDefaultArgs(tf.next);
497 1
        Parameters* params = stripParams(tf.parameterList.parameters);
498 1
        if (tret == tf.next && params == tf.parameterList.parameters)
499 1
            return t;
500 1
        TypeFunction tr = cast(TypeFunction)tf.copy();
501 1
        tr.parameterList.parameters = params;
502 1
        tr.next = tret;
503
        //printf("strip %s\n   <- %s\n", tr.toChars(), t.toChars());
504 1
        return tr;
505
    }
506 1
    else if (auto tt = t.isTypeTuple())
507
    {
508 1
        Parameters* args = stripParams(tt.arguments);
509 1
        if (args == tt.arguments)
510 1
            return t;
511 1
        TypeTuple tr = cast(TypeTuple)t.copy();
512 1
        tr.arguments = args;
513 1
        return tr;
514
    }
515 1
    else if (t.ty == Tenum)
516
    {
517
        // TypeEnum::nextOf() may be != NULL, but it's not necessary here.
518 1
        return t;
519
    }
520
    else
521
    {
522 1
        Type tn = t.nextOf();
523 1
        Type n = stripDefaultArgs(tn);
524 1
        if (n == tn)
525 1
            return t;
526 1
        TypeNext tr = cast(TypeNext)t.copy();
527 1
        tr.next = n;
528 1
        return tr;
529
    }
530
}
531

532
/******************************************
533
 * We've mistakenly parsed `t` as a type.
534
 * Redo `t` as an Expression only if there are no type modifiers.
535
 * Params:
536
 *      t = mistaken type
537
 * Returns:
538
 *      t redone as Expression, null if cannot
539
 */
540
Expression typeToExpression(Type t)
541
{
542
    static Expression visitSArray(TypeSArray t)
543
    {
544 1
        if (auto e = t.next.typeToExpression())
545 1
            return new ArrayExp(t.dim.loc, e, t.dim);
546 0
        return null;
547
    }
548

549
    static Expression visitAArray(TypeAArray t)
550
    {
551 1
        if (auto e = t.next.typeToExpression())
552
        {
553 1
            if (auto ei = t.index.typeToExpression())
554 1
                return new ArrayExp(t.loc, e, ei);
555
        }
556 1
        return null;
557
    }
558

559
    static Expression visitIdentifier(TypeIdentifier t)
560
    {
561 1
        return typeToExpressionHelper(t, new IdentifierExp(t.loc, t.ident));
562
    }
563

564
    static Expression visitInstance(TypeInstance t)
565
    {
566 1
        return typeToExpressionHelper(t, new ScopeExp(t.loc, t.tempinst));
567
    }
568

569
    // easy way to enable 'auto v = new int[mixin("exp")];' in 2.088+
570
    static Expression visitMixin(TypeMixin t)
571
    {
572 1
        return new TypeExp(t.loc, t);
573
    }
574

575 1
    if (t.mod)
576 1
        return null;
577 1
    switch (t.ty)
578
    {
579 1
        case Tsarray:   return visitSArray(cast(TypeSArray) t);
580 1
        case Taarray:   return visitAArray(cast(TypeAArray) t);
581 1
        case Tident:    return visitIdentifier(cast(TypeIdentifier) t);
582 1
        case Tinstance: return visitInstance(cast(TypeInstance) t);
583 1
        case Tmixin:    return visitMixin(cast(TypeMixin) t);
584 1
        default:        return null;
585
    }
586
}
587

588
/* Helper function for `typeToExpression`. Contains common code
589
 * for TypeQualified derived classes.
590
 */
591
Expression typeToExpressionHelper(TypeQualified t, Expression e, size_t i = 0)
592
{
593
    //printf("toExpressionHelper(e = %s %s)\n", Token.toChars(e.op), e.toChars());
594 1
    foreach (id; t.idents[i .. t.idents.dim])
595
    {
596
        //printf("\t[%d] e: '%s', id: '%s'\n", i, e.toChars(), id.toChars());
597

598 1
        final switch (id.dyncast())
599
        {
600
            // ... '. ident'
601 1
            case DYNCAST.identifier:
602 1
                e = new DotIdExp(e.loc, e, cast(Identifier)id);
603 1
                break;
604

605
            // ... '. name!(tiargs)'
606 1
            case DYNCAST.dsymbol:
607 1
                auto ti = (cast(Dsymbol)id).isTemplateInstance();
608 1
                assert(ti);
609 1
                e = new DotTemplateInstanceExp(e.loc, e, ti.name, ti.tiargs);
610 1
                break;
611

612
            // ... '[type]'
613 0
            case DYNCAST.type:          // https://issues.dlang.org/show_bug.cgi?id=1215
614 0
                e = new ArrayExp(t.loc, e, new TypeExp(t.loc, cast(Type)id));
615 0
                break;
616

617
            // ... '[expr]'
618 1
            case DYNCAST.expression:    // https://issues.dlang.org/show_bug.cgi?id=1215
619 1
                e = new ArrayExp(t.loc, e, cast(Expression)id);
620 1
                break;
621

622 0
            case DYNCAST.object:
623 0
            case DYNCAST.tuple:
624 0
            case DYNCAST.parameter:
625 0
            case DYNCAST.statement:
626 0
            case DYNCAST.condition:
627 0
            case DYNCAST.templateparameter:
628 0
                assert(0);
629
        }
630
    }
631 1
    return e;
632
}
633

634
/******************************************
635
 * Perform semantic analysis on a type.
636
 * Params:
637
 *      t = Type AST node
638
 *      loc = the location of the type
639
 *      sc = context
640
 * Returns:
641
 *      `Type` with completed semantic analysis, `Terror` if errors
642
 *      were encountered
643
 */
644
extern(C++) Type typeSemantic(Type t, const ref Loc loc, Scope* sc)
645
{
646
    static Type error()
647
    {
648 1
        return Type.terror;
649
    }
650

651
    Type visitType(Type t)
652
    {
653 1
        if (t.ty == Tint128 || t.ty == Tuns128)
654
        {
655 1
            .error(loc, "`cent` and `ucent` types not implemented");
656 1
            return error();
657
        }
658

659 1
        return t.merge();
660
    }
661

662
    Type visitVector(TypeVector mtype)
663
    {
664 1
        const errors = global.errors;
665 1
        mtype.basetype = mtype.basetype.typeSemantic(loc, sc);
666 1
        if (errors != global.errors)
667 0
            return error();
668 1
        mtype.basetype = mtype.basetype.toBasetype().mutableOf();
669 1
        if (mtype.basetype.ty != Tsarray)
670
        {
671 1
            .error(loc, "T in __vector(T) must be a static array, not `%s`", mtype.basetype.toChars());
672 1
            return error();
673
        }
674 1
        TypeSArray t = cast(TypeSArray)mtype.basetype;
675 1
        const sz = cast(int)t.size(loc);
676 1
        final switch (target.isVectorTypeSupported(sz, t.nextOf()))
677
        {
678 1
        case 0:
679
            // valid
680 1
            break;
681

682 0
        case 1:
683
            // no support at all
684 0
            .error(loc, "SIMD vector types not supported on this platform");
685 0
            return error();
686

687 1
        case 2:
688
            // invalid base type
689 1
            .error(loc, "vector type `%s` is not supported on this platform", mtype.toChars());
690 1
            return error();
691

692 1
        case 3:
693
            // invalid size
694 1
            .error(loc, "%d byte vector type `%s` is not supported on this platform", sz, mtype.toChars());
695 1
            return error();
696
        }
697 1
        return merge(mtype);
698
    }
699

700
    Type visitSArray(TypeSArray mtype)
701
    {
702
        //printf("TypeSArray::semantic() %s\n", toChars());
703 1
        Type t;
704 1
        Expression e;
705 1
        Dsymbol s;
706 1
        mtype.next.resolve(loc, sc, &e, &t, &s);
707

708 1
        if (auto tup = s ? s.isTupleDeclaration() : null)
709
        {
710 1
            mtype.dim = semanticLength(sc, tup, mtype.dim);
711 1
            mtype.dim = mtype.dim.ctfeInterpret();
712 1
            if (mtype.dim.op == TOK.error)
713 1
                return error();
714

715 1
            uinteger_t d = mtype.dim.toUInteger();
716 1
            if (d >= tup.objects.dim)
717
            {
718 1
                .error(loc, "tuple index %llu exceeds %llu", cast(ulong)d, cast(ulong)tup.objects.dim);
719 1
                return error();
720
            }
721

722 1
            RootObject o = (*tup.objects)[cast(size_t)d];
723 1
            if (o.dyncast() != DYNCAST.type)
724
            {
725 1
                .error(loc, "`%s` is not a type", mtype.toChars());
726 1
                return error();
727
            }
728 1
            return (cast(Type)o).addMod(mtype.mod);
729
        }
730

731 1
        Type tn = mtype.next.typeSemantic(loc, sc);
732 1
        if (tn.ty == Terror)
733 1
            return error();
734

735 1
        Type tbn = tn.toBasetype();
736 1
        if (mtype.dim)
737
        {
738
            //https://issues.dlang.org/show_bug.cgi?id=15478
739 1
            if (mtype.dim.isDotVarExp())
740
            {
741 1
                if (Declaration vd = mtype.dim.isDotVarExp().var)
742
                {
743 1
                    FuncDeclaration fd = vd.toAlias().isFuncDeclaration();
744 1
                    if (fd)
745 1
                        mtype.dim = new CallExp(loc, fd, null);
746
                }
747
            }
748

749 1
            auto errors = global.errors;
750 1
            mtype.dim = semanticLength(sc, tbn, mtype.dim);
751 1
            if (errors != global.errors)
752 1
                return error();
753

754 1
            mtype.dim = mtype.dim.optimize(WANTvalue);
755 1
            mtype.dim = mtype.dim.ctfeInterpret();
756 1
            if (mtype.dim.op == TOK.error)
757 1
                return error();
758

759 1
            errors = global.errors;
760 1
            dinteger_t d1 = mtype.dim.toInteger();
761 1
            if (errors != global.errors)
762 0
                return error();
763

764 1
            mtype.dim = mtype.dim.implicitCastTo(sc, Type.tsize_t);
765 1
            mtype.dim = mtype.dim.optimize(WANTvalue);
766 1
            if (mtype.dim.op == TOK.error)
767 0
                return error();
768

769 1
            errors = global.errors;
770 1
            dinteger_t d2 = mtype.dim.toInteger();
771 1
            if (errors != global.errors)
772 0
                return error();
773

774 1
            if (mtype.dim.op == TOK.error)
775 0
                return error();
776

777
            Type overflowError()
778
            {
779 1
                .error(loc, "`%s` size %llu * %llu exceeds 0x%llx size limit for static array",
780
                        mtype.toChars(), cast(ulong)tbn.size(loc), cast(ulong)d1, target.maxStaticDataSize);
781 1
                return error();
782
            }
783

784 1
            if (d1 != d2)
785 0
                return overflowError();
786

787 1
            Type tbx = tbn.baseElemOf();
788 1
            if (tbx.ty == Tstruct && !(cast(TypeStruct)tbx).sym.members ||
789 1
                tbx.ty == Tenum && !(cast(TypeEnum)tbx).sym.members)
790
            {
791
                /* To avoid meaningless error message, skip the total size limit check
792
                 * when the bottom of element type is opaque.
793
                 */
794
            }
795 1
            else if (tbn.isTypeBasic() ||
796 1
                     tbn.ty == Tpointer ||
797 1
                     tbn.ty == Tarray ||
798 1
                     tbn.ty == Tsarray ||
799 1
                     tbn.ty == Taarray ||
800 1
                     (tbn.ty == Tstruct && ((cast(TypeStruct)tbn).sym.sizeok == Sizeok.done)) ||
801 1
                     tbn.ty == Tclass)
802
            {
803
                /* Only do this for types that don't need to have semantic()
804
                 * run on them for the size, since they may be forward referenced.
805
                 */
806 1
                bool overflow = false;
807 1
                if (mulu(tbn.size(loc), d2, overflow) >= target.maxStaticDataSize || overflow)
808 1
                    return overflowError();
809
            }
810
        }
811 1
        switch (tbn.ty)
812
        {
813 1
        case Ttuple:
814
            {
815
                // Index the tuple to get the type
816 1
                assert(mtype.dim);
817 1
                TypeTuple tt = cast(TypeTuple)tbn;
818 1
                uinteger_t d = mtype.dim.toUInteger();
819 1
                if (d >= tt.arguments.dim)
820
                {
821 1
                    .error(loc, "tuple index %llu exceeds %llu", cast(ulong)d, cast(ulong)tt.arguments.dim);
822 1
                    return error();
823
                }
824 1
                Type telem = (*tt.arguments)[cast(size_t)d].type;
825 1
                return telem.addMod(mtype.mod);
826
            }
827

828 1
        case Tfunction:
829 1
        case Tnone:
830 1
            .error(loc, "cannot have array of `%s`", tbn.toChars());
831 1
            return error();
832

833 1
        default:
834 1
            break;
835
        }
836 1
        if (tbn.isscope())
837
        {
838 1
            .error(loc, "cannot have array of scope `%s`", tbn.toChars());
839 1
            return error();
840
        }
841

842
        /* Ensure things like const(immutable(T)[3]) become immutable(T[3])
843
         * and const(T)[3] become const(T[3])
844
         */
845 1
        mtype.next = tn;
846 1
        mtype.transitive();
847 1
        return mtype.addMod(tn.mod).merge();
848
    }
849

850
    Type visitDArray(TypeDArray mtype)
851
    {
852 1
        Type tn = mtype.next.typeSemantic(loc, sc);
853 1
        Type tbn = tn.toBasetype();
854 1
        switch (tbn.ty)
855
        {
856 1
        case Ttuple:
857 1
            return tbn;
858

859 1
        case Tfunction:
860 1
        case Tnone:
861 1
            .error(loc, "cannot have array of `%s`", tbn.toChars());
862 1
            return error();
863

864 1
        case Terror:
865 1
            return error();
866

867 1
        default:
868 1
            break;
869
        }
870 1
        if (tn.isscope())
871
        {
872 1
            .error(loc, "cannot have array of scope `%s`", tn.toChars());
873 1
            return error();
874
        }
875 1
        mtype.next = tn;
876 1
        mtype.transitive();
877 1
        return merge(mtype);
878
    }
879

880
    Type visitAArray(TypeAArray mtype)
881
    {
882
        //printf("TypeAArray::semantic() %s index.ty = %d\n", mtype.toChars(), mtype.index.ty);
883 1
        if (mtype.deco)
884
        {
885 1
            return mtype;
886
        }
887

888 1
        mtype.loc = loc;
889 1
        if (sc)
890 1
            sc.setNoFree();
891

892
        // Deal with the case where we thought the index was a type, but
893
        // in reality it was an expression.
894 1
        if (mtype.index.ty == Tident || mtype.index.ty == Tinstance || mtype.index.ty == Tsarray || mtype.index.ty == Ttypeof || mtype.index.ty == Treturn || mtype.index.ty == Tmixin)
895
        {
896 1
            Expression e;
897 1
            Type t;
898 1
            Dsymbol s;
899 1
            mtype.index.resolve(loc, sc, &e, &t, &s);
900

901
            //https://issues.dlang.org/show_bug.cgi?id=15478
902 1
            if (s)
903
            {
904 1
                if (FuncDeclaration fd = s.toAlias().isFuncDeclaration())
905 1
                    e = new CallExp(loc, fd, null);
906
            }
907

908 1
            if (e)
909
            {
910
                // It was an expression -
911
                // Rewrite as a static array
912 1
                auto tsa = new TypeSArray(mtype.next, e);
913 1
                return tsa.typeSemantic(loc, sc);
914
            }
915 1
            else if (t)
916 1
                mtype.index = t.typeSemantic(loc, sc);
917
            else
918
            {
919 0
                .error(loc, "index is not a type or an expression");
920 0
                return error();
921
            }
922
        }
923
        else
924 1
            mtype.index = mtype.index.typeSemantic(loc, sc);
925 1
        mtype.index = mtype.index.merge2();
926

927 1
        if (mtype.index.nextOf() && !mtype.index.nextOf().isImmutable())
928
        {
929 1
            mtype.index = mtype.index.constOf().mutableOf();
930
            version (none)
931
            {
932
                printf("index is %p %s\n", mtype.index, mtype.index.toChars());
933
                mtype.index.check();
934
                printf("index.mod = x%x\n", mtype.index.mod);
935
                printf("index.ito = x%x\n", mtype.index.ito);
936
                if (mtype.index.ito)
937
                {
938
                    printf("index.ito.mod = x%x\n", mtype.index.ito.mod);
939
                    printf("index.ito.ito = x%x\n", mtype.index.ito.ito);
940
                }
941
            }
942
        }
943

944 1
        switch (mtype.index.toBasetype().ty)
945
        {
946 1
        case Tfunction:
947 1
        case Tvoid:
948 1
        case Tnone:
949 1
        case Ttuple:
950 1
            .error(loc, "cannot have associative array key of `%s`", mtype.index.toBasetype().toChars());
951 1
            goto case Terror;
952 1
        case Terror:
953 1
            return error();
954

955 1
        default:
956 1
            break;
957
        }
958 1
        Type tbase = mtype.index.baseElemOf();
959 1
        while (tbase.ty == Tarray)
960 1
            tbase = tbase.nextOf().baseElemOf();
961 1
        if (auto ts = tbase.isTypeStruct())
962
        {
963
            /* AA's need typeid(index).equals() and getHash(). Issue error if not correctly set up.
964
             */
965 1
            StructDeclaration sd = ts.sym;
966 1
            if (sd.semanticRun < PASS.semanticdone)
967 1
                sd.dsymbolSemantic(null);
968

969
            // duplicate a part of StructDeclaration::semanticTypeInfoMembers
970
            //printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd.xeq, sd.xerreq, sd.xhash);
971 1
            if (sd.xeq && sd.xeq._scope && sd.xeq.semanticRun < PASS.semantic3done)
972
            {
973 1
                uint errors = global.startGagging();
974 1
                sd.xeq.semantic3(sd.xeq._scope);
975 1
                if (global.endGagging(errors))
976 1
                    sd.xeq = sd.xerreq;
977
            }
978

979
            //printf("AA = %s, key: xeq = %p, xhash = %p\n", toChars(), sd.xeq, sd.xhash);
980 1
            const(char)* s = (mtype.index.toBasetype().ty != Tstruct) ? "bottom of " : "";
981 1
            if (!sd.xeq)
982
            {
983
                // If sd.xhash != NULL:
984
                //   sd or its fields have user-defined toHash.
985
                //   AA assumes that its result is consistent with bitwise equality.
986
                // else:
987
                //   bitwise equality & hashing
988
            }
989 1
            else if (sd.xeq == sd.xerreq)
990
            {
991 1
                if (search_function(sd, Id.eq))
992
                {
993 1
                    .error(loc, "%sAA key type `%s` does not have `bool opEquals(ref const %s) const`", s, sd.toChars(), sd.toChars());
994
                }
995
                else
996
                {
997 1
                    .error(loc, "%sAA key type `%s` does not support const equality", s, sd.toChars());
998
                }
999 1
                return error();
1000
            }
1001 1
            else if (!sd.xhash)
1002
            {
1003 1
                if (search_function(sd, Id.eq))
1004
                {
1005 1
                    .error(loc, "%sAA key type `%s` should have `extern (D) size_t toHash() const nothrow @safe` if `opEquals` defined", s, sd.toChars());
1006
                }
1007
                else
1008
                {
1009 1
                    .error(loc, "%sAA key type `%s` supports const equality but doesn't support const hashing", s, sd.toChars());
1010
                }
1011 1
                return error();
1012
            }
1013
            else
1014
            {
1015
                // defined equality & hashing
1016 1
                assert(sd.xeq && sd.xhash);
1017

1018
                /* xeq and xhash may be implicitly defined by compiler. For example:
1019
                 *   struct S { int[] arr; }
1020
                 * With 'arr' field equality and hashing, compiler will implicitly
1021
                 * generate functions for xopEquals and xtoHash in TypeInfo_Struct.
1022
                 */
1023
            }
1024
        }
1025 1
        else if (tbase.ty == Tclass && !(cast(TypeClass)tbase).sym.isInterfaceDeclaration())
1026
        {
1027 1
            ClassDeclaration cd = (cast(TypeClass)tbase).sym;
1028 1
            if (cd.semanticRun < PASS.semanticdone)
1029 1
                cd.dsymbolSemantic(null);
1030

1031 1
            if (!ClassDeclaration.object)
1032
            {
1033 0
                .error(Loc.initial, "missing or corrupt object.d");
1034 0
                fatal();
1035
            }
1036

1037 1
            __gshared FuncDeclaration feq = null;
1038 1
            __gshared FuncDeclaration fcmp = null;
1039 1
            __gshared FuncDeclaration fhash = null;
1040 1
            if (!feq)
1041 1
                feq = search_function(ClassDeclaration.object, Id.eq).isFuncDeclaration();
1042 1
            if (!fcmp)
1043 1
                fcmp = search_function(ClassDeclaration.object, Id.cmp).isFuncDeclaration();
1044 1
            if (!fhash)
1045 1
                fhash = search_function(ClassDeclaration.object, Id.tohash).isFuncDeclaration();
1046 1
            assert(fcmp && feq && fhash);
1047

1048 1
            if (feq.vtblIndex < cd.vtbl.dim && cd.vtbl[feq.vtblIndex] == feq)
1049
            {
1050
                version (all)
1051
                {
1052 1
                    if (fcmp.vtblIndex < cd.vtbl.dim && cd.vtbl[fcmp.vtblIndex] != fcmp)
1053
                    {
1054 0
                        const(char)* s = (mtype.index.toBasetype().ty != Tclass) ? "bottom of " : "";
1055 0
                        .error(loc, "%sAA key type `%s` now requires equality rather than comparison", s, cd.toChars());
1056 0
                        errorSupplemental(loc, "Please override `Object.opEquals` and `Object.toHash`.");
1057
                    }
1058
                }
1059
            }
1060
        }
1061 1
        mtype.next = mtype.next.typeSemantic(loc, sc).merge2();
1062 1
        mtype.transitive();
1063

1064 1
        switch (mtype.next.toBasetype().ty)
1065
        {
1066 1
        case Tfunction:
1067 1
        case Tvoid:
1068 1
        case Tnone:
1069 1
        case Ttuple:
1070 1
            .error(loc, "cannot have associative array of `%s`", mtype.next.toChars());
1071 1
            goto case Terror;
1072 1
        case Terror:
1073 1
            return error();
1074 1
        default:
1075 1
            break;
1076
        }
1077 1
        if (mtype.next.isscope())
1078
        {
1079 1
            .error(loc, "cannot have array of scope `%s`", mtype.next.toChars());
1080 1
            return error();
1081
        }
1082 1
        return merge(mtype);
1083
    }
1084

1085
    Type visitPointer(TypePointer mtype)
1086
    {
1087
        //printf("TypePointer::semantic() %s\n", toChars());
1088 1
        if (mtype.deco)
1089
        {
1090 1
            return mtype;
1091
        }
1092 1
        Type n = mtype.next.typeSemantic(loc, sc);
1093 1
        switch (n.toBasetype().ty)
1094
        {
1095 1
        case Ttuple:
1096 1
            .error(loc, "cannot have pointer to `%s`", n.toChars());
1097 1
            goto case Terror;
1098 1
        case Terror:
1099 1
            return error();
1100 1
        default:
1101 1
            break;
1102
        }
1103 1
        if (n != mtype.next)
1104
        {
1105 1
            mtype.deco = null;
1106
        }
1107 1
        mtype.next = n;
1108 1
        if (mtype.next.ty != Tfunction)
1109
        {
1110 1
            mtype.transitive();
1111 1
            return merge(mtype);
1112
        }
1113
        version (none)
1114
        {
1115
            return merge(mtype);
1116
        }
1117
        else
1118
        {
1119 1
            mtype.deco = merge(mtype).deco;
1120
            /* Don't return merge(), because arg identifiers and default args
1121
             * can be different
1122
             * even though the types match
1123
             */
1124 1
            return mtype;
1125
        }
1126
    }
1127

1128
    Type visitReference(TypeReference mtype)
1129
    {
1130
        //printf("TypeReference::semantic()\n");
1131 0
        Type n = mtype.next.typeSemantic(loc, sc);
1132 0
        if (n != mtype.next)
1133 0
           mtype.deco = null;
1134 0
        mtype.next = n;
1135 0
        mtype.transitive();
1136 0
        return merge(mtype);
1137
    }
1138

1139
    Type visitFunction(TypeFunction mtype)
1140
    {
1141 1
        if (mtype.deco) // if semantic() already run
1142
        {
1143
            //printf("already done\n");
1144 1
            return mtype;
1145
        }
1146
        //printf("TypeFunction::semantic() this = %p\n", this);
1147
        //printf("TypeFunction::semantic() %s, sc.stc = %llx, fargs = %p\n", toChars(), sc.stc, fargs);
1148

1149 1
        bool errors = false;
1150

1151 1
        if (mtype.inuse > global.recursionLimit)
1152
        {
1153 0
            mtype.inuse = 0;
1154 0
            .error(loc, "recursive type");
1155 0
            return error();
1156
        }
1157

1158
        /* Copy in order to not mess up original.
1159
         * This can produce redundant copies if inferring return type,
1160
         * as semantic() will get called again on this.
1161
         */
1162 1
        TypeFunction tf = mtype.copy().toTypeFunction();
1163 1
        if (mtype.parameterList.parameters)
1164
        {
1165 1
            tf.parameterList.parameters = mtype.parameterList.parameters.copy();
1166 1
            for (size_t i = 0; i < mtype.parameterList.parameters.dim; i++)
1167
            {
1168 1
                Parameter p = cast(Parameter)mem.xmalloc(__traits(classInstanceSize, Parameter));
1169 1
                memcpy(cast(void*)p, cast(void*)(*mtype.parameterList.parameters)[i], __traits(classInstanceSize, Parameter));
1170 1
                (*tf.parameterList.parameters)[i] = p;
1171
            }
1172
        }
1173

1174 1
        if (sc.stc & STC.pure_)
1175 1
            tf.purity = PURE.fwdref;
1176 1
        if (sc.stc & STC.nothrow_)
1177 1
            tf.isnothrow = true;
1178 1
        if (sc.stc & STC.nogc)
1179 1
            tf.isnogc = true;
1180 1
        if (sc.stc & STC.ref_)
1181 1
            tf.isref = true;
1182 1
        if (sc.stc & STC.return_)
1183 0
            tf.isreturn = true;
1184 1
        if (sc.stc & STC.returninferred)
1185 0
            tf.isreturninferred = true;
1186 1
        if (sc.stc & STC.scope_)
1187 1
            tf.isScopeQual = true;
1188 1
        if (sc.stc & STC.scopeinferred)
1189 0
            tf.isscopeinferred = true;
1190

1191
//        if (tf.isreturn && !tf.isref)
1192
//            tf.isScopeQual = true;                                  // return by itself means 'return scope'
1193

1194 1
        if (tf.trust == TRUST.default_)
1195
        {
1196 1
            if (sc.stc & STC.safe)
1197 1
                tf.trust = TRUST.safe;
1198 1
            else if (sc.stc & STC.system)
1199 1
                tf.trust = TRUST.system;
1200 1
            else if (sc.stc & STC.trusted)
1201 1
                tf.trust = TRUST.trusted;
1202
        }
1203

1204 1
        if (sc.stc & STC.property)
1205 1
            tf.isproperty = true;
1206 1
        if (sc.stc & STC.live)
1207 1
            tf.islive = true;
1208

1209 1
        tf.linkage = sc.linkage;
1210
        version (none)
1211
        {
1212
            /* If the parent is @safe, then this function defaults to safe
1213
             * too.
1214
             * If the parent's @safe-ty is inferred, then this function's @safe-ty needs
1215
             * to be inferred first.
1216
             */
1217
            if (tf.trust == TRUST.default_)
1218
                for (Dsymbol p = sc.func; p; p = p.toParent2())
1219
                {
1220
                    FuncDeclaration fd = p.isFuncDeclaration();
1221
                    if (fd)
1222
                    {
1223
                        if (fd.isSafeBypassingInference())
1224
                            tf.trust = TRUST.safe; // default to @safe
1225
                        break;
1226
                    }
1227
                }
1228
        }
1229

1230 1
        bool wildreturn = false;
1231 1
        if (tf.next)
1232
        {
1233 1
            sc = sc.push();
1234 1
            sc.stc &= ~(STC.TYPECTOR | STC.FUNCATTR);
1235 1
            tf.next = tf.next.typeSemantic(loc, sc);
1236 1
            sc = sc.pop();
1237 1
            errors |= tf.checkRetType(loc);
1238 1
            if (tf.next.isscope() && !(sc.flags & SCOPE.ctor))
1239
            {
1240 1
                .error(loc, "functions cannot return `scope %s`", tf.next.toChars());
1241 1
                errors = true;
1242
            }
1243 1
            if (tf.next.hasWild())
1244 1
                wildreturn = true;
1245

1246 1
            if (tf.isreturn && !tf.isref && !tf.next.hasPointers())
1247
            {
1248 1
                tf.isreturn = false;
1249
            }
1250
        }
1251

1252 1
        ubyte wildparams = 0;
1253 1
        if (tf.parameterList.parameters)
1254
        {
1255
            /* Create a scope for evaluating the default arguments for the parameters
1256
             */
1257 1
            Scope* argsc = sc.push();
1258 1
            argsc.stc = 0; // don't inherit storage class
1259 1
            argsc.protection = Prot(Prot.Kind.public_);
1260 1
            argsc.func = null;
1261

1262 1
            size_t dim = tf.parameterList.length;
1263 1
            for (size_t i = 0; i < dim; i++)
1264
            {
1265 1
                Parameter fparam = tf.parameterList[i];
1266 1
                fparam.storageClass |= STC.parameter;
1267 1
                mtype.inuse++;
1268 1
                fparam.type = fparam.type.typeSemantic(loc, argsc);
1269 1
                mtype.inuse--;
1270

1271 1
                if (fparam.type.ty == Terror)
1272
                {
1273 1
                    errors = true;
1274 1
                    continue;
1275
                }
1276

1277 1
                fparam.type = fparam.type.addStorageClass(fparam.storageClass);
1278

1279 1
                if (fparam.storageClass & (STC.auto_ | STC.alias_ | STC.static_))
1280
                {
1281 1
                    if (!fparam.type)
1282 0
                        continue;
1283
                }
1284

1285 1
                Type t = fparam.type.toBasetype();
1286

1287 1
                if (t.ty == Tfunction)
1288
                {
1289 1
                    .error(loc, "cannot have parameter of function type `%s`", fparam.type.toChars());
1290 1
                    errors = true;
1291
                }
1292 1
                else if (!fparam.isReference() &&
1293 1
                         (t.ty == Tstruct || t.ty == Tsarray || t.ty == Tenum))
1294
                {
1295 1
                    Type tb2 = t.baseElemOf();
1296 1
                    if (tb2.ty == Tstruct && !(cast(TypeStruct)tb2).sym.members ||
1297 1
                        tb2.ty == Tenum && !(cast(TypeEnum)tb2).sym.memtype)
1298
                    {
1299 1
                        .error(loc, "cannot have parameter of opaque type `%s` by value", fparam.type.toChars());
1300 1
                        errors = true;
1301
                    }
1302
                }
1303 1
                else if (!(fparam.storageClass & STC.lazy_) && t.ty == Tvoid)
1304
                {
1305 1
                    .error(loc, "cannot have parameter of type `%s`", fparam.type.toChars());
1306 1
                    errors = true;
1307
                }
1308

1309 1
                if ((fparam.storageClass & (STC.ref_ | STC.wild)) == (STC.ref_ | STC.wild))
1310
                {
1311
                    // 'ref inout' implies 'return'
1312 1
                    fparam.storageClass |= STC.return_;
1313
                }
1314

1315 1
                if (fparam.storageClass & STC.return_)
1316
                {
1317 1
                    if (fparam.isReference())
1318
                    {
1319
                        // Disabled for the moment awaiting improvement to allow return by ref
1320
                        // to be transformed into return by scope.
1321 1
                        if (0 && !tf.isref)
1322
                        {
1323 0
                            auto stc = fparam.storageClass & (STC.ref_ | STC.out_);
1324 0
                            .error(loc, "parameter `%s` is `return %s` but function does not return by `ref`",
1325 0
                                fparam.ident ? fparam.ident.toChars() : "",
1326
                                stcToChars(stc));
1327 0
                            errors = true;
1328
                        }
1329
                    }
1330
                    else
1331
                    {
1332 1
                        if (!(fparam.storageClass & STC.scope_))
1333 1
                            fparam.storageClass |= STC.scope_ | STC.scopeinferred; // 'return' implies 'scope'
1334 1
                        if (tf.isref)
1335
                        {
1336
                        }
1337 1
                        else if (tf.next && !tf.next.hasPointers() && tf.next.toBasetype().ty != Tvoid)
1338
                        {
1339 0
                            fparam.storageClass &= ~STC.return_;   // https://issues.dlang.org/show_bug.cgi?id=18963
1340
                        }
1341
                    }
1342
                }
1343

1344 1
                if (fparam.storageClass & (STC.ref_ | STC.lazy_))
1345
                {
1346
                }
1347 1
                else if (fparam.storageClass & STC.out_)
1348
                {
1349 1
                    if (ubyte m = fparam.type.mod & (MODFlags.immutable_ | MODFlags.const_ | MODFlags.wild))
1350
                    {
1351 1
                        .error(loc, "cannot have `%s out` parameter of type `%s`", MODtoChars(m), t.toChars());
1352 1
                        errors = true;
1353
                    }
1354
                    else
1355
                    {
1356 1
                        Type tv = t.baseElemOf();
1357 1
                        if (tv.ty == Tstruct && (cast(TypeStruct)tv).sym.noDefaultCtor)
1358
                        {
1359 1
                            .error(loc, "cannot have `out` parameter of type `%s` because the default construction is disabled", fparam.type.toChars());
1360 1
                            errors = true;
1361
                        }
1362
                    }
1363
                }
1364

1365 1
                if (t.hasWild())
1366
                {
1367 1
                    wildparams |= 1;
1368
                    //if (tf.next && !wildreturn)
1369
                    //    error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with `ref`)");
1370
                }
1371

1372 1
                if (fparam.defaultArg)
1373
                {
1374 1
                    Expression e = fparam.defaultArg;
1375 1
                    const isRefOrOut = fparam.isReference();
1376 1
                    const isAuto = fparam.storageClass & (STC.auto_ | STC.autoref);
1377 1
                    if (isRefOrOut && !isAuto)
1378
                    {
1379 1
                        e = e.expressionSemantic(argsc);
1380 1
                        e = resolveProperties(argsc, e);
1381
                    }
1382
                    else
1383
                    {
1384 1
                        e = inferType(e, fparam.type);
1385 1
                        Initializer iz = new ExpInitializer(e.loc, e);
1386 1
                        iz = iz.initializerSemantic(argsc, fparam.type, INITnointerpret);
1387 1
                        e = iz.initializerToExpression();
1388
                    }
1389 1
                    if (e.op == TOK.function_) // https://issues.dlang.org/show_bug.cgi?id=4820
1390
                    {
1391 1
                        FuncExp fe = cast(FuncExp)e;
1392
                        // Replace function literal with a function symbol,
1393
                        // since default arg expression must be copied when used
1394
                        // and copying the literal itself is wrong.
1395 1
                        e = new VarExp(e.loc, fe.fd, false);
1396 1
                        e = new AddrExp(e.loc, e);
1397 1
                        e = e.expressionSemantic(argsc);
1398
                    }
1399 1
                    e = e.implicitCastTo(argsc, fparam.type);
1400

1401
                    // default arg must be an lvalue
1402 1
                    if (isRefOrOut && !isAuto)
1403 1
                        e = e.toLvalue(argsc, e);
1404

1405 1
                    fparam.defaultArg = e;
1406 1
                    if (e.op == TOK.error)
1407 1
                        errors = true;
1408
                }
1409

1410
                /* If fparam after semantic() turns out to be a tuple, the number of parameters may
1411
                 * change.
1412
                 */
1413 1
                if (auto tt = t.isTypeTuple())
1414
                {
1415
                    /* TypeFunction::parameter also is used as the storage of
1416
                     * Parameter objects for FuncDeclaration. So we should copy
1417
                     * the elements of TypeTuple::arguments to avoid unintended
1418
                     * sharing of Parameter object among other functions.
1419
                     */
1420 1
                    if (tt.arguments && tt.arguments.dim)
1421
                    {
1422
                        /* Propagate additional storage class from tuple parameters to their
1423
                         * element-parameters.
1424
                         * Make a copy, as original may be referenced elsewhere.
1425
                         */
1426 1
                        size_t tdim = tt.arguments.dim;
1427 1
                        auto newparams = new Parameters(tdim);
1428 1
                        for (size_t j = 0; j < tdim; j++)
1429
                        {
1430 1
                            Parameter narg = (*tt.arguments)[j];
1431

1432
                            // https://issues.dlang.org/show_bug.cgi?id=12744
1433
                            // If the storage classes of narg
1434
                            // conflict with the ones in fparam, it's ignored.
1435 1
                            StorageClass stc  = fparam.storageClass | narg.storageClass;
1436 1
                            StorageClass stc1 = fparam.storageClass & (STC.ref_ | STC.out_ | STC.lazy_);
1437 1
                            StorageClass stc2 =   narg.storageClass & (STC.ref_ | STC.out_ | STC.lazy_);
1438 1
                            if (stc1 && stc2 && stc1 != stc2)
1439
                            {
1440 1
                                OutBuffer buf1;  stcToBuffer(&buf1, stc1 | ((stc1 & STC.ref_) ? (fparam.storageClass & STC.auto_) : 0));
1441 1
                                OutBuffer buf2;  stcToBuffer(&buf2, stc2);
1442

1443 1
                                .error(loc, "incompatible parameter storage classes `%s` and `%s`",
1444
                                    buf1.peekChars(), buf2.peekChars());
1445 1
                                errors = true;
1446 1
                                stc = stc1 | (stc & ~(STC.ref_ | STC.out_ | STC.lazy_));
1447
                            }
1448

1449
                            /* https://issues.dlang.org/show_bug.cgi?id=18572
1450
                             *
1451
                             * If a tuple parameter has a default argument, when expanding the parameter
1452
                             * tuple the default argument tuple must also be expanded.
1453
                             */
1454 1
                            Expression paramDefaultArg = narg.defaultArg;
1455 1
                            TupleExp te = fparam.defaultArg ? fparam.defaultArg.isTupleExp() : null;
1456 1
                            if (te && te.exps && te.exps.length)
1457 1
                                paramDefaultArg = (*te.exps)[j];
1458

1459 1
                            (*newparams)[j] = new Parameter(
1460
                                stc, narg.type, narg.ident, paramDefaultArg, narg.userAttribDecl);
1461
                        }
1462 1
                        fparam.type = new TypeTuple(newparams);
1463
                    }
1464 1
                    fparam.storageClass = STC.parameter;
1465

1466
                    /* Reset number of parameters, and back up one to do this fparam again,
1467
                     * now that it is a tuple
1468
                     */
1469 1
                    dim = tf.parameterList.length;
1470 1
                    i--;
1471 1
                    continue;
1472
                }
1473

1474 1
                if (fparam.storageClass & STC.scope_ && !fparam.type.hasPointers())
1475
                {
1476
                    /*     X foo(ref return scope X) => Ref-ReturnScope
1477
                     * ref X foo(ref return scope X) => ReturnRef-Scope
1478
                     * But X has no pointers, we don't need the scope part, so:
1479
                     *     X foo(ref return scope X) => Ref
1480
                     * ref X foo(ref return scope X) => ReturnRef
1481
                     * Constructors are treated as if they are being returned through the hidden parameter,
1482
                     * which is by ref, and the ref there is ignored.
1483
                     */
1484 1
                    fparam.storageClass &= ~STC.scope_;
1485 1
                    if (!tf.isref || (sc.flags & SCOPE.ctor))
1486 1
                        fparam.storageClass &= ~STC.return_;
1487
                }
1488

1489
                /* Resolve "auto ref" storage class to be either ref or value,
1490
                 * based on the argument matching the parameter
1491
                 */
1492 1
                if (fparam.storageClass & STC.auto_)
1493
                {
1494 1
                    Expression farg = mtype.fargs && i < mtype.fargs.dim ? (*mtype.fargs)[i] : fparam.defaultArg;
1495 1
                    if (farg && (fparam.storageClass & STC.ref_))
1496
                    {
1497 1
                        if (farg.isLvalue())
1498
                        {
1499
                            // ref parameter
1500
                        }
1501
                        else
1502 1
                            fparam.storageClass &= ~STC.ref_; // value parameter
1503 1
                        fparam.storageClass &= ~STC.auto_;    // https://issues.dlang.org/show_bug.cgi?id=14656
1504 1
                        fparam.storageClass |= STC.autoref;
1505
                    }
1506 1
                    else if (mtype.incomplete && (fparam.storageClass & STC.ref_))
1507
                    {
1508
                        // the default argument may have been temporarily removed,
1509
                        // see usage of `TypeFunction.incomplete`.
1510
                        // https://issues.dlang.org/show_bug.cgi?id=19891
1511 1
                        fparam.storageClass &= ~STC.auto_;
1512 1
                        fparam.storageClass |= STC.autoref;
1513
                    }
1514
                    else
1515
                    {
1516 1
                        .error(loc, "`auto` can only be used as part of `auto ref` for template function parameters");
1517 1
                        errors = true;
1518
                    }
1519
                }
1520

1521
                // Remove redundant storage classes for type, they are already applied
1522 1
                fparam.storageClass &= ~(STC.TYPECTOR);
1523
            }
1524 1
            argsc.pop();
1525
        }
1526 1
        if (tf.isWild())
1527 1
            wildparams |= 2;
1528

1529 1
        if (wildreturn && !wildparams)
1530
        {
1531 1
            .error(loc, "`inout` on `return` means `inout` must be on a parameter as well for `%s`", mtype.toChars());
1532 1
            errors = true;
1533
        }
1534 1
        tf.isInOutParam = (wildparams & 1) != 0;
1535 1
        tf.isInOutQual  = (wildparams & 2) != 0;
1536

1537 1
        if (tf.isproperty && (tf.parameterList.varargs != VarArg.none || tf.parameterList.length > 2))
1538
        {
1539 1
            .error(loc, "properties can only have zero, one, or two parameter");
1540 1
            errors = true;
1541
        }
1542

1543 1
        if (tf.parameterList.varargs == VarArg.variadic && tf.linkage != LINK.d && tf.parameterList.length == 0)
1544
        {
1545 0
            .error(loc, "variadic functions with non-D linkage must have at least one parameter");
1546 0
            errors = true;
1547
        }
1548

1549 1
        if (errors)
1550 1
            return error();
1551

1552 1
        if (tf.next)
1553 1
            tf.deco = tf.merge().deco;
1554

1555
        /* Don't return merge(), because arg identifiers and default args
1556
         * can be different
1557
         * even though the types match
1558
         */
1559 1
        return tf;
1560
    }
1561

1562
    Type visitDelegate(TypeDelegate mtype)
1563
    {
1564
        //printf("TypeDelegate::semantic() %s\n", toChars());
1565 1
        if (mtype.deco) // if semantic() already run
1566
        {
1567
            //printf("already done\n");
1568 1
            return mtype;
1569
        }
1570 1
        mtype.next = mtype.next.typeSemantic(loc, sc);
1571 1
        if (mtype.next.ty != Tfunction)
1572 1
            return error();
1573

1574
        /* In order to deal with https://issues.dlang.org/show_bug.cgi?id=4028
1575
         * perhaps default arguments should
1576
         * be removed from next before the merge.
1577
         */
1578
        version (none)
1579
        {
1580
            return mtype.merge();
1581
        }
1582
        else
1583
        {
1584
            /* Don't return merge(), because arg identifiers and default args
1585
             * can be different
1586
             * even though the types match
1587
             */
1588 1
            mtype.deco = mtype.merge().deco;
1589 1
            return mtype;
1590
        }
1591
    }
1592

1593
    Type visitIdentifier(TypeIdentifier mtype)
1594
    {
1595 1
        Type t;
1596 1
        Expression e;
1597 1
        Dsymbol s;
1598
        //printf("TypeIdentifier::semantic(%s)\n", mtype.toChars());
1599 1
        mtype.resolve(loc, sc, &e, &t, &s);
1600 1
        if (t)
1601
        {
1602
            //printf("\tit's a type %d, %s, %s\n", t.ty, t.toChars(), t.deco);
1603 1
            return t.addMod(mtype.mod);
1604
        }
1605
        else
1606
        {
1607 1
            if (s)
1608
            {
1609 1
                auto td = s.isTemplateDeclaration;
1610 1
                if (td && td.onemember && td.onemember.isAggregateDeclaration)
1611 1
                    .error(loc, "template %s `%s` is used as a type without instantiation"
1612
                        ~ "; to instantiate it use `%s!(arguments)`",
1613
                        s.kind, s.toPrettyChars, s.ident.toChars);
1614
                else
1615 1
                    .error(loc, "%s `%s` is used as a type", s.kind, s.toPrettyChars);
1616
                //assert(0);
1617
            }
1618 1
            else if (e.op == TOK.variable) // special case: variable is used as a type
1619
            {
1620 1
                Dsymbol varDecl = mtype.toDsymbol(sc);
1621 1
                const(Loc) varDeclLoc = varDecl.getLoc();
1622 1
                Module varDeclModule = varDecl.getModule();
1623

1624 1
                .error(loc, "variable `%s` is used as a type", mtype.toChars());
1625

1626 1
                if (varDeclModule != sc._module) // variable is imported
1627
                {
1628 1
                    const(Loc) varDeclModuleImportLoc = varDeclModule.getLoc();
1629 1
                    .errorSupplemental(
1630
                        varDeclModuleImportLoc,
1631
                        "variable `%s` is imported here from: `%s`",
1632
                        varDecl.toChars,
1633
                        varDeclModule.toPrettyChars,
1634
                    );
1635
                }
1636

1637 1
                .errorSupplemental(varDeclLoc, "variable `%s` is declared here", varDecl.toChars);
1638
            }
1639
            else
1640 1
                .error(loc, "`%s` is used as a type", mtype.toChars());
1641 1
            return error();
1642
        }
1643
    }
1644

1645
    Type visitInstance(TypeInstance mtype)
1646
    {
1647 1
        Type t;
1648 1
        Expression e;
1649 1
        Dsymbol s;
1650

1651
        //printf("TypeInstance::semantic(%p, %s)\n", this, toChars());
1652
        {
1653 1
            const errors = global.errors;
1654 1
            mtype.resolve(loc, sc, &e, &t, &s);
1655
            // if we had an error evaluating the symbol, suppress further errors
1656 1
            if (!t && errors != global.errors)
1657 1
                return error();
1658
        }
1659

1660 1
        if (!t)
1661
        {
1662 1
            if (!e && s && s.errors)
1663
            {
1664
                // if there was an error evaluating the symbol, it might actually
1665
                // be a type. Avoid misleading error messages.
1666 0
               .error(loc, "`%s` had previous errors", mtype.toChars());
1667
            }
1668
            else
1669 1
               .error(loc, "`%s` is used as a type", mtype.toChars());
1670 1
            return error();
1671
        }
1672 1
        return t;
1673
    }
1674

1675
    Type visitTypeof(TypeTypeof mtype)
1676
    {
1677
        //printf("TypeTypeof::semantic() %s\n", mtype.toChars());
1678 1
        Expression e;
1679 1
        Type t;
1680 1
        Dsymbol s;
1681 1
        mtype.resolve(loc, sc, &e, &t, &s);
1682 1
        if (s && (t = s.getType()) !is null)
1683 0
            t = t.addMod(mtype.mod);
1684 1
        if (!t)
1685
        {
1686 0
            .error(loc, "`%s` is used as a type", mtype.toChars());
1687 0
            return error();
1688
        }
1689 1
        return t;
1690
    }
1691

1692
    Type visitTraits(TypeTraits mtype)
1693
    {
1694 1
        if (mtype.ty == Terror)
1695 0
            return mtype;
1696

1697 1
        const inAlias = (sc.flags & SCOPE.alias_) != 0;
1698 1
        if (mtype.exp.ident != Id.allMembers &&
1699 1
            mtype.exp.ident != Id.derivedMembers &&
1700 1
            mtype.exp.ident != Id.getMember &&
1701 1
            mtype.exp.ident != Id.parent &&
1702 1
            mtype.exp.ident != Id.child &&
1703 1
            mtype.exp.ident != Id.getOverloads &&
1704 1
            mtype.exp.ident != Id.getVirtualFunctions &&
1705 1
            mtype.exp.ident != Id.getVirtualMethods &&
1706 1
            mtype.exp.ident != Id.getAttributes &&
1707 1
            mtype.exp.ident != Id.getUnitTests &&
1708 1
            mtype.exp.ident != Id.getAliasThis)
1709
        {
1710
            static immutable (const(char)*)[2] ctxt = ["as type", "in alias"];
1711 1
            .error(mtype.loc, "trait `%s` is either invalid or not supported %s",
1712
                 mtype.exp.ident.toChars, ctxt[inAlias]);
1713 1
            mtype.ty = Terror;
1714 1
            return mtype;
1715
        }
1716

1717
        import dmd.traits : semanticTraits;
1718 1
        Type result;
1719

1720 1
        if (Expression e = semanticTraits(mtype.exp, sc))
1721
        {
1722 1
            switch (e.op)
1723
            {
1724 1
            case TOK.dotVariable:
1725 1
                mtype.sym = (cast(DotVarExp)e).var;
1726 1
                break;
1727 1
            case TOK.variable:
1728 1
                mtype.sym = (cast(VarExp)e).var;
1729 1
                break;
1730 0
            case TOK.function_:
1731 0
                auto fe = cast(FuncExp)e;
1732 0
                mtype.sym = fe.td ? fe.td : fe.fd;
1733 0
                break;
1734 0
            case TOK.dotTemplateDeclaration:
1735 0
                mtype.sym = (cast(DotTemplateExp)e).td;
1736 0
                break;
1737 0
            case TOK.dSymbol:
1738 0
                mtype.sym = (cast(DsymbolExp)e).s;
1739 0
                break;
1740 1
            case TOK.template_:
1741 1
                mtype.sym = (cast(TemplateExp)e).td;
1742 1
                break;
1743 1
            case TOK.scope_:
1744 1
                mtype.sym = (cast(ScopeExp)e).sds;
1745 1
                break;
1746 1
            case TOK.tuple:
1747 1
                TupleExp te = e.toTupleExp();
1748 1
                Objects* elems = new Objects(te.exps.dim);
1749 1
                foreach (i; 0 .. elems.dim)
1750
                {
1751 1
                    auto src = (*te.exps)[i];
1752 1
                    switch (src.op)
1753
                    {
1754 1
                    case TOK.type:
1755 1
                        (*elems)[i] = (cast(TypeExp)src).type;
1756 1
                        break;
1757 0
                    case TOK.dotType:
1758 0
                        (*elems)[i] = (cast(DotTypeExp)src).sym.isType();
1759 0
                        break;
1760 0
                    case TOK.overloadSet:
1761 0
                        (*elems)[i] = (cast(OverExp)src).type;
1762 0
                        break;
1763 1
                    default:
1764 1
                        if (auto sym = isDsymbol(src))
1765 0
                            (*elems)[i] = sym;
1766
                        else
1767 1
                            (*elems)[i] = src;
1768
                    }
1769
                }
1770 1
                TupleDeclaration td = new TupleDeclaration(e.loc, Identifier.generateId("__aliastup"), elems);
1771 1
                mtype.sym = td;
1772 1
                break;
1773 0
            case TOK.dotType:
1774 0
                result = (cast(DotTypeExp)e).sym.isType();
1775 0
                break;
1776 1
            case TOK.type:
1777 1
                result = (cast(TypeExp)e).type;
1778 1
                break;
1779 1
            case TOK.overloadSet:
1780 1
                result = (cast(OverExp)e).type;
1781 1
                break;
1782 0
            default:
1783 0
                break;
1784
            }
1785
        }
1786

1787 1
        if (result)
1788 1
            result = result.addMod(mtype.mod);
1789 1
        if (!inAlias && !result)
1790
        {
1791 1
            if (!global.errors)
1792 1
                .error(mtype.loc, "`%s` does not give a valid type", mtype.toChars);
1793 1
            return error();
1794
        }
1795

1796 1
        return result;
1797
    }
1798

1799
    Type visitReturn(TypeReturn mtype)
1800
    {
1801
        //printf("TypeReturn::semantic() %s\n", toChars());
1802 1
        Expression e;
1803 1
        Type t;
1804 1
        Dsymbol s;
1805 1
        mtype.resolve(loc, sc, &e, &t, &s);
1806 1
        if (s && (t = s.getType()) !is null)
1807 0
            t = t.addMod(mtype.mod);
1808 1
        if (!t)
1809
        {
1810 0
            .error(loc, "`%s` is used as a type", mtype.toChars());
1811 0
            return error();
1812
        }
1813 1
        return t;
1814
    }
1815

1816
    Type visitStruct(TypeStruct mtype)
1817
    {
1818
        //printf("TypeStruct::semantic('%s')\n", mtype.toChars());
1819 1
        if (mtype.deco)
1820 1
            return mtype;
1821

1822
        /* Don't semantic for sym because it should be deferred until
1823
         * sizeof needed or its members accessed.
1824
         */
1825
        // instead, parent should be set correctly
1826 1
        assert(mtype.sym.parent);
1827

1828 1
        if (mtype.sym.type.ty == Terror)
1829 0
            return error();
1830

1831 1
        return merge(mtype);
1832
    }
1833

1834
    Type visitEnum(TypeEnum mtype)
1835
    {
1836
        //printf("TypeEnum::semantic() %s\n", toChars());
1837 1
        return mtype.deco ? mtype : merge(mtype);
1838
    }
1839

1840
    Type visitClass(TypeClass mtype)
1841
    {
1842
        //printf("TypeClass::semantic(%s)\n", mtype.toChars());
1843 1
        if (mtype.deco)
1844 1
            return mtype;
1845

1846
        /* Don't semantic for sym because it should be deferred until
1847
         * sizeof needed or its members accessed.
1848
         */
1849
        // instead, parent should be set correctly
1850 1
        assert(mtype.sym.parent);
1851

1852 1
        if (mtype.sym.type.ty == Terror)
1853 0
            return error();
1854

1855 1
        return merge(mtype);
1856
    }
1857

1858
    Type visitTuple(TypeTuple mtype)
1859
    {
1860
        //printf("TypeTuple::semantic(this = %p)\n", this);
1861
        //printf("TypeTuple::semantic() %p, %s\n", this, toChars());
1862 1
        if (!mtype.deco)
1863 1
            mtype.deco = merge(mtype).deco;
1864

1865
        /* Don't return merge(), because a tuple with one type has the
1866
         * same deco as that type.
1867
         */
1868 1
        return mtype;
1869
    }
1870

1871
    Type visitSlice(TypeSlice mtype)
1872
    {
1873
        //printf("TypeSlice::semantic() %s\n", toChars());
1874 1
        Type tn = mtype.next.typeSemantic(loc, sc);
1875
        //printf("next: %s\n", tn.toChars());
1876

1877 1
        Type tbn = tn.toBasetype();
1878 1
        if (tbn.ty != Ttuple)
1879
        {
1880 1
            .error(loc, "can only slice tuple types, not `%s`", tbn.toChars());
1881 1
            return error();
1882
        }
1883 1
        TypeTuple tt = cast(TypeTuple)tbn;
1884

1885 1
        mtype.lwr = semanticLength(sc, tbn, mtype.lwr);
1886 1
        mtype.upr = semanticLength(sc, tbn, mtype.upr);
1887 1
        mtype.lwr = mtype.lwr.ctfeInterpret();
1888 1
        mtype.upr = mtype.upr.ctfeInterpret();
1889 1
        if (mtype.lwr.op == TOK.error || mtype.upr.op == TOK.error)
1890 0
            return error();
1891

1892 1
        uinteger_t i1 = mtype.lwr.toUInteger();
1893 1
        uinteger_t i2 = mtype.upr.toUInteger();
1894 1
        if (!(i1 <= i2 && i2 <= tt.arguments.dim))
1895
        {
1896 1
            .error(loc, "slice `[%llu..%llu]` is out of range of `[0..%llu]`",
1897
                cast(ulong)i1, cast(ulong)i2, cast(ulong)tt.arguments.dim);
1898 1
            return error();
1899
        }
1900

1901 1
        mtype.next = tn;
1902 1
        mtype.transitive();
1903

1904 1
        auto args = new Parameters();
1905 1
        args.reserve(cast(size_t)(i2 - i1));
1906 1
        foreach (arg; (*tt.arguments)[cast(size_t)i1 .. cast(size_t)i2])
1907
        {
1908 1
            args.push(arg);
1909
        }
1910 1
        Type t = new TypeTuple(args);
1911 1
        return t.typeSemantic(loc, sc);
1912
    }
1913

1914
    Type visitMixin(TypeMixin mtype)
1915
    {
1916
        //printf("TypeMixin::semantic() %s\n", toChars());
1917 1
        auto o = mtype.compileTypeMixin(loc, sc);
1918 1
        if (auto t = o.isType())
1919
        {
1920 1
            return t.typeSemantic(loc, sc).addMod(mtype.mod);
1921
        }
1922 1
        else if (auto e = o.isExpression())
1923
        {
1924 1
            e = e.expressionSemantic(sc);
1925 1
            if (auto et = e.isTypeExp())
1926 1
                return et.type.addMod(mtype.mod);
1927
            else
1928
            {
1929 0
                if (!global.errors)
1930 0
                    .error(e.loc, "`%s` does not give a valid type", o.toChars);
1931
            }
1932
        }
1933 0
        return error();
1934
    }
1935

1936 1
    switch (t.ty)
1937
    {
1938 1
        default:         return visitType(t);
1939 1
        case Tvector:    return visitVector(cast(TypeVector)t);
1940 1
        case Tsarray:    return visitSArray(cast(TypeSArray)t);
1941 1
        case Tarray:     return visitDArray(cast(TypeDArray)t);
1942 1
        case Taarray:    return visitAArray(cast(TypeAArray)t);
1943 1
        case Tpointer:   return visitPointer(cast(TypePointer)t);
1944 0
        case Treference: return visitReference(cast(TypeReference)t);
1945 1
        case Tfunction:  return visitFunction(cast(TypeFunction)t);
1946 1
        case Tdelegate:  return visitDelegate(cast(TypeDelegate)t);
1947 1
        case Tident:     return visitIdentifier(cast(TypeIdentifier)t);
1948 1
        case Tinstance:  return visitInstance(cast(TypeInstance)t);
1949 1
        case Ttypeof:    return visitTypeof(cast(TypeTypeof)t);
1950 1
        case Ttraits:    return visitTraits(cast(TypeTraits)t);
1951 1
        case Treturn:    return visitReturn(cast(TypeReturn)t);
1952 1
        case Tstruct:    return visitStruct(cast(TypeStruct)t);
1953 1
        case Tenum:      return visitEnum(cast(TypeEnum)t);
1954 1
        case Tclass:     return visitClass(cast(TypeClass)t);
1955 1
        case Ttuple:     return visitTuple (cast(TypeTuple)t);
1956 1
        case Tslice:     return visitSlice(cast(TypeSlice)t);
1957 1
        case Tmixin:     return visitMixin(cast(TypeMixin)t);
1958
    }
1959
}
1960

1961
/******************************************
1962
 * Compile the MixinType, returning the type or expression AST.
1963
 *
1964
 * Doesn't run semantic() on the returned object.
1965
 * Params:
1966
 *      tm = mixin to compile as a type or expression
1967
 *      loc = location for error messages
1968
 *      sc = context
1969
 * Return:
1970
 *      null if error, else RootObject AST as parsed
1971
 */
1972
RootObject compileTypeMixin(TypeMixin tm, Loc loc, Scope* sc)
1973
{
1974 1
    OutBuffer buf;
1975 1
    if (expressionsToString(buf, sc, tm.exps))
1976 0
        return null;
1977

1978 1
    const errors = global.errors;
1979 1
    const len = buf.length;
1980 1
    buf.writeByte(0);
1981 1
    const str = buf.extractSlice()[0 .. len];
1982 1
    scope p = new Parser!ASTCodegen(loc, sc._module, str, false);
1983 1
    p.nextToken();
1984
    //printf("p.loc.linnum = %d\n", p.loc.linnum);
1985

1986 1
    auto o = p.parseTypeOrAssignExp(TOK.endOfFile);
1987 1
    if (errors != global.errors)
1988
    {
1989 0
        assert(global.errors != errors); // should have caught all these cases
1990 0
        return null;
1991
    }
1992 1
    if (p.token.value != TOK.endOfFile)
1993
    {
1994 0
        .error(loc, "incomplete mixin type `%s`", str.ptr);
1995 0
        return null;
1996
    }
1997

1998 1
    Type t = o.isType();
1999 1
    Expression e = t ? t.typeToExpression() : o.isExpression();
2000

2001 1
    return (!e && t) ? t : e;
2002
}
2003

2004

2005
/************************************
2006
 * If an identical type to `type` is in `type.stringtable`, return
2007
 * the latter one. Otherwise, add it to `type.stringtable`.
2008
 * Some types don't get merged and are returned as-is.
2009
 * Params:
2010
 *      type = Type to check against existing types
2011
 * Returns:
2012
 *      the type that was merged
2013
 */
2014
Type merge(Type type)
2015
{
2016 1
    switch (type.ty)
2017
    {
2018 1
        case Terror:
2019 1
        case Ttypeof:
2020 1
        case Tident:
2021 1
        case Tinstance:
2022 1
        case Tmixin:
2023 1
            return type;
2024

2025 1
        case Tsarray:
2026
            // prevents generating the mangle if the array dim is not yet known
2027 1
            if (!(cast(TypeSArray) type).dim.isIntegerExp())
2028 1
                return type;
2029 1
            goto default;
2030

2031 1
        case Tenum:
2032 1
            break;
2033

2034 1
        case Taarray:
2035 1
            if (!(cast(TypeAArray)type).index.merge().deco)
2036 1
                return type;
2037 1
            goto default;
2038

2039 1
        default:
2040 1
            if (type.nextOf() && !type.nextOf().deco)
2041 1
                return type;
2042 1
            break;
2043
    }
2044

2045
    //printf("merge(%s)\n", toChars());
2046 1
    if (!type.deco)
2047
    {
2048 1
        OutBuffer buf;
2049 1
        buf.reserve(32);
2050

2051 1
        mangleToBuffer(type, &buf);
2052

2053 1
        auto sv = type.stringtable.update(buf[]);
2054 1
        if (sv.value)
2055
        {
2056 1
            Type t = sv.value;
2057
            debug
2058
            {
2059
                import core.stdc.stdio;
2060 1
                if (!t.deco)
2061 0
                    printf("t = %s\n", t.toChars());
2062
            }
2063 1
            assert(t.deco);
2064
            //printf("old value, deco = '%s' %p\n", t.deco, t.deco);
2065 1
            return t;
2066
        }
2067
        else
2068
        {
2069 1
            Type t = stripDefaultArgs(type);
2070 1
            sv.value = t;
2071 1
            type.deco = t.deco = cast(char*)sv.toDchars();
2072
            //printf("new value, deco = '%s' %p\n", t.deco, t.deco);
2073 1
            return t;
2074
        }
2075
    }
2076 1
    return type;
2077
}
2078

2079
/***************************************
2080
 * Calculate built-in properties which just the type is necessary.
2081
 *
2082
 * Params:
2083
 *  t = the type for which the property is calculated
2084
 *  scope_ = the scope from which the property is being accessed. Used for visibility checks only.
2085
 *  loc = the location where the property is encountered
2086
 *  ident = the identifier of the property
2087
 *  flag = if flag & 1, don't report "not a property" error and just return NULL.
2088
 * Returns:
2089
 *      expression representing the property, or null if not a property and (flag & 1)
2090
 */
2091
Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier ident, int flag)
2092
{
2093
    Expression visitType(Type mt)
2094
    {
2095 1
        Expression e;
2096
        static if (LOGDOTEXP)
2097
        {
2098
            printf("Type::getProperty(type = '%s', ident = '%s')\n", mt.toChars(), ident.toChars());
2099
        }
2100 1
        if (ident == Id.__sizeof)
2101
        {
2102 1
            d_uns64 sz = mt.size(loc);
2103 1
            if (sz == SIZE_INVALID)
2104 1
                return ErrorExp.get();
2105 1
            e = new IntegerExp(loc, sz, Type.tsize_t);
2106
        }
2107 1
        else if (ident == Id.__xalignof)
2108
        {
2109 1
            const explicitAlignment = mt.alignment();
2110 1
            const naturalAlignment = mt.alignsize();
2111 1
            const actualAlignment = (explicitAlignment == STRUCTALIGN_DEFAULT ? naturalAlignment : explicitAlignment);
2112 1
            e = new IntegerExp(loc, actualAlignment, Type.tsize_t);
2113
        }
2114 1
        else if (ident == Id._init)
2115
        {
2116 1
            Type tb = mt.toBasetype();
2117 1
            e = mt.defaultInitLiteral(loc);
2118 1
            if (tb.ty == Tstruct && tb.needsNested())
2119
            {
2120 1
                e.isStructLiteralExp().useStaticInit = true;
2121
            }
2122
        }
2123 1
        else if (ident == Id._mangleof)
2124
        {
2125 1
            if (!mt.deco)
2126
            {
2127 0
                error(loc, "forward reference of type `%s.mangleof`", mt.toChars());
2128 0
                e = ErrorExp.get();
2129
            }
2130
            else
2131
            {
2132 1
                e = new StringExp(loc, mt.deco.toDString());
2133 1
                Scope sc;
2134 1
                e = e.expressionSemantic(&sc);
2135
            }
2136
        }
2137 1
        else if (ident == Id.stringof)
2138
        {
2139 0
            const s = mt.toChars();
2140 0
            e = new StringExp(loc, s.toDString());
2141 0
            Scope sc;
2142 0
            e = e.expressionSemantic(&sc);
2143
        }
2144 1
        else if (flag && mt != Type.terror)
2145
        {
2146 1
            return null;
2147
        }
2148
        else
2149
        {
2150 1
            Dsymbol s = null;
2151 1
            if (mt.ty == Tstruct || mt.ty == Tclass || mt.ty == Tenum)
2152 1
                s = mt.toDsymbol(null);
2153 1
            if (s)
2154 1
                s = s.search_correct(ident);
2155 1
            if (s && !symbolIsVisible(scope_, s))
2156 1
                s = null;
2157 1
            if (mt != Type.terror)
2158
            {
2159 1
                if (s)
2160 1
                    error(loc, "no property `%s` for type `%s`, did you mean `%s`?", ident.toChars(), mt.toChars(), s.toPrettyChars());
2161
                else
2162
                {
2163 1
                    if (ident == Id.call && mt.ty == Tclass)
2164 1
                        error(loc, "no property `%s` for type `%s`, did you mean `new %s`?", ident.toChars(), mt.toChars(), mt.toPrettyChars());
2165
                    else
2166
                    {
2167 1
                        if (const n = importHint(ident.toString()))
2168 1
                            error(loc, "no property `%s` for type `%s`, perhaps `import %.*s;` is needed?", ident.toChars(), mt.toChars(), cast(int)n.length, n.ptr);
2169
                        else
2170 1
                            error(loc, "no property `%s` for type `%s`", ident.toChars(), mt.toPrettyChars(true));
2171
                    }
2172
                }
2173
            }
2174 1
            e = ErrorExp.get();
2175
        }
2176 1
        return e;
2177
    }
2178

2179
    Expression visitError(TypeError)
2180
    {
2181 1
        return ErrorExp.get();
2182
    }
2183

2184
    Expression visitBasic(TypeBasic mt)
2185
    {
2186
        Expression integerValue(dinteger_t i)
2187
        {
2188 1
            return new IntegerExp(loc, i, mt);
2189
        }
2190

2191
        Expression intValue(dinteger_t i)
2192
        {
2193 1
            return new IntegerExp(loc, i, Type.tint32);
2194
        }
2195

2196
        Expression floatValue(real_t r)
2197
        {
2198 1
            if (mt.isreal() || mt.isimaginary())
2199 1
                return new RealExp(loc, r, mt);
2200
            else
2201
            {
2202 1
                return new ComplexExp(loc, complex_t(r, r), mt);
2203
            }
2204
        }
2205

2206
        //printf("TypeBasic::getProperty('%s')\n", ident.toChars());
2207 1
        if (ident == Id.max)
2208
        {
2209 1
            switch (mt.ty)
2210
            {
2211 1
            case Tint8:        return integerValue(byte.max);
2212 1
            case Tuns8:        return integerValue(ubyte.max);
2213 1
            case Tint16:       return integerValue(short.max);
2214 1
            case Tuns16:       return integerValue(ushort.max);
2215 1
            case Tint32:       return integerValue(int.max);
2216 1
            case Tuns32:       return integerValue(uint.max);
2217 1
            case Tint64:       return integerValue(long.max);
2218 1
            case Tuns64:       return integerValue(ulong.max);
2219 1
            case Tbool:        return integerValue(bool.max);
2220 1
            case Tchar:        return integerValue(char.max);
2221 1
            case Twchar:       return integerValue(wchar.max);
2222 1
            case Tdchar:       return integerValue(dchar.max);
2223 0
            case Tcomplex32:
2224 1
            case Timaginary32:
2225 1
            case Tfloat32:     return floatValue(target.FloatProperties.max);
2226 0
            case Tcomplex64:
2227 0
            case Timaginary64:
2228 1
            case Tfloat64:     return floatValue(target.DoubleProperties.max);
2229 0
            case Tcomplex80:
2230 0
            case Timaginary80:
2231 1
            case Tfloat80:     return floatValue(target.RealProperties.max);
2232 0
            default:           break;
2233
            }
2234
        }
2235 1
        else if (ident == Id.min)
2236
        {
2237 1
            switch (mt.ty)
2238
            {
2239 1
            case Tint8:        return integerValue(byte.min);
2240 1
            case Tuns8:
2241 1
            case Tuns16:
2242 1
            case Tuns32:
2243 1
            case Tuns64:
2244 1
            case Tbool:
2245 1
            case Tchar:
2246 1
            case Twchar:
2247 1
            case Tdchar:       return integerValue(0);
2248 1
            case Tint16:       return integerValue(short.min);
2249 1
            case Tint32:       return integerValue(int.min);
2250 1
            case Tint64:       return integerValue(long.min);
2251 0
            default:           break;
2252
            }
2253
        }
2254 1
        else if (ident == Id.min_normal)
2255
        {
2256 1
            switch (mt.ty)
2257
            {
2258 0
            case Tcomplex32:
2259 0
            case Timaginary32:
2260 1
            case Tfloat32:     return floatValue(target.FloatProperties.min_normal);
2261 0
            case Tcomplex64:
2262 0
            case Timaginary64:
2263 1
            case Tfloat64:     return floatValue(target.DoubleProperties.min_normal);
2264 0
            case Tcomplex80:
2265 0
            case Timaginary80:
2266 1
            case Tfloat80:     return floatValue(target.RealProperties.min_normal);
2267 1
            default:           break;
2268
            }
2269
        }
2270 1
        else if (ident == Id.nan)
2271
        {
2272 1
            switch (mt.ty)
2273
            {
2274 1
            case Tcomplex32:
2275 1
            case Tcomplex64:
2276 1
            case Tcomplex80:
2277 1
            case Timaginary32:
2278 1
            case Timaginary64:
2279 1
            case Timaginary80:
2280 1
            case Tfloat32:
2281 1
            case Tfloat64:
2282 1
            case Tfloat80:     return floatValue(target.RealProperties.nan);
2283 1
            default:           break;
2284
            }
2285
        }
2286 1
        else if (ident == Id.infinity)
2287
        {
2288 1
            switch (mt.ty)
2289
            {
2290 0
            case Tcomplex32:
2291 0
            case Tcomplex64:
2292 1
            case Tcomplex80:
2293 1
            case Timaginary32:
2294 1
            case Timaginary64:
2295 1
            case Timaginary80:
2296 1
            case Tfloat32:
2297 1
            case Tfloat64:
2298 1
            case Tfloat80:     return floatValue(target.RealProperties.infinity);
2299 0
            default:           break;
2300
            }
2301
        }
2302 1
        else if (ident == Id.dig)
2303
        {
2304 1
            switch (mt.ty)
2305
            {
2306 0
            case Tcomplex32:
2307 0
            case Timaginary32:
2308 1
            case Tfloat32:     return intValue(target.FloatProperties.dig);
2309 0
            case Tcomplex64:
2310 0
            case Timaginary64:
2311 1
            case Tfloat64:     return intValue(target.DoubleProperties.dig);
2312 0
            case Tcomplex80:
2313 0
            case Timaginary80:
2314 1
            case Tfloat80:     return intValue(target.RealProperties.dig);
2315 0
            default:           break;
2316
            }
2317
        }
2318 1
        else if (ident == Id.epsilon)
2319
        {
2320 1
            switch (mt.ty)
2321
            {
2322 0
            case Tcomplex32:
2323 0
            case Timaginary32:
2324 1
            case Tfloat32:     return floatValue(target.FloatProperties.epsilon);
2325 0
            case Tcomplex64:
2326 0
            case Timaginary64:
2327 1
            case Tfloat64:     return floatValue(target.DoubleProperties.epsilon);
2328 0
            case Tcomplex80:
2329 0
            case Timaginary80:
2330 1
            case Tfloat80:     return floatValue(target.RealProperties.epsilon);
2331 1
            default:           break;
2332
            }
2333
        }
2334 1
        else if (ident == Id.mant_dig)
2335
        {
2336 1
            switch (mt.ty)
2337
            {
2338 0
            case Tcomplex32:
2339 0
            case Timaginary32:
2340 1
            case Tfloat32:     return intValue(target.FloatProperties.mant_dig);
2341 0
            case Tcomplex64:
2342 0
            case Timaginary64:
2343 1
            case Tfloat64:     return intValue(target.DoubleProperties.mant_dig);
2344 0
            case Tcomplex80:
2345 0
            case Timaginary80:
2346 1
            case Tfloat80:     return intValue(target.RealProperties.mant_dig);
2347 0
            default:           break;
2348
            }
2349
        }
2350 1
        else if (ident == Id.max_10_exp)
2351
        {
2352 1
            switch (mt.ty)
2353
            {
2354 0
            case Tcomplex32:
2355 0
            case Timaginary32:
2356 1
            case Tfloat32:     return intValue(target.FloatProperties.max_10_exp);
2357 0
            case Tcomplex64:
2358 0
            case Timaginary64:
2359 1
            case Tfloat64:     return intValue(target.DoubleProperties.max_10_exp);
2360 0
            case Tcomplex80:
2361 0
            case Timaginary80:
2362 1
            case Tfloat80:     return intValue(target.RealProperties.max_10_exp);
2363 0
            default:           break;
2364
            }
2365
        }
2366 1
        else if (ident == Id.max_exp)
2367
        {
2368 1
            switch (mt.ty)
2369
            {
2370 0
            case Tcomplex32:
2371 0
            case Timaginary32:
2372 1
            case Tfloat32:     return intValue(target.FloatProperties.max_exp);
2373 0
            case Tcomplex64:
2374 0
            case Timaginary64:
2375 1
            case Tfloat64:     return intValue(target.DoubleProperties.max_exp);
2376 0
            case Tcomplex80:
2377 0
            case Timaginary80:
2378 1
            case Tfloat80:     return intValue(target.RealProperties.max_exp);
2379 0
            default:           break;
2380
            }
2381
        }
2382 1
        else if (ident == Id.min_10_exp)
2383
        {
2384 1
            switch (mt.ty)
2385
            {
2386 0
            case Tcomplex32:
2387 0
            case Timaginary32:
2388 1
            case Tfloat32:     return intValue(target.FloatProperties.min_10_exp);
2389 0
            case Tcomplex64:
2390 0
            case Timaginary64:
2391 1
            case Tfloat64:     return intValue(target.DoubleProperties.min_10_exp);
2392 0
            case Tcomplex80:
2393 0
            case Timaginary80:
2394 1
            case Tfloat80:     return intValue(target.RealProperties.min_10_exp);
2395 0
            default:           break;
2396
            }
2397
        }
2398 1
        else if (ident == Id.min_exp)
2399
        {
2400 1
            switch (mt.ty)
2401
            {
2402 0
            case Tcomplex32:
2403 0
            case Timaginary32:
2404 1
            case Tfloat32:     return intValue(target.FloatProperties.min_exp);
2405 0
            case Tcomplex64:
2406 0
            case Timaginary64:
2407 1
            case Tfloat64:     return intValue(target.DoubleProperties.min_exp);
2408 0
            case Tcomplex80:
2409 0
            case Timaginary80:
2410 1
            case Tfloat80:     return intValue(target.RealProperties.min_exp);
2411 0
            default:           break;
2412
            }
2413
        }
2414 1
        return visitType(mt);
2415
    }
2416

2417
    Expression visitVector(TypeVector mt)
2418
    {
2419 1
        return visitType(mt);
2420
    }
2421

2422
    Expression visitEnum(TypeEnum mt)
2423
    {
2424 1
        Expression e;
2425 1
        if (ident == Id.max || ident == Id.min)
2426
        {
2427 1
            return mt.sym.getMaxMinValue(loc, ident);
2428
        }
2429 1
        else if (ident == Id._init)
2430
        {
2431 1
            e = mt.defaultInitLiteral(loc);
2432
        }
2433 1
        else if (ident == Id.stringof)
2434
        {
2435 0
            e = new StringExp(loc, mt.toString());
2436 0
            Scope sc;
2437 0
            e = e.expressionSemantic(&sc);
2438
        }
2439 1
        else if (ident == Id._mangleof)
2440
        {
2441 1
            e = visitType(mt);
2442
        }
2443
        else
2444
        {
2445 1
            e = mt.toBasetype().getProperty(scope_, loc, ident, flag);
2446
        }
2447 1
        return e;
2448
    }
2449

2450
    Expression visitTuple(TypeTuple mt)
2451
    {
2452 1
        Expression e;
2453
        static if (LOGDOTEXP)
2454
        {
2455
            printf("TypeTuple::getProperty(type = '%s', ident = '%s')\n", mt.toChars(), ident.toChars());
2456
        }
2457 1
        if (ident == Id.length)
2458
        {
2459 1
            e = new IntegerExp(loc, mt.arguments.dim, Type.tsize_t);
2460
        }
2461 1
        else if (ident == Id._init)
2462
        {
2463 1
            e = mt.defaultInitLiteral(loc);
2464
        }
2465 1
        else if (flag)
2466
        {
2467 1
            e = null;
2468
        }
2469
        else
2470
        {
2471 1
            error(loc, "no property `%s` for tuple `%s`", ident.toChars(), mt.toChars());
2472 1
            e = ErrorExp.get();
2473
        }
2474 1
        return e;
2475
    }
2476

2477 1
    switch (t.ty)
2478
    {
2479 1
        default:        return t.isTypeBasic() ?
2480 1
                                visitBasic(cast(TypeBasic)t) :
2481 1
                                visitType(t);
2482

2483 1
        case Terror:    return visitError (cast(TypeError)t);
2484 1
        case Tvector:   return visitVector(cast(TypeVector)t);
2485 1
        case Tenum:     return visitEnum  (cast(TypeEnum)t);
2486 1
        case Ttuple:    return visitTuple (cast(TypeTuple)t);
2487
    }
2488
}
2489

2490
/***************************************
2491
 * Normalize `e` as the result of resolve() process.
2492
 */
2493
private void resolveExp(Expression e, Type *pt, Expression *pe, Dsymbol* ps)
2494
{
2495 1
    *pt = null;
2496 1
    *pe = null;
2497 1
    *ps = null;
2498

2499 1
    Dsymbol s;
2500 1
    switch (e.op)
2501
    {
2502 1
        case TOK.error:
2503 1
            *pt = Type.terror;
2504 1
            return;
2505

2506 1
        case TOK.type:
2507 1
            *pt = e.type;
2508 1
            return;
2509

2510 1
        case TOK.variable:
2511 1
            s = (cast(VarExp)e).var;
2512 1
            if (s.isVarDeclaration())
2513 1
                goto default;
2514
            //if (s.isOverDeclaration())
2515
            //    todo;
2516 1
            break;
2517

2518 1
        case TOK.template_:
2519
            // TemplateDeclaration
2520 1
            s = (cast(TemplateExp)e).td;
2521 1
            break;
2522

2523 1
        case TOK.scope_:
2524 1
            s = (cast(ScopeExp)e).sds;
2525
            // TemplateDeclaration, TemplateInstance, Import, Package, Module
2526 1
            break;
2527

2528 0
        case TOK.function_:
2529 0
            s = getDsymbol(e);
2530 0
            break;
2531

2532 1
        case TOK.dotTemplateDeclaration:
2533 1
            s = (cast(DotTemplateExp)e).td;
2534 1
            break;
2535

2536
        //case TOK.this_:
2537
        //case TOK.super_:
2538

2539
        //case TOK.tuple:
2540

2541
        //case TOK.overloadSet:
2542

2543
        //case TOK.dotVariable:
2544
        //case TOK.dotTemplateInstance:
2545
        //case TOK.dotType:
2546
        //case TOK.dotIdentifier:
2547

2548 1
        default:
2549 1
            *pe = e;
2550 1
            return;
2551
    }
2552

2553 1
    *ps = s;
2554
}
2555

2556
/************************************
2557
 * Resolve type 'mt' to either type, symbol, or expression.
2558
 * If errors happened, resolved to Type.terror.
2559
 *
2560
 * Params:
2561
 *  mt = type to be resolved
2562
 *  loc = the location where the type is encountered
2563
 *  sc = the scope of the type
2564
 *  pe = is set if t is an expression
2565
 *  pt = is set if t is a type
2566
 *  ps = is set if t is a symbol
2567
 *  intypeid = true if in type id
2568
 */
2569
void resolve(Type mt, const ref Loc loc, Scope* sc, Expression* pe, Type* pt, Dsymbol* ps, bool intypeid = false)
2570
{
2571
    void returnExp(Expression e)
2572
    {
2573 1
        *pt = null;
2574 1
        *pe = e;
2575 1
        *ps = null;
2576
    }
2577

2578
    void returnType(Type t)
2579
    {
2580 1
        *pt = t;
2581 1
        *pe = null;
2582 1
        *ps = null;
2583
    }
2584

2585
    void returnSymbol(Dsymbol s)
2586
    {
2587 1
        *pt = null;
2588 1
        *pe = null;
2589 1
        *ps = s;
2590
    }
2591

2592
    void returnError()
2593
    {
2594 1
        returnType(Type.terror);
2595
    }
2596

2597
    void visitType(Type mt)
2598
    {
2599
        //printf("Type::resolve() %s, %d\n", mt.toChars(), mt.ty);
2600 1
        Type t = typeSemantic(mt, loc, sc);
2601 1
        assert(t);
2602 1
        returnType(t);
2603
    }
2604

2605
    void visitSArray(TypeSArray mt)
2606
    {
2607
        //printf("TypeSArray::resolve() %s\n", mt.toChars());
2608 1
        mt.next.resolve(loc, sc, pe, pt, ps, intypeid);
2609
        //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
2610 1
        if (*pe)
2611
        {
2612
            // It's really an index expression
2613 1
            if (Dsymbol s = getDsymbol(*pe))
2614 1
                *pe = new DsymbolExp(loc, s);
2615 1
            returnExp(new ArrayExp(loc, *pe, mt.dim));
2616
        }
2617 1
        else if (*ps)
2618
        {
2619 1
            Dsymbol s = *ps;
2620 1
            if (auto tup = s.isTupleDeclaration())
2621
            {
2622 1
                mt.dim = semanticLength(sc, tup, mt.dim);
2623 1
                mt.dim = mt.dim.ctfeInterpret();
2624 1
                if (mt.dim.op == TOK.error)
2625 0
                    return returnError();
2626

2627 1
                const d = mt.dim.toUInteger();
2628 1
                if (d >= tup.objects.dim)
2629
                {
2630 1
                    error(loc, "tuple index `%llu` exceeds length %llu", d, cast(ulong) tup.objects.dim);
2631 1
                    return returnError();
2632
                }
2633

2634 1
                RootObject o = (*tup.objects)[cast(size_t)d];
2635 1
                if (o.dyncast() == DYNCAST.dsymbol)
2636
                {
2637 1
                    return returnSymbol(cast(Dsymbol)o);
2638
                }
2639 1
                if (o.dyncast() == DYNCAST.expression)
2640
                {
2641 1
                    Expression e = cast(Expression)o;
2642 1
                    if (e.op == TOK.dSymbol)
2643 1
                        return returnSymbol((cast(DsymbolExp)e).s);
2644
                    else
2645 1
                        return returnExp(e);
2646
                }
2647 1
                if (o.dyncast() == DYNCAST.type)
2648
                {
2649 1
                    return returnType((cast(Type)o).addMod(mt.mod));
2650
                }
2651

2652
                /* Create a new TupleDeclaration which
2653
                 * is a slice [d..d+1] out of the old one.
2654
                 * Do it this way because TemplateInstance::semanticTiargs()
2655
                 * can handle unresolved Objects this way.
2656
                 */
2657 0
                auto objects = new Objects(1);
2658 0
                (*objects)[0] = o;
2659 0
                return returnSymbol(new TupleDeclaration(loc, tup.ident, objects));
2660
            }
2661
            else
2662 0
                return visitType(mt);
2663
        }
2664
        else
2665
        {
2666 1
            if ((*pt).ty != Terror)
2667 1
                mt.next = *pt; // prevent re-running semantic() on 'next'
2668 1
            visitType(mt);
2669
        }
2670

2671
    }
2672

2673
    void visitDArray(TypeDArray mt)
2674
    {
2675
        //printf("TypeDArray::resolve() %s\n", mt.toChars());
2676 1
        mt.next.resolve(loc, sc, pe, pt, ps, intypeid);
2677
        //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
2678 1
        if (*pe)
2679
        {
2680
            // It's really a slice expression
2681 1
            if (Dsymbol s = getDsymbol(*pe))
2682 1
                *pe = new DsymbolExp(loc, s);
2683 1
            returnExp(new ArrayExp(loc, *pe));
2684
        }
2685 1
        else if (*ps)
2686
        {
2687 1
            if (auto tup = (*ps).isTupleDeclaration())
2688
            {
2689
                // keep *ps
2690
            }
2691
            else
2692 0
                visitType(mt);
2693
        }
2694
        else
2695
        {
2696 1
            if ((*pt).ty != Terror)
2697 1
                mt.next = *pt; // prevent re-running semantic() on 'next'
2698 1
            visitType(mt);
2699
        }
2700
    }
2701

2702
    void visitAArray(TypeAArray mt)
2703
    {
2704
        //printf("TypeAArray::resolve() %s\n", mt.toChars());
2705
        // Deal with the case where we thought the index was a type, but
2706
        // in reality it was an expression.
2707 1
        if (mt.index.ty == Tident || mt.index.ty == Tinstance || mt.index.ty == Tsarray)
2708
        {
2709 1
            Expression e;
2710 1
            Type t;
2711 1
            Dsymbol s;
2712 1
            mt.index.resolve(loc, sc, &e, &t, &s, intypeid);
2713 1
            if (e)
2714
            {
2715
                // It was an expression -
2716
                // Rewrite as a static array
2717 1
                auto tsa = new TypeSArray(mt.next, e);
2718 1
                tsa.mod = mt.mod; // just copy mod field so tsa's semantic is not yet done
2719 1
                return tsa.resolve(loc, sc, pe, pt, ps, intypeid);
2720
            }
2721 1
            else if (t)
2722 1
                mt.index = t;
2723
            else
2724 0
                .error(loc, "index is not a type or an expression");
2725
        }
2726 1
        visitType(mt);
2727
    }
2728

2729
    /*************************************
2730
     * Takes an array of Identifiers and figures out if
2731
     * it represents a Type or an Expression.
2732
     * Output:
2733
     *      if expression, *pe is set
2734
     *      if type, *pt is set
2735
     */
2736
    void visitIdentifier(TypeIdentifier mt)
2737
    {
2738
        //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, mt.toChars());
2739 1
        if ((mt.ident.equals(Id._super) || mt.ident.equals(Id.This)) && !hasThis(sc))
2740
        {
2741
            // @@@DEPRECATED_v2.091@@@.
2742
            // Made an error in 2.086.
2743
            // Eligible for removal in 2.091.
2744 1
            if (mt.ident.equals(Id._super))
2745
            {
2746 1
                error(mt.loc, "Using `super` as a type is obsolete. Use `typeof(super)` instead");
2747
            }
2748
             // @@@DEPRECATED_v2.091@@@.
2749
            // Made an error in 2.086.
2750
            // Eligible for removal in 2.091.
2751 1
            if (mt.ident.equals(Id.This))
2752
            {
2753 1
                error(mt.loc, "Using `this` as a type is obsolete. Use `typeof(this)` instead");
2754
            }
2755 1
            if (AggregateDeclaration ad = sc.getStructClassScope())
2756
            {
2757 1
                if (ClassDeclaration cd = ad.isClassDeclaration())
2758
                {
2759 1
                    if (mt.ident.equals(Id.This))
2760 1
                        mt.ident = cd.ident;
2761 1
                    else if (cd.baseClass && mt.ident.equals(Id._super))
2762 1
                        mt.ident = cd.baseClass.ident;
2763
                }
2764
                else
2765
                {
2766