/**
 * Semantic analysis of expressions.
 *
 * Specification: ($LINK2 https://dlang.org/spec/expression.html, Expressions)
 *
 * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
 * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
 * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/expressionsem.d, _expressionsem.d)
 * Documentation:  https://dlang.org/phobos/dmd_expressionsem.html
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/expressionsem.d
 */

module dmd.expressionsem;

import core.stdc.stdio;

import dmd.access;
import dmd.aggregate;
import dmd.aliasthis;
import dmd.arrayop;
import dmd.arraytypes;
import dmd.attrib;
import dmd.astcodegen;
import dmd.astenums;
import dmd.canthrow;
import dmd.chkformat;
import dmd.ctorflow;
import dmd.dscope;
import dmd.dsymbol;
import dmd.declaration;
import dmd.dclass;
import dmd.dcast;
import dmd.delegatize;
import dmd.denum;
import dmd.dimport;
import dmd.dinterpret;
import dmd.dmangle;
import dmd.dmodule;
import dmd.dstruct;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
import dmd.escape;
import dmd.expression;
import dmd.file_manager;
import dmd.func;
import dmd.globals;
import dmd.hdrgen;
import dmd.id;
import dmd.identifier;
import dmd.imphint;
import dmd.importc;
import dmd.init;
import dmd.initsem;
import dmd.inline;
import dmd.intrange;
import dmd.mtype;
import dmd.mustuse;
import dmd.nspace;
import dmd.opover;
import dmd.optimize;
import dmd.parse;
import dmd.printast;
import dmd.root.array;
import dmd.root.ctfloat;
import dmd.root.file;
import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.rootobject;
import dmd.root.string;
import dmd.root.utf;
import dmd.semantic2;
import dmd.semantic3;
import dmd.sideeffect;
import dmd.safe;
import dmd.target;
import dmd.tokens;
import dmd.traits;
import dmd.typesem;
import dmd.typinf;
import dmd.utils;
import dmd.visitor;

enum LOGSEMANTIC = false;

/********************************************************
 * Perform semantic analysis and CTFE on expressions to produce
 * a string.
 * Params:
 *      buf = append generated string to buffer
 *      sc = context
 *      exps = array of Expressions
 * Returns:
 *      true on error
 */
bool expressionsToString(ref OutBuffer buf, Scope* sc, Expressions* exps)
{
    if (!exps)
        return false;

    foreach (ex; *exps)
    {
        if (!ex)
            continue;
        auto sc2 = sc.startCTFE();
        auto e2 = ex.expressionSemantic(sc2);
        auto e3 = resolveProperties(sc2, e2);
        sc2.endCTFE();

        // allowed to contain types as well as expressions
        auto e4 = ctfeInterpretForPragmaMsg(e3);
        if (!e4 || e4.op == EXP.error)
            return true;

        // expand tuple
        if (auto te = e4.isTupleExp())
        {
            if (expressionsToString(buf, sc, te.exps))
                return true;
            continue;
        }
        // char literals exp `.toStringExp` return `null` but we cant override it
        // because in most contexts we don't want the conversion to succeed.
        IntegerExp ie = e4.isIntegerExp();
        const ty = (ie && ie.type) ? ie.type.ty : Terror;
        if (ty.isSomeChar)
        {
            auto tsa = new TypeSArray(ie.type, IntegerExp.literal!1);
            e4 = new ArrayLiteralExp(ex.loc, tsa, ie);
        }

        if (StringExp se = e4.toStringExp())
            buf.writestring(se.toUTF8(sc).peekString());
        else
            buf.writestring(e4.toString());
    }
    return false;
}


/***********************************************************
 * Resolve `exp` as a compile-time known string.
 * Params:
 *  sc  = scope
 *  exp = Expression which expected as a string
 *  s   = What the string is expected for, will be used in error diagnostic.
 * Returns:
 *  String literal, or `null` if error happens.
 */
StringExp semanticString(Scope *sc, Expression exp, const char* s)
{
    sc = sc.startCTFE();
    exp = exp.expressionSemantic(sc);
    exp = resolveProperties(sc, exp);
    sc = sc.endCTFE();

    if (exp.op == EXP.error)
        return null;

    auto e = exp;
    if (exp.type.isString())
    {
        e = e.ctfeInterpret();
        if (e.op == EXP.error)
            return null;
    }

    auto se = e.toStringExp();
    if (!se)
    {
        exp.error("`string` expected for %s, not `(%s)` of type `%s`",
            s, exp.toChars(), exp.type.toChars());
        return null;
    }
    return se;
}

private Expression extractOpDollarSideEffect(Scope* sc, UnaExp ue)
{
    Expression e0;
    Expression e1 = Expression.extractLast(ue.e1, e0);
    // https://issues.dlang.org/show_bug.cgi?id=12585
    // Extract the side effect part if ue.e1 is comma.

    if ((sc.flags & SCOPE.ctfe) ? hasSideEffect(e1) : !isTrivialExp(e1)) // match logic in extractSideEffect()
    {
        /* Even if opDollar is needed, 'e1' should be evaluate only once. So
         * Rewrite:
         *      e1.opIndex( ... use of $ ... )
         *      e1.opSlice( ... use of $ ... )
         * as:
         *      (ref __dop = e1, __dop).opIndex( ... __dop.opDollar ...)
         *      (ref __dop = e1, __dop).opSlice( ... __dop.opDollar ...)
         */
        e1 = extractSideEffect(sc, "__dop", e0, e1, false);
        assert(e1.isVarExp());
        e1.isVarExp().var.storage_class |= STC.exptemp;     // lifetime limited to expression
    }
    ue.e1 = e1;
    return e0;
}

/**************************************
 * Runs semantic on ae.arguments. Declares temporary variables
 * if '$' was used.
 */
Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
{
    assert(!ae.lengthVar);
    *pe0 = null;
    AggregateDeclaration ad = isAggregate(ae.e1.type);
    Dsymbol slice = search_function(ad, Id.slice);
    //printf("slice = %s %s\n", slice.kind(), slice.toChars());
    foreach (i, e; *ae.arguments)
    {
        if (i == 0)
            *pe0 = extractOpDollarSideEffect(sc, ae);

        if (e.op == EXP.interval && !(slice && slice.isTemplateDeclaration()))
        {
        Lfallback:
            if (ae.arguments.dim == 1)
                return null;
            ae.error("multi-dimensional slicing requires template `opSlice`");
            return ErrorExp.get();
        }
        //printf("[%d] e = %s\n", i, e.toChars());

        // Create scope for '$' variable for this dimension
        auto sym = new ArrayScopeSymbol(sc, ae);
        sym.parent = sc.scopesym;
        sc = sc.push(sym);
        ae.lengthVar = null; // Create it only if required
        ae.currentDimension = i; // Dimension for $, if required

        e = e.expressionSemantic(sc);
        e = resolveProperties(sc, e);

        if (ae.lengthVar && sc.func)
        {
            // If $ was used, declare it now
            Expression de = new DeclarationExp(ae.loc, ae.lengthVar);
            de = de.expressionSemantic(sc);
            *pe0 = Expression.combine(*pe0, de);
        }
        sc = sc.pop();

        if (auto ie = e.isIntervalExp())
        {
            auto tiargs = new Objects();
            Expression edim = new IntegerExp(ae.loc, i, Type.tsize_t);
            edim = edim.expressionSemantic(sc);
            tiargs.push(edim);

            auto fargs = new Expressions(2);
            (*fargs)[0] = ie.lwr;
            (*fargs)[1] = ie.upr;

            uint xerrors = global.startGagging();
            sc = sc.push();
            FuncDeclaration fslice = resolveFuncCall(ae.loc, sc, slice, tiargs, ae.e1.type, fargs, FuncResolveFlag.quiet);
            sc = sc.pop();
            global.endGagging(xerrors);
            if (!fslice)
                goto Lfallback;

            e = new DotTemplateInstanceExp(ae.loc, ae.e1, slice.ident, tiargs);
            e = new CallExp(ae.loc, e, fargs);
            e = e.expressionSemantic(sc);
        }

        if (!e.type)
        {
            ae.error("`%s` has no value", e.toChars());
            e = ErrorExp.get();
        }
        if (e.op == EXP.error)
            return e;

        (*ae.arguments)[i] = e;
    }
    return ae;
}

/**************************************
 * Runs semantic on se.lwr and se.upr. Declares a temporary variable
 * if '$' was used.
 * Returns:
 *      ae, or ErrorExp if errors occurred
 */
Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* pe0)
{
    //assert(!ae.lengthVar);
    if (!ie)
        return ae;

    VarDeclaration lengthVar = ae.lengthVar;
    bool errors = false;

    // create scope for '$'
    auto sym = new ArrayScopeSymbol(sc, ae);
    sym.parent = sc.scopesym;
    sc = sc.push(sym);

    Expression sem(Expression e)
    {
        e = e.expressionSemantic(sc);
        e = resolveProperties(sc, e);
        if (!e.type)
        {
            ae.error("`%s` has no value", e.toChars());
            errors = true;
        }
        return e;
    }

    ie.lwr = sem(ie.lwr);
    ie.upr = sem(ie.upr);

    if (ie.lwr.isErrorExp() || ie.upr.isErrorExp())
        errors = true;

    if (lengthVar != ae.lengthVar && sc.func)
    {
        // If $ was used, declare it now
        Expression de = new DeclarationExp(ae.loc, ae.lengthVar);
        de = de.expressionSemantic(sc);
        *pe0 = Expression.combine(*pe0, de);
    }

    sc = sc.pop();

    return errors ? ErrorExp.get() : ae;
}

/******************************
 * Perform semantic() on an array of Expressions.
 */
extern(D) bool arrayExpressionSemantic(
    Expression[] exps, Scope* sc, bool preserveErrors = false)
{
    bool err = false;
    foreach (ref e; exps)
    {
        if (e is null) continue;
        auto e2 = e.expressionSemantic(sc);
        if (e2.op == EXP.error)
            err = true;
        if (preserveErrors || e2.op != EXP.error)
            e = e2;
    }
    return err;
}

/*
Checks if `exp` contains a direct access to a `noreturn`
variable. If that is the case, an `assert(0)` expression
is generated and returned. This function should be called
only after semantic analysis has been performed on `exp`.

Params:
    exp = expression that is checked

Returns:
    An `assert(0)` expression if `exp` contains a `noreturn`
    variable access, `exp` otherwise.
*/

Expression checkNoreturnVarAccess(Expression exp)
{
    assert(exp.type);

    Expression result = exp;
    if (exp.type.isTypeNoreturn() && !exp.isAssertExp() &&
        !exp.isThrowExp() && !exp.isCallExp())
    {
        auto msg = new StringExp(exp.loc, "Accessed expression of type `noreturn`");
        msg.type = Type.tstring;
        result = new AssertExp(exp.loc, IntegerExp.literal!0, msg);
        result.type = exp.type;
    }

    return result;
}

/******************************
 * Check the tail CallExp is really property function call.
 * Bugs:
 * This doesn't appear to do anything.
 */
private bool checkPropertyCall(Expression e)
{
    e = lastComma(e);

    if (auto ce = e.isCallExp())
    {
        if (ce.f)
        {
            auto tf = ce.f.type.isTypeFunction();
            /* If a forward reference to ce.f, try to resolve it
             */
            if (!tf.deco && ce.f.semanticRun < PASS.semanticdone)
            {
                ce.f.dsymbolSemantic(null);
                tf = ce.f.type.isTypeFunction();
            }
        }
        else if (!ce.e1.type.isFunction_Delegate_PtrToFunction())
            assert(0);
    }
    return false;
}

/******************************
 * Find symbol in accordance with the UFCS name look up rule
 */
private Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident)
{
    //printf("searchUFCS(ident = %s)\n", ident.toChars());
    Loc loc = ue.loc;

    // TODO: merge with Scope.search.searchScopes()
    Dsymbol searchScopes(int flags)
    {
        Dsymbol s = null;
        for (Scope* scx = sc; scx; scx = scx.enclosing)
        {
            if (!scx.scopesym)
                continue;
            if (scx.scopesym.isModule())
                flags |= SearchUnqualifiedModule;    // tell Module.search() that SearchLocalsOnly is to be obeyed
            s = scx.scopesym.search(loc, ident, flags);
            if (s)
            {
                // overload set contains only module scope symbols.
                if (s.isOverloadSet())
                    break;
                // selective/renamed imports also be picked up
                if (AliasDeclaration ad = s.isAliasDeclaration())
                {
                    if (ad._import)
                        break;
                }
                // See only module scope symbols for UFCS target.
                Dsymbol p = s.toParent2();
                if (p && p.isModule())
                    break;
            }
            s = null;

            // Stop when we hit a module, but keep going if that is not just under the global scope
            if (scx.scopesym.isModule() && !(scx.enclosing && !scx.enclosing.enclosing))
                break;
        }
        return s;
    }

    int flags = 0;
    Dsymbol s;

    if (sc.flags & SCOPE.ignoresymbolvisibility)
        flags |= IgnoreSymbolVisibility;

    // First look in local scopes
    s = searchScopes(flags | SearchLocalsOnly);
    if (!s)
    {
        // Second look in imported modules
        s = searchScopes(flags | SearchImportsOnly);
    }

    if (!s)
        return ue.e1.type.getProperty(sc, loc, ident, 0, ue.e1);

    FuncDeclaration f = s.isFuncDeclaration();
    if (f)
    {
        TemplateDeclaration td = getFuncTemplateDecl(f);
        if (td)
        {
            if (td.overroot)
                td = td.overroot;
            s = td;
        }
    }

    if (auto dti = ue.isDotTemplateInstanceExp())
    {
        auto ti = new TemplateInstance(loc, s.ident, dti.ti.tiargs);
        if (!ti.updateTempDecl(sc, s))
            return ErrorExp.get();
        return new ScopeExp(loc, ti);
    }
    else
    {
        //printf("-searchUFCS() %s\n", s.toChars());
        return new DsymbolExp(loc, s);
    }
}

/******************************
 * Pull out callable entity with UFCS.
 */
private Expression resolveUFCS(Scope* sc, CallExp ce)
{
    Loc loc = ce.loc;
    Expression eleft;
    Expression e;

    if (auto die = ce.e1.isDotIdExp())
    {
        Identifier ident = die.ident;

        Expression ex = die.semanticX(sc);
        if (ex != die)
        {
            ce.e1 = ex;
            return null;
        }
        eleft = die.e1;

        Type t = eleft.type.toBasetype();
        if (t.ty == Tarray || t.ty == Tsarray || t.ty == Tnull || (t.isTypeBasic() && t.ty != Tvoid))
        {
            /* Built-in types and arrays have no callable properties, so do shortcut.
             * It is necessary in: e.init()
             */
        }
        else if (t.ty == Taarray)
        {
            if (ident == Id.remove)
            {
                /* Transform:
                 *  aa.remove(arg) into delete aa[arg]
                 */
                if (!ce.arguments || ce.arguments.dim != 1)
                {
                    ce.error("expected key as argument to `aa.remove()`");
                    return ErrorExp.get();
                }
                if (!eleft.type.isMutable())
                {
                    ce.error("cannot remove key from `%s` associative array `%s`", MODtoChars(t.mod), eleft.toChars());
                    return ErrorExp.get();
                }
                Expression key = (*ce.arguments)[0];
                key = key.expressionSemantic(sc);
                key = resolveProperties(sc, key);

                TypeAArray taa = t.isTypeAArray();
                key = key.implicitCastTo(sc, taa.index);

                if (key.checkValue() || key.checkSharedAccess(sc))
                    return ErrorExp.get();

                semanticTypeInfo(sc, taa.index);

                return new RemoveExp(loc, eleft, key);
            }
        }
        else
        {
            if (Expression ey = die.semanticY(sc, 1))
            {
                if (ey.op == EXP.error)
                    return ey;
                ce.e1 = ey;
                if (isDotOpDispatch(ey))
                {
                    // even opDispatch and UFCS must have valid arguments,
                    // so now that we've seen indication of a problem,
                    // check them for issues.
                    Expressions* originalArguments = Expression.arraySyntaxCopy(ce.arguments);

                    uint errors = global.startGagging();
                    e = ce.expressionSemantic(sc);
                    if (!global.endGagging(errors))
                        return e;

                    if (arrayExpressionSemantic(originalArguments.peekSlice(), sc))
                        return ErrorExp.get();

                    /* fall down to UFCS */
                }
                else
                    return null;
            }
        }

        /* https://issues.dlang.org/show_bug.cgi?id=13953
         *
         * If a struct has an alias this to an associative array
         * and remove is used on a struct instance, we have to
         * check first if there is a remove function that can be called
         * on the struct. If not we must check the alias this.
         *
         * struct A
         * {
         *      string[string] a;
         *      alias a this;
         * }
         *
         * void fun()
         * {
         *      A s;
         *      s.remove("foo");
         * }
         */
        const errors = global.startGagging();
        e = searchUFCS(sc, die, ident);
        // if there were any errors and the identifier was remove
        if (global.endGagging(errors))
        {
            if (ident == Id.remove)
            {
                // check alias this
                Expression alias_e = resolveAliasThis(sc, die.e1, 1);
                if (alias_e && alias_e != die.e1)
                {
                    die.e1 = alias_e;
                    CallExp ce2 = ce.syntaxCopy();
                    ce2.e1 = die;
                    e = ce2.isCallExp().trySemantic(sc);
                    if (e)
                        return e;
                }
            }
            // if alias this did not work out, print the initial errors
            searchUFCS(sc, die, ident);
        }
    }
    else if (auto dti = ce.e1.isDotTemplateInstanceExp())
    {
        if (Expression ey = dti.semanticY(sc, 1))
        {
            ce.e1 = ey;
            return null;
        }
        eleft = dti.e1;
        e = searchUFCS(sc, dti, dti.ti.name);
    }
    else
        return null;

    // Rewrite
    ce.e1 = e;
    if (!ce.arguments)
        ce.arguments = new Expressions();
    ce.arguments.shift(eleft);

    return null;
}

/******************************
 * Pull out property with UFCS.
 */
private Expression resolveUFCSProperties(Scope* sc, Expression e1, Expression e2 = null)
{
    Loc loc = e1.loc;
    Expression eleft;
    Expression e;

    if (auto die = e1.isDotIdExp())
    {
        eleft = die.e1;
        e = searchUFCS(sc, die, die.ident);
    }
    else if (auto dti = e1.isDotTemplateInstanceExp())
    {
        eleft = dti.e1;
        e = searchUFCS(sc, dti, dti.ti.name);
    }
    else
        return null;

    if (e is null)
        return null;

    // Rewrite
    if (e2)
    {
        // run semantic without gagging
        e2 = e2.expressionSemantic(sc);

        /* f(e1) = e2
         */
        Expression ex = e.copy();
        auto a1 = new Expressions(1);
        (*a1)[0] = eleft;
        ex = new CallExp(loc, ex, a1);
        auto e1PassSemantic = ex.trySemantic(sc);

        /* f(e1, e2)
         */
        auto a2 = new Expressions(2);
        (*a2)[0] = eleft;
        (*a2)[1] = e2;
        e = new CallExp(loc, e, a2);
        e = e.trySemantic(sc);
        if (!e1PassSemantic && !e)
        {
            /* https://issues.dlang.org/show_bug.cgi?id=20448
             *
             * If both versions have failed to pass semantic,
             * f(e1) = e2 gets priority in error printing
             * because f might be a templated function that
             * failed to instantiate and we have to print
             * the instantiation errors.
             */
            return e1.expressionSemantic(sc);
        }
        else if (ex && !e)
        {
            checkPropertyCall(ex);
            ex = new AssignExp(loc, ex, e2);
            return ex.expressionSemantic(sc);
        }
        else
        {
            // strict setter prints errors if fails
            e = e.expressionSemantic(sc);
        }
        checkPropertyCall(e);
        return e;
    }
    else
    {
        /* f(e1)
         */
        auto arguments = new Expressions(1);
        (*arguments)[0] = eleft;
        e = new CallExp(loc, e, arguments);
        e = e.expressionSemantic(sc);
        checkPropertyCall(e);
        return e.expressionSemantic(sc);
    }
}

/******************************
 * If e1 is a property function (template), resolve it.
 */
Expression resolvePropertiesOnly(Scope* sc, Expression e1)
{
    //printf("e1 = %s %s\n", Token.toChars(e1.op), e1.toChars());

    Expression handleOverloadSet(OverloadSet os)
    {
        assert(os);
        foreach (s; os.a)
        {
            auto fd = s.isFuncDeclaration();
            auto td = s.isTemplateDeclaration();
            if (fd)
            {
                if (fd.type.isTypeFunction().isproperty)
                    return resolveProperties(sc, e1);
            }
            else if (td && td.onemember && (fd = td.onemember.isFuncDeclaration()) !is null)
            {
                if (fd.type.isTypeFunction().isproperty ||
                    (fd.storage_class2 & STC.property) ||
                    (td._scope.stc & STC.property))
                    return resolveProperties(sc, e1);
            }
        }
        return e1;
    }

    Expression handleTemplateDecl(TemplateDeclaration td)
    {
        assert(td);
        if (td.onemember)
        {
            if (auto fd = td.onemember.isFuncDeclaration())
            {
                if (fd.type.isTypeFunction().isproperty ||
                    (fd.storage_class2 & STC.property) ||
                    (td._scope.stc & STC.property))
                    return resolveProperties(sc, e1);
            }
        }
        return e1;
    }

    Expression handleFuncDecl(FuncDeclaration fd)
    {
        assert(fd);
        if (fd.type.isTypeFunction().isproperty)
            return resolveProperties(sc, e1);
        return e1;
    }

    if (auto de = e1.isDotExp())
    {
        if (auto os = de.e2.isOverExp())
            return handleOverloadSet(os.vars);
    }
    else if (auto oe = e1.isOverExp())
        return handleOverloadSet(oe.vars);
    else if (auto dti = e1.isDotTemplateInstanceExp())
    {
        if (dti.ti.tempdecl)
            if (auto td = dti.ti.tempdecl.isTemplateDeclaration())
                return handleTemplateDecl(td);
    }
    else if (auto dte = e1.isDotTemplateExp())
        return handleTemplateDecl(dte.td);
    else if (auto se = e1.isScopeExp())
    {
        Dsymbol s = se.sds;
        TemplateInstance ti = s.isTemplateInstance();
        if (ti && !ti.semanticRun && ti.tempdecl)
            if (auto td = ti.tempdecl.isTemplateDeclaration())
                return handleTemplateDecl(td);
    }
    else if (auto et = e1.isTemplateExp())
        return handleTemplateDecl(et.td);
    else if (e1.isDotVarExp() && e1.type.isTypeFunction())
    {
        DotVarExp dve = e1.isDotVarExp();
        return handleFuncDecl(dve.var.isFuncDeclaration());
    }
    else if (e1.isVarExp() && e1.type && e1.type.isTypeFunction() && (sc.intypeof || !e1.isVarExp().var.needThis()))
        return handleFuncDecl(e1.isVarExp().var.isFuncDeclaration());
    return e1;
}

/****************************************
 * Turn symbol `s` into the expression it represents.
 *
 * Params:
 *      s = symbol to resolve
 *      loc = location of use of `s`
 *      sc = context
 *      hasOverloads = applies if `s` represents a function.
 *          true means it's overloaded and will be resolved later,
 *          false means it's the exact function symbol.
 * Returns:
 *      `s` turned into an expression, `ErrorExp` if an error occurred
 */
Expression symbolToExp(Dsymbol s, const ref Loc loc, Scope *sc, bool hasOverloads)
{
    static if (LOGSEMANTIC)
    {
        printf("DsymbolExp::resolve(%s %s)\n", s.kind(), s.toChars());
    }

Lagain:
    Expression e;

    //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars());
    //printf("s = '%s', s.kind = '%s'\n", s.toChars(), s.kind());
    Dsymbol olds = s;
    Declaration d = s.isDeclaration();
    if (d && (d.storage_class & STC.templateparameter))
    {
        s = s.toAlias();
    }
    else
    {
        // functions are checked after overloading
        // templates are checked after matching constraints
        if (!s.isFuncDeclaration() && !s.isTemplateDeclaration())
        {
            s.checkDeprecated(loc, sc);
            if (d)
                d.checkDisabled(loc, sc);
        }

        // https://issues.dlang.org/show_bug.cgi?id=12023
        // if 's' is a tuple variable, the tuple is returned.
        s = s.toAlias();

        //printf("s = '%s', s.kind = '%s', s.needThis() = %p\n", s.toChars(), s.kind(), s.needThis());
        if (s != olds && !s.isFuncDeclaration() && !s.isTemplateDeclaration())
        {
            s.checkDeprecated(loc, sc);
            if (d)
                d.checkDisabled(loc, sc);
        }

        if (auto sd = s.isDeclaration())
        {
            if (sd.isSystem())
            {
                if (sc.setUnsafePreview(global.params.systemVariables, false, loc,
                    "cannot access `@system` variable `%s` in @safe code", sd))
                {
                    return ErrorExp.get();
                }
            }
        }
    }

    if (auto em = s.isEnumMember())
    {
        return em.getVarExp(loc, sc);
    }
    if (auto v = s.isVarDeclaration())
    {
        //printf("Identifier '%s' is a variable, type '%s'\n", s.toChars(), v.type.toChars());
        if (sc.intypeof == 1 && !v.inuse)
            v.dsymbolSemantic(sc);
        if (!v.type ||                  // during variable type inference
            !v.type.deco && v.inuse)    // during variable type semantic
        {
            if (v.inuse)    // variable type depends on the variable itself
                error(loc, "circular reference to %s `%s`", v.kind(), v.toPrettyChars());
            else            // variable type cannot be determined
                error(loc, "forward reference to %s `%s`", v.kind(), v.toPrettyChars());
            return ErrorExp.get();
        }
        if (v.type.ty == Terror)
            return ErrorExp.get();

        if ((v.storage_class & STC.manifest) && v._init)
        {
            if (v.inuse)
            {
                error(loc, "circular initialization of %s `%s`", v.kind(), v.toPrettyChars());
                return ErrorExp.get();
            }
            e = v.expandInitializer(loc);
            v.inuse++;
            e = e.expressionSemantic(sc);
            v.inuse--;
            return e;
        }

        // We need to run semantics to correctly set 'STC.field' if it is a member variable
        // that could be forward referenced. This is needed for 'v.needThis()' to work
        if (v.isThis())
            v.dsymbolSemantic(sc);

        // Change the ancestor lambdas to delegate before hasThis(sc) call.
        if (v.checkNestedReference(sc, loc))
            return ErrorExp.get();

        if (v.needThis() && hasThis(sc))
            e = new DotVarExp(loc, new ThisExp(loc), v);
        else
            e = new VarExp(loc, v);
        e = e.expressionSemantic(sc);
        return e;
    }
    if (auto fld = s.isFuncLiteralDeclaration())
    {
        //printf("'%s' is a function literal\n", fld.toChars());
        e = new FuncExp(loc, fld);
        return e.expressionSemantic(sc);
    }
    if (auto f = s.isFuncDeclaration())
    {
        f = f.toAliasFunc();
        if (!f.functionSemantic())
            return ErrorExp.get();

        if (!hasOverloads && f.checkForwardRef(loc))
            return ErrorExp.get();

        auto fd = s.isFuncDeclaration();
        fd.type = f.type;
        return new VarExp(loc, fd, hasOverloads);
    }
    if (OverDeclaration od = s.isOverDeclaration())
    {
        e = new VarExp(loc, od, true);
        e.type = Type.tvoid;
        return e;
    }
    if (OverloadSet o = s.isOverloadSet())
    {
        //printf("'%s' is an overload set\n", o.toChars());
        return new OverExp(loc, o);
    }

    if (Import imp = s.isImport())
    {
        if (!imp.pkg)
        {
            .error(loc, "forward reference of import `%s`", imp.toChars());
            return ErrorExp.get();
        }
        auto ie = new ScopeExp(loc, imp.pkg);
        return ie.expressionSemantic(sc);
    }
    if (Package pkg = s.isPackage())
    {
        auto ie = new ScopeExp(loc, pkg);
        return ie.expressionSemantic(sc);
    }
    if (Module mod = s.isModule())
    {
        auto ie = new ScopeExp(loc, mod);
        return ie.expressionSemantic(sc);
    }
    if (Nspace ns = s.isNspace())
    {
        auto ie = new ScopeExp(loc, ns);
        return ie.expressionSemantic(sc);
    }

    if (Type t = s.getType())
    {
        return (new TypeExp(loc, t)).expressionSemantic(sc);
    }

    if (TupleDeclaration tup = s.isTupleDeclaration())
    {
        if (tup.needThis() && hasThis(sc))
            e = new DotVarExp(loc, new ThisExp(loc), tup);
        else
            e = new TupleExp(loc, tup);
        e = e.expressionSemantic(sc);
        return e;
    }

    if (TemplateInstance ti = s.isTemplateInstance())
    {
        ti.dsymbolSemantic(sc);
        if (!ti.inst || ti.errors)
            return ErrorExp.get();
        s = ti.toAlias();
        if (!s.isTemplateInstance())
            goto Lagain;
        e = new ScopeExp(loc, ti);
        e = e.expressionSemantic(sc);
        return e;
    }
    if (TemplateDeclaration td = s.isTemplateDeclaration())
    {
        Dsymbol p = td.toParentLocal();
        FuncDeclaration fdthis = hasThis(sc);
        AggregateDeclaration ad = p ? p.isAggregateDeclaration() : null;
        if (fdthis && ad && fdthis.isMemberLocal() == ad && (td._scope.stc & STC.static_) == 0)
        {
            e = new DotTemplateExp(loc, new ThisExp(loc), td);
        }
        else
            e = new TemplateExp(loc, td);
        e = e.expressionSemantic(sc);
        return e;
    }

    .error(loc, "%s `%s` is not a variable", s.kind(), s.toChars());
    return ErrorExp.get();
}

/*************************************************************
 * Given var, get the
 * right `this` pointer if var is in an outer class, but our
 * existing `this` pointer is in an inner class.
 * Params:
 *      loc = location to use for error messages
 *      sc = context
 *      ad = struct or class we need the correct `this` for
 *      e1 = existing `this`
 *      var = the specific member of ad we're accessing
 *      flag = if true, return `null` instead of throwing an error
 * Returns:
 *      Expression representing the `this` for the var
 */
private Expression getRightThis(const ref Loc loc, Scope* sc, AggregateDeclaration ad, Expression e1, Dsymbol var, int flag = 0)
{
    //printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1.toChars(), ad.toChars(), var.toChars());
L1:
    Type t = e1.type.toBasetype();
    //printf("e1.type = %s, var.type = %s\n", e1.type.toChars(), var.type.toChars());

    if (e1.op == EXP.objcClassReference)
    {
        // We already have an Objective-C class reference, just use that as 'this'.
        return e1;
    }
    else if (ad && ad.isClassDeclaration && ad.isClassDeclaration.classKind == ClassKind.objc &&
             var.isFuncDeclaration && var.isFuncDeclaration.isStatic &&
             var.isFuncDeclaration.objc.selector)
    {
        return new ObjcClassReferenceExp(e1.loc, ad.isClassDeclaration());
    }

    /* Access of a member which is a template parameter in dual-scope scenario
     * class A { inc(alias m)() { ++m; } } // `m` needs `this` of `B`
     * class B {int m; inc() { new A().inc!m(); } }
     */
    if (e1.op == EXP.this_)
    {
        FuncDeclaration f = hasThis(sc);
        if (f && f.hasDualContext())
        {
            if (f.followInstantiationContext(ad))
            {
                e1 = new VarExp(loc, f.vthis);
                e1 = new PtrExp(loc, e1);
                e1 = new IndexExp(loc, e1, IntegerExp.literal!1);
                e1 = getThisSkipNestedFuncs(loc, sc, f.toParent2(), ad, e1, t, var);
                if (e1.op == EXP.error)
                    return e1;
                goto L1;
            }
        }
    }

    /* If e1 is not the 'this' pointer for ad
     */
    if (ad &&
        !(t.isTypePointer() && t.nextOf().isTypeStruct() && t.nextOf().isTypeStruct().sym == ad) &&
        !(t.isTypeStruct() && t.isTypeStruct().sym == ad))
    {
        ClassDeclaration cd = ad.isClassDeclaration();
        ClassDeclaration tcd = t.isClassHandle();

        /* e1 is the right this if ad is a base class of e1
         */
        if (!cd || !tcd || !(tcd == cd || cd.isBaseOf(tcd, null)))
        {
            /* Only classes can be inner classes with an 'outer'
             * member pointing to the enclosing class instance
             */
            if (tcd && tcd.isNested())
            {
                /* e1 is the 'this' pointer for an inner class: tcd.
                 * Rewrite it as the 'this' pointer for the outer class.
                 */
                auto vthis = tcd.followInstantiationContext(ad) ? tcd.vthis2 : tcd.vthis;
                e1 = new DotVarExp(loc, e1, vthis);
                e1.type = vthis.type;
                e1.type = e1.type.addMod(t.mod);
                // Do not call ensureStaticLinkTo()
                //e1 = e1.semantic(sc);

                // Skip up over nested functions, and get the enclosing
                // class type.
                e1 = getThisSkipNestedFuncs(loc, sc, tcd.toParentP(ad), ad, e1, t, var);
                if (e1.op == EXP.error)
                    return e1;
                goto L1;
            }

            /* Can't find a path from e1 to ad
             */
            if (flag)
                return null;
            e1.error("`this` for `%s` needs to be type `%s` not type `%s`", var.toChars(), ad.toChars(), t.toChars());
            return ErrorExp.get();
        }
    }
    return e1;
}

/***************************************
 * Pull out any properties.
 */
private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = null)
{
    //printf("resolvePropertiesX, e1 = %s %s, e2 = %s\n", EXPtoString(e1.op).ptr, e1.toChars(), e2 ? e2.toChars() : null);
    Loc loc = e1.loc;

    OverloadSet os;
    Dsymbol s;
    Objects* tiargs;
    Type tthis;
    if (auto de = e1.isDotExp())
    {
        if (auto oe = de.e2.isOverExp())
        {
            tiargs = null;
            tthis = de.e1.type;
            os = oe.vars;
            goto Los;
        }
    }
    else if (e1.isOverExp())
    {
        tiargs = null;
        tthis = null;
        os = e1.isOverExp().vars;
    Los:
        assert(os);
        FuncDeclaration fd = null;
        if (e2)
        {
            e2 = e2.expressionSemantic(sc);
            if (e2.op == EXP.error)
                return ErrorExp.get();
            e2 = resolveProperties(sc, e2);

            Expressions a;
            a.push(e2);

            for (size_t i = 0; i < os.a.dim; i++)
            {
                if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, &a, FuncResolveFlag.quiet))
                {
                    if (f.errors)
                        return ErrorExp.get();
                    fd = f;
                    assert(fd.type.ty == Tfunction);
                }
            }
            if (fd)
            {
                Expression e = new CallExp(loc, e1, e2);
                return e.expressionSemantic(sc);
            }
        }
        {
            for (size_t i = 0; i < os.a.dim; i++)
            {
                if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, null, FuncResolveFlag.quiet))
                {
                    if (f.errors)
                        return ErrorExp.get();
                    fd = f;
                    assert(fd.type.ty == Tfunction);
                    auto tf = fd.type.isTypeFunction();
                    if (!tf.isref && e2)
                    {
                        error(loc, "%s is not an lvalue", e1.toChars());
                        return ErrorExp.get();
                    }
                }
            }
            if (fd)
            {
                Expression e = new CallExp(loc, e1);
                if (e2)
                    e = new AssignExp(loc, e, e2);
                return e.expressionSemantic(sc);
            }
        }
        if (e2)
            goto Leprop;
    }
    else if (auto dti = e1.isDotTemplateInstanceExp())
    {
        if (!dti.findTempDecl(sc))
            goto Leprop;
        if (!dti.ti.semanticTiargs(sc))
            goto Leprop;
        tiargs = dti.ti.tiargs;
        tthis = dti.e1.type;
        if ((os = dti.ti.tempdecl.isOverloadSet()) !is null)
            goto Los;
        if ((s = dti.ti.tempdecl) !is null)
            goto Lfd;
    }
    else if (auto dte = e1.isDotTemplateExp())
    {
        s = dte.td;
        tiargs = null;
        tthis = dte.e1.type;
        goto Lfd;
    }
    else if (auto se = e1.isScopeExp())
    {
        s = se.sds;
        TemplateInstance ti = s.isTemplateInstance();
        if (ti && !ti.semanticRun && ti.tempdecl)
        {
            //assert(ti.needsTypeInference(sc));
            if (!ti.semanticTiargs(sc))
                goto Leprop;
            tiargs = ti.tiargs;
            tthis = null;
            if ((os = ti.tempdecl.isOverloadSet()) !is null)
                goto Los;
            if ((s = ti.tempdecl) !is null)
                goto Lfd;
        }
    }
    else if (auto te = e1.isTemplateExp())
    {
        s = te.td;
        tiargs = null;
        tthis = null;
        goto Lfd;
    }
    else if (e1.isDotVarExp() && e1.type && (e1.type.toBasetype().isTypeFunction() || e1.isDotVarExp().var.isOverDeclaration()))
    {
        DotVarExp dve = e1.isDotVarExp();
        s = dve.var;
        tiargs = null;
        tthis = dve.e1.type;
        goto Lfd;
    }
    else if (sc && sc.flags & SCOPE.Cfile && e1.isVarExp() && !e2)
    {
        // ImportC: do not implicitly call function if no ( ) are present
    }
    else if (e1.isVarExp() && e1.type && (e1.type.toBasetype().isTypeFunction() || e1.isVarExp().var.isOverDeclaration()))
    {
        s = e1.isVarExp().var;
        tiargs = null;
        tthis = null;
    Lfd:
        assert(s);
        if (e2)
        {
            e2 = e2.expressionSemantic(sc);
            if (e2.op == EXP.error)
                return ErrorExp.get();
            e2 = resolveProperties(sc, e2);

            Expressions a;
            a.push(e2);

            FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, &a, FuncResolveFlag.quiet);
            if (fd && fd.type)
            {
                if (fd.errors)
                    return ErrorExp.get();
                if (!checkSymbolAccess(sc, fd))
                {
                    // @@@DEPRECATED_2.105@@@
                    // When turning into error, uncomment the return statement
                    TypeFunction tf = fd.type.isTypeFunction();
                    deprecation(loc, "function `%s` of type `%s` is not accessible from module `%s`",
                                fd.toPrettyChars(), tf.toChars, sc._module.toChars);
                    //return ErrorExp.get();
                }
                assert(fd.type.ty == Tfunction);
                Expression e = new CallExp(loc, e1, e2);
                return e.expressionSemantic(sc);
            }
        }
        {
            FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, null, FuncResolveFlag.quiet);
            if (fd && fd.type)
            {
                if (fd.errors)
                    return ErrorExp.get();
                TypeFunction tf = fd.type.isTypeFunction();
                if (!e2 || tf.isref)
                {
                    if (!checkSymbolAccess(sc, fd))
                    {
                        // @@@DEPRECATED_2.105@@@
                        // When turning into error, uncomment the return statement
                        deprecation(loc, "function `%s` of type `%s` is not accessible from module `%s`",
                                    fd.toPrettyChars(), tf.toChars, sc._module.toChars);
                        //return ErrorExp.get();
                    }
                    Expression e = new CallExp(loc, e1);
                    if (e2)
                        e = new AssignExp(loc, e, e2);
                    return e.expressionSemantic(sc);
                }
            }
        }
        if (FuncDeclaration fd = s.isFuncDeclaration())
        {
            // Keep better diagnostic message for invalid property usage of functions
            assert(fd.type.ty == Tfunction);
            Expression e = new CallExp(loc, e1, e2);
            return e.expressionSemantic(sc);
        }
        if (e2)
            goto Leprop;
    }
    if (auto ve = e1.isVarExp())
    {
        if (auto v = ve.var.isVarDeclaration())
        {
            if (ve.checkPurity(sc, v))
                return ErrorExp.get();
        }
    }
    if (e2)
        return null;

    if (e1.type && !e1.isTypeExp()) // function type is not a property
    {
        /* Look for e1 being a lazy parameter; rewrite as delegate call
         * only if the symbol wasn't already treated as a delegate
         */
        auto ve = e1.isVarExp();
        if (ve && ve.var.storage_class & STC.lazy_ && !ve.delegateWasExtracted)
        {
                Expression e = new CallExp(loc, e1);
                return e.expressionSemantic(sc);
        }
        else if (e1.isDotVarExp())
        {
            // Check for reading overlapped pointer field in @safe code.
            if (checkUnsafeAccess(sc, e1, true, true))
                return ErrorExp.get();
        }
        else if (auto ce = e1.isCallExp())
        {
            // Check for reading overlapped pointer field in @safe code.
            if (checkUnsafeAccess(sc, ce.e1, true, true))
                return ErrorExp.get();
        }
    }

    if (!e1.type)
    {
        error(loc, "cannot resolve type for %s", e1.toChars());
        e1 = ErrorExp.get();
    }
    return e1;

Leprop:
    error(loc, "not a property %s", e1.toChars());
    return ErrorExp.get();
}

extern (C++) Expression resolveProperties(Scope* sc, Expression e)
{
    //printf("resolveProperties(%s)\n", e.toChars());
    e = resolvePropertiesX(sc, e);
    if (e.checkRightThis(sc))
        return ErrorExp.get();
    return e;
}

/****************************************
 * The common type is determined by applying ?: to each pair.
 * Output:
 *      exps[]  properties resolved, implicitly cast to common type, rewritten in place
 * Returns:
 *      The common type, or `null` if an error has occured
 */
private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps)
{
    /* Still have a problem with:
     *  ubyte[][] = [ cast(ubyte[])"hello", [1]];
     * which works if the array literal is initialized top down with the ubyte[][]
     * type, but fails with this function doing bottom up typing.
     */

    //printf("arrayExpressionToCommonType()\n");
    scope IntegerExp integerexp = IntegerExp.literal!0;
    scope CondExp condexp = new CondExp(Loc.initial, integerexp, null, null);

    Type t0 = null;
    Expression e0 = null;
    bool foundType;

    for (size_t i = 0; i < exps.dim; i++)
    {
        Expression e = exps[i];
        if (!e)
            continue;

        e = resolveProperties(sc, e);
        if (!e.type)
        {
            e.error("`%s` has no value", e.toChars());
            t0 = Type.terror;
            continue;
        }
        if (e.op == EXP.type)
        {
            foundType = true; // do not break immediately, there might be more errors
            e.checkValue(); // report an error "type T has no value"
            t0 = Type.terror;
            continue;
        }
        if (e.type.ty == Tvoid)
        {
            // void expressions do not concur to the determination of the common
            // type.
            continue;
        }
        if (checkNonAssignmentArrayOp(e))
        {
            t0 = Type.terror;
            continue;
        }

        e = doCopyOrMove(sc, e);

        if (!foundType && t0 && !t0.equals(e.type))
        {
            /* This applies ?: to merge the types. It's backwards;
             * ?: should call this function to merge types.
             */
            condexp.type = null;
            condexp.e1 = e0;
            condexp.e2 = e;
            condexp.loc = e.loc;
            Expression ex = condexp.expressionSemantic(sc);
            if (ex.op == EXP.error)
                e = ex;
            else
            {
                // Convert to common type
                exps[i] = condexp.e1.castTo(sc, condexp.type);
                e = condexp.e2.castTo(sc, condexp.type);
            }
        }
        e0 = e;
        t0 = e.type;
        if (e.op != EXP.error)
            exps[i] = e;
    }

    // [] is typed as void[]
    if (!t0)
        return Type.tvoid;

    // It's an error, don't do the cast
    if (t0.ty == Terror)
        return null;

    for (size_t i = 0; i < exps.dim; i++)
    {
        Expression e = exps[i];
        if (!e)
            continue;

        e = e.implicitCastTo(sc, t0);
        if (e.op == EXP.error)
        {
            /* https://issues.dlang.org/show_bug.cgi?id=13024
             * a workaround for the bug in typeMerge -
             * it should paint e1 and e2 by deduced common type,
             * but doesn't in this particular case.
             */
            return null;
        }
        exps[i] = e;
    }
    return t0;
}

private Expression opAssignToOp(const ref Loc loc, EXP op, Expression e1, Expression e2)
{
    Expression e;
    switch (op)
    {
    case EXP.addAssign:
        e = new AddExp(loc, e1, e2);
        break;

    case EXP.minAssign:
        e = new MinExp(loc, e1, e2);
        break;

    case EXP.mulAssign:
        e = new MulExp(loc, e1, e2);
        break;

    case EXP.divAssign:
        e = new DivExp(loc, e1, e2);
        break;

    case EXP.modAssign:
        e = new ModExp(loc, e1, e2);
        break;

    case EXP.andAssign:
        e = new AndExp(loc, e1, e2);
        break;

    case EXP.orAssign:
        e = new OrExp(loc, e1, e2);
        break;

    case EXP.xorAssign:
        e = new XorExp(loc, e1, e2);
        break;

    case EXP.leftShiftAssign:
        e = new ShlExp(loc, e1, e2);
        break;

    case EXP.rightShiftAssign:
        e = new ShrExp(loc, e1, e2);
        break;

    case EXP.unsignedRightShiftAssign:
        e = new UshrExp(loc, e1, e2);
        break;

    default:
        assert(0);
    }
    return e;
}

/*********************
 * Rewrite:
 *    array.length op= e2
 * as:
 *    array.length = array.length op e2
 * or:
 *    auto tmp = &array;
 *    (*tmp).length = (*tmp).length op e2
 */
private Expression rewriteOpAssign(BinExp exp)
{
    ArrayLengthExp ale = exp.e1.isArrayLengthExp();
    if (ale.e1.isVarExp())
    {
        Expression e = opAssignToOp(exp.loc, exp.op, ale, exp.e2);
        e = new AssignExp(exp.loc, ale.syntaxCopy(), e);
        return e;
    }
    else
    {
        /*    auto tmp = &array;
         *    (*tmp).length = (*tmp).length op e2
         */
        auto tmp = copyToTemp(0, "__arraylength", new AddrExp(ale.loc, ale.e1));

        Expression e1 = new ArrayLengthExp(ale.loc, new PtrExp(ale.loc, new VarExp(ale.loc, tmp)));
        Expression elvalue = e1.syntaxCopy();
        Expression e = opAssignToOp(exp.loc, exp.op, e1, exp.e2);
        e = new AssignExp(exp.loc, elvalue, e);
        e = new CommaExp(exp.loc, new DeclarationExp(ale.loc, tmp), e);
        return e;
    }
}

/****************************************
 * Preprocess arguments to function.
 * Input:
 *      reportErrors    whether or not to report errors here.  Some callers are not
 *                      checking actual function params, so they'll do their own error reporting
 * Output:
 *      exps[]  tuples expanded, properties resolved, rewritten in place
 * Returns:
 *      true    a semantic error occurred
 */
private bool preFunctionParameters(Scope* sc, Expressions* exps, const bool reportErrors = true)
{
    bool err = false;
    if (exps)
    {
        expandTuples(exps);

        for (size_t i = 0; i < exps.dim; i++)
        {
            Expression arg = (*exps)[i];
            arg = resolveProperties(sc, arg);
            arg = arg.arrayFuncConv(sc);
            if (arg.op == EXP.type)
            {
                // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
                arg = resolveAliasThis(sc, arg);

                if (arg.op == EXP.type)
                {
                    if (reportErrors)
                    {
                        arg.error("cannot pass type `%s` as a function argument", arg.toChars());
                        arg = ErrorExp.get();
                    }
                    err = true;
                }
            }
            else if (arg.type.toBasetype().ty == Tfunction)
            {
                if (reportErrors)
                {
                    arg.error("cannot pass function `%s` as a function argument", arg.toChars());
                    arg = ErrorExp.get();
                }
                err = true;
            }
            else if (checkNonAssignmentArrayOp(arg))
            {
                arg = ErrorExp.get();
                err = true;
            }
            (*exps)[i] = arg;
        }
    }
    return err;
}

/********************************************
 * Issue an error if default construction is disabled for type t.
 * Default construction is required for arrays and 'out' parameters.
 * Returns:
 *      true    an error was issued
 */
private bool checkDefCtor(Loc loc, Type t)
{
    if (auto ts = t.baseElemOf().isTypeStruct())
    {
        StructDeclaration sd = ts.sym;
        if (sd.noDefaultCtor)
        {
            sd.error(loc, "default construction is disabled");
            return true;
        }
    }
    return false;
}

/****************************************
 * Now that we know the exact type of the function we're calling,
 * the arguments[] need to be adjusted:
 *      1. implicitly convert argument to the corresponding parameter type
 *      2. add default arguments for any missing arguments
 *      3. do default promotions on arguments corresponding to ...
 *      4. add hidden _arguments[] argument
 *      5. call copy constructor for struct value arguments
 * Params:
 *      loc       = location of function call
 *      sc        = context
 *      tf        = type of the function
 *      ethis     = `this` argument, `null` if none or not known
 *      tthis     = type of `this` argument, `null` if no `this` argument
 *      arguments = array of actual arguments to function call
 *      fd        = the function being called, `null` if called indirectly
 *      prettype  = set to return type of function
 *      peprefix  = set to expression to execute before `arguments[]` are evaluated, `null` if none
 * Returns:
 *      true    errors happened
 */
private bool functionParameters(const ref Loc loc, Scope* sc,
    TypeFunction tf, Expression ethis, Type tthis, Expressions* arguments, FuncDeclaration fd,
    Type* prettype, Expression* peprefix)
{
    //printf("functionParameters() %s\n", fd ? fd.toChars() : "");
    assert(arguments);
    assert(fd || tf.next);
    size_t nargs = arguments ? arguments.dim : 0;
    const size_t nparams = tf.parameterList.length;
    const olderrors = global.errors;
    bool err = false;
    *prettype = Type.terror;
    Expression eprefix = null;
    *peprefix = null;

    if (nargs > nparams && tf.parameterList.varargs == VarArg.none)
    {
        error(loc, "expected %llu arguments, not %llu for non-variadic function type `%s`", cast(ulong)nparams, cast(ulong)nargs, tf.toChars());
        return true;
    }

    // If inferring return type, and semantic3() needs to be run if not already run
    if (!tf.next && fd.inferRetType)
    {
        fd.functionSemantic();
    }
    else if (fd && fd.parent)
    {
        TemplateInstance ti = fd.parent.isTemplateInstance();
        if (ti && ti.tempdecl)
        {
            fd.functionSemantic3();
        }
    }

    /* If calling a pragma(inline, true) function,
     * set flag to later scan for inlines.
     */
    if (fd && fd.inlining == PINLINE.always)
    {
        if (sc._module)
            sc._module.hasAlwaysInlines = true;
        if (sc.func)
            sc.func.hasAlwaysInlines = true;
    }

    const isCtorCall = fd && fd.needThis() && fd.isCtorDeclaration();

    const size_t n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)

    /* If the function return type has wildcards in it, we'll need to figure out the actual type
     * based on the actual argument types.
     * Start with the `this` argument, later on merge into wildmatch the mod bits of the rest
     * of the arguments.
     */
    MOD wildmatch = (tthis && !isCtorCall) ? tthis.Type.deduceWild(tf, false) : 0;

    bool done = false;
    foreach (const i; 0 .. n)
    {
        Expression arg = (i < nargs) ? (*arguments)[i] : null;

        if (i < nparams)
        {
            bool errorArgs()
            {
                error(loc, "expected %llu function arguments, not %llu", cast(ulong)nparams, cast(ulong)nargs);
                return true;
            }

            Parameter p = tf.parameterList[i];

            if (!arg)
            {
                if (!p.defaultArg)
                {
                    if (tf.parameterList.varargs == VarArg.typesafe && i + 1 == nparams)
                        goto L2;
                    return errorArgs();
                }
                arg = p.defaultArg;
                arg = inlineCopy(arg, sc);
                // __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__
                arg = arg.resolveLoc(loc, sc);
                arguments.push(arg);
                nargs++;
            }
            else
            {
                if (isDefaultInitOp(arg.op))
                {
                    arg = arg.resolveLoc(loc, sc);
                    (*arguments)[i] = arg;
                }
            }


            if (tf.parameterList.varargs == VarArg.typesafe && i + 1 == nparams) // https://dlang.org/spec/function.html#variadic
            {
                //printf("\t\tvarargs == 2, p.type = '%s'\n", p.type.toChars());
                {
                    MATCH m;
                    if ((m = arg.implicitConvTo(p.type)) > MATCH.nomatch)
                    {
                        if (p.type.nextOf() && arg.implicitConvTo(p.type.nextOf()) >= m)
                            goto L2;
                        else if (nargs != nparams)
                            return errorArgs();
                        goto L1;
                    }
                }
            L2:
                Type tb = p.type.toBasetype();
                switch (tb.ty)
                {
                case Tsarray:
                case Tarray:
                    {
                        /* Create a static array variable v of type arg.type:
                         *  T[dim] __arrayArg = [ arguments[i], ..., arguments[nargs-1] ];
                         *
                         * The array literal in the initializer of the hidden variable
                         * is now optimized.
                         * https://issues.dlang.org/show_bug.cgi?id=2356
                         */
                        Type tbn = (cast(TypeArray)tb).next;    // array element type
                        Type tret = p.isLazyArray();

                        auto elements = new Expressions(nargs - i);
                        foreach (u; 0 .. elements.dim)
                        {
                            Expression a = (*arguments)[i + u];
                            if (tret && a.implicitConvTo(tret))
                            {
                                // p is a lazy array of delegates, tret is return type of the delegates
                                a = a.implicitCastTo(sc, tret)
                                     .optimize(WANTvalue)
                                     .toDelegate(tret, sc);
                            }
                            else
                                a = a.implicitCastTo(sc, tbn);
                            a = a.addDtorHook(sc);
                            (*elements)[u] = a;
                        }
                        // https://issues.dlang.org/show_bug.cgi?id=14395
                        // Convert to a static array literal, or its slice.
                        arg = new ArrayLiteralExp(loc, tbn.sarrayOf(nargs - i), elements);
                        if (tb.ty == Tarray)
                        {
                            arg = new SliceExp(loc, arg, null, null);
                            arg.type = p.type;
                        }
                        break;
                    }
                case Tclass:
                    {
                        /* Set arg to be:
                         *      new Tclass(arg0, arg1, ..., argn)
                         */
                        auto args = new Expressions(nargs - i);
                        foreach (u; i .. nargs)
                            (*args)[u - i] = (*arguments)[u];
                        arg = new NewExp(loc, null, p.type, args);
                        break;
                    }
                default:
                    if (!arg)
                    {
                        error(loc, "not enough arguments");
                        return true;
                    }
                    break;
                }
                arg = arg.expressionSemantic(sc);
                //printf("\targ = '%s'\n", arg.toChars());
                arguments.setDim(i + 1);
                (*arguments)[i] = arg;
                nargs = i + 1;
                done = true;
            }

        L1:
            if (!(p.isLazy() && p.type.ty == Tvoid))
            {
                if (ubyte wm = arg.type.deduceWild(p.type, p.isReference()))
                {
                    wildmatch = wildmatch ? MODmerge(wildmatch, wm) : wm;
                    //printf("[%d] p = %s, a = %s, wm = %d, wildmatch = %d\n", i, p.type.toChars(), arg.type.toChars(), wm, wildmatch);
                }
            }
        }
        if (done)
            break;
    }
    if ((wildmatch == MODFlags.mutable || wildmatch == MODFlags.immutable_) &&
        tf.next && tf.next.hasWild() &&
        (tf.isref || !tf.next.implicitConvTo(tf.next.immutableOf())))
    {
        bool errorInout(MOD wildmatch)
        {
            const(char)* s = wildmatch == MODFlags.mutable ? "mutable" : MODtoChars(wildmatch);
            error(loc, "modify `inout` to `%s` is not allowed inside `inout` function", s);
            return true;
        }

        if (fd)
        {
            /* If the called function may return the reference to
             * outer inout data, it should be rejected.
             *
             * void foo(ref inout(int) x) {
             *   ref inout(int) bar(inout(int)) { return x; }
             *   struct S {
             *      ref inout(int) bar() inout { return x; }
             *      ref inout(int) baz(alias a)() inout { return x; }
             *   }
             *   bar(int.init) = 1;  // bad!
             *   S().bar() = 1;      // bad!
             * }
             * void test() {
             *   int a;
             *   auto s = foo(a);
             *   s.baz!a() = 1;      // bad!
             * }
             *
             */
            bool checkEnclosingWild(Dsymbol s)
            {
                bool checkWild(Dsymbol s)
                {
                    if (!s)
                        return false;
                    if (auto ad = s.isAggregateDeclaration())
                    {
                        if (ad.isNested())
                            return checkEnclosingWild(s);
                    }
                    else if (auto ff = s.isFuncDeclaration())
                    {
                        if (ff.type.isTypeFunction().iswild)
                            return errorInout(wildmatch);

                        if (ff.isNested() || ff.isThis())
                            return checkEnclosingWild(s);
                    }
                    return false;
                }

                Dsymbol ctx0 = s.toParent2();
                Dsymbol ctx1 = s.toParentLocal();
                if (checkWild(ctx0))
                    return true;
                if (ctx0 != ctx1)
                    return checkWild(ctx1);
                return false;
            }
            if ((fd.isThis() || fd.isNested()) && checkEnclosingWild(fd))
                return true;
        }
        else if (tf.isWild())
            return errorInout(wildmatch);
    }

    Expression firstArg = ((tf.next && tf.next.ty == Tvoid || isCtorCall) &&
                           tthis &&
                           tthis.isMutable() && tthis.toBasetype().ty == Tstruct &&
                           tthis.hasPointers())
                          ? ethis : null;

    assert(nargs >= nparams);
    foreach (const i, arg; (*arguments)[0 .. nargs])
    {
        assert(arg);
        if (i < nparams)
        {
            Parameter p = tf.parameterList[i];
            Type targ = arg.type;               // keep original type for isCopyable() because alias this
                                                // resolution may hide an uncopyable type

            if (!(p.isLazy() && p.type.ty == Tvoid))
            {
                Type tprm = p.type.hasWild()
                    ? p.type.substWildTo(wildmatch)
                    : p.type;

                const hasCopyCtor = arg.type.isTypeStruct() && arg.type.isTypeStruct().sym.hasCopyCtor;
                const typesMatch = arg.type.mutableOf().unSharedOf().equals(tprm.mutableOf().unSharedOf());
                if (!((hasCopyCtor && typesMatch) || tprm.equals(arg.type)))
                {
                    //printf("arg.type = %s, p.type = %s\n", arg.type.toChars(), p.type.toChars());
                    arg = arg.implicitCastTo(sc, tprm);
                    arg = arg.optimize(WANTvalue, p.isReference());
                }
            }

            // Support passing rvalue to `in` parameters
            if ((p.storageClass & (STC.in_ | STC.ref_)) == (STC.in_ | STC.ref_))
            {
                if (!arg.isLvalue())
                {
                    auto v = copyToTemp(STC.exptemp, "__rvalue", arg);
                    Expression ev = new DeclarationExp(arg.loc, v);
                    ev = new CommaExp(arg.loc, ev, new VarExp(arg.loc, v));
                    arg = ev.expressionSemantic(sc);
                }
                arg = arg.toLvalue(sc, arg);

                // Look for mutable misaligned pointer, etc., in @safe mode
                err |= checkUnsafeAccess(sc, arg, false, true);
            }
            else if (p.storageClass & STC.ref_)
            {
                if (global.params.rvalueRefParam == FeatureState.enabled &&
                    !arg.isLvalue() &&
                    targ.isCopyable())
                {   /* allow rvalues to be passed to ref parameters by copying
                     * them to a temp, then pass the temp as the argument
                     */
                    auto v = copyToTemp(0, "__rvalue", arg);
                    Expression ev = new DeclarationExp(arg.loc, v);
                    ev = new CommaExp(arg.loc, ev, new VarExp(arg.loc, v));
                    arg = ev.expressionSemantic(sc);
                }
                arg = arg.toLvalue(sc, arg);

                // Look for mutable misaligned pointer, etc., in @safe mode
                err |= checkUnsafeAccess(sc, arg, false, true);
            }
            else if (p.storageClass & STC.out_)
            {
                Type t = arg.type;
                if (!t.isMutable() || !t.isAssignable()) // check blit assignable
                {
                    arg.error("cannot modify struct `%s` with immutable members", arg.toChars());
                    err = true;
                }
                else
                {
                    // Look for misaligned pointer, etc., in @safe mode
                    err |= checkUnsafeAccess(sc, arg, false, true);
                    err |= checkDefCtor(arg.loc, t); // t must be default constructible
                }
                arg = arg.toLvalue(sc, arg);
            }
            else if (p.isLazy())
            {
                // Convert lazy argument to a delegate
                auto t = (p.type.ty == Tvoid) ? p.type : arg.type;
                arg = toDelegate(arg, t, sc);
            }
            //printf("arg: %s\n", arg.toChars());
            //printf("type: %s\n", arg.type.toChars());
            //printf("param: %s\n", p.toChars());

            const pStc = tf.parameterStorageClass(tthis, p);

            if (firstArg && (pStc & STC.return_))
            {
                /* Argument value can be assigned to firstArg.
                 * Check arg to see if it matters.
                 */
                err |= checkParamArgumentReturn(sc, firstArg, arg, p, false);
            }
            // Allow 'lazy' to imply 'scope' - lazy parameters can be passed along
            // as lazy parameters to the next function, but that isn't escaping.
            else if (!(pStc & STC.lazy_))
            {
                /* Argument value can escape from the called function.
                 * Check arg to see if it matters.
                 */
                VarDeclaration vPar = fd ? (fd.parameters ? (*fd.parameters)[i] : null) : null;
                err |= checkParamArgumentEscape(sc, fd, p, vPar, cast(STC) pStc, arg, false, false);
            }

            // Turning heap allocations into stack allocations is dangerous without dip1000, since `scope` inference
            // may be unreliable when scope violations only manifest as deprecation warnings.
            // However, existing `@nogc` code may rely on it, so still do it when the parameter is explicitly marked `scope`
            const explicitScope = p.isLazy() ||
                ((p.storageClass & STC.scope_) && !(p.storageClass & STC.scopeinferred));
            if ((pStc & (STC.scope_ | STC.lazy_)) &&
                ((global.params.useDIP1000 == FeatureState.enabled) || explicitScope) &&
                !(pStc & STC.return_))
            {
                /* Argument value cannot escape from the called function.
                 */
                Expression a = arg;
                if (auto ce = a.isCastExp())
                    a = ce.e1;

                ArrayLiteralExp ale;
                if (p.type.toBasetype().ty == Tarray &&
                    (ale = a.isArrayLiteralExp()) !is null && ale.elements && ale.elements.length > 0)
                {
                    // allocate the array literal as temporary static array on the stack
                    ale.type = ale.type.nextOf().sarrayOf(ale.elements.length);
                    auto tmp = copyToTemp(0, "__arrayliteral_on_stack", ale);
                    auto declareTmp = new DeclarationExp(ale.loc, tmp);
                    auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp),
                        p.type.substWildTo(MODFlags.mutable));
                    arg = CommaExp.combine(declareTmp, castToSlice);
                    arg = arg.expressionSemantic(sc);
                }
                else if (auto fe = a.isFuncExp())
                {
                    /* Function literals can only appear once, so if this
                     * appearance was scoped, there cannot be any others.
                     */
                    fe.fd.tookAddressOf = 0;
                }
                else if (auto de = a.isDelegateExp())
                {
                    /* For passing a delegate to a scoped parameter,
                     * this doesn't count as taking the address of it.
                     * We only worry about 'escaping' references to the function.
                     */
                    if (auto ve = de.e1.isVarExp())
                    {
                        if (auto f = ve.var.isFuncDeclaration())
                        {
                            if (f.tookAddressOf)
                                --f.tookAddressOf;
                            //printf("--tookAddressOf = %d\n", f.tookAddressOf);
                        }
                    }
                }
            }
            if (!p.isReference())
                err |= arg.checkSharedAccess(sc);

            arg = arg.optimize(WANTvalue, p.isReference());

            /* Determine if this parameter is the "first reference" parameter through which
             * later "return" arguments can be stored.
             */
            if (i == 0 && !tthis && p.isReference() && p.type &&
                (tf.next && tf.next.ty == Tvoid || isCtorCall))
            {
                Type tb = p.type.baseElemOf();
                if (tb.isMutable() && tb.hasPointers())
                {
                    firstArg = arg;
                }
            }
        }
        else
        {
            // These will be the trailing ... arguments
            // If not D linkage, do promotions
            if (tf.linkage != LINK.d)
            {
                // Promote bytes, words, etc., to ints
                arg = integralPromotions(arg, sc);

                // Promote floats to doubles
                switch (arg.type.ty)
                {
                case Tfloat32:
                    arg = arg.castTo(sc, Type.tfloat64);
                    break;

                case Timaginary32:
                    arg = arg.castTo(sc, Type.timaginary64);
                    break;

                default:
                    break;
                }
                if (tf.parameterList.varargs == VarArg.variadic)
                {
                    const(char)* p = tf.linkage == LINK.c ? "extern(C)" : "extern(C++)";
                    if (arg.type.ty == Tarray)
                    {
                        arg.error("cannot pass dynamic arrays to `%s` vararg functions", p);
                        err = true;
                    }
                    if (arg.type.ty == Tsarray)
                    {
                        arg.error("cannot pass static arrays to `%s` vararg functions", p);
                        err = true;
                    }
                }
            }

            // Do not allow types that need destructors or copy constructors.
            if (arg.type.needsDestruction())
            {
                arg.error("cannot pass types that need destruction as variadic arguments");
                err = true;
            }
            if (arg.type.needsCopyOrPostblit())
            {
                arg.error("cannot pass types with postblits or copy constructors as variadic arguments");
                err = true;
            }

            // Convert static arrays to dynamic arrays
            // BUG: I don't think this is right for D2
            Type tb = arg.type.toBasetype();
            if (auto ts = tb.isTypeSArray())
            {
                Type ta = ts.next.arrayOf();
                if (ts.size(arg.loc) == 0)
                    arg = new NullExp(arg.loc, ta);
                else
                    arg = arg.castTo(sc, ta);
            }
            if (tb.ty == Tstruct)
            {
                //arg = callCpCtor(sc, arg);
            }
            // Give error for overloaded function addresses
            if (auto se = arg.isSymOffExp())
            {
                if (se.hasOverloads && !se.var.isFuncDeclaration().isUnique())
                {
                    arg.error("function `%s` is overloaded", arg.toChars());
                    err = true;
                }
            }
            err |= arg.checkValue();
            err |= arg.checkSharedAccess(sc);
            arg = arg.optimize(WANTvalue);
        }
        (*arguments)[i] = arg;
    }

    /* If calling C scanf(), printf(), or any variants, check the format string against the arguments
     */
    const isVa_list = tf.parameterList.varargs == VarArg.none;
    if (fd && fd.printf)
    {
        if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())
        {
            checkPrintfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list);
        }
    }
    else if (fd && fd.scanf)
    {
        if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())
        {
            checkScanfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list);
        }
    }
    else
    {
        // TODO: not checking the "v" functions yet (for those, check format string only, not args)
    }

    /* Remaining problems:
     * 1. order of evaluation - some function push L-to-R, others R-to-L. Until we resolve what array assignment does (which is
     *    implemented by calling a function) we'll defer this for now.
     * 2. value structs (or static arrays of them) that need to be copy constructed
     * 3. value structs (or static arrays of them) that have destructors, and subsequent arguments that may throw before the
     *    function gets called.
     * 4. value structs need to be destructed after the function call for platforms where the caller destroys the arguments.
     * 2, 3 and 4 are handled by doing the argument construction in 'eprefix' so that if a later argument throws, they are cleaned
     * up properly. Pushing arguments on the stack then cannot fail.
     */
     {
        /* TODO: tackle problem 1)
         */
        const bool leftToRight = true; // TODO: Any cases that need rightToLeft?
        if (!leftToRight)
            assert(nargs == nparams); // no variadics for RTL order, as they would probably be evaluated LTR and so add complexity

        /* Does Problem (4) apply?
         */
        const bool callerDestroysArgs = !target.isCalleeDestroyingArgs(tf);

        const ptrdiff_t start = (leftToRight ? 0 : cast(ptrdiff_t)nargs - 1);
        const ptrdiff_t end   = (leftToRight ? cast(ptrdiff_t)nargs : -1);
        const ptrdiff_t step  = (leftToRight ? 1 : -1);

        /* Compute indices of last throwing argument and first arg needing destruction.
         * Used to not set up destructors unless an arg needs destruction on a throw
         * in a later argument.
         */
        ptrdiff_t lastthrow = -1;   // last argument that may throw
        ptrdiff_t firstdtor = -1;   // first argument that needs destruction
        ptrdiff_t lastdtor  = -1;   // last argument that needs destruction
        for (ptrdiff_t i = start; i != end; i += step)
        {
            Expression arg = (*arguments)[i];
            if (canThrow(arg, sc.func, false))
                lastthrow = i;
            if (arg.type.needsDestruction())
            {
                Parameter p = (i >= nparams ? null : tf.parameterList[i]);
                if (!(p && (p.isLazy() || p.isReference())))
                {
                    if (firstdtor == -1)
                        firstdtor = i;
                    lastdtor = i;
                }
            }
        }

        /* Do we need 'eprefix' for problems 3 or 4?
         */
        const bool needsPrefix = callerDestroysArgs
            ? firstdtor >= 0 // true if any argument needs destruction
            : firstdtor >= 0 && lastthrow >= 0 &&
              (lastthrow - firstdtor) * step > 0; // last throw after first destruction
        const ptrdiff_t lastPrefix = callerDestroysArgs
            ? lastdtor   // up to last argument requiring destruction
            : lastthrow; // up to last potentially throwing argument

        /* Problem 3: initialize 'eprefix' by declaring the gate
         */
        VarDeclaration gate;
        if (needsPrefix && !callerDestroysArgs)
        {
            // eprefix => bool __gate [= false]
            Identifier idtmp = Identifier.generateId("__gate");
            gate = new VarDeclaration(loc, Type.tbool, idtmp, null);
            gate.storage_class |= STC.temp | STC.ctfe | STC.volatile_;
            gate.dsymbolSemantic(sc);

            auto ae = new DeclarationExp(loc, gate);
            eprefix = ae.expressionSemantic(sc);
        }

        for (ptrdiff_t i = start; i != end; i += step)
        {
            Expression arg = (*arguments)[i];
            //printf("arg[%d]: %s\n", cast(int)i, arg.toChars());

            Parameter parameter = (i >= nparams ? null : tf.parameterList[i]);
            const bool isRef = parameter && parameter.isReference();
            const bool isLazy = parameter && parameter.isLazy();

            /* Skip lazy parameters
             */
            if (isLazy)
                continue;

            /* Do we have 'eprefix' and aren't past 'lastPrefix' yet?
             * Then declare a temporary variable for this arg and append that declaration
             * to 'eprefix', which will implicitly take care of potential problem 2) for
             * this arg.
             * 'eprefix' will therefore finally contain all args up to and including 'lastPrefix',
             * excluding all lazy parameters.
             */
            if (needsPrefix && (lastPrefix - i) * step >= 0)
            {
                const bool needsDtor = !isRef && arg.type.needsDestruction() &&
                                       // Problem 3: last throwing arg doesn't require dtor patching
                                       (callerDestroysArgs || i != lastPrefix);

                /* Declare temporary 'auto __pfx = arg' (needsDtor) or 'auto __pfy = arg' (!needsDtor)
                 */
                auto tmp = copyToTemp(
                    (parameter ? parameter.storageClass : tf.parameterList.stc) & (STC.scope_),
                    needsDtor ? "__pfx" : "__pfy",
                    !isRef ? arg : arg.addressOf());
                tmp.dsymbolSemantic(sc);

                if (callerDestroysArgs)
                {
                    /* Problem 4: Normal temporary, destructed after the call
                     */
                    if (needsDtor)
                        tmp.isArgDtorVar = true;   // mark it so that the backend passes it by ref to the function being called
                }
                else
                {
                    /* Problem 3: Modify the destructor so it only runs if gate==false,
                     * i.e., only if there was a throw while constructing the args
                     */
                    if (!needsDtor)
                    {
                        if (tmp.edtor)
                        {
                            assert(i == lastPrefix);
                            tmp.edtor = null;
                        }
                    }
                    else
                    {
                        // edtor => (__gate || edtor)
                        assert(tmp.edtor);
                        Expression e = tmp.edtor;
                        e = new LogicalExp(e.loc, EXP.orOr, new VarExp(e.loc, gate), e);
                        tmp.edtor = e.expressionSemantic(sc);
                        //printf("edtor: %s\n", tmp.edtor.toChars());
                    }
                }

                // eprefix => (eprefix, auto __pfx/y = arg)
                auto ae = new DeclarationExp(loc, tmp);
                eprefix = Expression.combine(eprefix, ae.expressionSemantic(sc));

                // arg => __pfx/y
                arg = new VarExp(loc, tmp);
                arg = arg.expressionSemantic(sc);
                if (isRef)
                {
                    arg = new PtrExp(loc, arg);
                    arg = arg.expressionSemantic(sc);
                }

                /* Problem 3: Last throwing arg?
                 * Then finalize eprefix => (eprefix, gate = true), i.e., disable the
                 * dtors right after constructing the last throwing arg.
                 * From now on, the callee will take care of destructing the args because
                 * the args are implicitly moved into function parameters.
                 */
                if (!callerDestroysArgs && i == lastPrefix)
                {
                    auto e = new AssignExp(gate.loc, new VarExp(gate.loc, gate), IntegerExp.createBool(true));
                    eprefix = Expression.combine(eprefix, e.expressionSemantic(sc));
                }
            }
            else // not part of 'eprefix'
            {
                /* Handle problem 2) by calling the copy constructor for value structs
                 * (or static arrays of them) if appropriate.
                 */
                Type tv = arg.type.baseElemOf();
                if (!isRef && tv.ty == Tstruct)
                    arg = doCopyOrMove(sc, arg, parameter ? parameter.type : null);
            }

            (*arguments)[i] = arg;
        }
    }
    //if (eprefix) printf("eprefix: %s\n", eprefix.toChars());

    /* Test compliance with DIP1021
     */
    if (global.params.useDIP1021 &&
        tf.trust != TRUST.system && tf.trust != TRUST.trusted)
        err |= checkMutableArguments(sc, fd, tf, ethis, arguments, false);

    // If D linkage and variadic, add _arguments[] as first argument
    if (tf.isDstyleVariadic())
    {
        assert(arguments.dim >= nparams);

        auto args = new Parameters(arguments.dim - nparams);
        for (size_t i = 0; i < arguments.dim - nparams; i++)
        {
            auto arg = new Parameter(STC.in_, (*arguments)[nparams + i].type, null, null, null);
            (*args)[i] = arg;
        }
        auto tup = new TypeTuple(args);
        Expression e = (new TypeidExp(loc, tup)).expressionSemantic(sc);
        arguments.insert(0, e);
    }

    /* Determine function return type: tret
     */
    Type tret = tf.next;
    if (isCtorCall)
    {
        //printf("[%s] fd = %s %s, %d %d %d\n", loc.toChars(), fd.toChars(), fd.type.toChars(),
        //    wildmatch, tf.isWild(), fd.isReturnIsolated());
        if (!tthis)
        {
            assert(sc.intypeof || global.errors);
            tthis = fd.isThis().type.addMod(fd.type.mod);
        }
        if (tf.isWild() && !fd.isReturnIsolated())
        {
            if (wildmatch)
                tret = tret.substWildTo(wildmatch);
            int offset;
            if (!tret.implicitConvTo(tthis) && !(MODimplicitConv(tret.mod, tthis.mod) && tret.isBaseOf(tthis, &offset) && offset == 0))
            {
                const(char)* s1 = tret.isNaked() ? " mutable" : tret.modToChars();
                const(char)* s2 = tthis.isNaked() ? " mutable" : tthis.modToChars();
                .error(loc, "`inout` constructor `%s` creates%s object, not%s", fd.toPrettyChars(), s1, s2);
                err = true;
            }
        }
        tret = tthis;
    }
    else if (wildmatch && tret)
    {
        /* Adjust function return type based on wildmatch
         */
        //printf("wildmatch = x%x, tret = %s\n", wildmatch, tret.toChars());
        tret = tret.substWildTo(wildmatch);
    }

    *prettype = tret;
    *peprefix = eprefix;
    return (err || olderrors != global.errors);
}

/**
 * Determines whether a symbol represents a module or package
 * (Used as a helper for is(type == module) and is(type == package))
 *
 * Params:
 *  sym = the symbol to be checked
 *
 * Returns:
 *  the symbol which `sym` represents (or `null` if it doesn't represent a `Package`)
 */
Package resolveIsPackage(Dsymbol sym)
{
    Package pkg;
    if (Import imp = sym.isImport())
    {
        if (imp.pkg is null)
        {
            .error(sym.loc, "internal compiler error: unable to process forward-referenced import `%s`",
                    imp.toChars());
            assert(0);
        }
        pkg = imp.pkg;
    }
    else if (auto mod = sym.isModule())
        pkg = mod.isPackageFile ? mod.pkg : sym.isPackage();
    else
        pkg = sym.isPackage();
    if (pkg)
        pkg.resolvePKGunknown();
    return pkg;
}

private Module loadStdMath()
{
    __gshared Import impStdMath = null;
    __gshared Identifier[1] stdID;
    if (!impStdMath)
    {
        stdID[0] = Id.std;
        auto s = new Import(Loc.initial, stdID[], Id.math, null, false);
        // Module.load will call fatal() if there's no std.math available.
        // Gag the error here, pushing the error handling to the caller.
        uint errors = global.startGagging();
        s.load(null);
        if (s.mod)
        {
            s.mod.importAll(null);
            s.mod.dsymbolSemantic(null);
        }
        global.endGagging(errors);
        impStdMath = s;
    }
    return impStdMath.mod;
}

private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
    alias visit = Visitor.visit;

    Scope* sc;
    Expression result;

    this(Scope* sc)
    {
        this.sc = sc;
    }

    private void setError()
    {
        result = ErrorExp.get();
    }

    /**************************
     * Semantically analyze Expression.
     * Determine types, fold constants, etc.
     */
    override void visit(Expression e)
    {
        static if (LOGSEMANTIC)
        {
            printf("Expression::semantic() %s\n", e.toChars());
        }
        if (e.type)
            e.type = e.type.typeSemantic(e.loc, sc);
        else
            e.type = Type.tvoid;
        result = e;
    }

    override void visit(IntegerExp e)
    {
        assert(e.type);
        if (e.type.ty == Terror)
            return setError();

        assert(e.type.deco);
        e.setInteger(e.getInteger());
        result = e;
    }

    override void visit(RealExp e)
    {
        if (!e.type)
            e.type = Type.tfloat64;
        else
            e.type = e.type.typeSemantic(e.loc, sc);
        result = e;
    }

    override void visit(ComplexExp e)
    {
        if (!e.type)
            e.type = Type.tcomplex80;
        else
            e.type = e.type.typeSemantic(e.loc, sc);
        result = e;
    }

    override void visit(IdentifierExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("IdentifierExp::semantic('%s')\n", exp.ident.toChars());
        }
        if (exp.type) // This is used as the dummy expression
        {
            result = exp;
            return;
        }

        Dsymbol scopesym;
        Dsymbol s = sc.search(exp.loc, exp.ident, &scopesym);
        if (s)
        {
            if (s.errors)
                return setError();

            Expression e;

            /* See if the symbol was a member of an enclosing 'with'
             */
            WithScopeSymbol withsym = scopesym.isWithScopeSymbol();
            if (withsym && withsym.withstate.wthis && symbolIsVisible(sc, s))
            {
                /* Disallow shadowing
                 */
                // First find the scope of the with
                Scope* scwith = sc;
                while (scwith.scopesym != scopesym)
                {
                    scwith = scwith.enclosing;
                    assert(scwith);
                }
                // Look at enclosing scopes for symbols with the same name,
                // in the same function
                for (Scope* scx = scwith; scx && scx.func == scwith.func; scx = scx.enclosing)
                {
                    Dsymbol s2;
                    if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s != s2)
                    {
                        exp.error("with symbol `%s` is shadowing local symbol `%s`", s.toPrettyChars(), s2.toPrettyChars());
                        return setError();
                    }
                }
                s = s.toAlias();

                // Same as wthis.ident
                //  TODO: DotIdExp.semantic will find 'ident' from 'wthis' again.
                //  The redudancy should be removed.
                e = new VarExp(exp.loc, withsym.withstate.wthis);
                e = new DotIdExp(exp.loc, e, exp.ident);
                e = e.expressionSemantic(sc);
            }
            else
            {
                if (withsym)
                {
                    if (withsym.withstate.exp.type.ty != Tvoid)
                    {
                        // 'with (exp)' is a type expression
                        // or 's' is not visible there (for error message)
                        e = new TypeExp(exp.loc, withsym.withstate.exp.type);
                    }
                    else
                    {
                        // 'with (exp)' is a Package/Module
                        e = withsym.withstate.exp;
                    }
                    e = new DotIdExp(exp.loc, e, exp.ident);
                    result = e.expressionSemantic(sc);
                    return;
                }

                /* If f is really a function template,
                 * then replace f with the function template declaration.
                 */
                FuncDeclaration f = s.isFuncDeclaration();
                if (f)
                {
                    TemplateDeclaration td = getFuncTemplateDecl(f);
                    if (td)
                    {
                        if (td.overroot) // if not start of overloaded list of TemplateDeclaration's
                            td = td.overroot; // then get the start
                        e = new TemplateExp(exp.loc, td, f);
                        e = e.expressionSemantic(sc);
                        result = e;
                        return;
                    }
                }

                if (global.params.fixAliasThis)
                {
                    ExpressionDsymbol expDsym = scopesym.isExpressionDsymbol();
                    if (expDsym)
                    {
                        //printf("expDsym = %s\n", expDsym.exp.toChars());
                        result = expDsym.exp.expressionSemantic(sc);
                        return;
                    }
                }
                // Haven't done overload resolution yet, so pass 1
                e = symbolToExp(s, exp.loc, sc, true);
            }
            result = e;
            return;
        }

        if (!global.params.fixAliasThis && hasThis(sc))
        {
            for (AggregateDeclaration ad = sc.getStructClassScope(); ad;)
            {
                if (ad.aliasthis)
                {
                    Expression e;
                    e = new ThisExp(exp.loc);
                    e = new DotIdExp(exp.loc, e, ad.aliasthis.ident);
                    e = new DotIdExp(exp.loc, e, exp.ident);
                    e = e.trySemantic(sc);
                    if (e)
                    {
                        result = e;
                        return;
                    }
                }

                auto cd = ad.isClassDeclaration();
                if (cd && cd.baseClass && cd.baseClass != ClassDeclaration.object)
                {
                    ad = cd.baseClass;
                    continue;
                }
                break;
            }
        }

        if (exp.ident == Id.ctfe)
        {
            if (sc.flags & SCOPE.ctfe)
            {
                exp.error("variable `__ctfe` cannot be read at compile time");
                return setError();
            }

            // Create the magic __ctfe bool variable
            auto vd = new VarDeclaration(exp.loc, Type.tbool, Id.ctfe, null);
            vd.storage_class |= STC.temp;
            vd.semanticRun = PASS.semanticdone;
            Expression e = new VarExp(exp.loc, vd);
            e = e.expressionSemantic(sc);
            result = e;
            return;
        }

        // If we've reached this point and are inside a with() scope then we may
        // try one last attempt by checking whether the 'wthis' object supports
        // dynamic dispatching via opDispatch.
        // This is done by rewriting this expression as wthis.ident.
        // The innermost with() scope of the hierarchy to satisfy the condition
        // above wins.
        // https://issues.dlang.org/show_bug.cgi?id=6400
        for (Scope* sc2 = sc; sc2; sc2 = sc2.enclosing)
        {
            if (!sc2.scopesym)
                continue;

            if (auto ss = sc2.scopesym.isWithScopeSymbol())
            {
                if (ss.withstate.wthis)
                {
                    Expression e;
                    e = new VarExp(exp.loc, ss.withstate.wthis);
                    e = new DotIdExp(exp.loc, e, exp.ident);
                    e = e.trySemantic(sc);
                    if (e)
                    {
                        result = e;
                        return;
                    }
                }
                // Try Type.opDispatch (so the static version)
                else if (ss.withstate.exp && ss.withstate.exp.op == EXP.type)
                {
                    if (Type t = ss.withstate.exp.isTypeExp().type)
                    {
                        Expression e;
                        e = new TypeExp(exp.loc, t);
                        e = new DotIdExp(exp.loc, e, exp.ident);
                        e = e.trySemantic(sc);
                        if (e)
                        {
                            result = e;
                            return;
                        }
                    }
                }
            }
        }

        /* Look for what user might have meant
         */
        if (const n = importHint(exp.ident.toString()))
            exp.error("`%s` is not defined, perhaps `import %.*s;` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr);
        else if (auto s2 = sc.search_correct(exp.ident))
            exp.error("undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
        else if (const p = Scope.search_correct_C(exp.ident))
            exp.error("undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p);
        else if (exp.ident == Id.dollar)
            exp.error("undefined identifier `$`");
        else
            exp.error("undefined identifier `%s`", exp.ident.toChars());

        result = ErrorExp.get();
    }

    override void visit(DsymbolExp e)
    {
        result = symbolToExp(e.s, e.loc, sc, e.hasOverloads);
    }

    override void visit(ThisExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("ThisExp::semantic()\n");
        }
        if (e.type)
        {
            result = e;
            return;
        }

        FuncDeclaration fd = hasThis(sc); // fd is the uplevel function with the 'this' variable
        AggregateDeclaration ad;

        /* Special case for typeof(this) and typeof(super) since both
         * should work even if they are not inside a non-static member function
         */
        if (!fd && sc.intypeof == 1)
        {
            // Find enclosing struct or class
            for (Dsymbol s = sc.getStructClassScope(); 1; s = s.parent)
            {
                if (!s)
                {
                    e.error("`%s` is not in a class or struct scope", e.toChars());
                    goto Lerr;
                }
                ClassDeclaration cd = s.isClassDeclaration();
                if (cd)
                {
                    e.type = cd.type;
                    result = e;
                    return;
                }
                StructDeclaration sd = s.isStructDeclaration();
                if (sd)
                {
                    e.type = sd.type;
                    result = e;
                    return;
                }
            }
        }
        if (!fd)
            goto Lerr;

        assert(fd.vthis);
        e.var = fd.vthis;
        assert(e.var.parent);
        ad = fd.isMemberLocal();
        if (!ad)
            ad = fd.isMember2();
        assert(ad);
        e.type = ad.type.addMod(e.var.type.mod);

        if (e.var.checkNestedReference(sc, e.loc))
            return setError();

        result = e;
        return;

    Lerr:
        e.error("`this` is only defined in non-static member functions, not `%s`", sc.parent.toChars());
        result = ErrorExp.get();
    }

    override void visit(SuperExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("SuperExp::semantic('%s')\n", e.toChars());
        }
        if (e.type)
        {
            result = e;
            return;
        }

        FuncDeclaration fd = hasThis(sc);
        ClassDeclaration cd;
        Dsymbol s;

        /* Special case for typeof(this) and typeof(super) since both
         * should work even if they are not inside a non-static member function
         */
        if (!fd && sc.intypeof == 1)
        {
            // Find enclosing class
            for (s = sc.getStructClassScope(); 1; s = s.parent)
            {
                if (!s)
                {
                    e.error("`%s` is not in a class scope", e.toChars());
                    goto Lerr;
                }
                cd = s.isClassDeclaration();
                if (cd)
                {
                    cd = cd.baseClass;
                    if (!cd)
                    {
                        e.error("class `%s` has no `super`", s.toChars());
                        goto Lerr;
                    }
                    e.type = cd.type;
                    result = e;
                    return;
                }
            }
        }
        if (!fd)
            goto Lerr;

        e.var = fd.vthis;
        assert(e.var && e.var.parent);

        s = fd.toParentDecl();
        if (s.isTemplateDeclaration()) // allow inside template constraint
            s = s.toParent();
        assert(s);
        cd = s.isClassDeclaration();
        //printf("parent is %s %s\n", fd.toParent().kind(), fd.toParent().toChars());
        if (!cd)
            goto Lerr;
        if (!cd.baseClass)
        {
            e.error("no base class for `%s`", cd.toChars());
            e.type = cd.type.addMod(e.var.type.mod);
        }
        else
        {
            e.type = cd.baseClass.type;
            e.type = e.type.castMod(e.var.type.mod);
        }

        if (e.var.checkNestedReference(sc, e.loc))
            return setError();

        result = e;
        return;

    Lerr:
        e.error("`super` is only allowed in non-static class member functions");
        result = ErrorExp.get();
    }

    override void visit(NullExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("NullExp::semantic('%s')\n", e.toChars());
        }
        // NULL is the same as (void *)0
        if (e.type)
        {
            result = e;
            return;
        }
        e.type = Type.tnull;
        result = e;
    }

    override void visit(StringExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("StringExp::semantic() %s\n", e.toChars());
        }
        if (e.type)
        {
            result = e;
            return;
        }

        OutBuffer buffer;
        size_t newlen = 0;
        size_t u;
        dchar c;

        switch (e.postfix)
        {
        case 'd':
            for (u = 0; u < e.len;)
            {
                if (const p = utf_decodeChar(e.peekString(), u, c))
                {
                    e.error("%.*s", cast(int)p.length, p.ptr);
                    return setError();
                }
                else
                {
                    buffer.write4(c);
                    newlen++;
                }
            }
            buffer.write4(0);
            e.setData(buffer.extractData(), newlen, 4);
            if (sc && sc.flags & SCOPE.Cfile)
                e.type = Type.tuns32.sarrayOf(e.len + 1);
            else
                e.type = Type.tdchar.immutableOf().arrayOf();
            e.committed = 1;
            break;

        case 'w':
            for (u = 0; u < e.len;)
            {
                if (const p = utf_decodeChar(e.peekString(), u, c))
                {
                    e.error("%.*s", cast(int)p.length, p.ptr);
                    return setError();
                }
                else
                {
                    buffer.writeUTF16(c);
                    newlen++;
                    if (c >= 0x10000)
                        newlen++;
                }
            }
            buffer.writeUTF16(0);
            e.setData(buffer.extractData(), newlen, 2);
            if (sc && sc.flags & SCOPE.Cfile)
                e.type = Type.tuns16.sarrayOf(e.len + 1);
            else
                e.type = Type.twchar.immutableOf().arrayOf();
            e.committed = 1;
            break;

        case 'c':
            e.committed = 1;
            goto default;

        default:
            if (sc && sc.flags & SCOPE.Cfile)
                e.type = Type.tchar.sarrayOf(e.len + 1);
            else
                e.type = Type.tchar.immutableOf().arrayOf();
            break;
        }
        e.type = e.type.typeSemantic(e.loc, sc);
        //type = type.immutableOf();
        //printf("type = %s\n", type.toChars());

        result = e;
    }

    override void visit(TupleExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("+TupleExp::semantic(%s)\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (exp.e0)
            exp.e0 = exp.e0.expressionSemantic(sc);

        // Run semantic() on each argument
        bool err = false;
        for (size_t i = 0; i < exp.exps.dim; i++)
        {
            Expression e = (*exp.exps)[i];
            e = e.expressionSemantic(sc);
            if (!e.type)
            {
                exp.error("`%s` has no value", e.toChars());
                err = true;
            }
            else if (e.op == EXP.error)
                err = true;
            else
                (*exp.exps)[i] = e;
        }
        if (err)
            return setError();

        expandTuples(exp.exps);

        exp.type = new TypeTuple(exp.exps);
        exp.type = exp.type.typeSemantic(exp.loc, sc);
        //printf("-TupleExp::semantic(%s)\n", toChars());
        result = exp;
    }

    override void visit(ArrayLiteralExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("ArrayLiteralExp::semantic('%s')\n", e.toChars());
        }
        if (e.type)
        {
            result = e;
            return;
        }

        /* Perhaps an empty array literal [ ] should be rewritten as null?
         */

        if (e.basis)
            e.basis = e.basis.expressionSemantic(sc);
        if (arrayExpressionSemantic(e.elements.peekSlice(), sc) || (e.basis && e.basis.op == EXP.error))
            return setError();

        expandTuples(e.elements);

        if (e.basis)
            e.elements.push(e.basis);
        Type t0 = arrayExpressionToCommonType(sc, *e.elements);
        if (e.basis)
            e.basis = e.elements.pop();
        if (t0 is null)
            return setError();

        e.type = t0.arrayOf();
        e.type = e.type.typeSemantic(e.loc, sc);

        /* Disallow array literals of type void being used.
         */
        if (e.elements.dim > 0 && t0.ty == Tvoid)
        {
            e.error("`%s` of type `%s` has no value", e.toChars(), e.type.toChars());
            return setError();
        }

        if (global.params.useTypeInfo && Type.dtypeinfo)
            semanticTypeInfo(sc, e.type);

        result = e;
    }

    override void visit(AssocArrayLiteralExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("AssocArrayLiteralExp::semantic('%s')\n", e.toChars());
        }
        if (e.type)
        {
            result = e;
            return;
        }

        // Run semantic() on each element
        bool err_keys = arrayExpressionSemantic(e.keys.peekSlice(), sc);
        bool err_vals = arrayExpressionSemantic(e.values.peekSlice(), sc);
        if (err_keys || err_vals)
            return setError();

        expandTuples(e.keys);
        expandTuples(e.values);
        if (e.keys.dim != e.values.dim)
        {
            e.error("number of keys is %llu, must match number of values %llu",
                        cast(ulong) e.keys.dim, cast(ulong) e.values.dim);
            return setError();
        }

        Type tkey = arrayExpressionToCommonType(sc, *e.keys);
        Type tvalue = arrayExpressionToCommonType(sc, *e.values);
        if (tkey is null || tvalue is null)
            return setError();

        e.type = new TypeAArray(tvalue, tkey);
        e.type = e.type.typeSemantic(e.loc, sc);

        semanticTypeInfo(sc, e.type);

        if (checkAssocArrayLiteralEscape(sc, e, false))
            return setError();

        result = e;
    }

    override void visit(StructLiteralExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("StructLiteralExp::semantic('%s')\n", e.toChars());
        }
        if (e.type)
        {
            result = e;
            return;
        }

        e.sd.size(e.loc);
        if (e.sd.sizeok != Sizeok.done)
            return setError();

        // run semantic() on each element
        if (arrayExpressionSemantic(e.elements.peekSlice(), sc))
            return setError();

        expandTuples(e.elements);

        /* Fit elements[] to the corresponding type of field[].
         */
        if (!e.sd.fit(e.loc, sc, e.elements, e.stype))
            return setError();

        /* Fill out remainder of elements[] with default initializers for fields[]
         */
        if (!e.sd.fill(e.loc, *e.elements, false))
        {
            /* An error in the initializer needs to be recorded as an error
             * in the enclosing function or template, since the initializer
             * will be part of the stuct declaration.
             */
            global.increaseErrorCount();
            return setError();
        }

        if (checkFrameAccess(e.loc, sc, e.sd, e.elements.dim))
            return setError();

        e.type = e.stype ? e.stype : e.sd.type;
        result = e;
    }

    override void visit(CompoundLiteralExp cle)
    {
        static if (LOGSEMANTIC)
        {
            printf("CompoundLiteralExp::semantic('%s')\n", cle.toChars());
        }
        Type t = cle.type.typeSemantic(cle.loc, sc);
        auto init = initializerSemantic(cle.initializer, sc, t, INITnointerpret);
        auto e = initializerToExpression(init, t, (sc.flags & SCOPE.Cfile) != 0);
        if (!e)
        {
            error(cle.loc, "cannot convert initializer `%s` to expression", init.toChars());
            return setError();
        }
        result = e;
        return;
    }

    override void visit(TypeExp exp)
    {
        if (exp.type.ty == Terror)
            return setError();

        //printf("TypeExp::semantic(%s)\n", exp.type.toChars());
        Expression e;
        Type t;
        Dsymbol s;

        dmd.typesem.resolve(exp.type, exp.loc, sc, e, t, s, true);
        if (e)
        {
            // `(Type)` is actually `(var)` so if `(var)` is a member requiring `this`
            // then rewrite as `(this.var)` in case it would be followed by a DotVar
            // to fix https://issues.dlang.org/show_bug.cgi?id=9490
            VarExp ve = e.isVarExp();
            if (ve && ve.var && exp.parens && !ve.var.isStatic() && !(sc.stc & STC.static_) &&
                sc.func && sc.func.needThis && ve.var.isMember2())
            {
                // printf("apply fix for issue 9490: add `this.` to `%s`...\n", e.toChars());
                e = new DotVarExp(exp.loc, new ThisExp(exp.loc), ve.var, false);
            }
            //printf("e = %s %s\n", Token.toChars(e.op), e.toChars());
            e = e.expressionSemantic(sc);
        }
        else if (t)
        {
            //printf("t = %d %s\n", t.ty, t.toChars());
            exp.type = t.typeSemantic(exp.loc, sc);
            e = exp;
        }
        else if (s)
        {
            //printf("s = %s %s\n", s.kind(), s.toChars());
            e = symbolToExp(s, exp.loc, sc, true);
        }
        else
            assert(0);

        exp.type.checkComplexTransition(exp.loc, sc);

        result = e;
    }

    override void visit(ScopeExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("+ScopeExp::semantic(%p '%s')\n", exp, exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        ScopeDsymbol sds2 = exp.sds;
        TemplateInstance ti = sds2.isTemplateInstance();
        while (ti)
        {
            WithScopeSymbol withsym;
            if (!ti.findTempDecl(sc, &withsym) || !ti.semanticTiargs(sc))
                return setError();
            if (withsym && withsym.withstate.wthis)
            {
                Expression e = new VarExp(exp.loc, withsym.withstate.wthis);
                e = new DotTemplateInstanceExp(exp.loc, e, ti);
                result = e.expressionSemantic(sc);
                return;
            }
            if (ti.needsTypeInference(sc))
            {
                if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())
                {
                    Dsymbol p = td.toParentLocal();
                    FuncDeclaration fdthis = hasThis(sc);
                    AggregateDeclaration ad = p ? p.isAggregateDeclaration() : null;
                    if (fdthis && ad && fdthis.isMemberLocal() == ad && (td._scope.stc & STC.static_) == 0)
                    {
                        Expression e = new DotTemplateInstanceExp(exp.loc, new ThisExp(exp.loc), ti);
                        result = e.expressionSemantic(sc);
                        return;
                    }
                }
                else if (OverloadSet os = ti.tempdecl.isOverloadSet())
                {
                    FuncDeclaration fdthis = hasThis(sc);
                    AggregateDeclaration ad = os.parent.isAggregateDeclaration();
                    if (fdthis && ad && fdthis.isMemberLocal() == ad)
                    {
                        Expression e = new DotTemplateInstanceExp(exp.loc, new ThisExp(exp.loc), ti);
                        result = e.expressionSemantic(sc);
                        return;
                    }
                }
                // ti is an instance which requires IFTI.
                exp.sds = ti;
                exp.type = Type.tvoid;
                result = exp;
                return;
            }
            ti.dsymbolSemantic(sc);
            if (!ti.inst || ti.errors)
                return setError();

            Dsymbol s = ti.toAlias();
            if (s == ti)
            {
                exp.sds = ti;
                exp.type = Type.tvoid;
                result = exp;
                return;
            }
            sds2 = s.isScopeDsymbol();
            if (sds2)
            {
                ti = sds2.isTemplateInstance();
                //printf("+ sds2 = %s, '%s'\n", sds2.kind(), sds2.toChars());
                continue;
            }

            if (auto v = s.isVarDeclaration())
            {
                if (!v.type)
                {
                    exp.error("forward reference of %s `%s`", v.kind(), v.toChars());
                    return setError();
                }
                if ((v.storage_class & STC.manifest) && v._init)
                {
                    /* When an instance that will be converted to a constant exists,
                     * the instance representation "foo!tiargs" is treated like a
                     * variable name, and its recursive appearance check (note that
                     * it's equivalent with a recursive instantiation of foo) is done
                     * separately from the circular initialization check for the
                     * eponymous enum variable declaration.
                     *
                     *  template foo(T) {
                     *    enum bool foo = foo;    // recursive definition check (v.inuse)
                     *  }
                     *  template bar(T) {
                     *    enum bool bar = bar!T;  // recursive instantiation check (ti.inuse)
                     *  }
                     */
                    if (ti.inuse)
                    {
                        exp.error("recursive expansion of %s `%s`", ti.kind(), ti.toPrettyChars());
                        return setError();
                    }
                    v.checkDeprecated(exp.loc, sc);
                    auto e = v.expandInitializer(exp.loc);
                    ti.inuse++;
                    e = e.expressionSemantic(sc);
                    ti.inuse--;
                    result = e;
                    return;
                }
            }

            //printf("s = %s, '%s'\n", s.kind(), s.toChars());
            auto e = symbolToExp(s, exp.loc, sc, true);
            //printf("-1ScopeExp::semantic()\n");
            result = e;
            return;
        }

        //printf("sds2 = %s, '%s'\n", sds2.kind(), sds2.toChars());
        //printf("\tparent = '%s'\n", sds2.parent.toChars());
        sds2.dsymbolSemantic(sc);

        // (Aggregate|Enum)Declaration
        if (auto t = sds2.getType())
        {
            result = (new TypeExp(exp.loc, t)).expressionSemantic(sc);
            return;
        }

        if (auto td = sds2.isTemplateDeclaration())
        {
            result = (new TemplateExp(exp.loc, td)).expressionSemantic(sc);
            return;
        }

        exp.sds = sds2;
        exp.type = Type.tvoid;
        //printf("-2ScopeExp::semantic() %s\n", toChars());
        result = exp;
    }

    override void visit(NewExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("NewExp::semantic() %s\n", exp.toChars());
            if (exp.thisexp)
                printf("\tthisexp = %s\n", exp.thisexp.toChars());
            printf("\tnewtype: %s\n", exp.newtype.toChars());
        }
        if (exp.type) // if semantic() already run
        {
            result = exp;
            return;
        }

        //for error messages if the argument in [] is not convertible to size_t
        const originalNewtype = exp.newtype;

        // https://issues.dlang.org/show_bug.cgi?id=11581
        // With the syntax `new T[edim]` or `thisexp.new T[edim]`,
        // T should be analyzed first and edim should go into arguments iff it's
        // not a tuple.
        Expression edim = null;
        if (!exp.arguments && exp.newtype.isTypeSArray())
        {
            auto ts = exp.newtype.isTypeSArray();
            // check `new Value[Key]`
            ts.dim = ts.dim.expressionSemantic(sc);
            if (ts.dim.op == EXP.type)
            {
                exp.newtype = new TypeAArray(ts.next, ts.dim.isTypeExp().type);
            }
            else
            {
                edim = ts.dim;
                exp.newtype = ts.next;
            }
        }

        ClassDeclaration cdthis = null;
        if (exp.thisexp)
        {
            exp.thisexp = exp.thisexp.expressionSemantic(sc);
            if (exp.thisexp.op == EXP.error)
                return setError();

            cdthis = exp.thisexp.type.isClassHandle();
            if (!cdthis)
            {
                exp.error("`this` for nested class must be a class type, not `%s`", exp.thisexp.type.toChars());
                return setError();
            }

            sc = sc.push(cdthis);
            exp.type = exp.newtype.typeSemantic(exp.loc, sc);
            sc = sc.pop();
        }
        else
        {
            exp.type = exp.newtype.typeSemantic(exp.loc, sc);
        }
        if (exp.type.ty == Terror)
            return setError();

        if (edim)
        {
            if (exp.type.toBasetype().ty == Ttuple)
            {
                // --> new T[edim]
                exp.type = new TypeSArray(exp.type, edim);
                exp.type = exp.type.typeSemantic(exp.loc, sc);
                if (exp.type.ty == Terror)
                    return setError();
            }
            else
            {
                // --> new T[](edim)
                exp.arguments = new Expressions();
                exp.arguments.push(edim);
                exp.type = exp.type.arrayOf();
            }
        }

        exp.newtype = exp.type; // in case type gets cast to something else
        Type tb = exp.type.toBasetype();
        //printf("tb: %s, deco = %s\n", tb.toChars(), tb.deco);
        if (arrayExpressionSemantic(exp.arguments.peekSlice(), sc))
        {
            return setError();
        }
        if (preFunctionParameters(sc, exp.arguments))
        {
            return setError();
        }

        if (exp.thisexp && tb.ty != Tclass)
        {
            exp.error("`.new` is only for allocating nested classes, not `%s`", tb.toChars());
            return setError();
        }

        const size_t nargs = exp.arguments ? exp.arguments.dim : 0;
        Expression newprefix = null;

        if (auto tc = tb.isTypeClass())
        {
            auto cd = tc.sym;
            cd.size(exp.loc);
            if (cd.sizeok != Sizeok.done)
                return setError();
            if (!cd.ctor)
                cd.ctor = cd.searchCtor();
            if (cd.noDefaultCtor && !nargs && !cd.defaultCtor)
            {
                exp.error("default construction is disabled for type `%s`", cd.type.toChars());
                return setError();
            }

            if (cd.isInterfaceDeclaration())
            {
                exp.error("cannot create instance of interface `%s`", cd.toChars());
                return setError();
            }

            if (cd.isAbstract())
            {
                exp.error("cannot create instance of abstract class `%s`", cd.toChars());
                for (size_t i = 0; i < cd.vtbl.dim; i++)
                {
                    FuncDeclaration fd = cd.vtbl[i].isFuncDeclaration();
                    if (fd && fd.isAbstract())
                    {
                        errorSupplemental(exp.loc, "function `%s` is not implemented",
                            fd.toFullSignature());
                    }
                }
                return setError();
            }
            // checkDeprecated() is already done in newtype.typeSemantic().

            if (cd.isNested())
            {
                /* We need a 'this' pointer for the nested class.
                 * Ensure we have the right one.
                 */
                Dsymbol s = cd.toParentLocal();

                //printf("cd isNested, parent = %s '%s'\n", s.kind(), s.toPrettyChars());
                if (auto cdn = s.isClassDeclaration())
                {
                    if (!cdthis)
                    {
                        if (!sc.hasThis)
                        {
                            string msg = "cannot construct " ~
                            (cd.isAnonymous ? "anonymous nested class" : "nested class `%s`") ~
                            " because no implicit `this` reference to outer class" ~
                            (cdn.isAnonymous ? "" : " `%s`") ~ " is available\0";

                            exp.error(msg.ptr, cd.toChars, cdn.toChars);
                            return setError();
                        }

                        // Supply an implicit 'this' and try again
                        exp.thisexp = new ThisExp(exp.loc);
                        for (Dsymbol sp = sc.parent; 1; sp = sp.toParentLocal())
                        {
                            ClassDeclaration cdp = sp.isClassDeclaration();
                            if (!cdp)
                                continue;
                            if (cdp == cdn || cdn.isBaseOf(cdp, null))
                                break;
                            // Add a '.outer' and try again
                            exp.thisexp = new DotIdExp(exp.loc, exp.thisexp, Id.outer);
                        }

                        exp.thisexp = exp.thisexp.expressionSemantic(sc);
                        if (exp.thisexp.op == EXP.error)
                            return setError();
                        cdthis = exp.thisexp.type.isClassHandle();
                    }
                    if (cdthis != cdn && !cdn.isBaseOf(cdthis, null))
                    {
                        //printf("cdthis = %s\n", cdthis.toChars());
                        exp.error("`this` for nested class must be of type `%s`, not `%s`",
                            cdn.toChars(), exp.thisexp.type.toChars());
                        return setError();
                    }
                    if (!MODimplicitConv(exp.thisexp.type.mod, exp.newtype.mod))
                    {
                        exp.error("nested type `%s` should have the same or weaker constancy as enclosing type `%s`",
                            exp.newtype.toChars(), exp.thisexp.type.toChars());
                        return setError();
                    }
                }
                else if (exp.thisexp)
                {
                    exp.error("`.new` is only for allocating nested classes");
                    return setError();
                }
                else if (auto fdn = s.isFuncDeclaration())
                {
                    // make sure the parent context fdn of cd is reachable from sc
                    if (!ensureStaticLinkTo(sc.parent, fdn))
                    {
                        exp.error("outer function context of `%s` is needed to `new` nested class `%s`",
                            fdn.toPrettyChars(), cd.toPrettyChars());
                        return setError();
                    }
                }
                else
                    assert(0);
            }
            else if (exp.thisexp)
            {
                exp.error("`.new` is only for allocating nested classes");
                return setError();
            }

            if (cd.vthis2)
            {
                if (AggregateDeclaration ad2 = cd.isMember2())
                {
                    Expression te = new ThisExp(exp.loc).expressionSemantic(sc);
                    if (te.op != EXP.error)
                        te = getRightThis(exp.loc, sc, ad2, te, cd);
                    if (te.op == EXP.error)
                    {
                        exp.error("need `this` of type `%s` needed to `new` nested class `%s`", ad2.toChars(), cd.toChars());
                        return setError();
                    }
                }
            }

            if (cd.disableNew && !exp.onstack)
            {
                exp.error("cannot allocate `class %s` with `new` because it is annotated with `@disable new()`",
                          originalNewtype.toChars());
                return setError();
            }

            if (cd.ctor)
            {
                FuncDeclaration f = resolveFuncCall(exp.loc, sc, cd.ctor, null, tb, exp.arguments, FuncResolveFlag.standard);
                if (!f || f.errors)
                    return setError();

                checkFunctionAttributes(exp, sc, f);
                checkAccess(cd, exp.loc, sc, f);

                TypeFunction tf = f.type.isTypeFunction();
                if (!exp.arguments)
                    exp.arguments = new Expressions();
                if (functionParameters(exp.loc, sc, tf, null, exp.type, exp.arguments, f, &exp.type, &exp.argprefix))
                    return setError();

                exp.member = f.isCtorDeclaration();
                assert(exp.member);
            }
            else
            {
                if (nargs)
                {
                    exp.error("no constructor for `%s`", cd.toChars());
                    return setError();
                }

                // https://issues.dlang.org/show_bug.cgi?id=19941
                // Run semantic on all field initializers to resolve any forward
                // references. This is the same as done for structs in sd.fill().
                for (ClassDeclaration c = cd; c; c = c.baseClass)
                {
                    foreach (v; c.fields)
                    {
                        if (v.inuse || v._scope is null || v._init is null ||
                            v._init.isVoidInitializer())
                            continue;
                        v.inuse++;
                        v._init = v._init.initializerSemantic(v._scope, v.type, INITinterpret);
                        v.inuse--;
                    }
                }
            }

            // When using `@nogc` exception handling, lower `throw new E(args)` to
            // `throw (__tmp = _d_newThrowable!E(), __tmp.__ctor(args), __tmp)`.
            if (global.params.ehnogc && exp.thrownew &&
                !cd.isCOMclass() && !cd.isCPPclass())
            {
                assert(cd.ctor);

                Expression id = new IdentifierExp(exp.loc, Id.empty);
                id = new DotIdExp(exp.loc, id, Id.object);

                auto tiargs = new Objects();
                tiargs.push(exp.newtype);
                id = new DotTemplateInstanceExp(exp.loc, id, Id._d_newThrowable, tiargs);
                id = new CallExp(exp.loc, id).expressionSemantic(sc);

                Expression idVal;
                Expression tmp = extractSideEffect(sc, "__tmpThrowable", idVal, id, true);
                // auto castTmp = new CastExp(exp.loc, tmp, exp.type);

                auto ctor = new DotIdExp(exp.loc, tmp, Id.ctor).expressionSemantic(sc);
                auto ctorCall = new CallExp(exp.loc, ctor, exp.arguments);

                id = Expression.combine(idVal, exp.argprefix).expressionSemantic(sc);
                id = Expression.combine(id, ctorCall).expressionSemantic(sc);
                // id = Expression.combine(id, castTmp).expressionSemantic(sc);

                result = id.expressionSemantic(sc);
                return;
            }
        }
        else if (auto ts = tb.isTypeStruct())
        {
            auto sd = ts.sym;
            sd.size(exp.loc);
            if (sd.sizeok != Sizeok.done)
                return setError();
            if (!sd.ctor)
                sd.ctor = sd.searchCtor();
            if (sd.noDefaultCtor && !nargs)
            {
                exp.error("default construction is disabled for type `%s`", sd.type.toChars());
                return setError();
            }
            // checkDeprecated() is already done in newtype.typeSemantic().

            if (sd.disableNew)
            {
                exp.error("cannot allocate `struct %s` with `new` because it is annotated with `@disable new()`",
                          originalNewtype.toChars());
                return setError();
            }

            // https://issues.dlang.org/show_bug.cgi?id=22639
            // If the new expression has arguments, we either should call a
            // regular constructor of a copy constructor if the first argument
            // is the same type as the struct
            if (nargs && (sd.hasRegularCtor() || (sd.ctor && (*exp.arguments)[0].type.mutableOf() == sd.type.mutableOf())))
            {
                FuncDeclaration f = resolveFuncCall(exp.loc, sc, sd.ctor, null, tb, exp.arguments, FuncResolveFlag.standard);
                if (!f || f.errors)
                    return setError();

                checkFunctionAttributes(exp, sc, f);
                checkAccess(sd, exp.loc, sc, f);

                TypeFunction tf = f.type.isTypeFunction();
                if (!exp.arguments)
                    exp.arguments = new Expressions();
                if (functionParameters(exp.loc, sc, tf, null, exp.type, exp.arguments, f, &exp.type, &exp.argprefix))
                    return setError();

                exp.member = f.isCtorDeclaration();
                assert(exp.member);

                if (checkFrameAccess(exp.loc, sc, sd, sd.fields.dim))
                    return setError();
            }
            else
            {
                if (!exp.arguments)
                    exp.arguments = new Expressions();

                if (!sd.fit(exp.loc, sc, exp.arguments, tb))
                    return setError();

                if (!sd.fill(exp.loc, *exp.arguments, false))
                    return setError();

                if (checkFrameAccess(exp.loc, sc, sd, exp.arguments ? exp.arguments.dim : 0))
                    return setError();

                /* Since a `new` allocation may escape, check each of the arguments for escaping
                 */
                foreach (arg; *exp.arguments)
                {
                    if (arg && checkNewEscape(sc, arg, false))
                        return setError();
                }
            }

            exp.type = exp.type.pointerTo();
        }
        else if (tb.ty == Tarray)
        {
            if (!nargs)
            {
                // https://issues.dlang.org/show_bug.cgi?id=20422
                // Without this check the compiler would give a misleading error
                exp.error("missing length argument for array");
                return setError();
            }

            Type tn = tb.nextOf().baseElemOf();
            Dsymbol s = tn.toDsymbol(sc);
            AggregateDeclaration ad = s ? s.isAggregateDeclaration() : null;
            if (ad && ad.noDefaultCtor)
            {
                exp.error("default construction is disabled for type `%s`", tb.nextOf().toChars());
                return setError();
            }
            for (size_t i = 0; i < nargs; i++)
            {
                if (tb.ty != Tarray)
                {
                    exp.error("too many arguments for array");
                    return setError();
                }

                Expression arg = (*exp.arguments)[i];
                arg = resolveProperties(sc, arg);
                arg = arg.implicitCastTo(sc, Type.tsize_t);
                if (arg.op == EXP.error)
                    return setError();
                arg = arg.optimize(WANTvalue);
                if (arg.op == EXP.int64 && cast(sinteger_t)arg.toInteger() < 0)
                {
                    exp.error("negative array index `%s`", arg.toChars());
                    return setError();
                }
                (*exp.arguments)[i] = arg;
                tb = tb.isTypeDArray().next.toBasetype();
            }
        }
        else if (tb.isscalar())
        {
            if (!nargs)
            {
            }
            else if (nargs == 1)
            {
                Expression e = (*exp.arguments)[0];
                e = e.implicitCastTo(sc, tb);
                (*exp.arguments)[0] = e;
            }
            else
            {
                exp.error("more than one argument for construction of `%s`", exp.type.toChars());
                return setError();
            }

            exp.type = exp.type.pointerTo();
        }
        else if (tb.ty == Taarray)
        {
            // e.g. `new Alias(args)`
            if (nargs)
            {
                exp.error("`new` cannot take arguments for an associative array");
                return setError();
            }
        }
        else
        {
            exp.error("cannot create a `%s` with `new`", exp.type.toChars());
            return setError();
        }

        //printf("NewExp: '%s'\n", toChars());
        //printf("NewExp:type '%s'\n", type.toChars());
        semanticTypeInfo(sc, exp.type);

        if (newprefix)
        {
            result = Expression.combine(newprefix, exp);
            return;
        }
        result = exp;
    }

    override void visit(NewAnonClassExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("NewAnonClassExp::semantic() %s\n", e.toChars());
            //printf("thisexp = %p\n", thisexp);
            //printf("type: %s\n", type.toChars());
        }

        Expression d = new DeclarationExp(e.loc, e.cd);
        sc = sc.push(); // just create new scope
        sc.flags &= ~SCOPE.ctfe; // temporary stop CTFE
        d = d.expressionSemantic(sc);
        sc = sc.pop();

        if (!e.cd.errors && sc.intypeof && !sc.parent.inNonRoot())
        {
            ScopeDsymbol sds = sc.tinst ? cast(ScopeDsymbol)sc.tinst : sc._module;
            if (!sds.members)
                sds.members = new Dsymbols();
            sds.members.push(e.cd);
        }

        Expression n = new NewExp(e.loc, e.thisexp, e.cd.type, e.arguments);

        Expression c = new CommaExp(e.loc, d, n);
        result = c.expressionSemantic(sc);
    }

    override void visit(SymOffExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("SymOffExp::semantic('%s')\n", e.toChars());
        }
        //var.dsymbolSemantic(sc);
        if (!e.type)
            e.type = e.var.type.pointerTo();

        if (auto v = e.var.isVarDeclaration())
        {
            if (v.checkNestedReference(sc, e.loc))
                return setError();
        }
        else if (auto f = e.var.isFuncDeclaration())
        {
            if (f.checkNestedReference(sc, e.loc))
                return setError();
        }

        result = e;
    }

    override void visit(VarExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("VarExp::semantic(%s)\n", e.toChars());
        }

        auto vd = e.var.isVarDeclaration();
        auto fd = e.var.isFuncDeclaration();

        if (fd)
        {
            //printf("L%d fd = %s\n", __LINE__, f.toChars());
            if (!fd.functionSemantic())
                return setError();
        }

        if (!e.type)
            e.type = e.var.type;
        if (e.type && !e.type.deco)
        {
            auto decl = e.var.isDeclaration();
            if (decl)
                decl.inuse++;
            e.type = e.type.typeSemantic(e.loc, sc);
            if (decl)
                decl.inuse--;
        }

        /* Fix for 1161 doesn't work because it causes visibility
         * problems when instantiating imported templates passing private
         * variables as alias template parameters.
         */
        //checkAccess(loc, sc, NULL, var);

        if (vd)
        {
            if (vd.checkNestedReference(sc, e.loc))
                return setError();

            // https://issues.dlang.org/show_bug.cgi?id=12025
            // If the variable is not actually used in runtime code,
            // the purity violation error is redundant.
            //checkPurity(sc, vd);
        }
        else if (fd)
        {
            // TODO: If fd isn't yet resolved its overload, the checkNestedReference
            // call would cause incorrect validation.
            // Maybe here should be moved in CallExp, or AddrExp for functions.
            if (fd.checkNestedReference(sc, e.loc))
                return setError();
        }
        else if (auto od = e.var.isOverDeclaration())
        {
            e.type = Type.tvoid; // ambiguous type?
        }

        result = e;
    }

    override void visit(FuncExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("FuncExp::semantic(%s)\n", exp.toChars());
            if (exp.fd.treq)
                printf("  treq = %s\n", exp.fd.treq.toChars());
        }

        if (exp.type)
        {
            result = exp;
            return;
        }

        Expression e = exp;
        uint olderrors;

        sc = sc.push(); // just create new scope
        sc.flags &= ~SCOPE.ctfe; // temporary stop CTFE
        sc.visibility = Visibility(Visibility.Kind.public_); // https://issues.dlang.org/show_bug.cgi?id=12506

        /* fd.treq might be incomplete type,
            * so should not semantic it.
            * void foo(T)(T delegate(int) dg){}
            * foo(a=>a); // in IFTI, treq == T delegate(int)
            */
        //if (fd.treq)
        //    fd.treq = fd.treq.dsymbolSemantic(loc, sc);

        exp.genIdent(sc);

        // Set target of return type inference
        if (exp.fd.treq && !exp.fd.type.nextOf())
        {
            TypeFunction tfv = null;
            if (exp.fd.treq.ty == Tdelegate || exp.fd.treq.isPtrToFunction())
                tfv = cast(TypeFunction)exp.fd.treq.nextOf();
            if (tfv)
            {
                TypeFunction tfl = cast(TypeFunction)exp.fd.type;
                tfl.next = tfv.nextOf();
            }
        }

        //printf("td = %p, treq = %p\n", td, fd.treq);
        if (exp.td)
        {
            assert(exp.td.parameters && exp.td.parameters.dim);
            exp.td.dsymbolSemantic(sc);
            exp.type = Type.tvoid; // temporary type

            if (exp.fd.treq) // defer type determination
            {
                FuncExp fe;
                if (exp.matchType(exp.fd.treq, sc, &fe) > MATCH.nomatch)
                    e = fe;
                else
                    e = ErrorExp.get();
            }
            goto Ldone;
        }

        olderrors = global.errors;
        exp.fd.dsymbolSemantic(sc);
        if (olderrors == global.errors)
        {
            exp.fd.semantic2(sc);
            if (olderrors == global.errors)
                exp.fd.semantic3(sc);
        }
        if (olderrors != global.errors)
        {
            if (exp.fd.type && exp.fd.type.ty == Tfunction && !exp.fd.type.nextOf())
                (cast(TypeFunction)exp.fd.type).next = Type.terror;
            e = ErrorExp.get();
            goto Ldone;
        }

        // Type is a "delegate to" or "pointer to" the function literal
        if ((exp.fd.isNested() && exp.fd.tok == TOK.delegate_) || (exp.tok == TOK.reserved && exp.fd.treq && exp.fd.treq.ty == Tdelegate))
        {
            // https://issues.dlang.org/show_bug.cgi?id=22686
            // if the delegate return type is an error
            // abort semantic of the FuncExp and propagate
            // the error
            if (exp.fd.type.isTypeError())
            {
                e = ErrorExp.get();
                goto Ldone;
            }
            exp.type = new TypeDelegate(exp.fd.type.isTypeFunction());
            exp.type = exp.type.typeSemantic(exp.loc, sc);

            exp.fd.tok = TOK.delegate_;
        }
        else
        {
            exp.type = new TypePointer(exp.fd.type);
            exp.type = exp.type.typeSemantic(exp.loc, sc);
            //type = fd.type.pointerTo();

            /* A lambda expression deduced to function pointer might become
                * to a delegate literal implicitly.
                *
                *   auto foo(void function() fp) { return 1; }
                *   assert(foo({}) == 1);
                *
                * So, should keep fd.tok == TOK.reserve if fd.treq == NULL.
                */
            if (exp.fd.treq && exp.fd.treq.ty == Tpointer)
            {
                // change to non-nested
                exp.fd.tok = TOK.function_;
                exp.fd.vthis = null;
            }
        }
        exp.fd.tookAddressOf++;

    Ldone:
        sc = sc.pop();
        result = e;
    }

    /**
     * Perform semantic analysis on function literals
     *
     * Test the following construct:
     * ---
     * (x, y, z) { return x + y + z; }(42, 84, 1992);
     * ---
     */
    Expression callExpSemantic(FuncExp exp, Scope* sc, Expressions* arguments)
    {
        if ((!exp.type || exp.type == Type.tvoid) && exp.td && arguments && arguments.dim)
        {
            for (size_t k = 0; k < arguments.dim; k++)
            {
                Expression checkarg = (*arguments)[k];
                if (checkarg.op == EXP.error)
                    return checkarg;
            }

            exp.genIdent(sc);

            assert(exp.td.parameters && exp.td.parameters.dim);
            exp.td.dsymbolSemantic(sc);

            TypeFunction tfl = cast(TypeFunction)exp.fd.type;
            size_t dim = tfl.parameterList.length;
            if (arguments.dim < dim)
            {
                // Default arguments are always typed, so they don't need inference.
                Parameter p = tfl.parameterList[arguments.dim];
                if (p.defaultArg)
                    dim = arguments.dim;
            }

            if ((tfl.parameterList.varargs == VarArg.none && arguments.dim > dim) ||
                arguments.dim < dim)
            {
                OutBuffer buf;
                foreach (idx, ref arg; *arguments)
                    buf.printf("%s%s", (idx ? ", ".ptr : "".ptr), arg.type.toChars());
                exp.error("function literal `%s%s` is not callable using argument types `(%s)`",
                          exp.fd.toChars(), parametersTypeToChars(tfl.parameterList),
                          buf.peekChars());
                exp.errorSupplemental("too %s arguments, expected `%d`, got `%d`",
                                      arguments.dim < dim ? "few".ptr : "many".ptr,
                                      cast(int)dim, cast(int)arguments.dim);
                return ErrorExp.get();
            }

            auto tiargs = new Objects();
            tiargs.reserve(exp.td.parameters.dim);

            for (size_t i = 0; i < exp.td.parameters.dim; i++)
            {
                TemplateParameter tp = (*exp.td.parameters)[i];
                assert(dim <= tfl.parameterList.length);
                foreach (u, p; tfl.parameterList)
                {
                    if (u == dim)
                        break;

                    if (p.type.ty == Tident && (cast(TypeIdentifier)p.type).ident == tp.ident)
                    {
                        Expression e = (*arguments)[u];
                        tiargs.push(e.type);
                        break;
                    }
                }
            }

            auto ti = new TemplateInstance(exp.loc, exp.td, tiargs);
            return (new ScopeExp(exp.loc, ti)).expressionSemantic(sc);
        }
        return exp.expressionSemantic(sc);
    }

    override void visit(CallExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("CallExp::semantic() %s\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return; // semantic() already run
        }

        Objects* tiargs = null; // initial list of template arguments
        Expression ethis = null;
        Type tthis = null;
        Expression e1org = exp.e1;

        if (auto ce = exp.e1.isCommaExp())
        {
            /* Rewrite (a,b)(args) as (a,(b(args)))
             */
            exp.e1 = ce.e2;
            ce.e2 = exp;
            result = ce.expressionSemantic(sc);
            return;
        }
        if (DelegateExp de = exp.e1.isDelegateExp())
        {
            exp.e1 = new DotVarExp(de.loc, de.e1, de.func, de.hasOverloads);
            visit(exp);
            return;
        }
        if (FuncExp fe = exp.e1.isFuncExp())
        {
            if (arrayExpressionSemantic(exp.arguments.peekSlice(), sc) ||
                preFunctionParameters(sc, exp.arguments))
                return setError();

            // Run e1 semantic even if arguments have any errors
            exp.e1 = callExpSemantic(fe, sc, exp.arguments);
            if (exp.e1.op == EXP.error)
            {
                result = exp.e1;
                return;
            }
        }
        if (sc.flags & SCOPE.Cfile)
        {
            /* See if need to rewrite the AST because of cast/call ambiguity
             */
            if (auto e = castCallAmbiguity(exp, sc))
            {
                result = expressionSemantic(e, sc);
                return;
            }
        }

        if (Expression ex = resolveUFCS(sc, exp))
        {
            result = ex;
            return;
        }

        /* This recognizes:
         *  foo!(tiargs)(funcargs)
         */
        if (ScopeExp se = exp.e1.isScopeExp())
        {
            TemplateInstance ti = se.sds.isTemplateInstance();
            if (ti)
            {
                /* Attempt to instantiate ti. If that works, go with it.
                 * If not, go with partial explicit specialization.
                 */
                WithScopeSymbol withsym;
                if (!ti.findTempDecl(sc, &withsym) || !ti.semanticTiargs(sc))
                    return setError();
                if (withsym && withsym.withstate.wthis)
                {
                    exp.e1 = new VarExp(exp.e1.loc, withsym.withstate.wthis);
                    exp.e1 = new DotTemplateInstanceExp(exp.e1.loc, exp.e1, ti);
                    goto Ldotti;
                }
                if (ti.needsTypeInference(sc, 1))
                {
                    /* Go with partial explicit specialization
                     */
                    tiargs = ti.tiargs;
                    assert(ti.tempdecl);
                    if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())
                        exp.e1 = new TemplateExp(exp.loc, td);
                    else if (OverDeclaration od = ti.tempdecl.isOverDeclaration())
                        exp.e1 = new VarExp(exp.loc, od);
                    else
                        exp.e1 = new OverExp(exp.loc, ti.tempdecl.isOverloadSet());
                }
                else
                {
                    Expression e1x = exp.e1.expressionSemantic(sc);
                    if (e1x.op == EXP.error)
                    {
                        result = e1x;
                        return;
                    }
                    exp.e1 = e1x;
                }
            }
        }

        /* This recognizes:
         *  expr.foo!(tiargs)(funcargs)
         */
    Ldotti:
        if (DotTemplateInstanceExp se = exp.e1.isDotTemplateInstanceExp())
        {
            TemplateInstance ti = se.ti;
            {
                /* Attempt to instantiate ti. If that works, go with it.
                 * If not, go with partial explicit specialization.
                 */
                if (!se.findTempDecl(sc) || !ti.semanticTiargs(sc))
                    return setError();
                if (ti.needsTypeInference(sc, 1))
                {
                    /* Go with partial explicit specialization
                     */
                    tiargs = ti.tiargs;
                    assert(ti.tempdecl);
                    if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())
                        exp.e1 = new DotTemplateExp(exp.loc, se.e1, td);
                    else if (OverDeclaration od = ti.tempdecl.isOverDeclaration())
                    {
                        exp.e1 = new DotVarExp(exp.loc, se.e1, od, true);
                    }
                    else
                        exp.e1 = new DotExp(exp.loc, se.e1, new OverExp(exp.loc, ti.tempdecl.isOverloadSet()));
                }
                else
                {
                    Expression e1x = exp.e1.expressionSemantic(sc);
                    if (e1x.op == EXP.error)
                    {
                        result = e1x;
                        return;
                    }
                    exp.e1 = e1x;
                }
            }
        }

    Lagain:
        //printf("Lagain: %s\n", toChars());
        exp.f = null;
        if (exp.e1.op == EXP.this_ || exp.e1.op == EXP.super_)
        {
            // semantic() run later for these
        }
        else
        {
            if (DotIdExp die = exp.e1.isDotIdExp())
            {
                exp.e1 = die.expressionSemantic(sc);
                /* Look for e1 having been rewritten to expr.opDispatch!(string)
                 * We handle such earlier, so go back.
                 * Note that in the rewrite, we carefully did not run semantic() on e1
                 */
                if (exp.e1.op == EXP.dotTemplateInstance)
                {
                    goto Ldotti;
                }
            }
            else
            {
                __gshared int nest;
                if (++nest > global.recursionLimit)
                {
                    exp.error("recursive evaluation of `%s`", exp.toChars());
                    --nest;
                    return setError();
                }
                Expression ex = unaSemantic(exp, sc);
                --nest;
                if (ex)
                {
                    result = ex;
                    return;
                }
            }

            /* Look for e1 being a lazy parameter
             */
            if (VarExp ve = exp.e1.isVarExp())
            {
                if (ve.var.storage_class & STC.lazy_)
                {
                    // lazy parameters can be called without violating purity and safety
                    Type tw = ve.var.type;
                    Type tc = ve.var.type.substWildTo(MODFlags.const_);
                    auto tf = new TypeFunction(ParameterList(), tc, LINK.d, STC.safe | STC.pure_);
                    (tf = cast(TypeFunction)tf.typeSemantic(exp.loc, sc)).next = tw; // hack for bug7757
                    auto t = new TypeDelegate(tf);
                    ve.type = t.typeSemantic(exp.loc, sc);
                }
                VarDeclaration v = ve.var.isVarDeclaration();
                if (v && ve.checkPurity(sc, v))
                    return setError();
            }

            if (exp.e1.op == EXP.symbolOffset && (cast(SymOffExp)exp.e1).hasOverloads)
            {
                SymOffExp se = cast(SymOffExp)exp.e1;
                exp.e1 = new VarExp(se.loc, se.var, true);
                exp.e1 = exp.e1.expressionSemantic(sc);
            }
            else if (DotExp de = exp.e1.isDotExp())
            {
                if (de.e2.op == EXP.overloadSet)
                {
                    ethis = de.e1;
                    tthis = de.e1.type;
                    exp.e1 = de.e2;
                }
            }
            else if (exp.e1.op == EXP.star && exp.e1.type.ty == Tfunction)
            {
                // Rewrite (*fp)(arguments) to fp(arguments)
                exp.e1 = (cast(PtrExp)exp.e1).e1;
            }
            else if (exp.e1.op == EXP.type && (sc && sc.flags & SCOPE.Cfile))
            {
                const numArgs = exp.arguments ? exp.arguments.length : 0;

                /* Ambiguous cases arise from CParser where there is not enough
                 * information to determine if we have a function call or declaration.
                 *   type-name ( identifier ) ;
                 *   identifier ( identifier ) ;
                 * If exp.e1 is a type-name, then this is a declaration. C11 does not
                 * have type construction syntax, so don't convert this to a cast().
                 */
                if (numArgs == 1)
                {
                    Expression arg = (*exp.arguments)[0];
                    if (auto ie = (*exp.arguments)[0].isIdentifierExp())
                    {
                        TypeExp te = cast(TypeExp)exp.e1;
                        auto initializer = new VoidInitializer(ie.loc);
                        Dsymbol s = new VarDeclaration(ie.loc, te.type, ie.ident, initializer);
                        auto decls = new Dsymbols(1);
                        (*decls)[0] = s;
                        s = new LinkDeclaration(s.loc, LINK.c, decls);
                        result = new DeclarationExp(exp.loc, s);
                        result = result.expressionSemantic(sc);
                    }
                    else
                    {
                        arg.error("identifier or `(` expected");
                        result = ErrorExp.get();
                    }
                    return;
                }
                exp.error("identifier or `(` expected before `)`");
                result = ErrorExp.get();
                return;
            }
        }

        Type t1 = exp.e1.type ? exp.e1.type.toBasetype() : null;

        if (exp.e1.op == EXP.error)
        {
            result = exp.e1;
            return;
        }
        if (arrayExpressionSemantic(exp.arguments.peekSlice(), sc) ||
            preFunctionParameters(sc, exp.arguments))
            return setError();

        // Check for call operator overload
        if (t1)
        {
            if (t1.ty == Tstruct)
            {
                auto sd = (cast(TypeStruct)t1).sym;
                sd.size(exp.loc); // Resolve forward references to construct object
                if (sd.sizeok != Sizeok.done)
                    return setError();
                if (!sd.ctor)
                    sd.ctor = sd.searchCtor();
                /* If `sd.ctor` is a generated copy constructor, this means that it
                   is the single constructor that this struct has. In order to not
                   disable default construction, the ctor is nullified. The side effect
                   of this is that the generated copy constructor cannot be called
                   explicitly, but that is ok, because when calling a constructor the
                   default constructor should have priority over the generated copy
                   constructor.
                */
                if (sd.ctor)
                {
                    auto ctor = sd.ctor.isCtorDeclaration();
                    if (ctor && ctor.isCpCtor && ctor.isGenerated())
                        sd.ctor = null;
                }

                // First look for constructor
                if (exp.e1.op == EXP.type && sd.ctor)
                {
                    if (!sd.noDefaultCtor && !(exp.arguments && exp.arguments.dim))
                        goto Lx;

                    /* https://issues.dlang.org/show_bug.cgi?id=20695
                       If all constructors are copy constructors, then
                       try default construction.
                     */
                    if (!sd.hasRegularCtor &&
                        // https://issues.dlang.org/show_bug.cgi?id=22639
                        // we might still have a copy constructor that could be called
                        (*exp.arguments)[0].type.mutableOf != sd.type.mutableOf())
                        goto Lx;

                    auto sle = new StructLiteralExp(exp.loc, sd, null, exp.e1.type);
                    if (!sd.fill(exp.loc, *sle.elements, true))
                        return setError();
                    if (checkFrameAccess(exp.loc, sc, sd, sle.elements.dim))
                        return setError();

                    // https://issues.dlang.org/show_bug.cgi?id=14556
                    // Set concrete type to avoid further redundant semantic().
                    sle.type = exp.e1.type;

                    /* Constructor takes a mutable object, so don't use
                     * the immutable initializer symbol.
                     */
                    sle.useStaticInit = false;

                    Expression e = sle;
                    if (auto cf = sd.ctor.isCtorDeclaration())
                    {
                        e = new DotVarExp(exp.loc, e, cf, true);
                    }
                    else if (auto td = sd.ctor.isTemplateDeclaration())
                    {
                        e = new DotIdExp(exp.loc, e, td.ident);
                    }
                    else if (auto os = sd.ctor.isOverloadSet())
                    {
                        e = new DotExp(exp.loc, e, new OverExp(exp.loc, os));
                    }
                    else
                        assert(0);
                    e = new CallExp(exp.loc, e, exp.arguments);
                    e = e.expressionSemantic(sc);
                    result = e;
                    return;
                }
                // No constructor, look for overload of opCall
                if (search_function(sd, Id.call))
                    goto L1;
                // overload of opCall, therefore it's a call
                if (exp.e1.op != EXP.type)
                {
                    if (sd.aliasthis && !isRecursiveAliasThis(exp.att1, exp.e1.type))
                    {
                        exp.e1 = resolveAliasThis(sc, exp.e1);
                        goto Lagain;
                    }
                    exp.error("%s `%s` does not overload ()", sd.kind(), sd.toChars());
                    return setError();
                }

                /* It's a struct literal
                 */
            Lx:
                Expression e = new StructLiteralExp(exp.loc, sd, exp.arguments, exp.e1.type);
                e = e.expressionSemantic(sc);
                result = e;
                return;
            }
            else if (t1.ty == Tclass)
            {
            L1:
                // Rewrite as e1.call(arguments)
                Expression e = new DotIdExp(exp.loc, exp.e1, Id.call);
                e = new CallExp(exp.loc, e, exp.arguments);
                e = e.expressionSemantic(sc);
                result = e;
                return;
            }
            else if (exp.e1.op == EXP.type && t1.isscalar())
            {
                Expression e;

                // Make sure to use the enum type itself rather than its
                // base type
                // https://issues.dlang.org/show_bug.cgi?id=16346
                if (exp.e1.type.ty == Tenum)
                {
                    t1 = exp.e1.type;
                }

                if (!exp.arguments || exp.arguments.dim == 0)
                {
                    e = t1.defaultInitLiteral(exp.loc);
                }
                else if (exp.arguments.dim == 1)
                {
                    e = (*exp.arguments)[0];
                    if (!e.type.isTypeNoreturn())
                        e = e.implicitCastTo(sc, t1);
                }
                else
                {
                    exp.error("more than one argument for construction of `%s`", t1.toChars());
                    return setError();
                }
                e = e.expressionSemantic(sc);
                result = e;
                return;
            }
        }

        static FuncDeclaration resolveOverloadSet(Loc loc, Scope* sc,
            OverloadSet os, Objects* tiargs, Type tthis, Expressions* arguments)
        {
            FuncDeclaration f = null;
            foreach (s; os.a)
            {
                if (tiargs && s.isFuncDeclaration())
                    continue;
                if (auto f2 = resolveFuncCall(loc, sc, s, tiargs, tthis, arguments, FuncResolveFlag.quiet))
                {
                    if (f2.errors)
                        return null;
                    if (f)
                    {
                        /* Error if match in more than one overload set,
                         * even if one is a 'better' match than the other.
                         */
                        ScopeDsymbol.multiplyDefined(loc, f, f2);
                    }
                    else
                        f = f2;
                }
            }
            if (!f)
                .error(loc, "no overload matches for `%s`", os.toChars());
            else if (f.errors)
                f = null;
            return f;
        }

        bool isSuper = false;
        if (exp.e1.op == EXP.dotVariable && t1.ty == Tfunction || exp.e1.op == EXP.dotTemplateDeclaration)
        {
            UnaExp ue = cast(UnaExp)exp.e1;

            Expression ue1old = ue.e1; // need for 'right this' check
            DotVarExp dve;
            DotTemplateExp dte;
            Dsymbol s;
            if (exp.e1.op == EXP.dotVariable)
            {
                dve = cast(DotVarExp)exp.e1;
                dte = null;
                s = dve.var;
                tiargs = null;
            }
            else
            {
                dve = null;
                dte = cast(DotTemplateExp)exp.e1;
                s = dte.td;
            }

            // Do overload resolution
            exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, ue.e1.type, exp.arguments, FuncResolveFlag.standard);
            if (!exp.f || exp.f.errors || exp.f.type.ty == Terror)
                return setError();

            if (exp.f.interfaceVirtual)
            {
                /* Cast 'this' to the type of the interface, and replace f with the interface's equivalent
                 */
                auto b = exp.f.interfaceVirtual;
                auto ad2 = b.sym;
                ue.e1 = ue.e1.castTo(sc, ad2.type.addMod(ue.e1.type.mod));
                ue.e1 = ue.e1.expressionSemantic(sc);
                auto vi = exp.f.findVtblIndex(&ad2.vtbl, cast(int)ad2.vtbl.dim);
                assert(vi >= 0);
                exp.f = ad2.vtbl[vi].isFuncDeclaration();
                assert(exp.f);
            }
            if (exp.f.needThis())
            {
                AggregateDeclaration ad = exp.f.isMemberLocal();
                ue.e1 = getRightThis(exp.loc, sc, ad, ue.e1, exp.f);
                if (ue.e1.op == EXP.error)
                {
                    result = ue.e1;
                    return;
                }
                ethis = ue.e1;
                tthis = ue.e1.type;
                if (!(exp.f.type.ty == Tfunction && (cast(TypeFunction)exp.f.type).isScopeQual))
                {
                    if (checkParamArgumentEscape(sc, exp.f, null, null, STC.undefined_, ethis, false, false))
                        return setError();
                }
            }

            /* Cannot call public functions from inside invariant
             * (because then the invariant would have infinite recursion)
             */
            if (sc.func && sc.func.isInvariantDeclaration() && ue.e1.op == EXP.this_ && exp.f.addPostInvariant())
            {
                exp.error("cannot call `public`/`export` function `%s` from invariant", exp.f.toChars());
                return setError();
            }

            if (!exp.ignoreAttributes)
                checkFunctionAttributes(exp, sc, exp.f);
            checkAccess(exp.loc, sc, ue.e1, exp.f);
            if (!exp.f.needThis())
            {
                exp.e1 = Expression.combine(ue.e1, new VarExp(exp.loc, exp.f, false));
            }
            else
            {
                if (ue1old.checkRightThis(sc))
                    return setError();
                if (exp.e1.op == EXP.dotVariable)
                {
                    dve.var = exp.f;
                    exp.e1.type = exp.f.type;
                }
                else
                {
                    exp.e1 = new DotVarExp(exp.loc, dte.e1, exp.f, false);
                    exp.e1 = exp.e1.expressionSemantic(sc);
                    if (exp.e1.op == EXP.error)
                        return setError();
                    ue = cast(UnaExp)exp.e1;
                }
                version (none)
                {
                    printf("ue.e1 = %s\n", ue.e1.toChars());
                    printf("f = %s\n", exp.f.toChars());
                    printf("t1 = %s\n", t1.toChars());
                    printf("e1 = %s\n", exp.e1.toChars());
                    printf("e1.type = %s\n", exp.e1.type.toChars());
                }

                // See if we need to adjust the 'this' pointer
                AggregateDeclaration ad = exp.f.isThis();
                ClassDeclaration cd = ue.e1.type.isClassHandle();
                if (ad && cd && ad.isClassDeclaration())
                {
                    if (ue.e1.op == EXP.dotType)
                    {
                        ue.e1 = (cast(DotTypeExp)ue.e1).e1;
                        exp.directcall = true;
                    }
                    else if (ue.e1.op == EXP.super_)
                        exp.directcall = true;
                    else if ((cd.storage_class & STC.final_) != 0) // https://issues.dlang.org/show_bug.cgi?id=14211
                        exp.directcall = true;

                    if (ad != cd)
                    {
                        ue.e1 = ue.e1.castTo(sc, ad.type.addMod(ue.e1.type.mod));
                        ue.e1 = ue.e1.expressionSemantic(sc);
                    }
                }
            }
            // If we've got a pointer to a function then deference it
            // https://issues.dlang.org/show_bug.cgi?id=16483
            if (exp.e1.type.isPtrToFunction())
            {
                Expression e = new PtrExp(exp.loc, exp.e1);
                e.type = exp.e1.type.nextOf();
                exp.e1 = e;
            }
            t1 = exp.e1.type;
        }
        else if (exp.e1.op == EXP.super_ || exp.e1.op == EXP.this_)
        {
            auto ad = sc.func ? sc.func.isThis() : null;
            auto cd = ad ? ad.isClassDeclaration() : null;

            isSuper = exp.e1.op == EXP.super_;
            if (isSuper)
            {
                // Base class constructor call
                if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration())
                {
                    exp.error("super class constructor call must be in a constructor");
                    return setError();
                }
                if (!cd.baseClass.ctor)
                {
                    exp.error("no super class constructor for `%s`", cd.baseClass.toChars());
                    return setError();
                }
            }
            else
            {
                // `this` call expression must be inside a
                // constructor
                if (!ad || !sc.func.isCtorDeclaration())
                {
                    exp.error("constructor call must be in a constructor");
                    return setError();
                }

                // https://issues.dlang.org/show_bug.cgi?id=18719
                // If `exp` is a call expression to another constructor
                // then it means that all struct/class fields will be
                // initialized after this call.
                foreach (ref field; sc.ctorflow.fieldinit)
                {
                    field.csx |= CSX.this_ctor;
                }
            }

            if (!sc.intypeof && !(sc.ctorflow.callSuper & CSX.halt))
            {
                if (sc.inLoop || sc.ctorflow.callSuper & CSX.label)
                    exp.error("constructor calls not allowed in loops or after labels");
                if (sc.ctorflow.callSuper & (CSX.super_ctor | CSX.this_ctor))
                    exp.error("multiple constructor calls");
                if ((sc.ctorflow.callSuper & CSX.return_) && !(sc.ctorflow.callSuper & CSX.any_ctor))
                    exp.error("an earlier `return` statement skips constructor");
                sc.ctorflow.callSuper |= CSX.any_ctor | (isSuper ? CSX.super_ctor : CSX.this_ctor);
            }

            tthis = ad.type.addMod(sc.func.type.mod);
            auto ctor = isSuper ? cd.baseClass.ctor : ad.ctor;
            if (auto os = ctor.isOverloadSet())
                exp.f = resolveOverloadSet(exp.loc, sc, os, null, tthis, exp.arguments);
            else
                exp.f = resolveFuncCall(exp.loc, sc, ctor, null, tthis, exp.arguments, FuncResolveFlag.standard);

            if (!exp.f || exp.f.errors)
                return setError();

            checkFunctionAttributes(exp, sc, exp.f);
            checkAccess(exp.loc, sc, null, exp.f);

            exp.e1 = new DotVarExp(exp.e1.loc, exp.e1, exp.f, false);
            exp.e1 = exp.e1.expressionSemantic(sc);
            // https://issues.dlang.org/show_bug.cgi?id=21095
            if (exp.e1.op == EXP.error)
                return setError();
            t1 = exp.e1.type;

            // BUG: this should really be done by checking the static
            // call graph
            if (exp.f == sc.func)
            {
                exp.error("cyclic constructor call");
                return setError();
            }
        }
        else if (auto oe = exp.e1.isOverExp())
        {
            exp.f = resolveOverloadSet(exp.loc, sc, oe.vars, tiargs, tthis, exp.arguments);
            if (!exp.f)
                return setError();
            if (ethis)
                exp.e1 = new DotVarExp(exp.loc, ethis, exp.f, false);
            else
                exp.e1 = new VarExp(exp.loc, exp.f, false);
            goto Lagain;
        }
        else if (!t1)
        {
            exp.error("function expected before `()`, not `%s`", exp.e1.toChars());
            return setError();
        }
        else if (t1.ty == Terror)
        {
            return setError();
        }
        else if (t1.ty != Tfunction)
        {
            TypeFunction tf;
            const(char)* p;
            Dsymbol s;
            exp.f = null;
            if (auto fe = exp.e1.isFuncExp())
            {
                // function literal that direct called is always inferred.
                assert(fe.fd);
                exp.f = fe.fd;
                tf = cast(TypeFunction)exp.f.type;
                p = "function literal";
            }
            else if (t1.ty == Tdelegate)
            {
                TypeDelegate td = cast(TypeDelegate)t1;
                assert(td.next.ty == Tfunction);
                tf = cast(TypeFunction)td.next;
                p = "delegate";
            }
            else if (auto tfx = t1.isPtrToFunction())
            {
                tf = tfx;
                p = "function pointer";
            }
            else if (exp.e1.op == EXP.dotVariable && (cast(DotVarExp)exp.e1).var.isOverDeclaration())
            {
                DotVarExp dve = cast(DotVarExp)exp.e1;
                exp.f = resolveFuncCall(exp.loc, sc, dve.var, tiargs, dve.e1.type, exp.arguments, FuncResolveFlag.overloadOnly);
                if (!exp.f)
                    return setError();
                if (exp.f.needThis())
                {
                    dve.var = exp.f;
                    dve.type = exp.f.type;
                    dve.hasOverloads = false;
                    goto Lagain;
                }
                exp.e1 = new VarExp(dve.loc, exp.f, false);
                Expression e = new CommaExp(exp.loc, dve.e1, exp);
                result = e.expressionSemantic(sc);
                return;
            }
            else if (exp.e1.op == EXP.variable && (cast(VarExp)exp.e1).var.isOverDeclaration())
            {
                s = (cast(VarExp)exp.e1).var;
                goto L2;
            }
            else if (exp.e1.op == EXP.template_)
            {
                s = (cast(TemplateExp)exp.e1).td;
            L2:
                exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.arguments, FuncResolveFlag.standard);
                if (!exp.f || exp.f.errors)
                    return setError();
                if (exp.f.needThis())
                {
                    if (hasThis(sc))
                    {
                        // Supply an implicit 'this', as in
                        //    this.ident
                        exp.e1 = new DotVarExp(exp.loc, (new ThisExp(exp.loc)).expressionSemantic(sc), exp.f, false);
                        goto Lagain;
                    }
                    else if (isNeedThisScope(sc, exp.f))
                    {
                        exp.error("need `this` for `%s` of type `%s`", exp.f.toChars(), exp.f.type.toChars());
                        return setError();
                    }
                }
                exp.e1 = new VarExp(exp.e1.loc, exp.f, false);
                goto Lagain;
            }
            else
            {
                exp.error("function expected before `()`, not `%s` of type `%s`", exp.e1.toChars(), exp.e1.type.toChars());
                return setError();
            }

            const(char)* failMessage;
            Expression[] fargs = exp.arguments ? (*exp.arguments)[] : null;
            if (!tf.callMatch(null, fargs, 0, &failMessage, sc))
            {
                OutBuffer buf;
                buf.writeByte('(');
                argExpTypesToCBuffer(&buf, exp.arguments);
                buf.writeByte(')');
                if (tthis)
                    tthis.modToBuffer(&buf);

                //printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
                .error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
                    p, exp.e1.toChars(), parametersTypeToChars(tf.parameterList), buf.peekChars());
                if (failMessage)
                    errorSupplemental(exp.loc, "%s", failMessage);
                return setError();
            }
            // Purity and safety check should run after testing arguments matching
            if (exp.f)
            {
                exp.checkPurity(sc, exp.f);
                exp.checkSafety(sc, exp.f);
                exp.checkNogc(sc, exp.f);
                if (exp.f.checkNestedReference(sc, exp.loc))
                    return setError();
            }
            else if (sc.func && sc.intypeof != 1 && !(sc.flags & (SCOPE.ctfe | SCOPE.debug_)))
            {
                bool err = false;
                if (!tf.purity && sc.func.setImpure())
                {
                    exp.error("`pure` %s `%s` cannot call impure %s `%s`",
                        sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
                    err = true;
                }
                if (!tf.isnogc && sc.func.setGC())
                {
                    exp.error("`@nogc` %s `%s` cannot call non-@nogc %s `%s`",
                        sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
                    err = true;
                }
                if (tf.trust <= TRUST.system && sc.setUnsafe(true, exp.loc,
                    "`@safe` function `%s` cannot call `@system` `%s`", sc.func, exp.e1))
                {
                    exp.error("`@safe` %s `%s` cannot call `@system` %s `%s`",
                        sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
                    err = true;
                }
                if (err)
                    return setError();
            }

            if (t1.ty == Tpointer)
            {
                Expression e = new PtrExp(exp.loc, exp.e1);
                e.type = tf;
                exp.e1 = e;
            }
            t1 = tf;
        }
        else if (VarExp ve = exp.e1.isVarExp())
        {
            // Do overload resolution
            exp.f = ve.var.isFuncDeclaration();
            assert(exp.f);
            tiargs = null;

            if (exp.f.overnext)
                exp.f = resolveFuncCall(exp.loc, sc, exp.f, tiargs, null, exp.arguments, FuncResolveFlag.overloadOnly);
            else
            {
                exp.f = exp.f.toAliasFunc();
                TypeFunction tf = cast(TypeFunction)exp.f.type;
                const(char)* failMessage;
                Expression[] fargs = exp.arguments ? (*exp.arguments)[] : null;
                if (!tf.callMatch(null, fargs, 0, &failMessage, sc))
                {
                    OutBuffer buf;
                    buf.writeByte('(');
                    argExpTypesToCBuffer(&buf, exp.arguments);
                    buf.writeByte(')');

                    //printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
                    .error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
                        exp.f.kind(), exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList), buf.peekChars());
                    if (failMessage)
                        errorSupplemental(exp.loc, "%s", failMessage);
                    exp.f = null;
                }
            }
            if (!exp.f || exp.f.errors)
                return setError();

            if (exp.f.needThis())
            {
                // Change the ancestor lambdas to delegate before hasThis(sc) call.
                if (exp.f.checkNestedReference(sc, exp.loc))
                    return setError();

                if (hasThis(sc))
                {
                    // Supply an implicit 'this', as in
                    //    this.ident
                    exp.e1 = new DotVarExp(exp.loc, (new ThisExp(exp.loc)).expressionSemantic(sc), ve.var);
                    // Note: we cannot use f directly, because further overload resolution
                    // through the supplied 'this' may cause different result.
                    goto Lagain;
                }
                else if (isNeedThisScope(sc, exp.f))
                {
                    // At this point it is possible that `exp.f` had an ambiguity error that was
                    // silenced because the previous call to `resolveFuncCall` was done using
                    // `FuncResolveFlag.overloadOnly`. To make sure that a proper error message
                    // is printed, redo the call with `FuncResolveFlag.standard`.
                    //
                    // https://issues.dlang.org/show_bug.cgi?id=22157
                    if (exp.f.overnext)
                        exp.f = resolveFuncCall(exp.loc, sc, exp.f, tiargs, null, exp.arguments, FuncResolveFlag.standard);

                    if (!exp.f || exp.f.errors)
                        return setError();

                    // If no error is printed, it means that `f` is the single matching overload
                    // and it needs `this`.
                    exp.error("need `this` for `%s` of type `%s`", exp.f.toChars(), exp.f.type.toChars());
                    return setError();
                }
            }

            checkFunctionAttributes(exp, sc, exp.f);
            checkAccess(exp.loc, sc, null, exp.f);
            if (exp.f.checkNestedReference(sc, exp.loc))
                return setError();

            ethis = null;
            tthis = null;

            if (ve.hasOverloads)
            {
                exp.e1 = new VarExp(ve.loc, exp.f, false);
                exp.e1.type = exp.f.type;
            }
            t1 = exp.f.type;
        }
        assert(t1.ty == Tfunction);

        Expression argprefix;
        if (!exp.arguments)
            exp.arguments = new Expressions();
        if (functionParameters(exp.loc, sc, cast(TypeFunction)t1, ethis, tthis, exp.arguments, exp.f, &exp.type, &argprefix))
            return setError();

        if (!exp.type)
        {
            exp.e1 = e1org; // https://issues.dlang.org/show_bug.cgi?id=10922
                        // avoid recursive expression printing
            exp.error("forward reference to inferred return type of function call `%s`", exp.toChars());
            return setError();
        }

        if (exp.f && exp.f.tintro)
        {
            Type t = exp.type;
            int offset = 0;
            TypeFunction tf = cast(TypeFunction)exp.f.tintro;
            if (tf.next.isBaseOf(t, &offset) && offset)
            {
                exp.type = tf.next;
                result = Expression.combine(argprefix, exp.castTo(sc, t));
                return;
            }
        }

        // Handle the case of a direct lambda call
        if (exp.f && exp.f.isFuncLiteralDeclaration() && sc.func && !sc.intypeof)
        {
            exp.f.tookAddressOf = 0;
        }

        result = Expression.combine(argprefix, exp);

        if (isSuper)
        {
            auto ad = sc.func ? sc.func.isThis() : null;
            auto cd = ad ? ad.isClassDeclaration() : null;
            if (cd && cd.classKind == ClassKind.cpp && exp.f && !exp.f.fbody)
            {
                // if super is defined in C++, it sets the vtable pointer to the base class
                // so we have to restore it, but still return 'this' from super() call:
                // (auto __vptrTmp = this.__vptr, auto __superTmp = super()), (this.__vptr = __vptrTmp, __superTmp)
                Loc loc = exp.loc;

                auto vptr = new DotIdExp(loc, new ThisExp(loc), Id.__vptr);
                auto vptrTmpDecl = copyToTemp(0, "__vptrTmp", vptr);
                auto declareVptrTmp = new DeclarationExp(loc, vptrTmpDecl);

                auto superTmpDecl = copyToTemp(0, "__superTmp", result);
                auto declareSuperTmp = new DeclarationExp(loc, superTmpDecl);

                auto declareTmps = new CommaExp(loc, declareVptrTmp, declareSuperTmp);

                auto restoreVptr = new AssignExp(loc, vptr.syntaxCopy(), new VarExp(loc, vptrTmpDecl));

                Expression e = new CommaExp(loc, declareTmps, new CommaExp(loc, restoreVptr, new VarExp(loc, superTmpDecl)));
                result = e.expressionSemantic(sc);
            }
        }

        // declare dual-context container
        if (exp.f && exp.f.hasDualContext() && !sc.intypeof && sc.func)
        {
            // check access to second `this`
            if (AggregateDeclaration ad2 = exp.f.isMember2())
            {
                Expression te = new ThisExp(exp.loc).expressionSemantic(sc);
                if (te.op != EXP.error)
                    te = getRightThis(exp.loc, sc, ad2, te, exp.f);
                if (te.op == EXP.error)
                {
                    exp.error("need `this` of type `%s` to call function `%s`", ad2.toChars(), exp.f.toChars());
                    return setError();
                }
            }
            exp.vthis2 = makeThis2Argument(exp.loc, sc, exp.f);
            Expression de = new DeclarationExp(exp.loc, exp.vthis2);
            result = Expression.combine(de, result);
            result = result.expressionSemantic(sc);
        }
    }

    override void visit(DeclarationExp e)
    {
        if (e.type)
        {
            result = e;
            return;
        }
        static if (LOGSEMANTIC)
        {
            printf("DeclarationExp::semantic() %s\n", e.toChars());
        }

        uint olderrors = global.errors;

        /* This is here to support extern(linkage) declaration,
         * where the extern(linkage) winds up being an AttribDeclaration
         * wrapper.
         */
        Dsymbol s = e.declaration;

        while (1)
        {
            AttribDeclaration ad = s.isAttribDeclaration();
            if (ad)
            {
                if (ad.decl && ad.decl.dim == 1)
                {
                    s = (*ad.decl)[0];
                    continue;
                }
            }
            break;
        }

        //printf("inserting '%s' %p into sc = %p\n", s.toChars(), s, sc);
        // Insert into both local scope and function scope.
        // Must be unique in both.
        if (s.ident)
        {
            VarDeclaration v = s.isVarDeclaration();
            if (v)
            {
                if (sc.flags & SCOPE.Cfile)
                {
                    /* Do semantic() on the type before inserting v into the symbol table
                     */
                    if (!v.originalType)
                        v.originalType = v.type.syntaxCopy();
                    Scope* sc2 = sc.push();
                    sc2.stc |= v.storage_class & STC.FUNCATTR;
                    sc2.linkage = LINK.c;       // account for the extern(C) in front of the declaration
                    v.inuse++;
                    v.type = v.type.typeSemantic(v.loc, sc2);
                    v.inuse--;
                    sc2.pop();
                }
                else
                {
                    /* Do semantic() on initializer first so this will be illegal:
                     *      int a = a;
                     */
                    e.declaration.dsymbolSemantic(sc);
                    s.parent = sc.parent;
                }
            }

            if (!sc.insert(s))
            {
                auto conflict = sc.search(Loc.initial, s.ident, null);
                e.error("declaration `%s` is already defined", s.toPrettyChars());
                errorSupplemental(conflict.loc, "`%s` `%s` is defined here",
                                  conflict.kind(), conflict.toChars());
                return setError();
            }

            if (v && (sc.flags & SCOPE.Cfile))
            {
                /* Do semantic() on initializer last so this will be legal:
                 *      int a = a;
                 */
                e.declaration.dsymbolSemantic(sc);
                s.parent = sc.parent;
            }

            if (sc.func)
            {
                // https://issues.dlang.org/show_bug.cgi?id=11720
                if ((s.isFuncDeclaration() ||
                     s.isAggregateDeclaration() ||
                     s.isEnumDeclaration() ||
                     s.isTemplateDeclaration() ||
                     v
                    ) && !sc.func.localsymtab.insert(s))
                {
                    // Get the previous symbol
                    Dsymbol originalSymbol = sc.func.localsymtab.lookup(s.ident);

                    // Perturb the name mangling so that the symbols can co-exist
                    // instead of colliding
                    s.localNum = cast(ushort)(originalSymbol.localNum + 1);
                    // 65535 should be enough for anyone
                    if (!s.localNum)
                    {
                        e.error("more than 65535 symbols with name `%s` generated", s.ident.toChars());
                        return setError();
                    }

                    // Replace originalSymbol with s, which updates the localCount
                    sc.func.localsymtab.update(s);

                    // The mangling change only works for D mangling
                }

                if (!(sc.flags & SCOPE.Cfile))
                {
                    /* https://issues.dlang.org/show_bug.cgi?id=21272
                     * If we are in a foreach body we need to extract the
                     * function containing the foreach
                     */
                    FuncDeclaration fes_enclosing_func;
                    if (sc.func && sc.func.fes)
                        fes_enclosing_func = sc.enclosing.enclosing.func;

                    // Disallow shadowing
                    for (Scope* scx = sc.enclosing; scx && (scx.func == sc.func || (fes_enclosing_func && scx.func == fes_enclosing_func)); scx = scx.enclosing)
                    {
                        Dsymbol s2;
                        if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s != s2)
                        {
                            // allow STC.local symbols to be shadowed
                            // TODO: not really an optimal design
                            auto decl = s2.isDeclaration();
                            if (!decl || !(decl.storage_class & STC.local))
                            {
                                if (sc.func.fes)
                                {
                                    e.deprecation("%s `%s` is shadowing %s `%s`. Rename the `foreach` variable.", s.kind(), s.ident.toChars(), s2.kind(), s2.toPrettyChars());
                                }
                                else
                                {
                                    e.error("%s `%s` is shadowing %s `%s`", s.kind(), s.ident.toChars(), s2.kind(), s2.toPrettyChars());
                                    return setError();
                                }
                            }
                        }
                    }
                }
            }
        }
        if (!s.isVarDeclaration())
        {
            Scope* sc2 = sc;
            if (sc2.stc & (STC.pure_ | STC.nothrow_ | STC.nogc))
                sc2 = sc.push();
            sc2.stc &= ~(STC.pure_ | STC.nothrow_ | STC.nogc);
            e.declaration.dsymbolSemantic(sc2);
            if (sc2 != sc)
                sc2.pop();
            s.parent = sc.parent;
        }
        if (global.errors == olderrors)
        {
            e.declaration.semantic2(sc);
            if (global.errors == olderrors)
            {
                e.declaration.semantic3(sc);
            }
        }
        // todo: error in declaration should be propagated.

        e.type = Type.tvoid;
        result = e;
    }

    override void visit(TypeidExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("TypeidExp::semantic() %s\n", exp.toChars());
        }
        Type ta = isType(exp.obj);
        Expression ea = isExpression(exp.obj);
        Dsymbol sa = isDsymbol(exp.obj);
        //printf("ta %p ea %p sa %p\n", ta, ea, sa);

        if (ta)
        {
            dmd.typesem.resolve(ta, exp.loc, sc, ea, ta, sa, true);
        }

        if (ea)
        {
            if (auto sym = getDsymbol(ea))
                ea = symbolToExp(sym, exp.loc, sc, false);
            else
                ea = ea.expressionSemantic(sc);
            ea = resolveProperties(sc, ea);
            ta = ea.type;
            if (ea.op == EXP.type)
                ea = null;
        }

        if (!ta)
        {
            //printf("ta %p ea %p sa %p\n", ta, ea, sa);
            exp.error("no type for `typeid(%s)`", ea ? ea.toChars() : (sa ? sa.toChars() : ""));
            return setError();
        }

        ta.checkComplexTransition(exp.loc, sc);

        Expression e;
        auto tb = ta.toBasetype();
        if (ea && tb.ty == Tclass)
        {
            if (tb.toDsymbol(sc).isClassDeclaration().classKind == ClassKind.cpp)
            {
                error(exp.loc, "runtime type information is not supported for `extern(C++)` classes");
                e = ErrorExp.get();
            }
            else if (!Type.typeinfoclass)
            {
                error(exp.loc, "`object.TypeInfo_Class` could not be found, but is implicitly used");
                e = ErrorExp.get();
            }
            else
            {
                /* Get the dynamic type, which is .classinfo
                */
                ea = ea.expressionSemantic(sc);
                e = new TypeidExp(ea.loc, ea);
                e.type = Type.typeinfoclass.type;
            }
        }
        else if (ta.ty == Terror)
        {
            e = ErrorExp.get();
        }
        else
        {
            // Handle this in the glue layer
            e = new TypeidExp(exp.loc, ta);
            e.type = getTypeInfoType(exp.loc, ta, sc);

            semanticTypeInfo(sc, ta);

            if (ea)
            {
                e = new CommaExp(exp.loc, ea, e); // execute ea
                e = e.expressionSemantic(sc);
            }
        }
        result = e;
    }

    override void visit(TraitsExp e)
    {
        result = semanticTraits(e, sc);
    }

    override void visit(HaltExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("HaltExp::semantic()\n");
        }
        e.type = Type.tnoreturn;
        result = e;
    }

    override void visit(IsExp e)
    {
        /* is(targ id tok tspec)
         * is(targ id :  tok2)
         * is(targ id == tok2)
         */
        Type tded = null;

        void yes()
        {
            //printf("yes\n");
            if (!e.id)
            {
                result = IntegerExp.createBool(true);
                return;
            }

            Dsymbol s;
            Tuple tup = isTuple(tded);
            if (tup)
                s = new TupleDeclaration(e.loc, e.id, &tup.objects);
            else
                s = new AliasDeclaration(e.loc, e.id, tded);
            s.dsymbolSemantic(sc);

            /* The reason for the !tup is unclear. It fails Phobos unittests if it is not there.
             * More investigation is needed.
             */
            if (!tup && !sc.insert(s))
            {
                auto conflict = sc.search(Loc.initial, s.ident, null);
                e.error("declaration `%s` is already defined", s.toPrettyChars());
                errorSupplemental(conflict.loc, "`%s` `%s` is defined here",
                                  conflict.kind(), conflict.toChars());
            }

            unSpeculative(sc, s);

            result = IntegerExp.createBool(true);
        }
        void no()
        {
            result = IntegerExp.createBool(false);
            //printf("no\n");
        }

        static if (LOGSEMANTIC)
        {
            printf("IsExp::semantic(%s)\n", e.toChars());
        }
        if (e.id && !(sc.flags & SCOPE.condition))
        {
            e.error("can only declare type aliases within `static if` conditionals or `static assert`s");
            return setError();
        }

        if (e.tok2 == TOK.package_ || e.tok2 == TOK.module_) // These is() expressions are special because they can work on modules, not just types.
        {
            const oldErrors = global.startGagging();
            Dsymbol sym = e.targ.toDsymbol(sc);
            global.endGagging(oldErrors);

            if (sym is null)
                return no();
            Package p = resolveIsPackage(sym);
            if (p is null)
                return no();
            if (e.tok2 == TOK.package_ && p.isModule()) // Note that isModule() will return null for package modules because they're not actually instances of Module.
                return no();
            else if(e.tok2 == TOK.module_ && !(p.isModule() || p.isPackageMod()))
                return no();
            tded = e.targ;
            return yes();
        }

        {
            Scope* sc2 = sc.copy(); // keep sc.flags
            sc2.tinst = null;
            sc2.minst = null;
            sc2.flags |= SCOPE.fullinst;
            Type t = e.targ.trySemantic(e.loc, sc2);
            sc2.pop();
            if (!t) // errors, so condition is false
                return no();
            e.targ = t;
        }

        if (e.tok2 != TOK.reserved)
        {
            switch (e.tok2)
            {
            case TOK.struct_:
                if (e.targ.ty != Tstruct)
                    return no();
                if ((cast(TypeStruct)e.targ).sym.isUnionDeclaration())
                    return no();
                tded = e.targ;
                break;

            case TOK.union_:
                if (e.targ.ty != Tstruct)
                    return no();
                if (!(cast(TypeStruct)e.targ).sym.isUnionDeclaration())
                    return no();
                tded = e.targ;
                break;

            case TOK.class_:
                if (e.targ.ty != Tclass)
                    return no();
                if ((cast(TypeClass)e.targ).sym.isInterfaceDeclaration())
                    return no();
                tded = e.targ;
                break;

            case TOK.interface_:
                if (e.targ.ty != Tclass)
                    return no();
                if (!(cast(TypeClass)e.targ).sym.isInterfaceDeclaration())
                    return no();
                tded = e.targ;
                break;

            case TOK.const_:
                if (!e.targ.isConst())
                    return no();
                tded = e.targ;
                break;

            case TOK.immutable_:
                if (!e.targ.isImmutable())
                    return no();
                tded = e.targ;
                break;

            case TOK.shared_:
                if (!e.targ.isShared())
                    return no();
                tded = e.targ;
                break;

            case TOK.inout_:
                if (!e.targ.isWild())
                    return no();
                tded = e.targ;
                break;

            case TOK.super_:
                // If class or interface, get the base class and interfaces
                if (e.targ.ty != Tclass)
                    return no();
                else
                {
                    ClassDeclaration cd = (cast(TypeClass)e.targ).sym;
                    auto args = new Parameters();
                    args.reserve(cd.baseclasses.dim);
                    if (cd.semanticRun < PASS.semanticdone)
                        cd.dsymbolSemantic(null);
                    for (size_t i = 0; i < cd.baseclasses.dim; i++)
                    {
                        BaseClass* b = (*cd.baseclasses)[i];
                        args.push(new Parameter(STC.in_, b.type, null, null, null));
                    }
                    tded = new TypeTuple(args);
                }
                break;

            case TOK.enum_:
                if (e.targ.ty != Tenum)
                    return no();
                if (e.id)
                    tded = (cast(TypeEnum)e.targ).sym.getMemtype(e.loc);
                else
                    tded = e.targ;

                if (tded.ty == Terror)
                    return setError();
                break;

            case TOK.delegate_:
                if (e.targ.ty != Tdelegate)
                    return no();
                tded = (cast(TypeDelegate)e.targ).next; // the underlying function type
                break;

            case TOK.function_:
            case TOK.parameters:
                {
                    if (e.targ.ty != Tfunction)
                        return no();
                    tded = e.targ;

                    /* Generate tuple from function parameter types.
                     */
                    assert(tded.ty == Tfunction);
                    auto tdedf = tded.isTypeFunction();
                    auto args = new Parameters();
                    foreach (i, arg; tdedf.parameterList)
                    {
                        assert(arg && arg.type);
                        /* If one of the default arguments was an error,
                           don't return an invalid tuple
                         */
                        if (e.tok2 == TOK.parameters && arg.defaultArg && arg.defaultArg.op == EXP.error)
                            return setError();
                        args.push(new Parameter(arg.storageClass, arg.type, (e.tok2 == TOK.parameters) ? arg.ident : null, (e.tok2 == TOK.parameters) ? arg.defaultArg : null, arg.userAttribDecl));
                    }
                    tded = new TypeTuple(args);
                    break;
                }
            case TOK.return_:
                /* Get the 'return type' for the function,
                 * delegate, or pointer to function.
                 */
                if (auto tf = e.targ.isFunction_Delegate_PtrToFunction())
                    tded = tf.next;
                else
                    return no();
                break;

            case TOK.argumentTypes:
                /* Generate a type tuple of the equivalent types used to determine if a
                 * function argument of this type can be passed in registers.
                 * The results of this are highly platform dependent, and intended
                 * primarly for use in implementing va_arg().
                 */
                tded = target.toArgTypes(e.targ);
                if (!tded)
                    return no();
                // not valid for a parameter
                break;

            case TOK.vector:
                if (e.targ.ty != Tvector)
                    return no();
                tded = (cast(TypeVector)e.targ).basetype;
                break;

            default:
                assert(0);
            }

            // https://issues.dlang.org/show_bug.cgi?id=18753
            if (tded)
                return yes();
            return no();
        }
        else if (e.tspec && !e.id && !(e.parameters && e.parameters.dim))
        {
            /* Evaluate to true if targ matches tspec
             * is(targ == tspec)
             * is(targ : tspec)
             */
            e.tspec = e.tspec.typeSemantic(e.loc, sc);
            //printf("targ  = %s, %s\n", e.targ.toChars(), e.targ.deco);
            //printf("tspec = %s, %s\n", e.tspec.toChars(), e.tspec.deco);

            if (e.tok == TOK.colon)
            {
                // current scope is itself deprecated, or deprecations are not errors
                const bool deprecationAllowed = sc.isDeprecated
                    || global.params.useDeprecated != DiagnosticReporting.error;
                const bool preventAliasThis = e.targ.hasDeprecatedAliasThis && !deprecationAllowed;

                if (preventAliasThis && e.targ.ty == Tstruct)
                {
                    if ((cast(TypeStruct) e.targ).implicitConvToWithoutAliasThis(e.tspec))
                        return yes();
                    else
                        return no();
                }
                else if (preventAliasThis && e.targ.ty == Tclass)
                {
                    if ((cast(TypeClass) e.targ).implicitConvToWithoutAliasThis(e.tspec))
                        return yes();
                    else
                        return no();
                }
                else if (e.targ.implicitConvTo(e.tspec))
                    return yes();
                else
                    return no();
            }
            else /* == */
            {
                if (e.targ.equals(e.tspec))
                    return yes();
                else
                    return no();
            }
        }
        else if (e.tspec)
        {
            /* Evaluate to true if targ matches tspec.
             * If true, declare id as an alias for the specialized type.
             * is(targ == tspec, tpl)
             * is(targ : tspec, tpl)
             * is(targ id == tspec)
             * is(targ id : tspec)
             * is(targ id == tspec, tpl)
             * is(targ id : tspec, tpl)
             */
            Identifier tid = e.id ? e.id : Identifier.generateId("__isexp_id");
            e.parameters.insert(0, new TemplateTypeParameter(e.loc, tid, null, null));

            Objects dedtypes = Objects(e.parameters.dim);
            dedtypes.zero();

            MATCH m = deduceType(e.targ, sc, e.tspec, e.parameters, &dedtypes, null, 0, e.tok == TOK.equal);
            //printf("targ: %s\n", targ.toChars());
            //printf("tspec: %s\n", tspec.toChars());
            if (m == MATCH.nomatch || (m != MATCH.exact && e.tok == TOK.equal))
            {
                return no();
            }
            else
            {
                tded = cast(Type)dedtypes[0];
                if (!tded)
                    tded = e.targ;
                Objects tiargs = Objects(1);
                tiargs[0] = e.targ;

                /* Declare trailing parameters
                 */
                for (size_t i = 1; i < e.parameters.dim; i++)
                {
                    TemplateParameter tp = (*e.parameters)[i];
                    Declaration s = null;

                    m = tp.matchArg(e.loc, sc, &tiargs, i, e.parameters, &dedtypes, &s);
                    if (m == MATCH.nomatch)
                        return no();
                    s.dsymbolSemantic(sc);
                    if (!sc.insert(s))
                    {
                        auto conflict = sc.search(Loc.initial, s.ident, null);
                        e.error("declaration `%s` is already defined", s.toPrettyChars());
                        errorSupplemental(conflict.loc, "`%s` `%s` is defined here",
                                          conflict.kind(), conflict.toChars());
                    }

                    unSpeculative(sc, s);
                }
                return yes();
            }
        }
        else if (e.id)
        {
            /* Declare id as an alias for type targ. Evaluate to true
             * is(targ id)
             */
            tded = e.targ;
        }
        return yes();
    }

    override void visit(BinAssignExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.e1.op == EXP.arrayLength)
        {
            // arr.length op= e2;
            e = rewriteOpAssign(exp);
            e = e.expressionSemantic(sc);
            result = e;
            return;
        }
        if (exp.e1.op == EXP.slice || exp.e1.type.ty == Tarray || exp.e1.type.ty == Tsarray)
        {
            if (checkNonAssignmentArrayOp(exp.e1))
                return setError();

            if (exp.e1.op == EXP.slice)
                (cast(SliceExp)exp.e1).arrayop = true;

            // T[] op= ...
            if (exp.e2.implicitConvTo(exp.e1.type.nextOf()))
            {
                // T[] op= T
                exp.e2 = exp.e2.castTo(sc, exp.e1.type.nextOf());
            }
            else if (Expression ex = typeCombine(exp, sc))
            {
                result = ex;
                return;
            }
            exp.type = exp.e1.type;
            result = arrayOp(exp, sc);
            return;
        }

        exp.e1 = exp.e1.expressionSemantic(sc);
        exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);
        exp.e1 = exp.e1.optimize(WANTvalue, /*keepLvalue*/ true);
        exp.type = exp.e1.type;

        if (auto ad = isAggregate(exp.e1.type))
        {
            if (const s = search_function(ad, Id.opOpAssign))
            {
                error(exp.loc, "none of the `opOpAssign` overloads of `%s` are callable for `%s` of type `%s`", ad.toChars(), exp.e1.toChars(), exp.e1.type.toChars());
                return setError();
            }
        }
        if (exp.e1.checkScalar() ||
            exp.e1.checkReadModifyWrite(exp.op, exp.e2) ||
            exp.e1.checkSharedAccess(sc))
            return setError();

        int arith = (exp.op == EXP.addAssign || exp.op == EXP.minAssign || exp.op == EXP.mulAssign || exp.op == EXP.divAssign || exp.op == EXP.modAssign || exp.op == EXP.powAssign);
        int bitwise = (exp.op == EXP.andAssign || exp.op == EXP.orAssign || exp.op == EXP.xorAssign);
        int shift = (exp.op == EXP.leftShiftAssign || exp.op == EXP.rightShiftAssign || exp.op == EXP.unsignedRightShiftAssign);

        if (bitwise && exp.type.toBasetype().ty == Tbool)
            exp.e2 = exp.e2.implicitCastTo(sc, exp.type);
        else if (exp.checkNoBool())
            return setError();

        if ((exp.op == EXP.addAssign || exp.op == EXP.minAssign) && exp.e1.type.toBasetype().ty == Tpointer && exp.e2.type.toBasetype().isintegral())
        {
            result = scaleFactor(exp, sc);
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        if (arith && (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc)))
            return setError();
        if ((bitwise || shift) && (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc)))
            return setError();

        if (shift)
        {
            if (exp.e2.type.toBasetype().ty != Tvector)
                exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt);
        }

        if (!target.isVectorOpSupported(exp.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }

        if (exp.e1.op == EXP.error || exp.e2.op == EXP.error)
            return setError();

        e = exp.checkOpAssignTypes(sc);
        if (e.op == EXP.error)
        {
            result = e;
            return;
        }

        assert(e.op == EXP.assign || e == exp);
        result = (cast(BinExp)e).reorderSettingAAElem(sc);
    }

    private Expression compileIt(MixinExp exp)
    {
        OutBuffer buf;
        if (expressionsToString(buf, sc, exp.exps))
            return null;

        uint errors = global.errors;
        const len = buf.length;
        const str = buf.extractChars()[0 .. len];
        scope p = new Parser!ASTCodegen(exp.loc, sc._module, str, false);
        p.nextToken();
        //printf("p.loc.linnum = %d\n", p.loc.linnum);

        Expression e = p.parseExpression();
        if (global.errors != errors)
            return null;

        if (p.token.value != TOK.endOfFile)
        {
            exp.error("incomplete mixin expression `%s`", str.ptr);
            return null;
        }
        return e;
    }

    override void visit(MixinExp exp)
    {
        /* https://dlang.org/spec/expression.html#mixin_expressions
         */

        static if (LOGSEMANTIC)
        {
            printf("MixinExp::semantic('%s')\n", exp.toChars());
        }

        auto e = compileIt(exp);
        if (!e)
            return setError();
        result = e.expressionSemantic(sc);
    }

    override void visit(ImportExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("ImportExp::semantic('%s')\n", e.toChars());
        }

        auto se = semanticString(sc, e.e1, "file name argument");
        if (!se)
            return setError();
        se = se.toUTF8(sc);

        auto namez = se.toStringz();
        if (!global.filePath)
        {
            e.error("need `-J` switch to import text file `%s`", namez.ptr);
            return setError();
        }

        /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory
         * ('Path Traversal') attacks.
         * https://cwe.mitre.org/data/definitions/22.html
         */

        if (FileName.absolute(namez))
        {
            e.error("absolute path is not allowed in import expression: `%s`", se.toChars());
            return setError();
        }

        auto idxReserved = FileName.findReservedChar(namez);
        if (idxReserved != size_t.max)
        {
            e.error("`%s` is not a valid filename on this platform", se.toChars());
            e.errorSupplemental("Character `'%c'` is reserved and cannot be used", namez[idxReserved]);
            return setError();
        }

        if (FileName.refersToParentDir(namez))
        {
            e.error("path refers to parent (`..`) directory: `%s`", se.toChars());
            return setError();
        }

        auto resolvedNamez = FileName.searchPath(global.filePath, namez, false);
        if (!resolvedNamez)
        {
            e.error("file `%s` cannot be found or not in a path specified with `-J`", se.toChars());
            e.errorSupplemental("Path(s) searched (as provided by `-J`):");
            foreach (idx, path; *global.filePath)
            {
                const attr = FileName.exists(path);
                const(char)* err = attr == 2 ? "" :
                    (attr == 1 ? " (not a directory)" : " (path not found)");
                e.errorSupplemental("[%llu]: `%s`%s", cast(ulong)idx, path, err);
            }
            return setError();
        }

        sc._module.contentImportedFiles.push(resolvedNamez.ptr);
        if (global.params.verbose)
        {
            const slice = se.peekString();
            message("file      %.*s\t(%s)", cast(int)slice.length, slice.ptr, resolvedNamez.ptr);
        }
        if (global.params.moduleDeps.buffer !is null)
        {
            OutBuffer* ob = global.params.moduleDeps.buffer;
            Module imod = sc._module;

            if (!global.params.moduleDeps.name)
                ob.writestring("depsFile ");
            ob.writestring(imod.toPrettyChars());
            ob.writestring(" (");
            escapePath(ob, imod.srcfile.toChars());
            ob.writestring(") : ");
            if (global.params.moduleDeps.name)
                ob.writestring("string : ");
            ob.write(se.peekString());
            ob.writestring(" (");
            escapePath(ob, resolvedNamez.ptr);
            ob.writestring(")");
            ob.writenl();
        }
        if (global.params.makeDeps.doOutput)
        {
            global.params.makeDeps.files.push(resolvedNamez.ptr);
        }

        {
            auto fileName = FileName(resolvedNamez);
            if (auto fmResult = global.fileManager.lookup(fileName))
            {
                se = new StringExp(e.loc, fmResult);
            }
            else
            {
                auto readResult = File.read(resolvedNamez);
                if (!readResult.success)
                {
                    e.error("cannot read file `%s`", resolvedNamez.ptr);
                    return setError();
                }
                else
                {
                    // take ownership of buffer (probably leaking)
                    auto data = readResult.extractSlice();
                    se = new StringExp(e.loc, data);
                    global.fileManager.add(fileName, data);
                }
            }
        }
        result = se.expressionSemantic(sc);
    }

    override void visit(AssertExp exp)
    {
        // https://dlang.org/spec/expression.html#assert_expressions
        static if (LOGSEMANTIC)
        {
            printf("AssertExp::semantic('%s')\n", exp.toChars());
        }

        const generateMsg = !exp.msg && global.params.checkAction == CHECKACTION.context && global.params.useAssert == CHECKENABLE.on;
        Expression temporariesPrefix;

        if (generateMsg)
        // no message - use assert expression as msg
        {
            if (!verifyHookExist(exp.loc, *sc, Id._d_assert_fail, "generating assert messages"))
                return setError();

            /*
            {
              auto a = e1, b = e2;
              assert(a == b, _d_assert_fail!"=="(a, b));
            }()
            */

            /*
            Stores the result of an operand expression into a temporary
            if necessary, e.g. if it is an impure fuction call containing side
            effects as in https://issues.dlang.org/show_bug.cgi?id=20114

            Params:
                op = an expression which may require a temporary (added to
                     `temporariesPrefix`: `auto tmp = op`) and will be replaced
                     by `tmp` if necessary

            Returns: (possibly replaced) `op`
            */
            Expression maybePromoteToTmp(ref Expression op)
            {
                // https://issues.dlang.org/show_bug.cgi?id=20989
                // Flag that _d_assert_fail will never dereference `array.ptr` to avoid safety
                // errors for `assert(!array.ptr)` => `_d_assert_fail!"!"(array.ptr)`
                {
                    auto die = op.isDotIdExp();
                    if (die && die.ident == Id.ptr)
                        die.noderef = true;
                }

                op = op.expressionSemantic(sc);
                op = resolveProperties(sc, op);

                // Detect assert's using static operator overloads (e.g. `"var" in environment`)
                if (auto te = op.isTypeExp())
                {
                    // Replace the TypeExp with it's textual representation
                    // Including "..." in the error message isn't quite right but
                    // proper solutions require more drastic changes, e.g. directly
                    // using miniFormat and combine instead of calling _d_assert_fail
                    auto name = new StringExp(te.loc, te.toString());
                    return name.expressionSemantic(sc);
                }

                // Create a temporary for expressions with side effects
                // Defensively assume that function calls may have side effects even
                // though it's not detected by hasSideEffect (e.g. `debug puts("Hello")` )
                // Rewriting CallExp's also avoids some issues with the inliner/debug generation
                if (op.hasSideEffect(true))
                {
                    // Don't create an invalid temporary for void-expressions
                    // Further semantic will issue an appropriate error
                    if (op.type.ty == Tvoid)
                        return op;

                    // https://issues.dlang.org/show_bug.cgi?id=21590
                    // Don't create unnecessary temporaries and detect `assert(a = b)`
                    if (op.isAssignExp() || op.isBinAssignExp())
                    {
                        auto left = (cast(BinExp) op).e1;

                        // Find leftmost expression to handle other rewrites,
                        // e.g. --(++a) => a += 1 -= 1
                        while (left.isAssignExp() || left.isBinAssignExp())
                            left = (cast(BinExp) left).e1;

                        // Only use the assignee if it's a variable and skip
                        // other lvalues (e.g. ref's returned by functions)
                        if (left.isVarExp())
                            return left;

                        // Sanity check that `op` can be converted to boolean
                        // But don't raise errors for assignments enclosed in another expression
                        if (op is exp.e1)
                            op.toBoolean(sc);
                    }

                    // Tuples with side-effects already receive a temporary during semantic
                    if (op.type.isTypeTuple())
                    {
                        auto te = op.isTupleExp();
                        assert(te);

                        // Create a new tuple without the associated temporary
                        auto res = new TupleExp(op.loc, te.exps);
                        return res.expressionSemantic(sc);
                    }

                    const stc = op.isLvalue() ? STC.ref_ : 0;
                    auto tmp = copyToTemp(stc, "__assertOp", op);
                    tmp.dsymbolSemantic(sc);

                    auto decl = new DeclarationExp(op.loc, tmp);
                    temporariesPrefix = Expression.combine(temporariesPrefix, decl);

                    op = new VarExp(op.loc, tmp);
                    op = op.expressionSemantic(sc);
                }
                return op;
            }

            // if the assert condition is a mixin expression, try to compile it
            if (auto ce = exp.e1.isMixinExp())
            {
                if (auto e1 = compileIt(ce))
                    exp.e1 = e1;
            }

            Expressions* es;
            Objects* tiargs;
            Loc loc = exp.e1.loc;

            const op = exp.e1.op;
            bool isEqualsCallExpression;
            if (const callExp = exp.e1.isCallExp())
            {
                // https://issues.dlang.org/show_bug.cgi?id=20331
                // callExp.f may be null if the assert contains a call to
                // a function pointer or literal
                if (const callExpFunc = callExp.f)
                {
                    const callExpIdent = callExpFunc.ident;
                    isEqualsCallExpression = callExpIdent == Id.__equals ||
                                             callExpIdent == Id.eq;
                }
            }
            if (op == EXP.equal || op == EXP.notEqual ||
                op == EXP.lessThan || op == EXP.greaterThan ||
                op == EXP.lessOrEqual || op == EXP.greaterOrEqual ||
                op == EXP.identity || op == EXP.notIdentity ||
                op == EXP.in_ ||
                isEqualsCallExpression)
            {
                es = new Expressions(3);
                tiargs = new Objects(1);

                if (isEqualsCallExpression)
                {
                    auto callExp = cast(CallExp) exp.e1;
                    auto args = callExp.arguments;

                    // structs with opEquals get rewritten to a DotVarExp:
                    // a.opEquals(b)
                    // https://issues.dlang.org/show_bug.cgi?id=20100
                    if (args.length == 1)
                    {
                        auto dv = callExp.e1.isDotVarExp();
                        assert(dv);

                        // runtime args
                        (*es)[1] = maybePromoteToTmp(dv.e1);
                        (*es)[2] = maybePromoteToTmp((*args)[0]);
                    }
                    else
                    {
                        // runtime args
                        (*es)[1] = maybePromoteToTmp((*args)[0]);
                        (*es)[2] = maybePromoteToTmp((*args)[1]);
                    }
                }
                else
                {
                    auto binExp = cast(EqualExp) exp.e1;

                    // runtime args
                    (*es)[1] = maybePromoteToTmp(binExp.e1);
                    (*es)[2] = maybePromoteToTmp(binExp.e2);
                }

                // template args
                Expression comp = new StringExp(loc, isEqualsCallExpression ? "==" : EXPtoString(exp.e1.op));
                comp = comp.expressionSemantic(sc);
                (*es)[0] = comp;
                (*tiargs)[0] = (*es)[1].type;
            }

            // Format exp.e1 before any additional boolean conversion
            // Ignore &&/|| because "assert(...) failed" is more informative than "false != true"
            else if (op != EXP.andAnd && op != EXP.orOr)
            {
                es = new Expressions(2);
                tiargs = new Objects(1);

                if (auto ne = exp.e1.isNotExp())
                {
                    // Fetch the (potential non-bool) expression and fold
                    // (n) negations into (n % 2) negations, e.g. !!a => a
                    for (bool neg = true; ; neg = !neg)
                    {
                        if (auto ne2 = ne.e1.isNotExp())
                            ne = ne2;
                        else
                        {
                            (*es)[0] = new StringExp(loc, neg ? "!" : "");
                            (*es)[1] = maybePromoteToTmp(ne.e1);
                            break;
                        }
                    }
                }
                else
                {   // Simply format exp.e1
                    (*es)[0] = new StringExp(loc, "");
                    (*es)[1] = maybePromoteToTmp(exp.e1);
                }

                (*tiargs)[0] = (*es)[1].type;

                // Passing __ctfe to auto ref infers ref and aborts compilation:
                // "cannot modify compiler-generated variable __ctfe"
                auto ve = (*es)[1].isVarExp();
                if (ve && ve.var.ident == Id.ctfe)
                {
                    exp.msg = new StringExp(loc, "assert(__ctfe) failed!");
                    goto LSkip;
                }
            }
            else
            {
                OutBuffer buf;
                buf.printf("%s failed", exp.toChars());
                exp.msg = new StringExp(Loc.initial, buf.extractSlice());
                goto LSkip;
            }

            Expression __assertFail = new IdentifierExp(exp.loc, Id.empty);
            auto assertFail = new DotIdExp(loc, __assertFail, Id.object);

            auto dt = new DotTemplateInstanceExp(loc, assertFail, Id._d_assert_fail, tiargs);
            auto ec = CallExp.create(loc, dt, es);
            exp.msg = ec;
        }

        LSkip:
        if (Expression ex = unaSemantic(exp, sc))
        {
            result = ex;
            return;
        }

        exp.e1 = resolveProperties(sc, exp.e1);
        // BUG: see if we can do compile time elimination of the Assert
        exp.e1 = exp.e1.optimize(WANTvalue);
        exp.e1 = exp.e1.toBoolean(sc);

        if (exp.e1.op == EXP.error)
        {
            result = exp.e1;
            return;
        }

        if (exp.msg)
        {
            exp.msg = expressionSemantic(exp.msg, sc);
            exp.msg = resolveProperties(sc, exp.msg);
            exp.msg = exp.msg.implicitCastTo(sc, Type.tchar.constOf().arrayOf());
            exp.msg = exp.msg.optimize(WANTvalue);
            checkParamArgumentEscape(sc, null, null, null, STC.undefined_, exp.msg, true, false);
        }

        if (exp.msg && exp.msg.op == EXP.error)
        {
            result = exp.msg;
            return;
        }

        auto f1 = checkNonAssignmentArrayOp(exp.e1);
        auto f2 = exp.msg && checkNonAssignmentArrayOp(exp.msg);
        if (f1 || f2)
            return setError();

        if (exp.e1.toBool().hasValue(false))
        {
            /* This is an `assert(0)` which means halt program execution
             */
            FuncDeclaration fd = sc.parent.isFuncDeclaration();
            if (fd)
                fd.hasReturnExp |= 4;
            sc.ctorflow.orCSX(CSX.halt);

            if (global.params.useAssert == CHECKENABLE.off)
            {
                Expression e = new HaltExp(exp.loc);
                e = e.expressionSemantic(sc);
                result = e;
                return;
            }

            // Only override the type when it isn't already some flavour of noreturn,
            // e.g. when this assert was generated by defaultInitLiteral
            if (!exp.type || !exp.type.isTypeNoreturn())
                exp.type = Type.tnoreturn;
        }
        else
            exp.type = Type.tvoid;

        result = !temporariesPrefix
            ? exp
            : Expression.combine(temporariesPrefix, exp).expressionSemantic(sc);
    }

    override void visit(ThrowExp te)
    {
        import dmd.statementsem;

        if (StatementSemanticVisitor.throwSemantic(te.loc, te.e1, sc))
            result = te;
        else
            setError();
    }

    override void visit(DotIdExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("DotIdExp::semantic(this = %p, '%s')\n", exp, exp.toChars());
            //printf("e1.op = %d, '%s'\n", e1.op, Token.toChars(e1.op));
        }

        if (sc.flags & SCOPE.Cfile)
        {
            /* See if need to rewrite the AST because of cast/call ambiguity
             */
            if (auto e = castCallAmbiguity(exp, sc))
            {
                result = expressionSemantic(e, sc);
                return;
            }
        }

        if (exp.arrow) // ImportC only
            exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);

        if (sc.flags & SCOPE.Cfile)
        {
            if (exp.ident == Id.__xalignof && exp.e1.isTypeExp())
            {
                // C11 6.5.3 says _Alignof only applies to types
                Expression e;
                Type t;
                Dsymbol s;
                dmd.typesem.resolve(exp.e1.type, exp.e1.loc, sc, e, t, s, true);
                if (e)
                {
                    exp.e1.error("argument to `_Alignof` must be a type");
                    return setError();
                }
                else if (t)
                {
                    // Note similarity to getProperty() implementation of __xalignof
                    const explicitAlignment = t.alignment();
                    const naturalAlignment = t.alignsize();
                    const actualAlignment = (explicitAlignment.isDefault() ? naturalAlignment : explicitAlignment.get());
                    result = new IntegerExp(exp.loc, actualAlignment, Type.tsize_t);
                }
                else if (s)
                {
                    exp.e1.error("argument to `_Alignof` must be a type");
                    return setError();
                }
                else
                    assert(0);
                return;
            }
        }

        if (sc.flags & SCOPE.Cfile && exp.ident != Id.__sizeof)
        {
            result = fieldLookup(exp.e1, sc, exp.ident);
            return;
        }

        Expression e = exp.semanticY(sc, 1);

        if (e && isDotOpDispatch(e))
        {
            auto ode = e;
            uint errors = global.startGagging();
            e = resolvePropertiesX(sc, e);
            // Any error or if 'e' is not resolved, go to UFCS
            if (global.endGagging(errors) || e is ode)
                e = null; /* fall down to UFCS */
            else
            {
                result = e;
                return;
            }
        }
        if (!e) // if failed to find the property
        {
            /* If ident is not a valid property, rewrite:
             *   e1.ident
             * as:
             *   .ident(e1)
             */
            e = resolveUFCSProperties(sc, exp);
        }
        result = e;
    }

    override void visit(DotTemplateExp e)
    {
        if (e.type)
        {
            result = e;
            return;
        }
        if (Expression ex = unaSemantic(e, sc))
        {
            result = ex;
            return;
        }
        // 'void' like TemplateExp
        e.type = Type.tvoid;
        result = e;
    }

    override void visit(DotVarExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("DotVarExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        exp.var = exp.var.toAlias().isDeclaration();

        exp.e1 = exp.e1.expressionSemantic(sc);

        if (auto tup = exp.var.isTupleDeclaration())
        {
            /* Replace:
             *  e1.tuple(a, b, c)
             * with:
             *  tuple(e1.a, e1.b, e1.c)
             */
            Expression e0;
            Expression ev = sc.func ? extractSideEffect(sc, "__tup", e0, exp.e1) : exp.e1;

            auto exps = new Expressions();
            exps.reserve(tup.objects.dim);
            for (size_t i = 0; i < tup.objects.dim; i++)
            {
                RootObject o = (*tup.objects)[i];
                Expression e;
                Declaration var;
                switch (o.dyncast()) with (DYNCAST)
                {
                case expression:
                    e = cast(Expression)o;
                    if (auto se = e.isDsymbolExp())
                        var = se.s.isDeclaration();
                    else if (auto ve = e.isVarExp())
                        if (!ve.var.isFuncDeclaration())
                            // Exempt functions for backwards compatibility reasons.
                            // See: https://issues.dlang.org/show_bug.cgi?id=20470#c1
                            var = ve.var;
                    break;
                case dsymbol:
                    Dsymbol s = cast(Dsymbol) o;
                    Declaration d = s.isDeclaration();
                    if (!d || d.isFuncDeclaration())
                        // Exempt functions for backwards compatibility reasons.
                        // See: https://issues.dlang.org/show_bug.cgi?id=20470#c1
                        e = new DsymbolExp(exp.loc, s);
                    else
                        var = d;
                    break;
                case type:
                    e = new TypeExp(exp.loc, cast(Type)o);
                    break;
                default:
                    exp.error("`%s` is not an expression", o.toChars());
                    return setError();
                }
                if (var)
                    e = new DotVarExp(exp.loc, ev, var);
                exps.push(e);
            }

            Expression e = new TupleExp(exp.loc, e0, exps);
            e = e.expressionSemantic(sc);
            result = e;
            return;
        }
        else if (auto ad = exp.var.isAliasDeclaration())
        {
            if (auto t = ad.getType())
            {
                result = new TypeExp(exp.loc, t).expressionSemantic(sc);
                return;
            }
        }

        exp.e1 = exp.e1.addDtorHook(sc);

        Type t1 = exp.e1.type;

        if (FuncDeclaration fd = exp.var.isFuncDeclaration())
        {
            // for functions, do checks after overload resolution
            if (!fd.functionSemantic())
                return setError();

            /* https://issues.dlang.org/show_bug.cgi?id=13843
             * If fd obviously has no overloads, we should
             * normalize AST, and it will give a chance to wrap fd with FuncExp.
             */
            if ((fd.isNested() && !fd.isThis()) || fd.isFuncLiteralDeclaration())
            {
                // (e1, fd)
                auto e = symbolToExp(fd, exp.loc, sc, false);
                result = Expression.combine(exp.e1, e);
                return;
            }

            exp.type = fd.type;
            assert(exp.type);
        }
        else if (OverDeclaration od = exp.var.isOverDeclaration())
        {
            exp.type = Type.tvoid; // ambiguous type?
        }
        else
        {
            exp.type = exp.var.type;
            if (!exp.type && global.errors) // var is goofed up, just return error.
                return setError();
            assert(exp.type);

            if (t1.ty == Tpointer)
                t1 = t1.nextOf();

            exp.type = exp.type.addMod(t1.mod);

            // https://issues.dlang.org/show_bug.cgi?id=23109
            // Run semantic on the DotVarExp type
            if (auto handle = exp.type.isClassHandle())
            {
                if (handle.semanticRun < PASS.semanticdone && !handle.isBaseInfoComplete())
                    handle.dsymbolSemantic(null);
            }

            Dsymbol vparent = exp.var.toParent();
            AggregateDeclaration ad = vparent ? vparent.isAggregateDeclaration() : null;
            if (Expression e1x = getRightThis(exp.loc, sc, ad, exp.e1, exp.var, 1))
                exp.e1 = e1x;
            else
            {
                /* Later checkRightThis will report correct error for invalid field variable access.
                 */
                Expression e = new VarExp(exp.loc, exp.var);
                e = e.expressionSemantic(sc);
                result = e;
                return;
            }
            checkAccess(exp.loc, sc, exp.e1, exp.var);

            VarDeclaration v = exp.var.isVarDeclaration();
            if (v && (v.isDataseg() || (v.storage_class & STC.manifest)))
            {
                Expression e = expandVar(WANTvalue, v);
                if (e)
                {
                    result = e;
                    return;
                }
            }

            if (v && (v.isDataseg() || // fix https://issues.dlang.org/show_bug.cgi?id=8238
                      (!v.needThis() && v.semanticRun > PASS.initial)))  // fix https://issues.dlang.org/show_bug.cgi?id=17258
            {
                // (e1, v)
                checkAccess(exp.loc, sc, exp.e1, v);
                Expression e = new VarExp(exp.loc, v);
                e = new CommaExp(exp.loc, exp.e1, e);
                e = e.expressionSemantic(sc);
                result = e;
                return;
            }
        }
        //printf("-DotVarExp::semantic('%s')\n", toChars());
        result = exp;
    }

    override void visit(DotTemplateInstanceExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("DotTemplateInstanceExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }
        // Indicate we need to resolve by UFCS.
        Expression e = exp.semanticY(sc, 1);
        if (!e)
            e = resolveUFCSProperties(sc, exp);
        if (e is exp)
            e.type = Type.tvoid; // Unresolved type, because it needs inference
        result = e;
    }

    override void visit(DelegateExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("DelegateExp::semantic('%s')\n", e.toChars());
        }
        if (e.type)
        {
            result = e;
            return;
        }

        e.e1 = e.e1.expressionSemantic(sc);

        e.type = new TypeDelegate(e.func.type.isTypeFunction());
        e.type = e.type.typeSemantic(e.loc, sc);

        FuncDeclaration f = e.func.toAliasFunc();
        AggregateDeclaration ad = f.isMemberLocal();
        if (f.needThis())
            e.e1 = getRightThis(e.loc, sc, ad, e.e1, f);
        if (e.e1.op == EXP.error)
            return setError();

        if (f.type.ty == Tfunction)
        {
            TypeFunction tf = cast(TypeFunction)f.type;
            if (!MODmethodConv(e.e1.type.mod, f.type.mod))
            {
                OutBuffer thisBuf, funcBuf;
                MODMatchToBuffer(&thisBuf, e.e1.type.mod, tf.mod);
                MODMatchToBuffer(&funcBuf, tf.mod, e.e1.type.mod);
                e.error("%smethod `%s` is not callable using a %s`%s`",
                    funcBuf.peekChars(), f.toPrettyChars(), thisBuf.peekChars(), e.e1.toChars());
                return setError();
            }
        }
        if (ad && ad.isClassDeclaration() && ad.type != e.e1.type)
        {
            // A downcast is required for interfaces
            // https://issues.dlang.org/show_bug.cgi?id=3706
            e.e1 = new CastExp(e.loc, e.e1, ad.type);
            e.e1 = e.e1.expressionSemantic(sc);
        }
        result = e;
        // declare dual-context container
        if (f.hasDualContext() && !sc.intypeof && sc.func)
        {
            // check access to second `this`
            if (AggregateDeclaration ad2 = f.isMember2())
            {
                Expression te = new ThisExp(e.loc).expressionSemantic(sc);
                if (te.op != EXP.error)
                    te = getRightThis(e.loc, sc, ad2, te, f);
                if (te.op == EXP.error)
                {
                    e.error("need `this` of type `%s` to make delegate from function `%s`", ad2.toChars(), f.toChars());
                    return setError();
                }
            }
            VarDeclaration vthis2 = makeThis2Argument(e.loc, sc, f);
            e.vthis2 = vthis2;
            Expression de = new DeclarationExp(e.loc, vthis2);
            result = Expression.combine(de, result);
            result = result.expressionSemantic(sc);
        }
    }

    override void visit(DotTypeExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("DotTypeExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (auto e = unaSemantic(exp, sc))
        {
            result = e;
            return;
        }

        exp.type = exp.sym.getType().addMod(exp.e1.type.mod);
        result = exp;
    }

    override void visit(AddrExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("AddrExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = unaSemantic(exp, sc))
        {
            result = ex;
            return;
        }

        if (sc.flags & SCOPE.Cfile)
        {
            /* Special handling for &"string"/&(T[]){0, 1}
             * since C regards string/array literals as lvalues
             */
            auto e = exp.e1;
            if(e.isStringExp() || e.isArrayLiteralExp())
            {
                e.type = typeSemantic(e.type, Loc.initial, sc);
                // if type is already a pointer exp is an illegal expression of the form `&(&"")`
                if (!e.type.isTypePointer())
                {
                    e.type = e.type.pointerTo();
                    result = e;
                    return;
                }
                else
                {
                    // `toLvalue` call further below is upon exp.e1, omitting & from the error message
                    exp.toLvalue(sc, null);
                    return setError();
                }
            }
        }

        int wasCond = exp.e1.op == EXP.question;

        if (exp.e1.op == EXP.dotTemplateInstance)
        {
            DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)exp.e1;
            TemplateInstance ti = dti.ti;
            {
                //assert(ti.needsTypeInference(sc));
                ti.dsymbolSemantic(sc);
                if (!ti.inst || ti.errors) // if template failed to expand
                    return setError();

                Dsymbol s = ti.toAlias();
                FuncDeclaration f = s.isFuncDeclaration();
                if (f)
                {
                    exp.e1 = new DotVarExp(exp.e1.loc, dti.e1, f);
                    exp.e1 = exp.e1.expressionSemantic(sc);
                }
            }
        }
        else if (exp.e1.op == EXP.scope_)
        {
            TemplateInstance ti = (cast(ScopeExp)exp.e1).sds.isTemplateInstance();
            if (ti)
            {
                //assert(ti.needsTypeInference(sc));
                ti.dsymbolSemantic(sc);
                if (!ti.inst || ti.errors) // if template failed to expand
                    return setError();

                Dsymbol s = ti.toAlias();
                FuncDeclaration f = s.isFuncDeclaration();
                if (f)
                {
                    exp.e1 = new VarExp(exp.e1.loc, f);
                    exp.e1 = exp.e1.expressionSemantic(sc);
                }
            }
        }
        /* https://issues.dlang.org/show_bug.cgi?id=809
         *
         * If the address of a lazy variable is taken,
         * the expression is rewritten so that the type
         * of it is the delegate type. This means that
         * the symbol is not going to represent a call
         * to the delegate anymore, but rather, the
         * actual symbol.
         */
        if (auto ve = exp.e1.isVarExp())
        {
            if (ve.var.storage_class & STC.lazy_)
            {
                exp.e1 = exp.e1.expressionSemantic(sc);
                exp.e1 = resolveProperties(sc, exp.e1);
                if (auto callExp = exp.e1.isCallExp())
                {
                    if (callExp.e1.type.toBasetype().ty == Tdelegate)
                    {
                        /* https://issues.dlang.org/show_bug.cgi?id=20551
                         *
                         * Cannot take address of lazy parameter in @safe code
                         * because it might end up being a pointer to undefined
                         * memory.
                         */
                        if (1)
                        {
                            if (sc.setUnsafe(false, exp.loc,
                                "cannot take address of lazy parameter `%s` in `@safe` function `%s`", ve, sc.func))
                            {
                                setError();
                                return;
                            }
                        }
                        VarExp ve2 = callExp.e1.isVarExp();
                        ve2.delegateWasExtracted = true;
                        ve2.var.storage_class |= STC.scope_;
                        result = ve2;
                        return;
                    }
                }
            }
        }

        exp.e1 = exp.e1.toLvalue(sc, null);
        if (exp.e1.op == EXP.error)
        {
            result = exp.e1;
            return;
        }
        if (checkNonAssignmentArrayOp(exp.e1))
            return setError();

        if (!exp.e1.type)
        {
            exp.error("cannot take address of `%s`", exp.e1.toChars());
            return setError();
        }
        if (!checkAddressable(exp, sc))
            return setError();

        bool hasOverloads;
        if (auto f = isFuncAddress(exp, &hasOverloads))
        {
            if (!hasOverloads && f.checkForwardRef(exp.loc))
                return setError();
        }
        else if (!exp.e1.type.deco)
        {
            // try to resolve the type
            exp.e1.type = exp.e1.type.typeSemantic(exp.e1.loc, null);
            if (!exp.e1.type.deco)  // still couldn't resolve it
            {
                if (auto ve = exp.e1.isVarExp())
                {
                    Declaration d = ve.var;
                    exp.error("forward reference to %s `%s`", d.kind(), d.toChars());
                }
                else
                    exp.error("forward reference to type `%s` of expression `%s`", exp.e1.type.toChars(), exp.e1.toChars());
                return setError();
            }
        }

        exp.type = exp.e1.type.pointerTo();

        // See if this should really be a delegate
        if (exp.e1.op == EXP.dotVariable)
        {
            DotVarExp dve = cast(DotVarExp)exp.e1;
            FuncDeclaration f = dve.var.isFuncDeclaration();
            if (f)
            {
                f = f.toAliasFunc(); // FIXME, should see overloads
                                     // https://issues.dlang.org/show_bug.cgi?id=1983
                if (!dve.hasOverloads)
                    f.tookAddressOf++;

                Expression e;
                if (f.needThis())
                    e = new DelegateExp(exp.loc, dve.e1, f, dve.hasOverloads);
                else // It is a function pointer. Convert &v.f() --> (v, &V.f())
                    e = new CommaExp(exp.loc, dve.e1, new AddrExp(exp.loc, new VarExp(exp.loc, f, dve.hasOverloads)));
                e = e.expressionSemantic(sc);
                result = e;
                return;
            }

            // Look for misaligned pointer in @safe mode
            if (checkUnsafeAccess(sc, dve, !exp.type.isMutable(), true))
                return setError();
        }
        else if (exp.e1.op == EXP.variable)
        {
            VarExp ve = cast(VarExp)exp.e1;
            VarDeclaration v = ve.var.isVarDeclaration();
            if (v)
            {
                if (!checkAddressVar(sc, exp.e1, v))
                    return setError();

                ve.checkPurity(sc, v);
            }
            FuncDeclaration f = ve.var.isFuncDeclaration();
            if (f)
            {
                /* Because nested functions cannot be overloaded,
                 * mark here that we took its address because castTo()
                 * may not be called with an exact match.
                 *
                 * https://issues.dlang.org/show_bug.cgi?id=19285 :
                 * We also need to make sure we aren't inside a typeof. Ideally the compiler
                 * would do typeof(...) semantic analysis speculatively then collect information
                 * about what it used rather than relying on what are effectively semantically-global
                 * variables but it doesn't.
                 */
                if (!sc.isFromSpeculativeSemanticContext() && (!ve.hasOverloads || (f.isNested() && !f.needThis())))
                {
                    // TODO: Refactor to use a proper interface that can keep track of causes.
                    f.tookAddressOf++;
                }

                if (f.isNested() && !f.needThis())
                {
                    if (f.isFuncLiteralDeclaration())
                    {
                        if (!f.FuncDeclaration.isNested())
                        {
                            /* Supply a 'null' for a this pointer if no this is available
                             */
                            Expression e = new DelegateExp(exp.loc, new NullExp(exp.loc, Type.tnull), f, ve.hasOverloads);
                            e = e.expressionSemantic(sc);
                            result = e;
                            return;
                        }
                    }
                    Expression e = new DelegateExp(exp.loc, exp.e1, f, ve.hasOverloads);
                    e = e.expressionSemantic(sc);
                    result = e;
                    return;
                }
                if (f.needThis())
                {
                    if (hasThis(sc))
                    {
                        /* Should probably supply 'this' after overload resolution,
                         * not before.
                         */
                        Expression ethis = new ThisExp(exp.loc);
                        Expression e = new DelegateExp(exp.loc, ethis, f, ve.hasOverloads);
                        e = e.expressionSemantic(sc);
                        result = e;
                        return;
                    }
                    if (sc.func && !sc.intypeof && !(sc.flags & SCOPE.debug_))
                    {
                        sc.setUnsafe(false, exp.loc,
                            "`this` reference necessary to take address of member `%s` in `@safe` function `%s`",
                            f, sc.func);
                    }
                }
            }
        }
        else if (exp.e1.op == EXP.index)
        {
            /* For:
             *   int[3] a;
             *   &a[i]
             * check 'a' the same as for a regular variable
             */
            if (VarDeclaration v = expToVariable(exp.e1))
            {
                exp.e1.checkPurity(sc, v);
            }
        }
        else if (wasCond)
        {
            /* a ? b : c was transformed to *(a ? &b : &c), but we still
             * need to do safety checks
             */
            assert(exp.e1.op == EXP.star);
            PtrExp pe = cast(PtrExp)exp.e1;
            assert(pe.e1.op == EXP.question);
            CondExp ce = cast(CondExp)pe.e1;
            assert(ce.e1.op == EXP.address);
            assert(ce.e2.op == EXP.address);

            // Re-run semantic on the address expressions only
            ce.e1.type = null;
            ce.e1 = ce.e1.expressionSemantic(sc);
            ce.e2.type = null;
            ce.e2 = ce.e2.expressionSemantic(sc);
        }
        result = exp.optimize(WANTvalue);
    }

    override void visit(PtrExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("PtrExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        exp.e1 = exp.e1.arrayFuncConv(sc);

        Type tb = exp.e1.type.toBasetype();
        switch (tb.ty)
        {
        case Tpointer:
            exp.type = (cast(TypePointer)tb).next;
            break;

        case Tsarray:
        case Tarray:
            if (isNonAssignmentArrayOp(exp.e1))
                goto default;
            exp.error("using `*` on an array is no longer supported; use `*(%s).ptr` instead", exp.e1.toChars());
            exp.type = (cast(TypeArray)tb).next;
            exp.e1 = exp.e1.castTo(sc, exp.type.pointerTo());
            break;

        case Terror:
            return setError();

        case Tnull:
            exp.type = Type.tnoreturn;  // typeof(*null) is bottom type
            break;

        default:
            exp.error("can only `*` a pointer, not a `%s`", exp.e1.type.toChars());
            goto case Terror;
        }

        if (exp.checkValue())
            return setError();

        result = exp;
    }

    override void visit(NegExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("NegExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        fix16997(sc, exp);
        exp.type = exp.e1.type;
        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp.e1))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }
        if (!target.isVectorOpSupported(tb, exp.op))
        {
            result = exp.incompatibleTypes();
            return;
        }
        if (exp.e1.checkNoBool())
            return setError();
        if (exp.e1.checkArithmetic() ||
            exp.e1.checkSharedAccess(sc))
            return setError();

        result = exp;
    }

    override void visit(UAddExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("UAddExp::semantic('%s')\n", exp.toChars());
        }
        assert(!exp.type);

        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        fix16997(sc, exp);
        if (!target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op))
        {
            result = exp.incompatibleTypes();
            return;
        }
        if (exp.e1.checkNoBool())
            return setError();
        if (exp.e1.checkArithmetic())
            return setError();
        if (exp.e1.checkSharedAccess(sc))
            return setError();

        result = exp.e1;
    }

    override void visit(ComExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        fix16997(sc, exp);
        exp.type = exp.e1.type;
        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp.e1))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }
        if (!target.isVectorOpSupported(tb, exp.op))
        {
            result = exp.incompatibleTypes();
            return;
        }
        if (exp.e1.checkNoBool())
            return setError();
        if (exp.e1.checkIntegral() ||
            exp.e1.checkSharedAccess(sc))
            return setError();

        result = exp;
    }

    override void visit(NotExp e)
    {
        if (e.type)
        {
            result = e;
            return;
        }

        e.setNoderefOperand();

        // Note there is no operator overload
        if (Expression ex = unaSemantic(e, sc))
        {
            result = ex;
            return;
        }

        // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
        if (e.e1.op == EXP.type)
            e.e1 = resolveAliasThis(sc, e.e1);

        e.e1 = resolveProperties(sc, e.e1);
        e.e1 = e.e1.toBoolean(sc);
        if (e.e1.type == Type.terror)
        {
            result = e.e1;
            return;
        }

        if (!target.isVectorOpSupported(e.e1.type.toBasetype(), e.op))
        {
            result = e.incompatibleTypes();
        }
        // https://issues.dlang.org/show_bug.cgi?id=13910
        // Today NotExp can take an array as its operand.
        if (checkNonAssignmentArrayOp(e.e1))
            return setError();

        e.type = (sc && sc.flags & SCOPE.Cfile) ? Type.tint32 : Type.tbool;
        result = e;
    }

    override void visit(DeleteExp exp)
    {
        // @@@DEPRECATED_2.109@@@
        // 1. Deprecated since 2.079
        // 2. Error since 2.099
        // 3. Removal of keyword, "delete" can be used for other identities
        if (!exp.isRAII)
        {
            error(exp.loc, "the `delete` keyword is obsolete");
            errorSupplemental(exp.loc, "use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead");
            return setError();
        }

        Expression e = exp;

        if (Expression ex = unaSemantic(exp, sc))
        {
            result = ex;
            return;
        }
        exp.e1 = resolveProperties(sc, exp.e1);
        exp.e1 = exp.e1.modifiableLvalue(sc, null);
        if (exp.e1.op == EXP.error)
        {
            result = exp.e1;
            return;
        }
        exp.type = Type.tvoid;

        Type tb = exp.e1.type.toBasetype();

        /* Now that `delete` in user code is an error, we only get here when
         * `isRAII` has been set to true for the deletion of a `scope class`.  */
        if (tb.ty != Tclass)
        {
            exp.error("cannot delete type `%s`", exp.e1.type.toChars());
            return setError();
        }

        ClassDeclaration cd = (cast(TypeClass)tb).sym;
        if (cd.isCOMinterface())
        {
            /* Because COM classes are deleted by IUnknown.Release()
             */
            exp.error("cannot `delete` instance of COM interface `%s`", cd.toChars());
            return setError();
        }

        bool err = false;
        if (cd.dtor)
        {
            err |= !cd.dtor.functionSemantic();
            err |= exp.checkPurity(sc, cd.dtor);
            err |= exp.checkSafety(sc, cd.dtor);
            err |= exp.checkNogc(sc, cd.dtor);
        }
        if (err)
            return setError();

        result = e;
    }

    override void visit(CastExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("CastExp::semantic('%s')\n", exp.toChars());
        }
        //static int x; assert(++x < 10);
        if (exp.type)
        {
            result = exp;
            return;
        }

        if ((sc && sc.flags & SCOPE.Cfile) &&
            exp.to && (exp.to.ty == Tident || exp.to.ty == Tsarray) &&
            (exp.e1.op == EXP.address || exp.e1.op == EXP.star ||
             exp.e1.op == EXP.uadd || exp.e1.op == EXP.negate))
        {
            /* Ambiguous cases arise from CParser if type-name is just an identifier.
             *   ( identifier ) cast-expression
             *   ( identifier [expression]) cast-expression
             * If we determine that `identifier` is a variable, and cast-expression
             * is one of the unary operators (& * + -), then rewrite this cast
             * as a binary expression.
             */
            Loc loc = exp.loc;
            Type t;
            Expression e;
            Dsymbol s;
            exp.to.resolve(loc, sc, e, t, s);
            if (e !is null)
            {
                if (auto ex = exp.e1.isAddrExp())       // (ident) &exp -> (ident & exp)
                    result = new AndExp(loc, e, ex.e1);
                else if (auto ex = exp.e1.isPtrExp())   // (ident) *exp -> (ident * exp)
                    result = new MulExp(loc, e, ex.e1);
                else if (auto ex = exp.e1.isUAddExp())  // (ident) +exp -> (ident + exp)
                    result = new AddExp(loc, e, ex.e1);
                else if (auto ex = exp.e1.isNegExp())   // (ident) -exp -> (ident - exp)
                    result = new MinExp(loc, e, ex.e1);

                assert(result);
                result = result.expressionSemantic(sc);
                return;
            }
        }

        if (exp.to)
        {
            exp.to = exp.to.typeSemantic(exp.loc, sc);
            if (exp.to == Type.terror)
                return setError();

            if (!exp.to.hasPointers())
                exp.setNoderefOperand();

            // When e1 is a template lambda, this cast may instantiate it with
            // the type 'to'.
            exp.e1 = inferType(exp.e1, exp.to);
        }

        if (auto e = unaSemantic(exp, sc))
        {
            result = e;
            return;
        }

        if (exp.e1.type.isTypeNoreturn() && (!exp.to || !exp.to.isTypeNoreturn()))
        {
            result = exp.e1;
            return;
        }
        if (exp.to && !exp.to.isTypeSArray() && !exp.to.isTypeFunction())
            exp.e1 = exp.e1.arrayFuncConv(sc);

        // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
        if (exp.e1.op == EXP.type)
            exp.e1 = resolveAliasThis(sc, exp.e1);

        auto e1x = resolveProperties(sc, exp.e1);
        if (e1x.op == EXP.error)
        {
            result = e1x;
            return;
        }
        if (e1x.checkType())
            return setError();
        exp.e1 = e1x;

        if (!exp.e1.type)
        {
            exp.error("cannot cast `%s`", exp.e1.toChars());
            return setError();
        }

        // https://issues.dlang.org/show_bug.cgi?id=19954
        if (exp.e1.type.ty == Ttuple)
        {
            if (exp.to)
            {
                if (TypeTuple tt = exp.to.isTypeTuple())
                {
                    if (exp.e1.type.implicitConvTo(tt))
                    {
                        result = exp.e1.castTo(sc, tt);
                        return;
                    }
                }
            }
            TupleExp te = exp.e1.isTupleExp();
            if (te.exps.dim == 1)
                exp.e1 = (*te.exps)[0];
        }

        // only allow S(x) rewrite if cast specified S explicitly.
        // See https://issues.dlang.org/show_bug.cgi?id=18545
        const bool allowImplicitConstruction = exp.to !is null;

        if (!exp.to) // Handle cast(const) and cast(immutable), etc.
        {
            exp.to = exp.e1.type.castMod(exp.mod);
            exp.to = exp.to.typeSemantic(exp.loc, sc);

            if (exp.to == Type.terror)
                return setError();
        }

        if (exp.to.ty == Ttuple)
        {
            exp.error("cannot cast `%s` of type `%s` to tuple type `%s`", exp.e1.toChars(), exp.e1.type.toChars(), exp.to.toChars());
            return setError();
        }

        // cast(void) is used to mark e1 as unused, so it is safe
        if (exp.to.ty == Tvoid)
        {
            exp.type = exp.to;
            result = exp;
            return;
        }

        if (!exp.to.equals(exp.e1.type) && exp.mod == cast(ubyte)~0)
        {
            if (Expression e = exp.op_overload(sc))
            {
                result = e.implicitCastTo(sc, exp.to);
                return;
            }
        }

        Type t1b = exp.e1.type.toBasetype();
        Type tob = exp.to.toBasetype();

        if (allowImplicitConstruction && tob.ty == Tstruct && !tob.equals(t1b))
        {
            /* Look to replace:
             *  cast(S)t
             * with:
             *  S(t)
             */

            // Rewrite as to.call(e1)
            Expression e = new TypeExp(exp.loc, exp.to);
            e = new CallExp(exp.loc, e, exp.e1);
            e = e.trySemantic(sc);
            if (e)
            {
                result = e;
                return;
            }
        }

        if (!t1b.equals(tob) && (t1b.ty == Tarray || t1b.ty == Tsarray))
        {
            if (checkNonAssignmentArrayOp(exp.e1))
                return setError();
        }

        // Look for casting to a vector type
        if (tob.ty == Tvector && t1b.ty != Tvector)
        {
            result = new VectorExp(exp.loc, exp.e1, exp.to);
            result = result.expressionSemantic(sc);
            return;
        }

        Expression ex = exp.e1.castTo(sc, exp.to);
        if (ex.op == EXP.error)
        {
            result = ex;
            return;
        }

        // Check for unsafe casts
        if (!isSafeCast(ex, t1b, tob))
        {
            // This is an ad-hoc fix for https://issues.dlang.org/show_bug.cgi?id=19646
            // Should be replaced by a more general @system variables implementation
            if (!sc.func && sc.stc & STC.safe)
            {
                exp.error("cast from `%s` to `%s` not allowed in safe code", exp.e1.type.toChars(), exp.to.toChars());
                return setError();
            }

            if (sc.setUnsafe(false, exp.loc, "cast from `%s` to `%s` not allowed in safe code", exp.e1.type, exp.to))
            {
                return setError();
            }
        }

        // `object.__ArrayCast` is a rewrite of an old runtime hook `_d_arraycast`. `_d_arraycast` was not built
        // to handle certain casts.  Those casts which `object.__ArrayCast` does not support are filtered out.
        // See `e2ir.toElemCast` for other types of casts.  If `object.__ArrayCast` is improved to support more
        // casts these conditions and potentially some logic in `e2ir.toElemCast` can be removed.
        if (tob.ty == Tarray)
        {
            // https://issues.dlang.org/show_bug.cgi?id=19840
            if (auto ad = isAggregate(t1b))
            {
                if (ad.aliasthis)
                {
                    Expression e = resolveAliasThis(sc, exp.e1);
                    e = new CastExp(exp.loc, e, exp.to);
                    result = e.expressionSemantic(sc);
                    return;
                }
            }

            if(t1b.ty == Tarray && exp.e1.op != EXP.arrayLiteral && (sc.flags & SCOPE.ctfe) == 0)
            {
                auto tFrom = t1b.nextOf();
                auto tTo = tob.nextOf();

                // https://issues.dlang.org/show_bug.cgi?id=20130
                if (exp.e1.op != EXP.string_ || !ex.isStringExp)
                {
                    const uint fromSize = cast(uint)tFrom.size();
                    const uint toSize = cast(uint)tTo.size();
                    if (fromSize == SIZE_INVALID || toSize == SIZE_INVALID)
                        return setError();

                    // If array element sizes do not match, we must adjust the dimensions
                    if (fromSize != toSize)
                    {
                        if (!verifyHookExist(exp.loc, *sc, Id.__ArrayCast, "casting array of structs"))
                            return setError();

                        // A runtime check is needed in case arrays don't line up.  That check should
                        // be done in the implementation of `object.__ArrayCast`
                        if (toSize == 0 || (fromSize % toSize) != 0)
                        {
                            // lower to `object.__ArrayCast!(TFrom, TTo)(from)`

                            // fully qualify as `object.__ArrayCast`
                            Expression id = new IdentifierExp(exp.loc, Id.empty);
                            auto dotid = new DotIdExp(exp.loc, id, Id.object);

                            auto tiargs = new Objects();
                            tiargs.push(tFrom);
                            tiargs.push(tTo);
                            auto dt = new DotTemplateInstanceExp(exp.loc, dotid, Id.__ArrayCast, tiargs);

                            auto arguments = new Expressions();
                            arguments.push(exp.e1);
                            Expression ce = new CallExp(exp.loc, dt, arguments);

                            result = expressionSemantic(ce, sc);
                            return;
                        }
                    }
                }
            }
        }

        if (sc && sc.flags & SCOPE.Cfile)
        {
            /* C11 6.5.4-5: A cast does not yield an lvalue.
             * So ensure that castTo does not strip away the cast so that this
             * can be enforced in other semantic visitor methods.
             */
            if (!ex.isCastExp())
            {
                ex = new CastExp(exp.loc, ex, exp.to);
                ex.type = exp.to;
            }
        }
        result = ex;
    }

    override void visit(VectorExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("VectorExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        exp.e1 = exp.e1.expressionSemantic(sc);
        exp.type = exp.to.typeSemantic(exp.loc, sc);
        if (exp.e1.op == EXP.error || exp.type.ty == Terror)
        {
            result = exp.e1;
            return;
        }

        Type tb = exp.type.toBasetype();
        assert(tb.ty == Tvector);
        TypeVector tv = cast(TypeVector)tb;
        Type te = tv.elementType();
        exp.dim = cast(int)(tv.size(exp.loc) / te.size(exp.loc));

        bool checkElem(Expression elem)
        {
            if (elem.isConst() == 1)
                return false;

             exp.error("constant expression expected, not `%s`", elem.toChars());
             return true;
        }

        exp.e1 = exp.e1.optimize(WANTvalue);
        bool res;
        if (exp.e1.op == EXP.arrayLiteral)
        {
            foreach (i; 0 .. exp.dim)
            {
                // Do not stop on first error - check all AST nodes even if error found
                res |= checkElem(exp.e1.isArrayLiteralExp()[i]);
            }
        }
        else if (exp.e1.type.ty == Tvoid)
            checkElem(exp.e1);

        result = res ? ErrorExp.get() : exp;
    }

    override void visit(VectorArrayExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("VectorArrayExp::semantic('%s')\n", e.toChars());
        }
        if (!e.type)
        {
            unaSemantic(e, sc);
            e.e1 = resolveProperties(sc, e.e1);

            if (e.e1.op == EXP.error)
            {
                result = e.e1;
                return;
            }
            assert(e.e1.type.ty == Tvector);
            e.type = e.e1.type.isTypeVector().basetype;
        }
        result = e;
    }

    override void visit(SliceExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("SliceExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        // operator overloading should be handled in ArrayExp already.
        if (Expression ex = unaSemantic(exp, sc))
        {
            result = ex;
            return;
        }
        exp.e1 = resolveProperties(sc, exp.e1);
        if (exp.e1.op == EXP.type && exp.e1.type.ty != Ttuple)
        {
            if (exp.lwr || exp.upr)
            {
                exp.error("cannot slice type `%s`", exp.e1.toChars());
                return setError();
            }
            Expression e = new TypeExp(exp.loc, exp.e1.type.arrayOf());
            result = e.expressionSemantic(sc);
            return;
        }
        if (!exp.lwr && !exp.upr)
        {
            if (exp.e1.op == EXP.arrayLiteral)
            {
                // Convert [a,b,c][] to [a,b,c]
                Type t1b = exp.e1.type.toBasetype();
                Expression e = exp.e1;
                if (t1b.ty == Tsarray)
                {
                    e = e.copy();
                    e.type = t1b.nextOf().arrayOf();
                }
                result = e;
                return;
            }
            if (exp.e1.op == EXP.slice)
            {
                // Convert e[][] to e[]
                SliceExp se = cast(SliceExp)exp.e1;
                if (!se.lwr && !se.upr)
                {
                    result = se;
                    return;
                }
            }
            if (isArrayOpOperand(exp.e1))
            {
                // Convert (a[]+b[])[] to a[]+b[]
                result = exp.e1;
                return;
            }
        }
        if (exp.e1.op == EXP.error)
        {
            result = exp.e1;
            return;
        }
        if (exp.e1.type.ty == Terror)
            return setError();

        Type t1b = exp.e1.type.toBasetype();
        if (auto tp = t1b.isTypePointer())
        {
            if (t1b.isPtrToFunction())
            {
                exp.error("cannot slice function pointer `%s`", exp.e1.toChars());
                return setError();
            }
            if (!exp.lwr || !exp.upr)
            {
                exp.error("upper and lower bounds are needed to slice a pointer");
                if (auto ad = isAggregate(tp.next.toBasetype()))
                {
                    auto s = search_function(ad, Id.index);
                    if (!s) s = search_function(ad, Id.slice);
                    if (s)
                    {
                        auto fd = s.isFuncDeclaration();
                        if ((fd && !fd.getParameterList().length) || s.isTemplateDeclaration())
                        {
                            exp.errorSupplemental(
                                "pointer `%s` points to an aggregate that defines an `%s`, perhaps you meant `(*%s)[]`",
                                exp.e1.toChars(),
                                s.ident.toChars(),
                                exp.e1.toChars()
                            );
                        }

                    }
                }

                return setError();
            }
            if (sc.setUnsafe(false, exp.loc, "pointer slicing not allowed in safe functions"))
                return setError();
        }
        else if (t1b.ty == Tarray)
        {
        }
        else if (t1b.ty == Tsarray)
        {
        }
        else if (t1b.ty == Ttuple)
        {
            if (!exp.lwr && !exp.upr)
            {
                result = exp.e1;
                return;
            }
            if (!exp.lwr || !exp.upr)
            {
                exp.error("need upper and lower bound to slice tuple");
                return setError();
            }
        }
        else if (t1b.ty == Tvector && exp.e1.isLvalue())
        {
            // Convert e1 to corresponding static array
            TypeVector tv1 = cast(TypeVector)t1b;
            t1b = tv1.basetype;
            t1b = t1b.castMod(tv1.mod);
            exp.e1.type = t1b;
        }
        else
        {
            exp.error("`%s` cannot be sliced with `[]`", t1b.ty == Tvoid ? exp.e1.toChars() : t1b.toChars());
            return setError();
        }

        /* Run semantic on lwr and upr.
         */
        Scope* scx = sc;
        if (t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Ttuple)
        {
            // Create scope for 'length' variable
            ScopeDsymbol sym = new ArrayScopeSymbol(sc, exp);
            sym.parent = sc.scopesym;
            sc = sc.push(sym);
        }
        if (exp.lwr)
        {
            if (t1b.ty == Ttuple)
                sc = sc.startCTFE();
            exp.lwr = exp.lwr.expressionSemantic(sc);
            exp.lwr = resolveProperties(sc, exp.lwr);
            if (t1b.ty == Ttuple)
                sc = sc.endCTFE();
            exp.lwr = exp.lwr.implicitCastTo(sc, Type.tsize_t);
        }
        if (exp.upr)
        {
            if (t1b.ty == Ttuple)
                sc = sc.startCTFE();
            exp.upr = exp.upr.expressionSemantic(sc);
            exp.upr = resolveProperties(sc, exp.upr);
            if (t1b.ty == Ttuple)
                sc = sc.endCTFE();
            exp.upr = exp.upr.implicitCastTo(sc, Type.tsize_t);
        }
        if (sc != scx)
            sc = sc.pop();
        if (exp.lwr && exp.lwr.type == Type.terror || exp.upr && exp.upr.type == Type.terror)
            return setError();

        if (t1b.ty == Ttuple)
        {
            exp.lwr = exp.lwr.ctfeInterpret();
            exp.upr = exp.upr.ctfeInterpret();
            uinteger_t i1 = exp.lwr.toUInteger();
            uinteger_t i2 = exp.upr.toUInteger();

            TupleExp te;
            TypeTuple tup;
            size_t length;
            if (exp.e1.op == EXP.tuple) // slicing an expression tuple
            {
                te = cast(TupleExp)exp.e1;
                tup = null;
                length = te.exps.dim;
            }
            else if (exp.e1.op == EXP.type) // slicing a type tuple
            {
                te = null;
                tup = cast(TypeTuple)t1b;
                length = Parameter.dim(tup.arguments);
            }
            else
                assert(0);

            if (i2 < i1 || length < i2)
            {
                exp.error("string slice `[%llu .. %llu]` is out of bounds", i1, i2);
                return setError();
            }

            size_t j1 = cast(size_t)i1;
            size_t j2 = cast(size_t)i2;
            Expression e;
            if (exp.e1.op == EXP.tuple)
            {
                auto exps = new Expressions(j2 - j1);
                for (size_t i = 0; i < j2 - j1; i++)
                {
                    (*exps)[i] = (*te.exps)[j1 + i];
                }
                e = new TupleExp(exp.loc, te.e0, exps);
            }
            else
            {
                auto args = new Parameters();
                args.reserve(j2 - j1);
                for (size_t i = j1; i < j2; i++)
                {
                    Parameter arg = Parameter.getNth(tup.arguments, i);
                    args.push(arg);
                }
                e = new TypeExp(exp.e1.loc, new TypeTuple(args));
            }
            e = e.expressionSemantic(sc);
            result = e;
            return;
        }

        exp.type = t1b.nextOf().arrayOf();
        // Allow typedef[] -> typedef[]
        if (exp.type.equals(t1b))
            exp.type = exp.e1.type;

        // We might know $ now
        setLengthVarIfKnown(exp.lengthVar, t1b);

        if (exp.lwr && exp.upr)
        {
            exp.lwr = exp.lwr.optimize(WANTvalue);
            exp.upr = exp.upr.optimize(WANTvalue);

            IntRange lwrRange = getIntRange(exp.lwr);
            IntRange uprRange = getIntRange(exp.upr);

            if (t1b.ty == Tsarray || t1b.ty == Tarray)
            {
                Expression el = new ArrayLengthExp(exp.loc, exp.e1);
                el = el.expressionSemantic(sc);
                el = el.optimize(WANTvalue);
                if (el.op == EXP.int64 && t1b.ty == Tsarray)
                {
                    // Array length is known at compile-time. Upper is in bounds if it fits length.
                    dinteger_t length = el.toInteger();
                    auto bounds = IntRange(SignExtendedNumber(0), SignExtendedNumber(length));
                    exp.upperIsInBounds = bounds.contains(uprRange);
                    if (exp.lwr.op == EXP.int64 && exp.upr.op == EXP.int64 && exp.lwr.toInteger() > exp.upr.toInteger())
                    {
                        exp.error("in slice `%s[%llu .. %llu]`, lower bound is greater than upper bound", exp.e1.toChars, exp.lwr.toInteger(), exp.upr.toInteger());
                        return setError();
                    }
                    if (exp.upr.op == EXP.int64 && exp.upr.toInteger() > length)
                    {
                        exp.error("in slice `%s[%llu .. %llu]`, upper bound is greater than array length `%llu`", exp.e1.toChars, exp.lwr.toInteger(), exp.upr.toInteger(), length);
                        return setError();
                    }
                }
                else if (exp.upr.op == EXP.int64 && exp.upr.toInteger() == 0)
                {
                    // Upper slice expression is '0'. Value is always in bounds.
                    exp.upperIsInBounds = true;
                }
                else if (exp.upr.op == EXP.variable && (cast(VarExp)exp.upr).var.ident == Id.dollar)
                {
                    // Upper slice expression is '$'. Value is always in bounds.
                    exp.upperIsInBounds = true;
                }
            }
            else if (t1b.ty == Tpointer)
            {
                exp.upperIsInBounds = true;
            }
            else
                assert(0);

            exp.lowerIsLessThanUpper = (lwrRange.imax <= uprRange.imin);

            //printf("upperIsInBounds = %d lowerIsLessThanUpper = %d\n", exp.upperIsInBounds, exp.lowerIsLessThanUpper);
        }

        result = exp;
    }

    override void visit(ArrayLengthExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("ArrayLengthExp::semantic('%s')\n", e.toChars());
        }
        if (e.type)
        {
            result = e;
            return;
        }

        if (Expression ex = unaSemantic(e, sc))
        {
            result = ex;
            return;
        }
        e.e1 = resolveProperties(sc, e.e1);

        e.type = Type.tsize_t;
        result = e;
    }

    override void visit(ArrayExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("ArrayExp::semantic('%s')\n", exp.toChars());
        }
        assert(!exp.type);

        if (sc.flags & SCOPE.Cfile)
        {
            /* See if need to rewrite the AST because of cast/call ambiguity
             */
            if (auto e = castCallAmbiguity(exp, sc))
            {
                result = expressionSemantic(e, sc);
                return;
            }
        }

        result = exp.carraySemantic(sc);  // C semantics
        if (result)
            return;

        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (isAggregate(exp.e1.type))
            exp.error("no `[]` operator overload for type `%s`", exp.e1.type.toChars());
        else if (exp.e1.op == EXP.type && exp.e1.type.ty != Ttuple)
            exp.error("static array of `%s` with multiple lengths not allowed", exp.e1.type.toChars());
        else if (isIndexableNonAggregate(exp.e1.type))
            exp.error("only one index allowed to index `%s`", exp.e1.type.toChars());
        else
            exp.error("cannot use `[]` operator on expression of type `%s`", exp.e1.type.toChars());

        result = ErrorExp.get();
    }

    override void visit(DotExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("DotExp::semantic('%s')\n", exp.toChars());
            if (exp.type)
                printf("\ttype = %s\n", exp.type.toChars());
        }
        exp.e1 = exp.e1.expressionSemantic(sc);
        exp.e2 = exp.e2.expressionSemantic(sc);

        if (exp.e1.op == EXP.type)
        {
            result = exp.e2;
            return;
        }
        if (exp.e2.op == EXP.type)
        {
            result = exp.e2;
            return;
        }
        if (auto te = exp.e2.isTemplateExp())
        {
            Expression e = new DotTemplateExp(exp.loc, exp.e1, te.td);
            result = e.expressionSemantic(sc);
            return;
        }
        if (!exp.type)
            exp.type = exp.e2.type;
        result = exp;
    }

    override void visit(CommaExp e)
    {
        //printf("Semantic.CommaExp() %s\n", e.toChars());
        if (e.type)
        {
            result = e;
            return;
        }

        // Allow `((a,b),(x,y))`
        if (e.allowCommaExp)
        {
            CommaExp.allow(e.e1);
            CommaExp.allow(e.e2);
        }

        if (Expression ex = binSemanticProp(e, sc))
        {
            result = ex;
            return;
        }
        e.e1 = e.e1.addDtorHook(sc);

        if (checkNonAssignmentArrayOp(e.e1))
            return setError();

        // Comma expressions trigger this conversion
        e.e2 = e.e2.arrayFuncConv(sc);

        e.type = e.e2.type;
        result = e;

        if (sc.flags & SCOPE.Cfile)
            return;

        if (e.type is Type.tvoid)
        {
            checkMustUse(e.e1, sc);
            discardValue(e.e1);
        }
        else if (!e.allowCommaExp && !e.isGenerated)
            e.error("using the result of a comma expression is not allowed");
    }

    override void visit(IntervalExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("IntervalExp::semantic('%s')\n", e.toChars());
        }
        if (e.type)
        {
            result = e;
            return;
        }

        Expression le = e.lwr;
        le = le.expressionSemantic(sc);
        le = resolveProperties(sc, le);

        Expression ue = e.upr;
        ue = ue.expressionSemantic(sc);
        ue = resolveProperties(sc, ue);

        if (le.op == EXP.error)
        {
            result = le;
            return;
        }
        if (ue.op == EXP.error)
        {
            result = ue;
            return;
        }

        e.lwr = le;
        e.upr = ue;

        e.type = Type.tvoid;
        result = e;
    }

    override void visit(DelegatePtrExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("DelegatePtrExp::semantic('%s')\n", e.toChars());
        }
        if (!e.type)
        {
            unaSemantic(e, sc);
            e.e1 = resolveProperties(sc, e.e1);

            if (e.e1.op == EXP.error)
            {
                result = e.e1;
                return;
            }
            e.type = Type.tvoidptr;
        }
        result = e;
    }

    override void visit(DelegateFuncptrExp e)
    {
        static if (LOGSEMANTIC)
        {
            printf("DelegateFuncptrExp::semantic('%s')\n", e.toChars());
        }
        if (!e.type)
        {
            unaSemantic(e, sc);
            e.e1 = resolveProperties(sc, e.e1);
            if (e.e1.op == EXP.error)
            {
                result = e.e1;
                return;
            }
            e.type = e.e1.type.nextOf().pointerTo();
        }
        result = e;
    }

    override void visit(IndexExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("IndexExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        // operator overloading should be handled in ArrayExp already.
        if (!exp.e1.type)
            exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
        assert(exp.e1.type); // semantic() should already be run on it
        if (exp.e1.op == EXP.type && exp.e1.type.ty != Ttuple)
        {
            exp.e2 = exp.e2.expressionSemantic(sc);
            exp.e2 = resolveProperties(sc, exp.e2);
            Type nt;
            if (exp.e2.op == EXP.type)
                nt = new TypeAArray(exp.e1.type, exp.e2.type);
            else
                nt = new TypeSArray(exp.e1.type, exp.e2);
            Expression e = new TypeExp(exp.loc, nt);
            result = e.expressionSemantic(sc);
            return;
        }
        if (exp.e1.op == EXP.error)
        {
            result = exp.e1;
            return;
        }
        if (exp.e1.type.ty == Terror)
            return setError();

        // Note that unlike C we do not implement the int[ptr]

        Type t1b = exp.e1.type.toBasetype();

        if (t1b.ty == Tvector)
        {
            // Convert e1 to corresponding static array
            TypeVector tv1 = cast(TypeVector)t1b;
            t1b = tv1.basetype;
            t1b = t1b.castMod(tv1.mod);
            exp.e1.type = t1b;
        }
        if (t1b.ty == Tsarray || t1b.ty == Tarray)
        {
            if (!checkAddressable(exp, sc))
                return setError();
        }

        /* Run semantic on e2
         */
        Scope* scx = sc;
        if (t1b.ty == Tsarray || t1b.ty == Tarray || t1b.ty == Ttuple)
        {
            // Create scope for 'length' variable
            ScopeDsymbol sym = new ArrayScopeSymbol(sc, exp);
            sym.parent = sc.scopesym;
            sc = sc.push(sym);
        }
        if (t1b.ty == Ttuple)
            sc = sc.startCTFE();
        exp.e2 = exp.e2.expressionSemantic(sc).arrayFuncConv(sc);
        exp.e2 = resolveProperties(sc, exp.e2);
        if (t1b.ty == Ttuple)
            sc = sc.endCTFE();
        if (exp.e2.op == EXP.tuple)
        {
            TupleExp te = cast(TupleExp)exp.e2;
            if (te.exps && te.exps.dim == 1)
                exp.e2 = Expression.combine(te.e0, (*te.exps)[0]); // bug 4444 fix
        }
        if (sc != scx)
            sc = sc.pop();
        if (exp.e2.type == Type.terror)
            return setError();

        if (checkNonAssignmentArrayOp(exp.e1))
            return setError();

        switch (t1b.ty)
        {
        case Tpointer:
            if (t1b.isPtrToFunction())
            {
                exp.error("cannot index function pointer `%s`", exp.e1.toChars());
                return setError();
            }
            exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);
            if (exp.e2.type == Type.terror)
                return setError();
            exp.e2 = exp.e2.optimize(WANTvalue);
            if (exp.e2.op == EXP.int64 && exp.e2.toInteger() == 0)
            {
            }
            else if (sc.setUnsafe(false, exp.loc, "`@safe` function `%s` cannot index pointer `%s`", sc.func, exp.e1))
            {
                return setError();
            }
            exp.type = (cast(TypeNext)t1b).next;
            break;

        case Tarray:
            exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);
            if (exp.e2.type == Type.terror)
                return setError();
            exp.type = (cast(TypeNext)t1b).next;
            break;

        case Tsarray:
            {
                exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);
                if (exp.e2.type == Type.terror)
                    return setError();
                exp.type = t1b.nextOf();
                break;
            }
        case Taarray:
            {
                TypeAArray taa = cast(TypeAArray)t1b;
                /* We can skip the implicit conversion if they differ only by
                 * constness
                 * https://issues.dlang.org/show_bug.cgi?id=2684
                 * see also bug https://issues.dlang.org/show_bug.cgi?id=2954 b
                 */
                if (!arrayTypeCompatibleWithoutCasting(exp.e2.type, taa.index))
                {
                    exp.e2 = exp.e2.implicitCastTo(sc, taa.index); // type checking
                    if (exp.e2.type == Type.terror)
                        return setError();
                }

                semanticTypeInfo(sc, taa);

                exp.type = taa.next;
                break;
            }
        case Ttuple:
            {
                exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);
                if (exp.e2.type == Type.terror)
                    return setError();

                exp.e2 = exp.e2.ctfeInterpret();
                uinteger_t index = exp.e2.toUInteger();

                TupleExp te;
                TypeTuple tup;
                size_t length;
                if (exp.e1.op == EXP.tuple)
                {
                    te = cast(TupleExp)exp.e1;
                    tup = null;
                    length = te.exps.dim;
                }
                else if (exp.e1.op == EXP.type)
                {
                    te = null;
                    tup = cast(TypeTuple)t1b;
                    length = Parameter.dim(tup.arguments);
                }
                else
                    assert(0);

                if (length <= index)
                {
                    exp.error("array index `[%llu]` is outside array bounds `[0 .. %llu]`", index, cast(ulong)length);
                    return setError();
                }
                Expression e;
                if (exp.e1.op == EXP.tuple)
                {
                    e = (*te.exps)[cast(size_t)index];
                    e = Expression.combine(te.e0, e);
                }
                else
                    e = new TypeExp(exp.e1.loc, Parameter.getNth(tup.arguments, cast(size_t)index).type);
                result = e;
                return;
            }
        default:
            exp.error("`%s` must be an array or pointer type, not `%s`", exp.e1.toChars(), exp.e1.type.toChars());
            return setError();
        }

        // We might know $ now
        setLengthVarIfKnown(exp.lengthVar, t1b);

        if (t1b.ty == Tsarray || t1b.ty == Tarray)
        {
            Expression el = new ArrayLengthExp(exp.loc, exp.e1);
            el = el.expressionSemantic(sc);
            el = el.optimize(WANTvalue);
            if (el.op == EXP.int64)
            {
                exp.e2 = exp.e2.optimize(WANTvalue);
                dinteger_t length = el.toInteger();
                if (length)
                {
                    auto bounds = IntRange(SignExtendedNumber(0), SignExtendedNumber(length - 1));
                    // OR it in, because it might already be set for C array indexing
                    exp.indexIsInBounds |= bounds.contains(getIntRange(exp.e2));
                }
                else if (sc.flags & SCOPE.Cfile && t1b.ty == Tsarray)
                {
                    if (auto ve = exp.e1.isVarExp())
                    {
                        /* Rewrite 0-length C array ve[exp.e2] as *(ve + exp.e2)
                         */
                        auto vp = ve.castTo(sc, t1b.isTypeSArray().next.pointerTo());
                        auto e = new AddExp(exp.loc, vp, exp.e2);
                        auto pe = new PtrExp(exp.loc, e);
                        result = pe.expressionSemantic(sc).optimize(WANTvalue);
                        return;
                    }
                }
            }
        }

        result = exp;
    }

    override void visit(PostExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("PostExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (sc.flags & SCOPE.Cfile)
        {
            /* See if need to rewrite the AST because of cast/call ambiguity
             */
            if (auto e = castCallAmbiguity(exp, sc))
            {
                result = expressionSemantic(e, sc);
                return;
            }
        }

        if (Expression ex = binSemantic(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e1x = resolveProperties(sc, exp.e1);
        if (e1x.op == EXP.error)
        {
            result = e1x;
            return;
        }
        exp.e1 = e1x;

        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.e1.checkReadModifyWrite(exp.op))
            return setError();

        if (exp.e1.op == EXP.slice)
        {
            const(char)* s = exp.op == EXP.plusPlus ? "increment" : "decrement";
            exp.error("cannot post-%s array slice `%s`, use pre-%s instead", s, exp.e1.toChars(), s);
            return setError();
        }

        Type t1 = exp.e1.type.toBasetype();
        if (t1.ty == Tclass || t1.ty == Tstruct || exp.e1.op == EXP.arrayLength)
        {
            /* Check for operator overloading,
             * but rewrite in terms of ++e instead of e++
             */

            /* If e1 is not trivial, take a reference to it
             */
            Expression de = null;
            if (exp.e1.op != EXP.variable && exp.e1.op != EXP.arrayLength)
            {
                // ref v = e1;
                auto v = copyToTemp(STC.ref_, "__postref", exp.e1);
                de = new DeclarationExp(exp.loc, v);
                exp.e1 = new VarExp(exp.e1.loc, v);
            }

            /* Rewrite as:
             * auto tmp = e1; ++e1; tmp
             */
            auto tmp = copyToTemp(0, "__pitmp", exp.e1);
            Expression ea = new DeclarationExp(exp.loc, tmp);

            Expression eb = exp.e1.syntaxCopy();
            eb = new PreExp(exp.op == EXP.plusPlus ? EXP.prePlusPlus : EXP.preMinusMinus, exp.loc, eb);

            Expression ec = new VarExp(exp.loc, tmp);

            // Combine de,ea,eb,ec
            if (de)
                ea = new CommaExp(exp.loc, de, ea);
            e = new CommaExp(exp.loc, ea, eb);
            e = new CommaExp(exp.loc, e, ec);
            e = e.expressionSemantic(sc);
            result = e;
            return;
        }

        exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);
        exp.e1 = exp.e1.optimize(WANTvalue, /*keepLvalue*/ true);

        e = exp;
        if (exp.e1.checkScalar() ||
            exp.e1.checkSharedAccess(sc))
            return setError();
        if (exp.e1.checkNoBool())
            return setError();

        if (exp.e1.type.ty == Tpointer)
            e = scaleFactor(exp, sc);
        else
            exp.e2 = exp.e2.castTo(sc, exp.e1.type);
        e.type = exp.e1.type;
        result = e;
    }

    override void visit(PreExp exp)
    {
        Expression e = exp.op_overload(sc);
        // printf("PreExp::semantic('%s')\n", toChars());
        if (e)
        {
            result = e;
            return;
        }

        // Rewrite as e1+=1 or e1-=1
        if (exp.op == EXP.prePlusPlus)
            e = new AddAssignExp(exp.loc, exp.e1, IntegerExp.literal!1);
        else
            e = new MinAssignExp(exp.loc, exp.e1, IntegerExp.literal!1);
        result = e.expressionSemantic(sc);
    }

    /*
     * Get the expression initializer for a specific struct
     *
     * Params:
     *  sd = the struct for which the expression initializer is needed
     *  loc = the location of the initializer
     *  sc = the scope where the expression is located
     *  t = the type of the expression
     *
     * Returns:
     *  The expression initializer or error expression if any errors occured
     */
    private Expression getInitExp(StructDeclaration sd, Loc loc, Scope* sc, Type t)
    {
        if (sd.zeroInit && !sd.isNested())
        {
            // https://issues.dlang.org/show_bug.cgi?id=14606
            // Always use BlitExp for the special expression: (struct = 0)
            return IntegerExp.literal!0;
        }

        if (sd.isNested())
        {
            auto sle = new StructLiteralExp(loc, sd, null, t);
            if (!sd.fill(loc, *sle.elements, true))
                return ErrorExp.get();
            if (checkFrameAccess(loc, sc, sd, sle.elements.dim))
                return ErrorExp.get();

            sle.type = t;
            return sle;
        }

        return t.defaultInit(loc);
    }

    override void visit(AssignExp exp)
    {
        static if (LOGSEMANTIC)
        {
            if (exp.op == EXP.blit)      printf("BlitExp.toElem('%s')\n", exp.toChars());
            if (exp.op == EXP.assign)    printf("AssignExp.toElem('%s')\n", exp.toChars());
            if (exp.op == EXP.construct) printf("ConstructExp.toElem('%s')\n", exp.toChars());
        }

        void setResult(Expression e, int line = __LINE__)
        {
            //printf("line %d\n", line);
            result = e;
        }

        if (exp.type)
        {
            return setResult(exp);
        }

        Expression e1old = exp.e1;

        if (auto e2comma = exp.e2.isCommaExp())
        {
            if (!e2comma.isGenerated && !(sc.flags & SCOPE.Cfile))
                exp.error("using the result of a comma expression is not allowed");

            /* Rewrite to get rid of the comma from rvalue
             *   e1=(e0,e2) => e0,(e1=e2)
             */
            Expression e0;
            exp.e2 = Expression.extractLast(e2comma, e0);
            Expression e = Expression.combine(e0, exp);
            return setResult(e.expressionSemantic(sc));
        }

        /* Look for operator overloading of a[arguments] = e2.
         * Do it before e1.expressionSemantic() otherwise the ArrayExp will have been
         * converted to unary operator overloading already.
         */
        if (auto ae = exp.e1.isArrayExp())
        {
            Expression res;

            ae.e1 = ae.e1.expressionSemantic(sc);
            ae.e1 = resolveProperties(sc, ae.e1);
            Expression ae1old = ae.e1;

            const(bool) maybeSlice =
                (ae.arguments.dim == 0 ||
                 ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);

            IntervalExp ie = null;
            if (maybeSlice && ae.arguments.dim)
            {
                assert((*ae.arguments)[0].op == EXP.interval);
                ie = cast(IntervalExp)(*ae.arguments)[0];
            }
            while (true)
            {
                if (ae.e1.op == EXP.error)
                    return setResult(ae.e1);

                Expression e0 = null;
                Expression ae1save = ae.e1;
                ae.lengthVar = null;

                Type t1b = ae.e1.type.toBasetype();
                AggregateDeclaration ad = isAggregate(t1b);
                if (!ad)
                    break;
                if (search_function(ad, Id.indexass))
                {
                    // Deal with $
                    res = resolveOpDollar(sc, ae, &e0);
                    if (!res) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j)
                        goto Lfallback;
                    if (res.op == EXP.error)
                        return setResult(res);

                    res = exp.e2.expressionSemantic(sc);
                    if (res.op == EXP.error)
                        return setResult(res);
                    exp.e2 = res;

                    /* Rewrite (a[arguments] = e2) as:
                     *      a.opIndexAssign(e2, arguments)
                     */
                    Expressions* a = ae.arguments.copy();
                    a.insert(0, exp.e2);
                    res = new DotIdExp(exp.loc, ae.e1, Id.indexass);
                    res = new CallExp(exp.loc, res, a);
                    if (maybeSlice) // a[] = e2 might be: a.opSliceAssign(e2)
                        res = res.trySemantic(sc);
                    else
                        res = res.expressionSemantic(sc);
                    if (res)
                        return setResult(Expression.combine(e0, res));
                }

            Lfallback:
                if (maybeSlice && search_function(ad, Id.sliceass))
                {
                    // Deal with $
                    res = resolveOpDollar(sc, ae, ie, &e0);
                    if (res.op == EXP.error)
                        return setResult(res);

                    res = exp.e2.expressionSemantic(sc);
                    if (res.op == EXP.error)
                        return setResult(res);

                    exp.e2 = res;

                    /* Rewrite (a[i..j] = e2) as:
                     *      a.opSliceAssign(e2, i, j)
                     */
                    auto a = new Expressions();
                    a.push(exp.e2);
                    if (ie)
                    {
                        a.push(ie.lwr);
                        a.push(ie.upr);
                    }
                    res = new DotIdExp(exp.loc, ae.e1, Id.sliceass);
                    res = new CallExp(exp.loc, res, a);
                    res = res.expressionSemantic(sc);
                    return setResult(Expression.combine(e0, res));
                }

                // No operator overloading member function found yet, but
                // there might be an alias this to try.
                if (ad.aliasthis && !isRecursiveAliasThis(ae.att1, ae.e1.type))
                {
                    /* Rewrite (a[arguments] op e2) as:
                     *      a.aliasthis[arguments] op e2
                     */
                    ae.e1 = resolveAliasThis(sc, ae1save, true);
                    if (ae.e1)
                        continue;
                }
                break;
            }
            ae.e1 = ae1old; // recovery
            ae.lengthVar = null;
        }

        /* Run this.e1 semantic.
         */
        {
            Expression e1x = exp.e1;

            /* With UFCS, e.f = value
             * Could mean:
             *      .f(e, value)
             * or:
             *      .f(e) = value
             */
            if (auto dti = e1x.isDotTemplateInstanceExp())
            {
                Expression e = dti.semanticY(sc, 1);
                if (!e)
                {
                    return setResult(resolveUFCSProperties(sc, e1x, exp.e2));
                }

                e1x = e;
            }
            else if (sc.flags & SCOPE.Cfile && e1x.isDotIdExp())
            {
                auto die = e1x.isDotIdExp();
                e1x = fieldLookup(die.e1, sc, die.ident);
            }
            else if (auto die = e1x.isDotIdExp())
            {
                Expression e = die.semanticY(sc, 1);
                if (e && isDotOpDispatch(e))
                {
                    /* https://issues.dlang.org/show_bug.cgi?id=19687
                     *
                     * On this branch, e2 is semantically analyzed in resolvePropertiesX,
                     * but that call is done with gagged errors. That is the only time when
                     * semantic gets ran on e2, that is why the error never gets to be printed.
                     * In order to make sure that UFCS is tried with correct parameters, e2
                     * needs to have semantic ran on it.
                     */
                    auto ode = e;
                    exp.e2 = exp.e2.expressionSemantic(sc);
                    uint errors = global.startGagging();
                    e = resolvePropertiesX(sc, e, exp.e2);
                    // Any error or if 'e' is not resolved, go to UFCS
                    if (global.endGagging(errors) || e is ode)
                        e = null; /* fall down to UFCS */
                    else
                        return setResult(e);
                }
                if (!e)
                    return setResult(resolveUFCSProperties(sc, e1x, exp.e2));
                e1x = e;
            }
            else
            {
                if (auto se = e1x.isSliceExp())
                    se.arrayop = true;

                e1x = e1x.expressionSemantic(sc);
            }

            /* We have f = value.
             * Could mean:
             *      f(value)
             * or:
             *      f() = value
             */
            if (Expression e = resolvePropertiesX(sc, e1x, exp.e2))
                return setResult(e);

            if (e1x.checkRightThis(sc))
            {
                return setError();
            }
            exp.e1 = e1x;
            assert(exp.e1.type);
        }
        Type t1 = exp.e1.type.isTypeEnum() ? exp.e1.type : exp.e1.type.toBasetype();

        /* Run this.e2 semantic.
         * Different from other binary expressions, the analysis of e2
         * depends on the result of e1 in assignments.
         */
        {
            Expression e2x = inferType(exp.e2, t1.baseElemOf());
            e2x = e2x.expressionSemantic(sc);
            if (!t1.isTypeSArray())
                e2x = e2x.arrayFuncConv(sc);
            e2x = resolveProperties(sc, e2x);
            if (e2x.op == EXP.type)
                e2x = resolveAliasThis(sc, e2x); //https://issues.dlang.org/show_bug.cgi?id=17684
            if (e2x.op == EXP.error)
                return setResult(e2x);
            // We delay checking the value for structs/classes as these might have
            // an opAssign defined.
            if ((t1.ty != Tstruct && t1.ty != Tclass && e2x.checkValue()) ||
                e2x.checkSharedAccess(sc))
                return setError();

            auto etmp = checkNoreturnVarAccess(e2x);
            if (etmp != e2x)
                return setResult(etmp);

            exp.e2 = e2x;
        }

        /* Rewrite tuple assignment as a tuple of assignments.
         */
        {
            Expression e2x = exp.e2;

        Ltupleassign:
            if (exp.e1.op == EXP.tuple && e2x.op == EXP.tuple)
            {
                TupleExp tup1 = cast(TupleExp)exp.e1;
                TupleExp tup2 = cast(TupleExp)e2x;
                size_t dim = tup1.exps.dim;
                Expression e = null;
                if (dim != tup2.exps.dim)
                {
                    exp.error("mismatched tuple lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.dim);
                    return setError();
                }
                if (dim == 0)
                {
                    e = IntegerExp.literal!0;
                    e = new CastExp(exp.loc, e, Type.tvoid); // avoid "has no effect" error
                    e = Expression.combine(tup1.e0, tup2.e0, e);
                }
                else
                {
                    auto exps = new Expressions(dim);
                    for (size_t i = 0; i < dim; i++)
                    {
                        Expression ex1 = (*tup1.exps)[i];
                        Expression ex2 = (*tup2.exps)[i];
                        (*exps)[i] = new AssignExp(exp.loc, ex1, ex2);
                    }
                    e = new TupleExp(exp.loc, Expression.combine(tup1.e0, tup2.e0), exps);
                }
                return setResult(e.expressionSemantic(sc));
            }

            /* Look for form: e1 = e2.aliasthis.
             */
            if (exp.e1.op == EXP.tuple)
            {
                TupleDeclaration td = isAliasThisTuple(e2x);
                if (!td)
                    goto Lnomatch;

                assert(exp.e1.type.ty == Ttuple);
                TypeTuple tt = cast(TypeTuple)exp.e1.type;

                Expression e0;
                Expression ev = extractSideEffect(sc, "__tup", e0, e2x);

                auto iexps = new Expressions();
                iexps.push(ev);
                for (size_t u = 0; u < iexps.dim; u++)
                {
                Lexpand:
                    Expression e = (*iexps)[u];

                    Parameter arg = Parameter.getNth(tt.arguments, u);
                    //printf("[%d] iexps.dim = %d, ", u, iexps.dim);
                    //printf("e = (%s %s, %s), ", Token.toChars[e.op], e.toChars(), e.type.toChars());
                    //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());

                    if (!arg || !e.type.implicitConvTo(arg.type))
                    {
                        // expand initializer to tuple
                        if (expandAliasThisTuples(iexps, u) != -1)
                        {
                            if (iexps.dim <= u)
                                break;
                            goto Lexpand;
                        }
                        goto Lnomatch;
                    }
                }
                e2x = new TupleExp(e2x.loc, e0, iexps);
                e2x = e2x.expressionSemantic(sc);
                if (e2x.op == EXP.error)
                {
                    result = e2x;
                    return;
                }
                // Do not need to overwrite this.e2
                goto Ltupleassign;
            }
        Lnomatch:
        }

        /* Inside constructor, if this is the first assignment of object field,
         * rewrite this to initializing the field.
         */
        if (exp.op == EXP.assign
            && exp.e1.checkModifiable(sc) == Modifiable.initialization)
        {
            //printf("[%s] change to init - %s\n", exp.loc.toChars(), exp.toChars());
            auto t = exp.type;
            exp = new ConstructExp(exp.loc, exp.e1, exp.e2);
            exp.type = t;

            // https://issues.dlang.org/show_bug.cgi?id=13515
            // set Index::modifiable flag for complex AA element initialization
            if (auto ie1 = exp.e1.isIndexExp())
            {
                Expression e1x = ie1.markSettingAAElem();
                if (e1x.op == EXP.error)
                {
                    result = e1x;
                    return;
                }
            }
        }
        else if (exp.op == EXP.construct && exp.e1.op == EXP.variable &&
                 (cast(VarExp)exp.e1).var.storage_class & (STC.out_ | STC.ref_))
        {
            exp.memset = MemorySet.referenceInit;
        }

        if (exp.op == EXP.assign)  // skip EXP.blit and EXP.construct, which are initializations
        {
            exp.e1.checkSharedAccess(sc);
            checkUnsafeAccess(sc, exp.e1, false, true);
        }

        checkUnsafeAccess(sc, exp.e2, true, true); // Initializer must always be checked

        /* If it is an assignment from a 'foreign' type,
         * check for operator overloading.
         */
        if (exp.memset == MemorySet.referenceInit)
        {
            // If this is an initialization of a reference,
            // do nothing
        }
        else if (t1.ty == Tstruct)
        {
            auto e1x = exp.e1;
            auto e2x = exp.e2;
            auto sd = (cast(TypeStruct)t1).sym;

            if (exp.op == EXP.construct)
            {
                Type t2 = e2x.type.toBasetype();
                if (t2.ty == Tstruct && sd == (cast(TypeStruct)t2).sym)
                {
                    sd.size(exp.loc);
                    if (sd.sizeok != Sizeok.done)
                        return setError();
                    if (!sd.ctor)
                        sd.ctor = sd.searchCtor();

                    // https://issues.dlang.org/show_bug.cgi?id=15661
                    // Look for the form from last of comma chain.
                    auto e2y = lastComma(e2x);

                    CallExp ce = (e2y.op == EXP.call) ? cast(CallExp)e2y : null;
                    DotVarExp dve = (ce && ce.e1.op == EXP.dotVariable)
                        ? cast(DotVarExp)ce.e1 : null;
                    if (sd.ctor && ce && dve && dve.var.isCtorDeclaration() &&
                        // https://issues.dlang.org/show_bug.cgi?id=19389
                        dve.e1.op != EXP.dotVariable &&
                        e2y.type.implicitConvTo(t1))
                    {
                        /* Look for form of constructor call which is:
                         *    __ctmp.ctor(arguments...)
                         */

                        /* Before calling the constructor, initialize
                         * variable with a bit copy of the default
                         * initializer
                         */
                        Expression einit = getInitExp(sd, exp.loc, sc, t1);
                        if (einit.op == EXP.error)
                        {
                            result = einit;
                            return;
                        }

                        auto ae = new BlitExp(exp.loc, exp.e1, einit);
                        ae.type = e1x.type;

                        /* Replace __ctmp being constructed with e1.
                         * We need to copy constructor call expression,
                         * because it may be used in other place.
                         */
                        auto dvx = cast(DotVarExp)dve.copy();
                        dvx.e1 = e1x;
                        auto cx = cast(CallExp)ce.copy();
                        cx.e1 = dvx;
                        if (checkConstructorEscape(sc, cx, false))
                            return setError();

                        Expression e0;
                        Expression.extractLast(e2x, e0);

                        auto e = Expression.combine(e0, ae, cx);
                        e = e.expressionSemantic(sc);
                        result = e;
                        return;
                    }
                    // https://issues.dlang.org/show_bug.cgi?id=21586
                    // Rewrite CondExp or e1 will miss direct construction, e.g.
                    // e1 = a ? S(1) : ...; -> AST: e1 = a ? (S(0)).this(1) : ...;
                    // a temporary created and an extra destructor call.
                    // AST will be rewritten to:
                    // a ? e1 = 0, e1.this(1) : ...; -> blitting plus construction
                    if (e2x.op == EXP.question)
                    {
                        /* Rewrite as:
                         *  a ? e1 = b : e1 = c;
                         */
                        CondExp econd = cast(CondExp)e2x;
                        Expression ea1 = new ConstructExp(econd.e1.loc, e1x, econd.e1);
                        Expression ea2 = new ConstructExp(econd.e2.loc, e1x, econd.e2);
                        Expression e = new CondExp(exp.loc, econd.econd, ea1, ea2);
                        result = e.expressionSemantic(sc);
                        return;
                    }
                    if (sd.postblit || sd.hasCopyCtor)
                    {
                        /* We have a copy constructor for this
                         */

                        if (e2x.isLvalue())
                        {
                            if (sd.hasCopyCtor)
                            {
                                /* Rewrite as:
                                 * e1 = init, e1.copyCtor(e2);
                                 */
                                Expression einit = new BlitExp(exp.loc, exp.e1, getInitExp(sd, exp.loc, sc, t1));
                                einit.type = e1x.type;

                                Expression e;
                                e = new DotIdExp(exp.loc, e1x, Id.ctor);
                                e = new CallExp(exp.loc, e, e2x);
                                e = new CommaExp(exp.loc, einit, e);

                                //printf("e: %s\n", e.toChars());

                                result = e.expressionSemantic(sc);
                                return;
                            }
                            else
                            {
                                if (!e2x.type.implicitConvTo(e1x.type))
                                {
                                    exp.error("conversion error from `%s` to `%s`",
                                        e2x.type.toChars(), e1x.type.toChars());
                                    return setError();
                                }

                                /* Rewrite as:
                                 *  (e1 = e2).postblit();
                                 *
                                 * Blit assignment e1 = e2 returns a reference to the original e1,
                                 * then call the postblit on it.
                                 */
                                Expression e = e1x.copy();
                                e.type = e.type.mutableOf();
                                if (e.type.isShared && !sd.type.isShared)
                                    e.type = e.type.unSharedOf();
                                e = new BlitExp(exp.loc, e, e2x);
                                e = new DotVarExp(exp.loc, e, sd.postblit, false);
                                e = new CallExp(exp.loc, e);
                                result = e.expressionSemantic(sc);
                                return;
                            }
                        }
                        else
                        {
                            /* The struct value returned from the function is transferred
                             * so should not call the destructor on it.
                             */
                            e2x = valueNoDtor(e2x);
                        }
                    }

                    // https://issues.dlang.org/show_bug.cgi?id=19251
                    // if e2 cannot be converted to e1.type, maybe there is an alias this
                    if (!e2x.implicitConvTo(t1))
                    {
                        AggregateDeclaration ad2 = isAggregate(e2x.type);
                        if (ad2 && ad2.aliasthis && !isRecursiveAliasThis(exp.att2, exp.e2.type))
                        {
                            /* Rewrite (e1 op e2) as:
                             *      (e1 op e2.aliasthis)
                             */
                            exp.e2 = new DotIdExp(exp.e2.loc, exp.e2, ad2.aliasthis.ident);
                            result = exp.expressionSemantic(sc);
                            return;
                        }
                    }
                }
                else if (!e2x.implicitConvTo(t1))
                {
                    sd.size(exp.loc);
                    if (sd.sizeok != Sizeok.done)
                        return setError();
                    if (!sd.ctor)
                        sd.ctor = sd.searchCtor();

                    if (sd.ctor)
                    {
                        /* Look for implicit constructor call
                         * Rewrite as:
                         *  e1 = init, e1.ctor(e2)
                         */

                        /* Fix Issue 5153 : https://issues.dlang.org/show_bug.cgi?id=5153
                         * Using `new` to initialize a struct object is a common mistake, but
                         * the error message from the compiler is not very helpful in that
                         * case. If exp.e2 is a NewExp and the type of new is the same as
                         * the type as exp.e1 (struct in this case), then we know for sure
                         * that the user wants to instantiate a struct. This is done to avoid
                         * issuing an error when the user actually wants to call a constructor
                         * which receives a class object.
                         *
                         * Foo f = new Foo2(0); is a valid expression if Foo has a constructor
                         * which receives an instance of a Foo2 class
                         */
                        if (exp.e2.op == EXP.new_)
                        {
                            auto newExp = cast(NewExp)(exp.e2);
                            if (newExp.newtype && newExp.newtype == t1)
                            {
                                error(exp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
                                      newExp.toChars(), newExp.type.toChars(), t1.toChars());
                                errorSupplemental(exp.loc, "Perhaps remove the `new` keyword?");
                                return setError();
                            }
                        }

                        Expression einit = new BlitExp(exp.loc, e1x, getInitExp(sd, exp.loc, sc, t1));
                        einit.type = e1x.type;

                        Expression e;
                        e = new DotIdExp(exp.loc, e1x, Id.ctor);
                        e = new CallExp(exp.loc, e, e2x);
                        e = new CommaExp(exp.loc, einit, e);
                        e = e.expressionSemantic(sc);
                        result = e;
                        return;
                    }
                    if (search_function(sd, Id.call))
                    {
                        /* Look for static opCall
                         * https://issues.dlang.org/show_bug.cgi?id=2702
                         * Rewrite as:
                         *  e1 = typeof(e1).opCall(arguments)
                         */
                        e2x = typeDotIdExp(e2x.loc, e1x.type, Id.call);
                        e2x = new CallExp(exp.loc, e2x, exp.e2);

                        e2x = e2x.expressionSemantic(sc);
                        e2x = resolveProperties(sc, e2x);
                        if (e2x.op == EXP.error)
                        {
                            result = e2x;
                            return;
                        }
                        if (e2x.checkValue() || e2x.checkSharedAccess(sc))
                            return setError();
                    }
                }
                else // https://issues.dlang.org/show_bug.cgi?id=11355
                {
                    AggregateDeclaration ad2 = isAggregate(e2x.type);
                    if (ad2 && ad2.aliasthis && !isRecursiveAliasThis(exp.att2, exp.e2.type))
                    {
                        /* Rewrite (e1 op e2) as:
                         *      (e1 op e2.aliasthis)
                         */
                        exp.e2 = new DotIdExp(exp.e2.loc, exp.e2, ad2.aliasthis.ident);
                        result = exp.expressionSemantic(sc);
                        return;
                    }
                }
            }
            else if (exp.op == EXP.assign)
            {
                if (e1x.op == EXP.index && (cast(IndexExp)e1x).e1.type.toBasetype().ty == Taarray)
                {
                    /*
                     * Rewrite:
                     *      aa[key] = e2;
                     * as:
                     *      ref __aatmp = aa;
                     *      ref __aakey = key;
                     *      ref __aaval = e2;
                     *      (__aakey in __aatmp
                     *          ? __aatmp[__aakey].opAssign(__aaval)
                     *          : ConstructExp(__aatmp[__aakey], __aaval));
                     */
                    // ensure we keep the expr modifiable
                    Expression esetting = (cast(IndexExp)e1x).markSettingAAElem();
                    if (esetting.op == EXP.error)
                    {
                        result = esetting;
                        return;
                    }
                    assert(esetting.op == EXP.index);
                    IndexExp ie = cast(IndexExp) esetting;
                    Type t2 = e2x.type.toBasetype();

                    Expression e0 = null;
                    Expression ea = extractSideEffect(sc, "__aatmp", e0, ie.e1);
                    Expression ek = extractSideEffect(sc, "__aakey", e0, ie.e2);
                    Expression ev = extractSideEffect(sc, "__aaval", e0, e2x);

                    AssignExp ae = cast(AssignExp)exp.copy();
                    ae.e1 = new IndexExp(exp.loc, ea, ek);
                    ae.e1 = ae.e1.expressionSemantic(sc);
                    ae.e1 = ae.e1.optimize(WANTvalue);
                    ae.e2 = ev;
                    Expression e = ae.op_overload(sc);
                    if (e)
                    {
                        Expression ey = null;
                        if (t2.ty == Tstruct && sd == t2.toDsymbol(sc))
                        {
                            ey = ev;
                        }
                        else if (!ev.implicitConvTo(ie.type) && sd.ctor)
                        {
                            // Look for implicit constructor call
                            // Rewrite as S().ctor(e2)
                            ey = new StructLiteralExp(exp.loc, sd, null);
                            ey = new DotIdExp(exp.loc, ey, Id.ctor);
                            ey = new CallExp(exp.loc, ey, ev);
                            ey = ey.trySemantic(sc);
                        }
                        if (ey)
                        {
                            Expression ex;
                            ex = new IndexExp(exp.loc, ea, ek);
                            ex = ex.expressionSemantic(sc);
                            ex = ex.modifiableLvalue(sc, ex); // allocate new slot
                            ex = ex.optimize(WANTvalue);

                            ey = new ConstructExp(exp.loc, ex, ey);
                            ey = ey.expressionSemantic(sc);
                            if (ey.op == EXP.error)
                            {
                                result = ey;
                                return;
                            }
                            ex = e;

                            // https://issues.dlang.org/show_bug.cgi?id=14144
                            // The whole expression should have the common type
                            // of opAssign() return and assigned AA entry.
                            // Even if there's no common type, expression should be typed as void.
                            if (!typeMerge(sc, EXP.question, ex, ey))
                            {
                                ex = new CastExp(ex.loc, ex, Type.tvoid);
                                ey = new CastExp(ey.loc, ey, Type.tvoid);
                            }
                            e = new CondExp(exp.loc, new InExp(exp.loc, ek, ea), ex, ey);
                        }
                        e = Expression.combine(e0, e);
                        e = e.expressionSemantic(sc);
                        result = e;
                        return;
                    }
                }
                else
                {
                    Expression e = exp.op_overload(sc);
                    if (e)
                    {
                        result = e;
                        return;
                    }
                }
            }
            else
                assert(exp.op == EXP.blit);

            if (e2x.checkValue())
                return setError();

            exp.e1 = e1x;
            exp.e2 = e2x;
        }
        else if (t1.ty == Tclass)
        {
            // Disallow assignment operator overloads for same type
            if (exp.op == EXP.assign && !exp.e2.implicitConvTo(exp.e1.type))
            {
                Expression e = exp.op_overload(sc);
                if (e)
                {
                    result = e;
                    return;
                }
            }
            if (exp.e2.checkValue())
                return setError();
        }
        else if (t1.ty == Tsarray)
        {
            // SliceExp cannot have static array type without context inference.
            assert(exp.e1.op != EXP.slice);
            Expression e1x = exp.e1;
            Expression e2x = exp.e2;

            /* C strings come through as static arrays. May need to adjust the size of the
             * string to match the size of e1.
             */
            Type t2 = e2x.type.toBasetype();
            if (sc.flags & SCOPE.Cfile && e2x.isStringExp() && t2.isTypeSArray())
            {
                uinteger_t dim1 = t1.isTypeSArray().dim.toInteger();
                uinteger_t dim2 = t2.isTypeSArray().dim.toInteger();
                if (dim1 + 1 == dim2 || dim2 < dim1)
                {
                    auto tsa2 = t2.isTypeSArray();
                    auto newt = tsa2.next.sarrayOf(dim1).immutableOf();
                    e2x = castTo(e2x, sc, newt);
                    exp.e2 = e2x;
                }
            }

            if (e2x.implicitConvTo(e1x.type))
            {
                if (exp.op != EXP.blit && (e2x.op == EXP.slice && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op == EXP.cast_ && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op != EXP.slice && e2x.isLvalue()))
                {
                    if (e1x.checkPostblit(sc, t1))
                        return setError();
                }

                // e2 matches to t1 because of the implicit length match, so
                if (isUnaArrayOp(e2x.op) || isBinArrayOp(e2x.op))
                {
                    // convert e1 to e1[]
                    // e.g. e1[] = a[] + b[];
                    auto sle = new SliceExp(e1x.loc, e1x, null, null);
                    sle.arrayop = true;
                    e1x = sle.expressionSemantic(sc);
                }
                else
                {
                    // convert e2 to t1 later
                    // e.g. e1 = [1, 2, 3];
                }
            }
            else
            {
                if (e2x.implicitConvTo(t1.nextOf().arrayOf()) > MATCH.nomatch)
                {
                    uinteger_t dim1 = (cast(TypeSArray)t1).dim.toInteger();
                    uinteger_t dim2 = dim1;
                    if (auto ale = e2x.isArrayLiteralExp())
                    {
                        dim2 = ale.elements ? ale.elements.dim : 0;
                    }
                    else if (auto se = e2x.isSliceExp())
                    {
                        Type tx = toStaticArrayType(se);
                        if (tx)
                            dim2 = (cast(TypeSArray)tx).dim.toInteger();
                    }
                    if (dim1 != dim2)
                    {
                        exp.error("mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2);
                        return setError();
                    }
                }

                // May be block or element-wise assignment, so
                // convert e1 to e1[]
                if (exp.op != EXP.assign)
                {
                    // If multidimensional static array, treat as one large array
                    //
                    // Find the appropriate array type depending on the assignment, e.g.
                    // int[3] = int => int[3]
                    // int[3][2] = int => int[6]
                    // int[3][2] = int[] => int[3][2]
                    // int[3][2][4] + int => int[24]
                    // int[3][2][4] + int[] => int[3][8]
                    ulong dim = t1.isTypeSArray().dim.toUInteger();
                    auto type = t1.nextOf();

                    for (TypeSArray tsa; (tsa = type.isTypeSArray()) !is null; )
                    {
                        import core.checkedint : mulu;

                        // Accumulate skipped dimensions
                        bool overflow = false;
                        dim = mulu(dim, tsa.dim.toUInteger(), overflow);
                        if (overflow || dim >= uint.max)
                        {
                            // dym exceeds maximum array size
                            exp.error("static array `%s` size overflowed to %llu",
                                        e1x.type.toChars(), cast(ulong) dim);
                            return setError();
                        }

                        // Move to the element type
                        type = tsa.nextOf().toBasetype();

                        // Rewrite ex1 as a static array if a matching type was found
                        if (e2x.implicitConvTo(type) > MATCH.nomatch)
                        {
                            e1x.type = type.sarrayOf(dim);
                            break;
                        }
                    }
                }
                auto sle = new SliceExp(e1x.loc, e1x, null, null);
                sle.arrayop = true;
                e1x = sle.expressionSemantic(sc);
            }
            if (e1x.op == EXP.error)
                return setResult(e1x);
            if (e2x.op == EXP.error)
                return setResult(e2x);

            exp.e1 = e1x;
            exp.e2 = e2x;
            t1 = e1x.type.toBasetype();
        }
        /* Check the mutability of e1.
         */
        if (auto ale = exp.e1.isArrayLengthExp())
        {
            // e1 is not an lvalue, but we let code generator handle it

            auto ale1x = ale.e1.modifiableLvalue(sc, exp.e1);
            if (ale1x.op == EXP.error)
                return setResult(ale1x);
            ale.e1 = ale1x;

            Type tn = ale.e1.type.toBasetype().nextOf();
            checkDefCtor(ale.loc, tn);

            Identifier hook = global.params.tracegc ? Id._d_arraysetlengthTTrace : Id._d_arraysetlengthT;
            if (!verifyHookExist(exp.loc, *sc, Id._d_arraysetlengthTImpl, "resizing arrays"))
                return setError();

            exp.e2 = exp.e2.expressionSemantic(sc);
            auto lc = lastComma(exp.e2);
            lc = lc.optimize(WANTvalue);
            // use slice expression when arr.length = 0 to avoid runtime call
            if(lc.op == EXP.int64 && lc.toInteger() == 0)
            {
                Expression se = new SliceExp(ale.loc, ale.e1, lc, lc);
                Expression as = new AssignExp(ale.loc, ale.e1, se);
                as = as.expressionSemantic(sc);
                auto res = Expression.combine(as, exp.e2);
                res.type = ale.type;
                return setResult(res);
            }

            // Lower to object._d_arraysetlengthTImpl!(typeof(e1))._d_arraysetlengthT{,Trace}(e1, e2)
            Expression id = new IdentifierExp(ale.loc, Id.empty);
            id = new DotIdExp(ale.loc, id, Id.object);
            auto tiargs = new Objects();
            tiargs.push(ale.e1.type);
            id = new DotTemplateInstanceExp(ale.loc, id, Id._d_arraysetlengthTImpl, tiargs);
            id = new DotIdExp(ale.loc, id, hook);
            id = id.expressionSemantic(sc);

            auto arguments = new Expressions();
            arguments.reserve(5);
            if (global.params.tracegc)
            {
                auto funcname = (sc.callsc && sc.callsc.func) ? sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
                arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
                arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
                arguments.push(new StringExp(exp.loc, funcname.toDString()));
            }
            arguments.push(ale.e1);
            arguments.push(exp.e2);

            Expression ce = new CallExp(ale.loc, id, arguments);
            auto res = ce.expressionSemantic(sc);
            // if (global.params.verbose)
            //     message("lowered   %s =>\n          %s", exp.toChars(), res.toChars());
            return setResult(res);
        }
        else if (auto se = exp.e1.isSliceExp())
        {
            Type tn = se.type.nextOf();
            const fun = sc.func;
            if (exp.op == EXP.assign && !tn.isMutable() &&
                // allow modifiation in module ctor, see
                // https://issues.dlang.org/show_bug.cgi?id=9884
                (!fun || (fun && !fun.isStaticCtorDeclaration())))
            {
                exp.error("slice `%s` is not mutable", se.toChars());
                return setError();
            }

            if (exp.op == EXP.assign && !tn.baseElemOf().isAssignable())
            {
                exp.error("slice `%s` is not mutable, struct `%s` has immutable members",
                    exp.e1.toChars(), tn.baseElemOf().toChars());
                result = ErrorExp.get();
                return;
            }

            // For conditional operator, both branches need conversion.
            while (se.e1.op == EXP.slice)
                se = cast(SliceExp)se.e1;
            if (se.e1.op == EXP.question && se.e1.type.toBasetype().ty == Tsarray)
            {
                se.e1 = se.e1.modifiableLvalue(sc, exp.e1);
                if (se.e1.op == EXP.error)
                    return setResult(se.e1);
            }
        }
        else
        {
            if (t1.ty == Tsarray && exp.op == EXP.assign)
            {
                Type tn = exp.e1.type.nextOf();
                if (tn && !tn.baseElemOf().isAssignable())
                {
                    exp.error("array `%s` is not mutable, struct `%s` has immutable members",
                        exp.e1.toChars(), tn.baseElemOf().toChars());
                    result = ErrorExp.get();
                    return;
                }
            }

            Expression e1x = exp.e1;

            // Try to do a decent error message with the expression
            // before it gets constant folded
            if (exp.op == EXP.assign)
                e1x = e1x.modifiableLvalue(sc, e1old);

            e1x = e1x.optimize(WANTvalue, /*keepLvalue*/ true);

            if (e1x.op == EXP.error)
            {
                result = e1x;
                return;
            }
            exp.e1 = e1x;
        }

        /* Tweak e2 based on the type of e1.
         */
        Expression e2x = exp.e2;
        Type t2 = e2x.type.toBasetype();

        // If it is a array, get the element type. Note that it may be
        // multi-dimensional.
        Type telem = t1;
        while (telem.ty == Tarray)
            telem = telem.nextOf();

        if (exp.e1.op == EXP.slice && t1.nextOf() &&
            (telem.ty != Tvoid || e2x.op == EXP.null_) &&
            e2x.implicitConvTo(t1.nextOf()))
        {
            // Check for block assignment. If it is of type void[], void[][], etc,
            // '= null' is the only allowable block assignment (Bug 7493)
            exp.memset = MemorySet.blockAssign;    // make it easy for back end to tell what this is
            e2x = e2x.implicitCastTo(sc, t1.nextOf());
            if (exp.op != EXP.blit && e2x.isLvalue() && exp.e1.checkPostblit(sc, t1.nextOf()))
                return setError();
        }
        else if (exp.e1.op == EXP.slice &&
                 (t2.ty == Tarray || t2.ty == Tsarray) &&
                 t2.nextOf().implicitConvTo(t1.nextOf()))
        {
            // Check element-wise assignment.

            /* If assigned elements number is known at compile time,
             * check the mismatch.
             */
            SliceExp se1 = cast(SliceExp)exp.e1;
            TypeSArray tsa1 = cast(TypeSArray)toStaticArrayType(se1);
            TypeSArray tsa2 = null;
            if (auto ale = e2x.isArrayLiteralExp())
                tsa2 = cast(TypeSArray)t2.nextOf().sarrayOf(ale.elements.dim);
            else if (auto se = e2x.isSliceExp())
                tsa2 = cast(TypeSArray)toStaticArrayType(se);
            else
                tsa2 = t2.isTypeSArray();

            if (tsa1 && tsa2)
            {
                uinteger_t dim1 = tsa1.dim.toInteger();
                uinteger_t dim2 = tsa2.dim.toInteger();
                if (dim1 != dim2)
                {
                    exp.error("mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toChars());
                    return setError();
                }
            }

            if (exp.op != EXP.blit &&
                (e2x.op == EXP.slice && (cast(UnaExp)e2x).e1.isLvalue() ||
                 e2x.op == EXP.cast_ && (cast(UnaExp)e2x).e1.isLvalue() ||
                 e2x.op != EXP.slice && e2x.isLvalue()))
            {
                if (exp.e1.checkPostblit(sc, t1.nextOf()))
                    return setError();
            }

            if (0 && global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
                e2x.op != EXP.slice && e2x.op != EXP.assign &&
                e2x.op != EXP.arrayLiteral && e2x.op != EXP.string_ &&
                !(e2x.op == EXP.add || e2x.op == EXP.min ||
                  e2x.op == EXP.mul || e2x.op == EXP.div ||
                  e2x.op == EXP.mod || e2x.op == EXP.xor ||
                  e2x.op == EXP.and || e2x.op == EXP.or ||
                  e2x.op == EXP.pow ||
                  e2x.op == EXP.tilde || e2x.op == EXP.negate))
            {
                const(char)* e1str = exp.e1.toChars();
                const(char)* e2str = e2x.toChars();
                exp.warning("explicit element-wise assignment `%s = (%s)[]` is better than `%s = %s`", e1str, e2str, e1str, e2str);
            }

            Type t2n = t2.nextOf();
            Type t1n = t1.nextOf();
            int offset;
            if (t2n.equivalent(t1n) ||
                t1n.isBaseOf(t2n, &offset) && offset == 0)
            {
                /* Allow copy of distinct qualifier elements.
                 * eg.
                 *  char[] dst;  const(char)[] src;
                 *  dst[] = src;
                 *
                 *  class C {}   class D : C {}
                 *  C[2] ca;  D[] da;
                 *  ca[] = da;
                 */
                if (isArrayOpValid(e2x))
                {
                    // Don't add CastExp to keep AST for array operations
                    e2x = e2x.copy();
                    e2x.type = exp.e1.type.constOf();
                }
                else
                    e2x = e2x.castTo(sc, exp.e1.type.constOf());
            }
            else
            {
                /* https://issues.dlang.org/show_bug.cgi?id=15778
                 * A string literal has an array type of immutable
                 * elements by default, and normally it cannot be convertible to
                 * array type of mutable elements. But for element-wise assignment,
                 * elements need to be const at best. So we should give a chance
                 * to change code unit size for polysemous string literal.
                 */
                if (e2x.op == EXP.string_)
                    e2x = e2x.implicitCastTo(sc, exp.e1.type.constOf());
                else
                    e2x = e2x.implicitCastTo(sc, exp.e1.type);
            }
            if (t1n.toBasetype.ty == Tvoid && t2n.toBasetype.ty == Tvoid)
            {
                if (sc.setUnsafe(false, exp.loc, "cannot copy `void[]` to `void[]` in `@safe` code"))
                    return setError();
            }
        }
        else
        {
            if (0 && global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
                t1.ty == Tarray && t2.ty == Tsarray &&
                e2x.op != EXP.slice &&
                t2.implicitConvTo(t1))
            {
                // Disallow ar[] = sa (Converted to ar[] = sa[])
                // Disallow da   = sa (Converted to da   = sa[])
                const(char)* e1str = exp.e1.toChars();
                const(char)* e2str = e2x.toChars();
                const(char)* atypestr = exp.e1.op == EXP.slice ? "element-wise" : "slice";
                exp.warning("explicit %s assignment `%s = (%s)[]` is better than `%s = %s`", atypestr, e1str, e2str, e1str, e2str);
            }
            if (exp.op == EXP.blit)
                e2x = e2x.castTo(sc, exp.e1.type);
            else
            {
                e2x = e2x.implicitCastTo(sc, exp.e1.type);

                // Fix Issue 13435: https://issues.dlang.org/show_bug.cgi?id=13435

                // If the implicit cast has failed and the assign expression is
                // the initialization of a struct member field
                if (e2x.op == EXP.error && exp.op == EXP.construct && t1.ty == Tstruct)
                {
                    scope sd = (cast(TypeStruct)t1).sym;
                    Dsymbol opAssign = search_function(sd, Id.assign);

                    // and the struct defines an opAssign
                    if (opAssign)
                    {
                        // offer more information about the cause of the problem
                        errorSupplemental(exp.loc,
                                          "`%s` is the first assignment of `%s` therefore it represents its initialization",
                                          exp.toChars(), exp.e1.toChars());
                        errorSupplemental(exp.loc,
                                          "`opAssign` methods are not used for initialization, but for subsequent assignments");
                    }
                }
            }
        }
        if (e2x.op == EXP.error)
        {
            result = e2x;
            return;
        }
        exp.e2 = e2x;
        t2 = exp.e2.type.toBasetype();

        /* Look for array operations
         */
        if ((t2.ty == Tarray || t2.ty == Tsarray) && isArrayOpValid(exp.e2))
        {
            // Look for valid array operations
            if (exp.memset != MemorySet.blockAssign &&
                exp.e1.op == EXP.slice &&
                (isUnaArrayOp(exp.e2.op) || isBinArrayOp(exp.e2.op)))
            {
                exp.type = exp.e1.type;
                if (exp.op == EXP.construct) // https://issues.dlang.org/show_bug.cgi?id=10282
                                        // tweak mutability of e1 element
                    exp.e1.type = exp.e1.type.nextOf().mutableOf().arrayOf();
                result = arrayOp(exp, sc);
                return;
            }

            // Drop invalid array operations in e2
            //  d = a[] + b[], d = (a[] + b[])[0..2], etc
            if (checkNonAssignmentArrayOp(exp.e2, exp.memset != MemorySet.blockAssign && exp.op == EXP.assign))
                return setError();

            // Remains valid array assignments
            //  d = d[], d = [1,2,3], etc
        }

        /* Don't allow assignment to classes that were allocated on the stack with:
         *      scope Class c = new Class();
         */
        if (exp.e1.op == EXP.variable && exp.op == EXP.assign)
        {
            VarExp ve = cast(VarExp)exp.e1;
            VarDeclaration vd = ve.var.isVarDeclaration();
            if (vd && vd.onstack)
            {
                assert(t1.ty == Tclass);
                exp.error("cannot rebind scope variables");
            }
        }

        if (exp.e1.op == EXP.variable && (cast(VarExp)exp.e1).var.ident == Id.ctfe)
        {
            exp.error("cannot modify compiler-generated variable `__ctfe`");
        }

        exp.type = exp.e1.type;
        assert(exp.type);
        auto assignElem = exp.e2;
        auto res = exp.op == EXP.assign ? exp.reorderSettingAAElem(sc) : exp;
        /* https://issues.dlang.org/show_bug.cgi?id=22366
         *
         * `reorderSettingAAElem` creates a tree of comma expressions, however,
         * `checkAssignExp` expects only AssignExps.
         */
        if (res == exp) // no `AA[k] = v` rewrite was performed
            checkAssignEscape(sc, res, false, false);
        else
            checkNewEscape(sc, assignElem, false); // assigning to AA puts it on heap

        if (auto ae = res.isConstructExp())
        {
            Type t1b = ae.e1.type.toBasetype();
            if (t1b.ty != Tsarray && t1b.ty != Tarray)
                return setResult(res);

            // only non-trivial array constructions may need to be lowered (non-POD elements basically)
            Type t1e = t1b.nextOf();
            TypeStruct ts = t1e.baseElemOf().isTypeStruct();
            if (!ts || (!ts.sym.postblit && !ts.sym.hasCopyCtor && !ts.sym.dtor))
                return setResult(res);

            // don't lower ref-constructions etc.
            if (!(t1b.ty == Tsarray || ae.e1.isSliceExp) ||
                (ae.e1.isVarExp && ae.e1.isVarExp.var.isVarDeclaration.isReference))
                return setResult(res);

            // Construction from an equivalent other array?
            // Only lower with lvalue RHS elements; let the glue layer move rvalue elements.
            Type t2b = ae.e2.type.toBasetype();
            // skip over a (possibly implicit) cast of a static array RHS to a slice
            Expression rhs = ae.e2;
            Type rhsType = t2b;
            if (t2b.ty == Tarray)
            {
                if (auto ce = rhs.isCastExp())
                {
                    auto ct = ce.e1.type.toBasetype();
                    if (ct.ty == Tsarray)
                    {
                        rhs = ce.e1;
                        rhsType = ct;
                    }
                }
            }
            const lowerToArrayCtor =
                ( (rhsType.ty == Tarray && !rhs.isArrayLiteralExp) ||
                  (rhsType.ty == Tsarray && rhs.isLvalue) ) &&
                t1e.equivalent(t2b.nextOf);

            // Construction from a single element?
            // If the RHS is an rvalue, then we'll need to make a temporary for it (copied multiple times).
            const lowerToArraySetCtor = !lowerToArrayCtor && t1e.equivalent(t2b);

            if (lowerToArrayCtor || lowerToArraySetCtor)
            {
                auto func = lowerToArrayCtor ? Id._d_arrayctor : Id._d_arraysetctor;
                const other = lowerToArrayCtor ? "other array" : "value";
                if (!verifyHookExist(exp.loc, *sc, func, "construct array with " ~ other, Id.object))
                    return setError();

                // Lower to object._d_array{,set}ctor(e1, e2)
                Expression id = new IdentifierExp(exp.loc, Id.empty);
                id = new DotIdExp(exp.loc, id, Id.object);
                id = new DotIdExp(exp.loc, id, func);

                auto arguments = new Expressions();
                arguments.push(new CastExp(ae.loc, ae.e1, t1e.arrayOf).expressionSemantic(sc));
                if (lowerToArrayCtor)
                {
                    arguments.push(new CastExp(ae.loc, rhs, t2b.nextOf.arrayOf).expressionSemantic(sc));
                    Expression ce = new CallExp(exp.loc, id, arguments);
                    res = ce.expressionSemantic(sc);
                }
                else
                {
                    Expression e0;
                    // promote an rvalue RHS element to a temporary, it's passed by ref to _d_arraysetctor
                    if (!ae.e2.isLvalue)
                    {
                        auto vd = copyToTemp(STC.scope_, "__setctor", ae.e2);
                        e0 = new DeclarationExp(vd.loc, vd).expressionSemantic(sc);
                        arguments.push(new VarExp(vd.loc, vd).expressionSemantic(sc));
                    }
                    else
                        arguments.push(ae.e2);

                    Expression ce = new CallExp(exp.loc, id, arguments);
                    res = Expression.combine(e0, ce).expressionSemantic(sc);
                }

                if (global.params.verbose)
                    message("lowered   %s =>\n          %s", exp.toChars(), res.toChars());
            }
        }
        else if (auto ae = res.isAssignExp())
            res = lowerArrayAssign(ae);
        else if (auto ce = res.isCommaExp())
        {
            if (auto ae1 = ce.e1.isAssignExp())
                ce.e1 = lowerArrayAssign(ae1, true);
            if (auto ae2 = ce.e2.isAssignExp())
                ce.e2 = lowerArrayAssign(ae2, true);
        }

        return setResult(res);
    }

    /***************************************
     * Lower AssignExp to `_d_array{setassign,assign_l,assign_r}` if needed.
     *
     * Params:
     *      ae = the AssignExp to be lowered
     *      fromCommaExp = indicates whether `ae` is part of a CommaExp or not,
     *                     so no unnecessary temporay variable is created.
     * Returns:
     *      a CommaExp contiaining call a to `_d_array{setassign,assign_l,assign_r}`
     *      if needed or `ae` otherwise
     */
    private Expression lowerArrayAssign(AssignExp ae, bool fromCommaExp = false)
    {
        Type t1b = ae.e1.type.toBasetype();
        if (t1b.ty != Tsarray && t1b.ty != Tarray)
            return ae;

        const isArrayAssign = (ae.e1.isSliceExp() || ae.e1.type.ty == Tsarray) &&
            (ae.e2.type.ty == Tsarray || ae.e2.type.ty == Tarray) &&
            (ae.e1.type.nextOf() && ae.e2.type.nextOf() && ae.e1.type.nextOf.mutableOf.equals(ae.e2.type.nextOf.mutableOf()));

        const isArraySetAssign = (ae.e1.isSliceExp() || ae.e1.type.ty == Tsarray) &&
            (ae.e1.type.nextOf() && ae.e2.type.implicitConvTo(ae.e1.type.nextOf()));

        if (!isArrayAssign && !isArraySetAssign)
            return ae;

        const ts = t1b.nextOf().baseElemOf().isTypeStruct();
        if (!ts || (!ts.sym.postblit && !ts.sym.dtor))
            return ae;

        Expression res;
        Identifier func = isArraySetAssign ? Id._d_arraysetassign :
            ae.e2.isLvalue() || ae.e2.isSliceExp() ? Id._d_arrayassign_l : Id._d_arrayassign_r;

        // Lower to `.object._d_array{setassign,assign_l,assign_r}(e1, e2)``
        Expression id = new IdentifierExp(ae.loc, Id.empty);
        id = new DotIdExp(ae.loc, id, Id.object);
        id = new DotIdExp(ae.loc, id, func);

        auto arguments = new Expressions();
        arguments.push(new CastExp(ae.loc, ae.e1, ae.e1.type.nextOf.arrayOf)
            .expressionSemantic(sc));

        Expression eValue2, value2 = ae.e2;
        if (isArrayAssign && value2.isLvalue())
            value2 = new CastExp(ae.loc, ae.e2, ae.e2.type.nextOf.arrayOf())
                .expressionSemantic(sc);
        else if (!fromCommaExp &&
            (isArrayAssign || (isArraySetAssign && !value2.isLvalue())))
        {
            // Rvalues from CommaExps were introduced in `visit(AssignExp)`
            // and are temporary variables themselves. Rvalues from trivial
            // SliceExps are simply passed by reference without any copying.

            // `__assigntmp` will be destroyed together with the array `ae.e1`.
            // When `ae.e2` is a variadic arg array, it is also `scope`, so
            // `__assigntmp` may also be scope.
            StorageClass stc = STC.nodtor;
            if (isArrayAssign)
                stc |= STC.rvalue | STC.scope_;

            auto vd = copyToTemp(stc, "__assigntmp", ae.e2);
            eValue2 = new DeclarationExp(vd.loc, vd).expressionSemantic(sc);
            value2 = new VarExp(vd.loc, vd).expressionSemantic(sc);
        }
        arguments.push(value2);

        Expression ce = new CallExp(ae.loc, id, arguments);
        res = Expression.combine(eValue2, ce).expressionSemantic(sc);
        if (isArrayAssign)
            res = Expression.combine(res, ae.e1).expressionSemantic(sc);

        if (global.params.verbose)
            message("lowered   %s =>\n          %s", ae.toChars(), res.toChars());

        return res;
    }

    override void visit(PowAssignExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.e1.checkReadModifyWrite(exp.op, exp.e2))
            return setError();

        assert(exp.e1.type && exp.e2.type);
        if (exp.e1.op == EXP.slice || exp.e1.type.ty == Tarray || exp.e1.type.ty == Tsarray)
        {
            if (checkNonAssignmentArrayOp(exp.e1))
                return setError();

            // T[] ^^= ...
            if (exp.e2.implicitConvTo(exp.e1.type.nextOf()))
            {
                // T[] ^^= T
                exp.e2 = exp.e2.castTo(sc, exp.e1.type.nextOf());
            }
            else if (Expression ex = typeCombine(exp, sc))
            {
                result = ex;
                return;
            }

            // Check element types are arithmetic
            Type tb1 = exp.e1.type.nextOf().toBasetype();
            Type tb2 = exp.e2.type.toBasetype();
            if (tb2.ty == Tarray || tb2.ty == Tsarray)
                tb2 = tb2.nextOf().toBasetype();
            if ((tb1.isintegral() || tb1.isfloating()) && (tb2.isintegral() || tb2.isfloating()))
            {
                exp.type = exp.e1.type;
                result = arrayOp(exp, sc);
                return;
            }
        }
        else
        {
            exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);
        }

        if ((exp.e1.type.isintegral() || exp.e1.type.isfloating()) && (exp.e2.type.isintegral() || exp.e2.type.isfloating()))
        {
            Expression e0 = null;
            e = exp.reorderSettingAAElem(sc);
            e = Expression.extractLast(e, e0);
            assert(e == exp);

            if (exp.e1.op == EXP.variable)
            {
                // Rewrite: e1 = e1 ^^ e2
                e = new PowExp(exp.loc, exp.e1.syntaxCopy(), exp.e2);
                e = new AssignExp(exp.loc, exp.e1, e);
            }
            else
            {
                // Rewrite: ref tmp = e1; tmp = tmp ^^ e2
                auto v = copyToTemp(STC.ref_, "__powtmp", exp.e1);
                auto de = new DeclarationExp(exp.e1.loc, v);
                auto ve = new VarExp(exp.e1.loc, v);
                e = new PowExp(exp.loc, ve, exp.e2);
                e = new AssignExp(exp.loc, new VarExp(exp.e1.loc, v), e);
                e = new CommaExp(exp.loc, de, e);
            }
            e = Expression.combine(e0, e);
            e = e.expressionSemantic(sc);
            result = e;
            return;
        }
        result = exp.incompatibleTypes();
    }

    override void visit(CatAssignExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        //printf("CatAssignExp::semantic() %s\n", exp.toChars());
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (SliceExp se = exp.e1.isSliceExp())
        {
            if (se.e1.type.toBasetype().ty == Tsarray)
            {
                exp.error("cannot append to static array `%s`", se.e1.type.toChars());
                return setError();
            }
        }

        exp.e1 = exp.e1.modifiableLvalue(sc, exp.e1);
        if (exp.e1.op == EXP.error)
        {
            result = exp.e1;
            return;
        }
        if (exp.e2.op == EXP.error)
        {
            result = exp.e2;
            return;
        }

        if (checkNonAssignmentArrayOp(exp.e2))
            return setError();

        Type tb1 = exp.e1.type.toBasetype();
        Type tb1next = tb1.nextOf();
        Type tb2 = exp.e2.type.toBasetype();

        /* Possibilities:
         * EXP.concatenateAssign: appending T[] to T[]
         * EXP.concatenateElemAssign: appending T to T[]
         * EXP.concatenateDcharAssign: appending dchar to T[]
         */
        if ((tb1.ty == Tarray) &&
            (tb2.ty == Tarray || tb2.ty == Tsarray) &&
            (exp.e2.implicitConvTo(exp.e1.type) ||
             (tb2.nextOf().implicitConvTo(tb1next) &&
              (tb2.nextOf().size(Loc.initial) == tb1next.size(Loc.initial)))))
        {
            // EXP.concatenateAssign
            assert(exp.op == EXP.concatenateAssign);
            if (exp.e1.checkPostblit(sc, tb1next))
                return setError();

            exp.e2 = exp.e2.castTo(sc, exp.e1.type);
        }
        else if ((tb1.ty == Tarray) && exp.e2.implicitConvTo(tb1next))
        {
            /* https://issues.dlang.org/show_bug.cgi?id=19782
             *
             * If e2 is implicitly convertible to tb1next, the conversion
             * might be done through alias this, in which case, e2 needs to
             * be modified accordingly (e2 => e2.aliasthis).
             */
            if (tb2.ty == Tstruct && (cast(TypeStruct)tb2).implicitConvToThroughAliasThis(tb1next))
                goto Laliasthis;
            if (tb2.ty == Tclass && (cast(TypeClass)tb2).implicitConvToThroughAliasThis(tb1next))
                goto Laliasthis;
            // Append element
            if (exp.e2.checkPostblit(sc, tb2))
                return setError();

            if (checkNewEscape(sc, exp.e2, false))
                return setError();

            exp = new CatElemAssignExp(exp.loc, exp.type, exp.e1, exp.e2.castTo(sc, tb1next));
            exp.e2 = doCopyOrMove(sc, exp.e2);
        }
        else if (tb1.ty == Tarray &&
                 (tb1next.ty == Tchar || tb1next.ty == Twchar) &&
                 exp.e2.type.ty != tb1next.ty &&
                 exp.e2.implicitConvTo(Type.tdchar))
        {
            // Append dchar to char[] or wchar[]
            exp = new CatDcharAssignExp(exp.loc, exp.type, exp.e1, exp.e2.castTo(sc, Type.tdchar));

            /* Do not allow appending wchar to char[] because if wchar happens
             * to be a surrogate pair, nothing good can result.
             */
        }
        else
        {
            // Try alias this on first operand
            static Expression tryAliasThisForLhs(BinAssignExp exp, Scope* sc)
            {
                AggregateDeclaration ad1 = isAggregate(exp.e1.type);
                if (!ad1 || !ad1.aliasthis)
                    return null;

                /* Rewrite (e1 op e2) as:
                 *      (e1.aliasthis op e2)
                 */
                if (isRecursiveAliasThis(exp.att1, exp.e1.type))
                    return null;
                //printf("att %s e1 = %s\n", Token.toChars(e.op), e.e1.type.toChars());
                Expression e1 = new DotIdExp(exp.loc, exp.e1, ad1.aliasthis.ident);
                BinExp be = cast(BinExp)exp.copy();
                be.e1 = e1;
                return be.trySemantic(sc);
            }

            // Try alias this on second operand
            static Expression tryAliasThisForRhs(BinAssignExp exp, Scope* sc)
            {
                AggregateDeclaration ad2 = isAggregate(exp.e2.type);
                if (!ad2 || !ad2.aliasthis)
                    return null;
                /* Rewrite (e1 op e2) as:
                 *      (e1 op e2.aliasthis)
                 */
                if (isRecursiveAliasThis(exp.att2, exp.e2.type))
                    return null;
                //printf("att %s e2 = %s\n", Token.toChars(e.op), e.e2.type.toChars());
                Expression e2 = new DotIdExp(exp.loc, exp.e2, ad2.aliasthis.ident);
                BinExp be = cast(BinExp)exp.copy();
                be.e2 = e2;
                return be.trySemantic(sc);
            }

    Laliasthis:
            result = tryAliasThisForLhs(exp, sc);
            if (result)
                return;

            result = tryAliasThisForRhs(exp, sc);
            if (result)
                return;

            exp.error("cannot append type `%s` to type `%s`", tb2.toChars(), tb1.toChars());
            return setError();
        }

        if (exp.e2.checkValue() || exp.e2.checkSharedAccess(sc))
            return setError();

        exp.type = exp.e1.type;
        auto res = exp.reorderSettingAAElem(sc);
        if (exp.op == EXP.concatenateElemAssign || exp.op == EXP.concatenateDcharAssign)
            checkAssignEscape(sc, res, false, false);
        result = res;

        if ((exp.op == EXP.concatenateAssign || exp.op == EXP.concatenateElemAssign) &&
            !(sc.flags & (SCOPE.ctfe | SCOPE.compile)))
        {
            // if aa ordering is triggered, `res` will be a CommaExp
            // and `.e2` will be the rewritten original expression.

            // `output` will point to the expression that the lowering will overwrite
            Expression* output;
            if (auto comma = res.isCommaExp())
            {
                output = &comma.e2;
                // manual cast because it could be either CatAssignExp or CatElemAssignExp
                exp = cast(CatAssignExp)comma.e2;
            }
            else
            {
                output = &result;
                exp = cast(CatAssignExp)result;
            }

            if (exp.op == EXP.concatenateAssign)
            {
                Identifier hook = global.params.tracegc ? Id._d_arrayappendTTrace : Id._d_arrayappendT;

                if (!verifyHookExist(exp.loc, *sc, hook, "appending array to arrays", Id.object))
                    return setError();

                // Lower to object._d_arrayappendT{,Trace}({file, line, funcname}, e1, e2)
                Expression id = new IdentifierExp(exp.loc, Id.empty);
                id = new DotIdExp(exp.loc, id, Id.object);
                id = new DotIdExp(exp.loc, id, hook);

                auto arguments = new Expressions();
                arguments.reserve(5);
                if (global.params.tracegc)
                {
                    auto funcname = (sc.callsc && sc.callsc.func) ? sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
                    arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
                    arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
                    arguments.push(new StringExp(exp.loc, funcname.toDString()));
                }

                arguments.push(exp.e1);
                arguments.push(exp.e2);
                Expression ce = new CallExp(exp.loc, id, arguments);
                *output = ce.expressionSemantic(sc);
            }
            else if (exp.op == EXP.concatenateElemAssign)
            {
                /* Do not lower concats to the indices array returned by
                 *`static foreach`, as this array is only used at compile-time.
                 */
                if (auto ve = exp.e1.isVarExp)
                {
                    import core.stdc.ctype : isdigit;
                    // The name of the indices array that static foreach loops uses.
                    // See dmd.cond.lowerNonArrayAggregate
                    enum varName = "__res";
                    const(char)[] id = ve.var.ident.toString;
                    if (ve.var.storage_class & STC.temp && id.length > varName.length &&
                        id[0 .. varName.length] == varName && id[varName.length].isdigit)
                        return;
                }

                Identifier hook = global.params.tracegc ? Id._d_arrayappendcTXTrace : Id._d_arrayappendcTX;
                if (!verifyHookExist(exp.loc, *sc, Id._d_arrayappendcTXImpl, "appending element to arrays", Id.object))
                    return setError();

                // Lower to object._d_arrayappendcTXImpl!(typeof(e1))._d_arrayappendcTX{,Trace}(e1, 1), e1[$-1]=e2
                Expression id = new IdentifierExp(exp.loc, Id.empty);
                id = new DotIdExp(exp.loc, id, Id.object);
                auto tiargs = new Objects();
                tiargs.push(exp.e1.type);
                id = new DotTemplateInstanceExp(exp.loc, id, Id._d_arrayappendcTXImpl, tiargs);
                id = new DotIdExp(exp.loc, id, hook);

                auto arguments = new Expressions();
                arguments.reserve(5);
                if (global.params.tracegc)
                {
                    auto funcname = (sc.callsc && sc.callsc.func) ? sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
                    arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
                    arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
                    arguments.push(new StringExp(exp.loc, funcname.toDString()));
                }

                Expression eValue1;
                Expression value1 = extractSideEffect(sc, "__appendtmp", eValue1, exp.e1);

                arguments.push(value1);
                arguments.push(new IntegerExp(exp.loc, 1, Type.tsize_t));

                Expression ce = new CallExp(exp.loc, id, arguments);

                Expression eValue2;
                Expression value2 = exp.e2;
                if (!value2.isVarExp() && !value2.isConst())
                {
                    /* Before the template hook, this check was performed in e2ir.d
                     * for expressions like `a ~= a[$-1]`. Here, $ will be modified
                     * by calling `_d_arrayappendcT`, so we need to save `a[$-1]` in
                     * a temporary variable.
                     */
                    value2 = extractSideEffect(sc, "__appendtmp", eValue2, value2, true);
                    exp.e2 = value2;

                    // `__appendtmp*` will be destroyed together with the array `exp.e1`.
                    auto vd = eValue2.isDeclarationExp().declaration.isVarDeclaration();
                    vd.storage_class |= STC.nodtor;
                    // Be more explicit that this "declaration" is local to the expression
                    vd.storage_class |= STC.exptemp;
                }

                auto ale = new ArrayLengthExp(exp.loc, value1);
                auto elem = new IndexExp(exp.loc, value1, new MinExp(exp.loc, ale, IntegerExp.literal!1));
                auto ae = new ConstructExp(exp.loc, elem, value2);

                auto e0 = Expression.combine(ce, ae).expressionSemantic(sc);
                e0 = Expression.combine(e0, value1);
                e0 = Expression.combine(eValue1, e0);

                e0 = Expression.combine(eValue2, e0);

                *output = e0.expressionSemantic(sc);
            }
        }

    }

    override void visit(AddExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("AddExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        /* ImportC: convert arrays to pointers, functions to pointers to functions
         */
        exp.e1 = exp.e1.arrayFuncConv(sc);
        exp.e2 = exp.e2.arrayFuncConv(sc);

        Type tb1 = exp.e1.type.toBasetype();
        Type tb2 = exp.e2.type.toBasetype();

        bool err = false;
        if (tb1.ty == Tdelegate || tb1.isPtrToFunction())
        {
            err |= exp.e1.checkArithmetic() || exp.e1.checkSharedAccess(sc);
        }
        if (tb2.ty == Tdelegate || tb2.isPtrToFunction())
        {
            err |= exp.e2.checkArithmetic() || exp.e2.checkSharedAccess(sc);
        }
        if (err)
            return setError();

        if (tb1.ty == Tpointer && exp.e2.type.isintegral() || tb2.ty == Tpointer && exp.e1.type.isintegral())
        {
            result = scaleFactor(exp, sc);
            return;
        }

        if (tb1.ty == Tpointer && tb2.ty == Tpointer)
        {
            result = exp.incompatibleTypes();
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }

        tb1 = exp.e1.type.toBasetype();
        if (!target.isVectorOpSupported(tb1, exp.op, tb2))
        {
            result = exp.incompatibleTypes();
            return;
        }
        if ((tb1.isreal() && exp.e2.type.isimaginary()) || (tb1.isimaginary() && exp.e2.type.isreal()))
        {
            switch (exp.type.toBasetype().ty)
            {
            case Tfloat32:
            case Timaginary32:
                exp.type = Type.tcomplex32;
                break;

            case Tfloat64:
            case Timaginary64:
                exp.type = Type.tcomplex64;
                break;

            case Tfloat80:
            case Timaginary80:
                exp.type = Type.tcomplex80;
                break;

            default:
                assert(0);
            }
        }
        result = exp;
    }

    override void visit(MinExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("MinExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        /* ImportC: convert arrays to pointers, functions to pointers to functions
         */
        exp.e1 = exp.e1.arrayFuncConv(sc);
        exp.e2 = exp.e2.arrayFuncConv(sc);

        Type t1 = exp.e1.type.toBasetype();
        Type t2 = exp.e2.type.toBasetype();

        bool err = false;
        if (t1.ty == Tdelegate || t1.isPtrToFunction())
        {
            err |= exp.e1.checkArithmetic() || exp.e1.checkSharedAccess(sc);
        }
        if (t2.ty == Tdelegate || t2.isPtrToFunction())
        {
            err |= exp.e2.checkArithmetic() || exp.e2.checkSharedAccess(sc);
        }
        if (err)
            return setError();

        if (t1.ty == Tpointer)
        {
            if (t2.ty == Tpointer)
            {
                // https://dlang.org/spec/expression.html#add_expressions
                // "If both operands are pointers, and the operator is -, the pointers are
                // subtracted and the result is divided by the size of the type pointed to
                // by the operands. It is an error if the pointers point to different types."
                Type p1 = t1.nextOf();
                Type p2 = t2.nextOf();

                if (!p1.equivalent(p2))
                {
                    // Deprecation to remain for at least a year, after which this should be
                    // changed to an error
                    // See https://github.com/dlang/dmd/pull/7332
                    deprecation(exp.loc,
                        "cannot subtract pointers to different types: `%s` and `%s`.",
                        t1.toChars(), t2.toChars());
                }

                // Need to divide the result by the stride
                // Replace (ptr - ptr) with (ptr - ptr) / stride
                long stride;

                // make sure pointer types are compatible
                if (Expression ex = typeCombine(exp, sc))
                {
                    result = ex;
                    return;
                }

                exp.type = Type.tptrdiff_t;
                stride = t2.nextOf().size();
                if (stride == 0)
                {
                    e = new IntegerExp(exp.loc, 0, Type.tptrdiff_t);
                }
                else if (stride == cast(long)SIZE_INVALID)
                    e = ErrorExp.get();
                else
                {
                    e = new DivExp(exp.loc, exp, new IntegerExp(Loc.initial, stride, Type.tptrdiff_t));
                    e.type = Type.tptrdiff_t;
                }
            }
            else if (t2.isintegral())
                e = scaleFactor(exp, sc);
            else
            {
                exp.error("can't subtract `%s` from pointer", t2.toChars());
                e = ErrorExp.get();
            }
            result = e;
            return;
        }
        if (t2.ty == Tpointer)
        {
            exp.type = exp.e2.type;
            exp.error("can't subtract pointer from `%s`", exp.e1.type.toChars());
            return setError();
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }

        t1 = exp.e1.type.toBasetype();
        t2 = exp.e2.type.toBasetype();
        if (!target.isVectorOpSupported(t1, exp.op, t2))
        {
            result = exp.incompatibleTypes();
            return;
        }
        if ((t1.isreal() && t2.isimaginary()) || (t1.isimaginary() && t2.isreal()))
        {
            switch (exp.type.ty)
            {
            case Tfloat32:
            case Timaginary32:
                exp.type = Type.tcomplex32;
                break;

            case Tfloat64:
            case Timaginary64:
                exp.type = Type.tcomplex64;
                break;

            case Tfloat80:
            case Timaginary80:
                exp.type = Type.tcomplex80;
                break;

            default:
                assert(0);
            }
        }
        result = exp;
        return;
    }

    override void visit(CatExp exp)
    {
        // https://dlang.org/spec/expression.html#cat_expressions
        //printf("CatExp.semantic() %s\n", toChars());
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        Type tb1 = exp.e1.type.toBasetype();
        Type tb2 = exp.e2.type.toBasetype();

        auto f1 = checkNonAssignmentArrayOp(exp.e1);
        auto f2 = checkNonAssignmentArrayOp(exp.e2);
        if (f1 || f2)
            return setError();

        Type tb1next = tb1.nextOf();
        Type tb2next = tb2.nextOf();

        // Check for: array ~ array
        if (tb1next && tb2next && (tb1next.implicitConvTo(tb2next) >= MATCH.constant || tb2next.implicitConvTo(tb1next) >= MATCH.constant || exp.e1.op == EXP.arrayLiteral && exp.e1.implicitConvTo(tb2) || exp.e2.op == EXP.arrayLiteral && exp.e2.implicitConvTo(tb1)))
        {
            /* https://issues.dlang.org/show_bug.cgi?id=9248
             * Here to avoid the case of:
             *    void*[] a = [cast(void*)1];
             *    void*[] b = [cast(void*)2];
             *    a ~ b;
             * becoming:
             *    a ~ [cast(void*)b];
             */

            /* https://issues.dlang.org/show_bug.cgi?id=14682
             * Also to avoid the case of:
             *    int[][] a;
             *    a ~ [];
             * becoming:
             *    a ~ cast(int[])[];
             */
            goto Lpeer;
        }

        // Check for: array ~ element
        if ((tb1.ty == Tsarray || tb1.ty == Tarray) && tb2.ty != Tvoid)
        {
            if (exp.e1.op == EXP.arrayLiteral)
            {
                exp.e2 = doCopyOrMove(sc, exp.e2);
                // https://issues.dlang.org/show_bug.cgi?id=14686
                // Postblit call appears in AST, and this is
                // finally translated  to an ArrayLiteralExp in below optimize().
            }
            else if (exp.e1.op == EXP.string_)
            {
                // No postblit call exists on character (integer) value.
            }
            else
            {
                if (exp.e2.checkPostblit(sc, tb2))
                    return setError();
                // Postblit call will be done in runtime helper function
            }

            if (exp.e1.op == EXP.arrayLiteral && exp.e1.implicitConvTo(tb2.arrayOf()))
            {
                exp.e1 = exp.e1.implicitCastTo(sc, tb2.arrayOf());
                exp.type = tb2.arrayOf();
                goto L2elem;
            }
            if (exp.e2.implicitConvTo(tb1next) >= MATCH.convert)
            {
                exp.e2 = exp.e2.implicitCastTo(sc, tb1next);
                exp.type = tb1next.arrayOf();
            L2elem:
                if (tb2.ty == Tarray || tb2.ty == Tsarray)
                {
                    // Make e2 into [e2]
                    exp.e2 = new ArrayLiteralExp(exp.e2.loc, exp.type, exp.e2);
                }
                else if (checkNewEscape(sc, exp.e2, false))
                    return setError();
                result = exp.optimize(WANTvalue);
                return;
            }
        }
        // Check for: element ~ array
        if ((tb2.ty == Tsarray || tb2.ty == Tarray) && tb1.ty != Tvoid)
        {
            if (exp.e2.op == EXP.arrayLiteral)
            {
                exp.e1 = doCopyOrMove(sc, exp.e1);
            }
            else if (exp.e2.op == EXP.string_)
            {
            }
            else
            {
                if (exp.e1.checkPostblit(sc, tb1))
                    return setError();
            }

            if (exp.e2.op == EXP.arrayLiteral && exp.e2.implicitConvTo(tb1.arrayOf()))
            {
                exp.e2 = exp.e2.implicitCastTo(sc, tb1.arrayOf());
                exp.type = tb1.arrayOf();
                goto L1elem;
            }
            if (exp.e1.implicitConvTo(tb2next) >= MATCH.convert)
            {
                exp.e1 = exp.e1.implicitCastTo(sc, tb2next);
                exp.type = tb2next.arrayOf();
            L1elem:
                if (tb1.ty == Tarray || tb1.ty == Tsarray)
                {
                    // Make e1 into [e1]
                    exp.e1 = new ArrayLiteralExp(exp.e1.loc, exp.type, exp.e1);
                }
                else if (checkNewEscape(sc, exp.e1, false))
                    return setError();
                result = exp.optimize(WANTvalue);
                return;
            }
        }

    Lpeer:
        if ((tb1.ty == Tsarray || tb1.ty == Tarray) && (tb2.ty == Tsarray || tb2.ty == Tarray) && (tb1next.mod || tb2next.mod) && (tb1next.mod != tb2next.mod))
        {
            Type t1 = tb1next.mutableOf().constOf().arrayOf();
            Type t2 = tb2next.mutableOf().constOf().arrayOf();
            if (exp.e1.op == EXP.string_ && !(cast(StringExp)exp.e1).committed)
                exp.e1.type = t1;
            else
                exp.e1 = exp.e1.castTo(sc, t1);
            if (exp.e2.op == EXP.string_ && !(cast(StringExp)exp.e2).committed)
                exp.e2.type = t2;
            else
                exp.e2 = exp.e2.castTo(sc, t2);
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }
        exp.type = exp.type.toHeadMutable();

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tsarray)
            exp.type = tb.nextOf().arrayOf();
        if (exp.type.ty == Tarray && tb1next && tb2next && tb1next.mod != tb2next.mod)
        {
            exp.type = exp.type.nextOf().toHeadMutable().arrayOf();
        }
        if (Type tbn = tb.nextOf())
        {
            if (exp.checkPostblit(sc, tbn))
                return setError();
        }
        Type t1 = exp.e1.type.toBasetype();
        Type t2 = exp.e2.type.toBasetype();
        if ((t1.ty == Tarray || t1.ty == Tsarray) &&
            (t2.ty == Tarray || t2.ty == Tsarray))
        {
            // Normalize to ArrayLiteralExp or StringExp as far as possible
            e = exp.optimize(WANTvalue);
        }
        else
        {
            //printf("(%s) ~ (%s)\n", e1.toChars(), e2.toChars());
            result = exp.incompatibleTypes();
            return;
        }

        result = e;
    }

    override void visit(MulExp exp)
    {
        version (none)
        {
            printf("MulExp::semantic() %s\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }

        if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
            return setError();

        if (exp.type.isfloating())
        {
            Type t1 = exp.e1.type;
            Type t2 = exp.e2.type;

            if (t1.isreal())
            {
                exp.type = t2;
            }
            else if (t2.isreal())
            {
                exp.type = t1;
            }
            else if (t1.isimaginary())
            {
                if (t2.isimaginary())
                {
                    switch (t1.toBasetype().ty)
                    {
                    case Timaginary32:
                        exp.type = Type.tfloat32;
                        break;

                    case Timaginary64:
                        exp.type = Type.tfloat64;
                        break;

                    case Timaginary80:
                        exp.type = Type.tfloat80;
                        break;

                    default:
                        assert(0);
                    }

                    // iy * iv = -yv
                    exp.e1.type = exp.type;
                    exp.e2.type = exp.type;
                    e = new NegExp(exp.loc, exp);
                    e = e.expressionSemantic(sc);
                    result = e;
                    return;
                }
                else
                    exp.type = t2; // t2 is complex
            }
            else if (t2.isimaginary())
            {
                exp.type = t1; // t1 is complex
            }
        }
        else if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }
        result = exp;
    }

    override void visit(DivExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }

        if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
            return setError();

        if (exp.type.isfloating())
        {
            Type t1 = exp.e1.type;
            Type t2 = exp.e2.type;

            if (t1.isreal())
            {
                exp.type = t2;
                if (t2.isimaginary())
                {
                    // x/iv = i(-x/v)
                    exp.e2.type = t1;
                    e = new NegExp(exp.loc, exp);
                    e = e.expressionSemantic(sc);
                    result = e;
                    return;
                }
            }
            else if (t2.isreal())
            {
                exp.type = t1;
            }
            else if (t1.isimaginary())
            {
                if (t2.isimaginary())
                {
                    switch (t1.toBasetype().ty)
                    {
                    case Timaginary32:
                        exp.type = Type.tfloat32;
                        break;

                    case Timaginary64:
                        exp.type = Type.tfloat64;
                        break;

                    case Timaginary80:
                        exp.type = Type.tfloat80;
                        break;

                    default:
                        assert(0);
                    }
                }
                else
                    exp.type = t2; // t2 is complex
            }
            else if (t2.isimaginary())
            {
                exp.type = t1; // t1 is complex
            }
        }
        else if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }
        result = exp;
    }

    override void visit(ModExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }
        if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }

        if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
            return setError();

        if (exp.type.isfloating())
        {
            exp.type = exp.e1.type;
            if (exp.e2.type.iscomplex())
            {
                exp.error("cannot perform modulo complex arithmetic");
                return setError();
            }
        }
        result = exp;
    }

    override void visit(PowExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        //printf("PowExp::semantic() %s\n", toChars());
        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }

        if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
            return setError();

        if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }

        // First, attempt to fold the expression.
        e = exp.optimize(WANTvalue);
        if (e.op != EXP.pow)
        {
            e = e.expressionSemantic(sc);
            result = e;
            return;
        }

        Module mmath = loadStdMath();
        if (!mmath)
        {
            e.error("`%s` requires `std.math` for `^^` operators", e.toChars());
            return setError();
        }
        e = new ScopeExp(exp.loc, mmath);

        if (exp.e2.op == EXP.float64 && exp.e2.toReal() == CTFloat.half)
        {
            // Replace e1 ^^ 0.5 with .std.math.sqrt(e1)
            e = new CallExp(exp.loc, new DotIdExp(exp.loc, e, Id._sqrt), exp.e1);
        }
        else
        {
            // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
            e = new CallExp(exp.loc, new DotIdExp(exp.loc, e, Id._pow), exp.e1, exp.e2);
        }
        e = e.expressionSemantic(sc);
        result = e;
        return;
    }

    override void visit(ShlExp exp)
    {
        //printf("ShlExp::semantic(), type = %p\n", type);
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
            return setError();

        if (!target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }
        exp.e1 = integralPromotions(exp.e1, sc);
        if (exp.e2.type.toBasetype().ty != Tvector)
            exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt);

        exp.type = exp.e1.type;
        result = exp;
    }

    override void visit(ShrExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
            return setError();

        if (!target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }
        exp.e1 = integralPromotions(exp.e1, sc);
        if (exp.e2.type.toBasetype().ty != Tvector)
            exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt);

        exp.type = exp.e1.type;
        result = exp;
    }

    override void visit(UshrExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
            return setError();

        if (!target.isVectorOpSupported(exp.e1.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }
        exp.e1 = integralPromotions(exp.e1, sc);
        if (exp.e2.type.toBasetype().ty != Tvector)
            exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt);

        exp.type = exp.e1.type;
        result = exp;
    }

    override void visit(AndExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.e1.type.toBasetype().ty == Tbool && exp.e2.type.toBasetype().ty == Tbool)
        {
            exp.type = exp.e1.type;
            result = exp;
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }
        if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }
        if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
            return setError();

        result = exp;
    }

    override void visit(OrExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.e1.type.toBasetype().ty == Tbool && exp.e2.type.toBasetype().ty == Tbool)
        {
            exp.type = exp.e1.type;
            result = exp;
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }
        if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }
        if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
            return setError();

        result = exp;
    }

    override void visit(XorExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        if (exp.e1.type.toBasetype().ty == Tbool && exp.e2.type.toBasetype().ty == Tbool)
        {
            exp.type = exp.e1.type;
            result = exp;
            return;
        }

        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        Type tb = exp.type.toBasetype();
        if (tb.ty == Tarray || tb.ty == Tsarray)
        {
            if (!isArrayOpValid(exp))
            {
                result = arrayOpInvalidError(exp);
                return;
            }
            result = exp;
            return;
        }
        if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
        {
            result = exp.incompatibleTypes();
            return;
        }
        if (exp.checkIntegralBin() || exp.checkSharedAccessBin(sc))
            return setError();

        result = exp;
    }

    override void visit(LogicalExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("LogicalExp::semantic() %s\n", exp.toChars());
        }

        if (exp.type)
        {
            result = exp;
            return;
        }

        exp.setNoderefOperands();

        Expression e1x = exp.e1.expressionSemantic(sc);

        // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
        if (e1x.op == EXP.type)
            e1x = resolveAliasThis(sc, e1x);

        e1x = resolveProperties(sc, e1x);
        e1x = e1x.toBoolean(sc);

        if (sc.flags & SCOPE.condition)
        {
            /* If in static if, don't evaluate e2 if we don't have to.
             */
            e1x = e1x.optimize(WANTvalue);
            if (e1x.toBool().hasValue(exp.op == EXP.orOr))
            {
                if (sc.flags & SCOPE.Cfile)
                    result = new IntegerExp(exp.op == EXP.orOr);
                else
                    result = IntegerExp.createBool(exp.op == EXP.orOr);
                return;
            }
        }

        CtorFlow ctorflow = sc.ctorflow.clone();
        Expression e2x = exp.e2.expressionSemantic(sc);
        sc.merge(exp.loc, ctorflow);
        ctorflow.freeFieldinit();

        // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
        if (e2x.op == EXP.type)
            e2x = resolveAliasThis(sc, e2x);

        e2x = resolveProperties(sc, e2x);

        auto f1 = checkNonAssignmentArrayOp(e1x);
        auto f2 = checkNonAssignmentArrayOp(e2x);
        if (f1 || f2)
            return setError();

        // Unless the right operand is 'void', the expression is converted to 'bool'.
        if (e2x.type.ty != Tvoid)
            e2x = e2x.toBoolean(sc);

        if (e2x.op == EXP.type || e2x.op == EXP.scope_)
        {
            exp.error("`%s` is not an expression", exp.e2.toChars());
            return setError();
        }
        if (e1x.op == EXP.error || e1x.type.ty == Tnoreturn)
        {
            result = e1x;
            return;
        }
        if (e2x.op == EXP.error)
        {
            result = e2x;
            return;
        }

        // The result type is 'bool', unless the right operand has type 'void'.
        if (e2x.type.ty == Tvoid)
            exp.type = Type.tvoid;
        else
            exp.type = (sc && sc.flags & SCOPE.Cfile) ? Type.tint32 : Type.tbool;

        exp.e1 = e1x;
        exp.e2 = e2x;
        result = exp;
    }


    override void visit(CmpExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("CmpExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        exp.setNoderefOperands();

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Type t1 = exp.e1.type.toBasetype();
        Type t2 = exp.e2.type.toBasetype();
        if (t1.ty == Tclass && exp.e2.op == EXP.null_ || t2.ty == Tclass && exp.e1.op == EXP.null_)
        {
            exp.error("do not use `null` when comparing class types");
            return setError();
        }


        EXP cmpop = exp.op;
        if (auto e = exp.op_overload(sc, &cmpop))
        {
            if (!e.type.isscalar() && e.type.equals(exp.e1.type))
            {
                exp.error("recursive `opCmp` expansion");
                return setError();
            }
            if (e.op == EXP.call)
            {

                if (t1.ty == Tclass && t2.ty == Tclass)
                {
                    // Lower to object.__cmp(e1, e2)
                    Expression cl = new IdentifierExp(exp.loc, Id.empty);
                    cl = new DotIdExp(exp.loc, cl, Id.object);
                    cl = new DotIdExp(exp.loc, cl, Id.__cmp);
                    cl = cl.expressionSemantic(sc);

                    auto arguments = new Expressions();
                    // Check if op_overload found a better match by calling e2.opCmp(e1)
                    // If the operands were swapped, then the result must be reversed
                    // e1.opCmp(e2) == -e2.opCmp(e1)
                    // cmpop takes care of this
                    if (exp.op == cmpop)
                    {
                        arguments.push(exp.e1);
                        arguments.push(exp.e2);
                    }
                    else
                    {
                        // Use better match found by op_overload
                        arguments.push(exp.e2);
                        arguments.push(exp.e1);
                    }

                    cl = new CallExp(exp.loc, cl, arguments);
                    cl = new CmpExp(cmpop, exp.loc, cl, new IntegerExp(0));
                    result = cl.expressionSemantic(sc);
                    return;
                }

                e = new CmpExp(cmpop, exp.loc, e, IntegerExp.literal!0);
                e = e.expressionSemantic(sc);
            }
            result = e;
            return;
        }


        if (Expression ex = typeCombine(exp, sc))
        {
            result = ex;
            return;
        }

        auto f1 = checkNonAssignmentArrayOp(exp.e1);
        auto f2 = checkNonAssignmentArrayOp(exp.e2);
        if (f1 || f2)
            return setError();

        exp.type = (sc && sc.flags & SCOPE.Cfile) ? Type.tint32 : Type.tbool;

        // Special handling for array comparisons
        Expression arrayLowering = null;
        t1 = exp.e1.type.toBasetype();
        t2 = exp.e2.type.toBasetype();
        if ((t1.ty == Tarray || t1.ty == Tsarray || t1.ty == Tpointer) && (t2.ty == Tarray || t2.ty == Tsarray || t2.ty == Tpointer))
        {
            Type t1next = t1.nextOf();
            Type t2next = t2.nextOf();
            if (t1next.implicitConvTo(t2next) < MATCH.constant && t2next.implicitConvTo(t1next) < MATCH.constant && (t1next.ty != Tvoid && t2next.ty != Tvoid))
            {
                exp.error("array comparison type mismatch, `%s` vs `%s`", t1next.toChars(), t2next.toChars());
                return setError();
            }
            if ((t1.ty == Tarray || t1.ty == Tsarray) && (t2.ty == Tarray || t2.ty == Tsarray))
            {
                if (!verifyHookExist(exp.loc, *sc, Id.__cmp, "comparing arrays"))
                    return setError();

                // Lower to object.__cmp(e1, e2)
                Expression al = new IdentifierExp(exp.loc, Id.empty);
                al = new DotIdExp(exp.loc, al, Id.object);
                al = new DotIdExp(exp.loc, al, Id.__cmp);
                al = al.expressionSemantic(sc);

                auto arguments = new Expressions(2);
                (*arguments)[0] = exp.e1;
                (*arguments)[1] = exp.e2;

                al = new CallExp(exp.loc, al, arguments);
                al = new CmpExp(exp.op, exp.loc, al, IntegerExp.literal!0);

                arrayLowering = al;
            }
        }
        else if (t1.ty == Tstruct || t2.ty == Tstruct || (t1.ty == Tclass && t2.ty == Tclass))
        {
            if (t2.ty == Tstruct)
                exp.error("need member function `opCmp()` for %s `%s` to compare", t2.toDsymbol(sc).kind(), t2.toChars());
            else
                exp.error("need member function `opCmp()` for %s `%s` to compare", t1.toDsymbol(sc).kind(), t1.toChars());
            return setError();
        }
        else if (t1.iscomplex() || t2.iscomplex())
        {
            exp.error("compare not defined for complex operands");
            return setError();
        }
        else if (t1.ty == Taarray || t2.ty == Taarray)
        {
            exp.error("`%s` is not defined for associative arrays", EXPtoString(exp.op).ptr);
            return setError();
        }
        else if (!target.isVectorOpSupported(t1, exp.op, t2))
        {
            result = exp.incompatibleTypes();
            return;
        }
        else
        {
            bool r1 = exp.e1.checkValue() || exp.e1.checkSharedAccess(sc);
            bool r2 = exp.e2.checkValue() || exp.e2.checkSharedAccess(sc);
            if (r1 || r2)
                return setError();
        }

        //printf("CmpExp: %s, type = %s\n", e.toChars(), e.type.toChars());
        if (arrayLowering)
        {
            arrayLowering = arrayLowering.expressionSemantic(sc);
            result = arrayLowering;
            return;
        }

        if (t1.isTypeVector())
            exp.type = t1;

        result = exp;
        return;
    }

    override void visit(InExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (Expression ex = binSemanticProp(exp, sc))
        {
            result = ex;
            return;
        }
        Expression e = exp.op_overload(sc);
        if (e)
        {
            result = e;
            return;
        }

        Type t2b = exp.e2.type.toBasetype();
        switch (t2b.ty)
        {
        case Taarray:
            {
                TypeAArray ta = cast(TypeAArray)t2b;

                // Special handling for array keys
                if (!arrayTypeCompatibleWithoutCasting(exp.e1.type, ta.index))
                {
                    // Convert key to type of key
                    exp.e1 = exp.e1.implicitCastTo(sc, ta.index);
                }

                semanticTypeInfo(sc, ta.index);

                // Return type is pointer to value
                exp.type = ta.nextOf().pointerTo();
                break;
            }

        case Terror:
            return setError();

        case Tarray, Tsarray:
            result = exp.incompatibleTypes();
            exp.errorSupplemental("`in` is only allowed on associative arrays");
            const(char)* slice = (t2b.ty == Tsarray) ? "[]" : "";
            exp.errorSupplemental("perhaps use `std.algorithm.find(%s, %s%s)` instead",
                exp.e1.toChars(), exp.e2.toChars(), slice);
            return;

        default:
            result = exp.incompatibleTypes();
            return;
        }
        result = exp;
    }

    override void visit(RemoveExp e)
    {
        if (Expression ex = binSemantic(e, sc))
        {
            result = ex;
            return;
        }
        result = e;
    }

    override void visit(EqualExp exp)
    {
        //printf("EqualExp::semantic('%s')\n", exp.toChars());
        if (exp.type)
        {
            result = exp;
            return;
        }

        exp.setNoderefOperands();

        if (auto e = binSemanticProp(exp, sc))
        {
            result = e;
            return;
        }
        if (exp.e1.op == EXP.type || exp.e2.op == EXP.type)
        {
            /* https://issues.dlang.org/show_bug.cgi?id=12520
             * empty tuples are represented as types so special cases are added
             * so that they can be compared for equality with tuples of values.
             */
            static auto extractTypeTupAndExpTup(Expression e)
            {
                static struct Result { bool ttEmpty; bool te; }
                auto tt = e.op == EXP.type ? e.isTypeExp().type.isTypeTuple() : null;
                return Result(tt && (!tt.arguments || !tt.arguments.dim), e.isTupleExp() !is null);
            }
            auto tups1 = extractTypeTupAndExpTup(exp.e1);
            auto tups2 = extractTypeTupAndExpTup(exp.e2);
            // AliasSeq!() == AliasSeq!(<at least a value>)
            if (tups1.ttEmpty && tups2.te)
            {
                result = IntegerExp.createBool(exp.op != EXP.equal);
                return;
            }
            // AliasSeq!(<at least a value>) == AliasSeq!()
            else if (tups1.te && tups2.ttEmpty)
            {
                result = IntegerExp.createBool(exp.op != EXP.equal);
                return;
            }
            // AliasSeq!() == AliasSeq!()
            else if (tups1.ttEmpty && tups2.ttEmpty)
            {
                result = IntegerExp.createBool(exp.op == EXP.equal);
                return;
            }
            // otherwise, two types are really not comparable
            result = exp.incompatibleTypes();
            return;
        }

        {
            auto t1 = exp.e1.type;
            auto t2 = exp.e2.type;
            if (t1.ty == Tenum && t2.ty == Tenum && !t1.equivalent(t2))
                exp.error("comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`",
                    t1.toChars(), t2.toChars());
        }

        /* Before checking for operator overloading, check to see if we're
         * comparing the addresses of two statics. If so, we can just see
         * if they are the same symbol.
         */
        if (exp.e1.op == EXP.address && exp.e2.op == EXP.address)
        {
            AddrExp ae1 = cast(AddrExp)exp.e1;
            AddrExp ae2 = cast(AddrExp)exp.e2;
            if (ae1.e1.op == EXP.variable && ae2.e1.op == EXP.variable)
            {
                VarExp ve1 = cast(VarExp)ae1.e1;
                VarExp ve2 = cast(VarExp)ae2.e1;
                if (ve1.var == ve2.var)
                {
                    // They are the same, result is 'true' for ==, 'false' for !=
                    result = IntegerExp.createBool(exp.op == EXP.equal);
                    return;
                }
            }
        }

        Type t1 = exp.e1.type.toBasetype();
        Type t2 = exp.e2.type.toBasetype();

        // Indicates whether the comparison of the 2 specified array types
        // requires an object.__equals() lowering.
        static bool needsDirectEq(Type t1, Type t2, Scope* sc)
        {
            Type t1n = t1.nextOf().toBasetype();
            Type t2n = t2.nextOf().toBasetype();
            if ((t1n.ty.isSomeChar && t2n.ty.isSomeChar) ||
                (t1n.ty == Tvoid || t2n.ty == Tvoid))
            {
                return false;
            }
            if (t1n.constOf() != t2n.constOf())
                return true;

            Type t = t1n;
            while (t.toBasetype().nextOf())
                t = t.nextOf().toBasetype();
            if (auto ts = t.isTypeStruct())
            {
                // semanticTypeInfo() makes sure hasIdentityEquals has been computed
                if (global.params.useTypeInfo && Type.dtypeinfo)
                    semanticTypeInfo(sc, ts);

                return ts.sym.hasIdentityEquals; // has custom opEquals
            }

            return false;
        }

        if (auto e = exp.op_overload(sc))
        {
            result = e;
            return;
        }


        const isArrayComparison = (t1.ty == Tarray || t1.ty == Tsarray) &&
                                  (t2.ty == Tarray || t2.ty == Tsarray);
        const needsArrayLowering = isArrayComparison && needsDirectEq(t1, t2, sc);

        if (!needsArrayLowering)
        {
            if (auto e = typeCombine(exp, sc))
            {
                result = e;
                return;
            }
        }

        auto f1 = checkNonAssignmentArrayOp(exp.e1);
        auto f2 = checkNonAssignmentArrayOp(exp.e2);
        if (f1 || f2)
            return setError();

        exp.type = (sc && sc.flags & SCOPE.Cfile) ? Type.tint32 : Type.tbool;

        if (!isArrayComparison)
        {
            if (exp.e1.type != exp.e2.type && exp.e1.type.isfloating() && exp.e2.type.isfloating())
            {
                // Cast both to complex
                exp.e1 = exp.e1.castTo(sc, Type.tcomplex80);
                exp.e2 = exp.e2.castTo(sc, Type.tcomplex80);
            }
        }

        // lower some array comparisons to object.__equals(e1, e2)
        if (needsArrayLowering || (t1.ty == Tarray && t2.ty == Tarray))
        {
            //printf("Lowering to __equals %s %s\n", exp.e1.toChars(), exp.e2.toChars());

            // https://issues.dlang.org/show_bug.cgi?id=22390
            // Equality comparison between array of noreturns simply lowers to length equality comparison
            if (t1.nextOf.isTypeNoreturn() && t2.nextOf.isTypeNoreturn())
            {
                Expression exp_l1 = new DotIdExp(exp.e1.loc, exp.e1, Id.length);
                Expression exp_l2 = new DotIdExp(exp.e2.loc, exp.e2, Id.length);
                auto e = new EqualExp(EXP.equal, exp.loc, exp_l1, exp_l2);
                result = e.expressionSemantic(sc);
                return;
            }

            if (!verifyHookExist(exp.loc, *sc, Id.__equals, "equal checks on arrays"))
                return setError();

            Expression __equals = new IdentifierExp(exp.loc, Id.empty);
            Identifier id = Identifier.idPool("__equals");
            __equals = new DotIdExp(exp.loc, __equals, Id.object);
            __equals = new DotIdExp(exp.loc, __equals, id);

            auto arguments = new Expressions(2);
            (*arguments)[0] = exp.e1;
            (*arguments)[1] = exp.e2;

            __equals = new CallExp(exp.loc, __equals, arguments);
            if (exp.op == EXP.notEqual)
            {
                __equals = new NotExp(exp.loc, __equals);
            }
            __equals = __equals.trySemantic(sc); // for better error message
            if (!__equals)
            {
                exp.error("incompatible types for array comparison: `%s` and `%s`",
                          exp.e1.type.toChars(), exp.e2.type.toChars());
                __equals = ErrorExp.get();
            }

            result = __equals;
            return;
        }

        if (exp.e1.type.toBasetype().ty == Taarray)
            semanticTypeInfo(sc, exp.e1.type.toBasetype());


        if (!target.isVectorOpSupported(t1, exp.op, t2))
        {
            result = exp.incompatibleTypes();
            return;
        }

        if (t1.isTypeVector())
            exp.type = t1;

        result = exp;
    }

    override void visit(IdentityExp exp)
    {
        if (exp.type)
        {
            result = exp;
            return;
        }

        exp.setNoderefOperands();

        if (auto e = binSemanticProp(exp, sc))
        {
            result = e;
            return;
        }

        if (auto e = typeCombine(exp, sc))
        {
            result = e;
            return;
        }

        auto f1 = checkNonAssignmentArrayOp(exp.e1);
        auto f2 = checkNonAssignmentArrayOp(exp.e2);
        if (f1 || f2)
            return setError();

        if (exp.e1.op == EXP.type || exp.e2.op == EXP.type)
        {
            result = exp.incompatibleTypes();
            return;
        }

        exp.type = Type.tbool;

        if (exp.e1.type != exp.e2.type && exp.e1.type.isfloating() && exp.e2.type.isfloating())
        {
            // Cast both to complex
            exp.e1 = exp.e1.castTo(sc, Type.tcomplex80);
            exp.e2 = exp.e2.castTo(sc, Type.tcomplex80);
        }

        auto tb1 = exp.e1.type.toBasetype();
        auto tb2 = exp.e2.type.toBasetype();
        if (!target.isVectorOpSupported(tb1, exp.op, tb2))
        {
            result = exp.incompatibleTypes();
            return;
        }

        if (exp.e1.op == EXP.call)
            exp.e1 = (cast(CallExp)exp.e1).addDtorHook(sc);
        if (exp.e2.op == EXP.call)
            exp.e2 = (cast(CallExp)exp.e2).addDtorHook(sc);

        if (exp.e1.type.toBasetype().ty == Tsarray ||
            exp.e2.type.toBasetype().ty == Tsarray)
            exp.deprecation("identity comparison of static arrays "
                ~ "implicitly coerces them to slices, "
                ~ "which are compared by reference");

        result = exp;
    }

    override void visit(CondExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("CondExp::semantic('%s')\n", exp.toChars());
        }
        if (exp.type)
        {
            result = exp;
            return;
        }

        if (auto die = exp.econd.isDotIdExp())
            die.noderef = true;

        Expression ec = exp.econd.expressionSemantic(sc);
        ec = resolveProperties(sc, ec);
        ec = ec.toBoolean(sc);

        CtorFlow ctorflow_root = sc.ctorflow.clone();
        Expression e1x = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
        e1x = resolveProperties(sc, e1x);

        CtorFlow ctorflow1 = sc.ctorflow;
        sc.ctorflow = ctorflow_root;
        Expression e2x = exp.e2.expressionSemantic(sc).arrayFuncConv(sc);
        e2x = resolveProperties(sc, e2x);

        sc.merge(exp.loc, ctorflow1);
        ctorflow1.freeFieldinit();

        if (ec.op == EXP.error)
        {
            result = ec;
            return;
        }
        if (ec.type == Type.terror)
            return setError();
        exp.econd = ec;

        if (e1x.op == EXP.error)
        {
            result = e1x;
            return;
        }
        if (e1x.type == Type.terror)
            return setError();
        exp.e1 = e1x;

        if (e2x.op == EXP.error)
        {
            result = e2x;
            return;
        }
        if (e2x.type == Type.terror)
            return setError();
        exp.e2 = e2x;

        auto f0 = checkNonAssignmentArrayOp(exp.econd);
        auto f1 = checkNonAssignmentArrayOp(exp.e1);
        auto f2 = checkNonAssignmentArrayOp(exp.e2);
        if (f0 || f1 || f2)
            return setError();

        Type t1 = exp.e1.type;
        Type t2 = exp.e2.type;
        if (t1.ty == Tnoreturn)
        {
            exp.type = t2;
        }
        else if (t2.ty == Tnoreturn)
        {
            exp.type = t1;
        }
        // If either operand is void the result is void, we have to cast both
        // the expression to void so that we explicitly discard the expression
        // value if any
        // https://issues.dlang.org/show_bug.cgi?id=16598
        else if (t1.ty == Tvoid || t2.ty == Tvoid)
        {
            exp.type = Type.tvoid;
            exp.e1 = exp.e1.castTo(sc, exp.type);
            exp.e2 = exp.e2.castTo(sc, exp.type);
        }
        else if (t1 == t2)
            exp.type = t1;
        else
        {
            if (Expression ex = typeCombine(exp, sc))
            {
                result = ex;
                return;
            }

            switch (exp.e1.type.toBasetype().ty)
            {
            case Tcomplex32:
            case Tcomplex64:
            case Tcomplex80:
                exp.e2 = exp.e2.castTo(sc, exp.e1.type);
                break;
            default:
                break;
            }
            switch (exp.e2.type.toBasetype().ty)
            {
            case Tcomplex32:
            case Tcomplex64:
            case Tcomplex80:
                exp.e1 = exp.e1.castTo(sc, exp.e2.type);
                break;
            default:
                break;
            }
            if (exp.type.toBasetype().ty == Tarray)
            {
                exp.e1 = exp.e1.castTo(sc, exp.type);
                exp.e2 = exp.e2.castTo(sc, exp.type);
            }
        }
        exp.type = exp.type.merge2();
        version (none)
        {
            printf("res: %s\n", exp.type.toChars());
            printf("e1 : %s\n", exp.e1.type.toChars());
            printf("e2 : %s\n", exp.e2.type.toChars());
        }

        /* https://issues.dlang.org/show_bug.cgi?id=14696
         * If either e1 or e2 contain temporaries which need dtor,
         * make them conditional.
         * Rewrite:
         *      cond ? (__tmp1 = ..., __tmp1) : (__tmp2 = ..., __tmp2)
         * to:
         *      (auto __cond = cond) ? (... __tmp1) : (... __tmp2)
         * and replace edtors of __tmp1 and __tmp2 with:
         *      __tmp1.edtor --> __cond && __tmp1.dtor()
         *      __tmp2.edtor --> __cond || __tmp2.dtor()
         */
        exp.hookDtors(sc);

        result = exp;
    }

    override void visit(GenericExp exp)
    {
        static if (LOGSEMANTIC)
        {
            printf("GenericExp::semantic('%s')\n", exp.toChars());
        }
        // C11 6.5.1.1 Generic Selection

        auto ec = exp.cntlExp.expressionSemantic(sc).arrayFuncConv(sc);
        bool errors = ec.isErrorExp() !is null;
        auto tc = ec.type;

        auto types = (*exp.types)[];
        foreach (i, ref t; types)
        {
            if (!t)
                continue;       // `default:` case
            t = t.typeSemantic(ec.loc, sc);
            if (t.isTypeError())
            {
                errors = true;
                continue;
            }

            /* C11 6.5.1-2 duplicate check
             */
            /* C11 distinguishes int, long, and long long. But D doesn't, so depending on the
             * C target, a long may have the same type as `int` in the D type system.
             * So, skip checks when this may be the case. Later pick the first match
             */
            if (
                (t.ty == Tint32 || t.ty == Tuns32) && target.c.longsize == 4 ||
                (t.ty == Tint64 || t.ty == Tuns64) && target.c.longsize == 8 ||
                (t.ty == Tfloat64 || t.ty == Timaginary64 || t.ty == Tcomplex64) && target.c.long_doublesize == 8
               )
                continue;

            foreach (t2; types[0 .. i])
            {
                if (t2 && t2.equals(t))
                {
                    error(ec.loc, "generic association type `%s` can only appear once", t.toChars());
                    errors = true;
                    break;
                }
            }
        }

        auto exps = (*exp.exps)[];
        foreach (ref e; exps)
        {
            e = e.expressionSemantic(sc);
            if (e.isErrorExp())
                errors = true;
        }

        if (errors)
            return setError();

        enum size_t None = ~0;
        size_t imatch = None;
        size_t idefault = None;
        foreach (const i, t; types)
        {
            if (t)
            {
                /* if tc is compatible with t, it's a match
                 * C11 6.2.7 defines a compatible type as being the same type, including qualifiers
                 */
                if (tc.equals(t))
                {
                    assert(imatch == None);
                    imatch = i;
                    break;              // pick first match
                }
            }
            else
                idefault = i;  // multiple defaults are not allowed, and are caught by cparse
        }

        if (imatch == None)
            imatch = idefault;
        if (imatch == None)
        {
            error(exp.loc, "no compatible generic association type for controlling expression type `%s`", tc.toChars());
            return setError();
        }

        result = exps[imatch];
    }

    override void visit(FileInitExp e)
    {
        //printf("FileInitExp::semantic()\n");
        e.type = Type.tstring;
        result = e;
    }

    override void visit(LineInitExp e)
    {
        e.type = Type.tint32;
        result = e;
    }

    override void visit(ModuleInitExp e)
    {
        //printf("ModuleInitExp::semantic()\n");
        e.type = Type.tstring;
        result = e;
    }

    override void visit(FuncInitExp e)
    {
        //printf("FuncInitExp::semantic()\n");
        e.type = Type.tstring;
        if (sc.func)
        {
            result = e.resolveLoc(Loc.initial, sc);
            return;
        }
        result = e;
    }

    override void visit(PrettyFuncInitExp e)
    {
        //printf("PrettyFuncInitExp::semantic()\n");
        e.type = Type.tstring;
        if (sc.func)
        {
            result = e.resolveLoc(Loc.initial, sc);
            return;
        }

        result = e;
    }
}

/**********************************
 * Try to run semantic routines.
 * If they fail, return NULL.
 */
Expression trySemantic(Expression exp, Scope* sc)
{
    //printf("+trySemantic(%s)\n", exp.toChars());
    uint errors = global.startGagging();
    Expression e = expressionSemantic(exp, sc);
    if (global.endGagging(errors))
    {
        e = null;
    }
    //printf("-trySemantic(%s)\n", exp.toChars());
    return e;
}

/**************************
 * Helper function for easy error propagation.
 * If error occurs, returns ErrorExp. Otherwise returns NULL.
 */
Expression unaSemantic(UnaExp e, Scope* sc)
{
    static if (LOGSEMANTIC)
    {
        printf("UnaExp::semantic('%s')\n", e.toChars());
    }
    Expression e1x = e.e1.expressionSemantic(sc);
    if (e1x.op == EXP.error)
        return e1x;
    e.e1 = e1x;
    return null;
}

/**************************
 * Helper function for easy error propagation.
 * If error occurs, returns ErrorExp. Otherwise returns NULL.
 */
Expression binSemantic(BinExp e, Scope* sc)
{
    static if (LOGSEMANTIC)
    {
        printf("BinExp::semantic('%s')\n", e.toChars());
    }
    Expression e1x = e.e1.expressionSemantic(sc);
    Expression e2x = e.e2.expressionSemantic(sc);

    // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
    if (e1x.op == EXP.type)
        e1x = resolveAliasThis(sc, e1x);
    if (e2x.op == EXP.type)
        e2x = resolveAliasThis(sc, e2x);

    if (e1x.op == EXP.error)
        return e1x;
    if (e2x.op == EXP.error)
        return e2x;
    e.e1 = e1x;
    e.e2 = e2x;
    return null;
}

Expression binSemanticProp(BinExp e, Scope* sc)
{
    if (Expression ex = binSemantic(e, sc))
        return ex;
    Expression e1x = resolveProperties(sc, e.e1);
    Expression e2x = resolveProperties(sc, e.e2);
    if (e1x.op == EXP.error)
        return e1x;
    if (e2x.op == EXP.error)
        return e2x;
    e.e1 = e1x;
    e.e2 = e2x;
    return null;
}

// entrypoint for semantic ExpressionSemanticVisitor
extern (C++) Expression expressionSemantic(Expression e, Scope* sc)
{
    scope v = new ExpressionSemanticVisitor(sc);
    e.accept(v);
    return v.result;
}

Expression semanticX(DotIdExp exp, Scope* sc)
{
    //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars());
    if (Expression ex = unaSemantic(exp, sc))
        return ex;

    if (!(sc.flags & SCOPE.Cfile) && exp.ident == Id._mangleof)
    {
        // symbol.mangleof

        // return mangleof as an Expression
        static Expression dotMangleof(const ref Loc loc, Scope* sc, Dsymbol ds)
        {
            assert(ds);
            if (auto f = ds.isFuncDeclaration())
            {
                if (f.checkForwardRef(loc))
                    return ErrorExp.get();

                if (f.purityInprocess || f.safetyInprocess || f.nothrowInprocess || f.nogcInprocess)
                {
                    f.error(loc, "cannot retrieve its `.mangleof` while inferring attributes");
                    return ErrorExp.get();
                }
            }
            OutBuffer buf;
            mangleToBuffer(ds, &buf);
            Expression e = new StringExp(loc, buf.extractSlice());
            return e.expressionSemantic(sc);
        }

        Dsymbol ds;
        switch (exp.e1.op)
        {
            case EXP.scope_:      return dotMangleof(exp.loc, sc, exp.e1.isScopeExp().sds);
            case EXP.variable:    return dotMangleof(exp.loc, sc, exp.e1.isVarExp().var);
            case EXP.dotVariable: return dotMangleof(exp.loc, sc, exp.e1.isDotVarExp().var);
            case EXP.overloadSet: return dotMangleof(exp.loc, sc, exp.e1.isOverExp().vars);
            case EXP.template_:
            {
                TemplateExp te = exp.e1.isTemplateExp();
                return dotMangleof(exp.loc, sc, ds = te.fd ? te.fd.isDsymbol() : te.td);
            }

            default:
                break;
        }
    }

    if (exp.e1.isVarExp() && exp.e1.type.toBasetype().isTypeSArray() && exp.ident == Id.length)
    {
        // bypass checkPurity
        return exp.e1.type.dotExp(sc, exp.e1, exp.ident, exp.noderef ? DotExpFlag.noDeref : 0);
    }

    if (!exp.e1.isDotExp())
    {
        exp.e1 = resolvePropertiesX(sc, exp.e1);
    }

    if (auto te = exp.e1.isTupleExp())
    {
        if (exp.ident == Id.offsetof)
        {
            /* 'distribute' the .offsetof to each of the tuple elements.
             */
            auto exps = new Expressions(te.exps.dim);
            foreach (i, e; (*te.exps)[])
            {
                (*exps)[i] = new DotIdExp(e.loc, e, Id.offsetof);
            }
            // Don't evaluate te.e0 in runtime
            Expression e = new TupleExp(exp.loc, null, exps);
            e = e.expressionSemantic(sc);
            return e;
        }
        if (exp.ident == Id.length)
        {
            // Don't evaluate te.e0 in runtime
            return new IntegerExp(exp.loc, te.exps.dim, Type.tsize_t);
        }
    }

    // https://issues.dlang.org/show_bug.cgi?id=14416
    // Template has no built-in properties except for 'stringof'.
    if ((exp.e1.isDotTemplateExp() || exp.e1.isTemplateExp()) && exp.ident != Id.stringof)
    {
        exp.error("template `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars());
        return ErrorExp.get();
    }
    if (!exp.e1.type)
    {
        exp.error("expression `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars());
        return ErrorExp.get();
    }

    return exp;
}

/******************************
 * Resolve properties, i.e. `e1.ident`, without seeing UFCS.
 * Params:
 *      exp = expression to resolve
 *      sc = context
 *      flag = if 1 then do not emit error messages, just return null
 * Returns:
 *      resolved expression, null if error
 */
Expression semanticY(DotIdExp exp, Scope* sc, int flag)
{
    //printf("DotIdExp::semanticY(this = %p, '%s')\n", exp, exp.toChars());

    //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }

    const cfile = (sc.flags & SCOPE.Cfile) != 0;

    /* Special case: rewrite this.id and super.id
     * to be classtype.id and baseclasstype.id
     * if we have no this pointer.
     */
    if ((exp.e1.isThisExp() || exp.e1.isSuperExp()) && !hasThis(sc))
    {
        if (AggregateDeclaration ad = sc.getStructClassScope())
        {
            if (exp.e1.isThisExp())
            {
                exp.e1 = new TypeExp(exp.e1.loc, ad.type);
            }
            else
            {
                if (auto cd = ad.isClassDeclaration())
                {
                    if (cd.baseClass)
                        exp.e1 = new TypeExp(exp.e1.loc, cd.baseClass.type);
                }
            }
        }
    }

    {
        Expression e = semanticX(exp, sc);
        if (e != exp)
            return e;
    }

    Expression eleft;
    Expression eright;
    if (auto de = exp.e1.isDotExp())
    {
        eleft = de.e1;
        eright = de.e2;
    }
    else
    {
        eleft = null;
        eright = exp.e1;
    }

    Type t1b = exp.e1.type.toBasetype();

    if (auto ie = eright.isScopeExp()) // also used for template alias's
    {
        auto flags = SearchLocalsOnly;
        /* Disable access to another module's private imports.
         * The check for 'is sds our current module' is because
         * the current module should have access to its own imports.
         */
        if (ie.sds.isModule() && ie.sds != sc._module)
            flags |= IgnorePrivateImports;
        if (sc.flags & SCOPE.ignoresymbolvisibility)
            flags |= IgnoreSymbolVisibility;
        Dsymbol s = ie.sds.search(exp.loc, exp.ident, flags);
        /* Check for visibility before resolving aliases because public
         * aliases to private symbols are public.
         */
        if (s && !(sc.flags & SCOPE.ignoresymbolvisibility) && !symbolIsVisible(sc._module, s))
        {
            s = null;
        }
        if (s)
        {
            auto p = s.isPackage();
            if (p && checkAccess(sc, p))
            {
                s = null;
            }
        }
        if (s)
        {
            // if 's' is a tuple variable, the tuple is returned.
            s = s.toAlias();

            exp.checkDeprecated(sc, s);
            exp.checkDisabled(sc, s);

            if (auto em = s.isEnumMember())
            {
                return em.getVarExp(exp.loc, sc);
            }
            if (auto v = s.isVarDeclaration())
            {
                //printf("DotIdExp:: Identifier '%s' is a variable, type '%s'\n", toChars(), v.type.toChars());
                if (!v.type ||
                    !v.type.deco && v.inuse)
                {
                    if (v.inuse)
                        exp.error("circular reference to %s `%s`", v.kind(), v.toPrettyChars());
                    else
                        exp.error("forward reference to %s `%s`", v.kind(), v.toPrettyChars());
                    return ErrorExp.get();
                }
                if (v.type.isTypeError())
                    return ErrorExp.get();

                if ((v.storage_class & STC.manifest) && v._init && !exp.wantsym)
                {
                    /* Normally, the replacement of a symbol with its initializer is supposed to be in semantic2().
                     * Introduced by https://github.com/dlang/dmd/pull/5588 which should probably
                     * be reverted. `wantsym` is the hack to work around the problem.
                     */
                    if (v.inuse)
                    {
                        error(exp.loc, "circular initialization of %s `%s`", v.kind(), v.toPrettyChars());
                        return ErrorExp.get();
                    }
                    auto e = v.expandInitializer(exp.loc);
                    v.inuse++;
                    e = e.expressionSemantic(sc);
                    v.inuse--;
                    return e;
                }

                Expression e;
                if (v.needThis())
                {
                    if (!eleft)
                        eleft = new ThisExp(exp.loc);
                    e = new DotVarExp(exp.loc, eleft, v);
                    e = e.expressionSemantic(sc);
                }
                else
                {
                    e = new VarExp(exp.loc, v);
                    if (eleft)
                    {
                        e = new CommaExp(exp.loc, eleft, e);
                        e.type = v.type;
                    }
                }
                e = e.deref();
                return e.expressionSemantic(sc);
            }

            if (auto f = s.isFuncDeclaration())
            {
                //printf("it's a function\n");
                if (!f.functionSemantic())
                    return ErrorExp.get();
                Expression e;
                if (f.needThis())
                {
                    if (!eleft)
                        eleft = new ThisExp(exp.loc);
                    e = new DotVarExp(exp.loc, eleft, f, true);
                    e = e.expressionSemantic(sc);
                }
                else
                {
                    e = new VarExp(exp.loc, f, true);
                    if (eleft)
                    {
                        e = new CommaExp(exp.loc, eleft, e);
                        e.type = f.type;
                    }
                }
                return e;
            }
            if (auto td = s.isTemplateDeclaration())
            {
                Expression e;
                if (eleft)
                    e = new DotTemplateExp(exp.loc, eleft, td);
                else
                    e = new TemplateExp(exp.loc, td);
                e = e.expressionSemantic(sc);
                return e;
            }
            if (OverDeclaration od = s.isOverDeclaration())
            {
                Expression e = new VarExp(exp.loc, od, true);
                if (eleft)
                {
                    e = new CommaExp(exp.loc, eleft, e);
                    e.type = Type.tvoid; // ambiguous type?
                }
                return e.expressionSemantic(sc);
            }
            if (auto o = s.isOverloadSet())
            {
                //printf("'%s' is an overload set\n", o.toChars());
                return new OverExp(exp.loc, o);
            }

            if (auto t = s.getType())
            {
                return (new TypeExp(exp.loc, t)).expressionSemantic(sc);
            }

            if (auto tup = s.isTupleDeclaration())
            {
                if (eleft)
                {
                    Expression e = new DotVarExp(exp.loc, eleft, tup);
                    e = e.expressionSemantic(sc);
                    return e;
                }
                Expression e = new TupleExp(exp.loc, tup);
                e = e.expressionSemantic(sc);
                return e;
            }

            if (auto sds = s.isScopeDsymbol())
            {
                //printf("it's a ScopeDsymbol %s\n", ident.toChars());
                Expression e = new ScopeExp(exp.loc, sds);
                e = e.expressionSemantic(sc);
                if (eleft)
                    e = new DotExp(exp.loc, eleft, e);
                return e;
            }

            if (auto imp = s.isImport())
            {
                Expression se = new ScopeExp(exp.loc, imp.pkg);
                return se.expressionSemantic(sc);
            }
            // BUG: handle other cases like in IdentifierExp::semantic()
            debug
            {
                printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind());
            }
            assert(0);
        }
        else if (exp.ident == Id.stringof)
        {
            Expression e = new StringExp(exp.loc, ie.toString());
            e = e.expressionSemantic(sc);
            return e;
        }
        if (ie.sds.isPackage() || ie.sds.isImport() || ie.sds.isModule())
        {
            flag = 0;
        }
        if (flag)
            return null;
        s = ie.sds.search_correct(exp.ident);
        if (s && symbolIsVisible(sc, s))
        {
            if (s.isPackage())
                exp.error("undefined identifier `%s` in %s `%s`, perhaps add `static import %s;`", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.toPrettyChars());
            else
                exp.error("undefined identifier `%s` in %s `%s`, did you mean %s `%s`?", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars(), s.kind(), s.toChars());
        }
        else
            exp.error("undefined identifier `%s` in %s `%s`", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars());
        return ErrorExp.get();
    }
    else if (t1b.ty == Tpointer && exp.e1.type.ty != Tenum &&
             !(
               exp.ident == Id.__sizeof ||
               exp.ident == Id.__xalignof ||
               !cfile &&
                (exp.ident == Id._mangleof ||
                 exp.ident == Id.offsetof ||
                 exp.ident == Id._init ||
                 exp.ident == Id.stringof)
              ))
    {
        Type t1bn = t1b.nextOf();
        if (flag)
        {
            if (AggregateDeclaration ad = isAggregate(t1bn))
            {
                if (!ad.members) // https://issues.dlang.org/show_bug.cgi?id=11312
                    return null;
            }
        }

        /* Rewrite:
         *   p.ident
         * as:
         *   (*p).ident
         */
        if (flag && t1bn.ty == Tvoid)
            return null;
        Expression e = new PtrExp(exp.loc, exp.e1);
        e = e.expressionSemantic(sc);
        return e.type.dotExp(sc, e, exp.ident, flag | (exp.noderef ? DotExpFlag.noDeref : 0));
    }
    else if (exp.ident == Id.__xalignof &&
             exp.e1.isVarExp() &&
             exp.e1.isVarExp().var.isVarDeclaration() &&
             !exp.e1.isVarExp().var.isVarDeclaration().alignment.isUnknown())
    {
        // For `x.alignof` get the alignment of the variable, not the alignment of its type
        const explicitAlignment = exp.e1.isVarExp().var.isVarDeclaration().alignment;
        const naturalAlignment = exp.e1.type.alignsize();
        const actualAlignment = explicitAlignment.isDefault() ? naturalAlignment : explicitAlignment.get();
        Expression e = new IntegerExp(exp.loc, actualAlignment, Type.tsize_t);
        return e;
    }
    else if ((exp.ident == Id.max || exp.ident == Id.min) &&
             exp.e1.isVarExp() &&
             exp.e1.isVarExp().var.isBitFieldDeclaration())
    {
        // For `x.max` and `x.min` get the max/min of the bitfield, not the max/min of its type
        auto bf = exp.e1.isVarExp().var.isBitFieldDeclaration();
        return new IntegerExp(exp.loc, bf.getMinMax(exp.ident), bf.type);
    }
    else if ((exp.ident == Id.max || exp.ident == Id.min) &&
             exp.e1.isDotVarExp() &&
             exp.e1.isDotVarExp().var.isBitFieldDeclaration())
    {
        // For `x.max` and `x.min` get the max/min of the bitfield, not the max/min of its type
        auto bf = exp.e1.isDotVarExp().var.isBitFieldDeclaration();
        return new IntegerExp(exp.loc, bf.getMinMax(exp.ident), bf.type);
    }
    else
    {
        if (exp.e1.isTypeExp() || exp.e1.isTemplateExp())
            flag = 0;
        Expression e = exp.e1.type.dotExp(sc, exp.e1, exp.ident, flag | (exp.noderef ? DotExpFlag.noDeref : 0));
        if (e)
        {
            e = e.expressionSemantic(sc);
        }
        return e;
    }
}

// Resolve e1.ident!tiargs without seeing UFCS.
// If flag == 1, stop "not a property" error and return NULL.
Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag)
{
    static if (LOGSEMANTIC)
    {
        printf("DotTemplateInstanceExpY::semantic('%s')\n", exp.toChars());
    }

    static Expression errorExp()
    {
        return ErrorExp.get();
    }

    Expression e1 = exp.e1;

    if (exp.ti.tempdecl && exp.ti.tempdecl.parent && exp.ti.tempdecl.parent.isTemplateMixin())
    {
        // if 'ti.tempdecl' happens to be found in a mixin template don't lose that info
        // and do the symbol search in that context (Issue: 19476)
        auto tm = cast(TemplateMixin)exp.ti.tempdecl.parent;
        e1 = new DotExp(exp.e1.loc, exp.e1, new ScopeExp(tm.loc, tm));
    }

    auto die = new DotIdExp(exp.loc, e1, exp.ti.name);

    Expression e = die.semanticX(sc);
    if (e == die)
    {
        exp.e1 = die.e1; // take back
        Type t1b = exp.e1.type.toBasetype();
        if (t1b.ty == Tarray || t1b.ty == Tsarray || t1b.ty == Taarray || t1b.ty == Tnull || (t1b.isTypeBasic() && t1b.ty != Tvoid))
        {
            /* No built-in type has templatized properties, so do shortcut.
             * It is necessary in: 1024.max!"a < b"
             */
            if (flag)
                return null;
        }
        e = die.semanticY(sc, flag);
        if (flag)
        {
            if (!e ||
                isDotOpDispatch(e))
            {
                /* opDispatch!tiargs would be a function template that needs IFTI,
                 * so it's not a template
                 */
                return null;
            }
        }
    }
    assert(e);

    if (e.op == EXP.error)
        return e;
    if (DotVarExp dve = e.isDotVarExp())
    {
        if (FuncDeclaration fd = dve.var.isFuncDeclaration())
        {
            if (TemplateDeclaration td = fd.findTemplateDeclRoot())
            {
                e = new DotTemplateExp(dve.loc, dve.e1, td);
                e = e.expressionSemantic(sc);
            }
        }
        else if (OverDeclaration od = dve.var.isOverDeclaration())
        {
            exp.e1 = dve.e1; // pull semantic() result

            if (!exp.findTempDecl(sc))
                goto Lerr;
            if (exp.ti.needsTypeInference(sc))
                return exp;
            exp.ti.dsymbolSemantic(sc);
            if (!exp.ti.inst || exp.ti.errors) // if template failed to expand
                return errorExp();

            if (Declaration v = exp.ti.toAlias().isDeclaration())
            {
                if (v.type && !v.type.deco)
                    v.type = v.type.typeSemantic(v.loc, sc);
                return new DotVarExp(exp.loc, exp.e1, v)
                       .expressionSemantic(sc);
            }
            return new DotExp(exp.loc, exp.e1, new ScopeExp(exp.loc, exp.ti))
                   .expressionSemantic(sc);
        }
    }
    else if (e.op == EXP.variable)
    {
        VarExp ve = cast(VarExp)e;
        if (FuncDeclaration fd = ve.var.isFuncDeclaration())
        {
            if (TemplateDeclaration td = fd.findTemplateDeclRoot())
            {
                e = new TemplateExp(ve.loc, td)
                    .expressionSemantic(sc);
            }
        }
        else if (OverDeclaration od = ve.var.isOverDeclaration())
        {
            exp.ti.tempdecl = od;
            return new ScopeExp(exp.loc, exp.ti)
                   .expressionSemantic(sc);
        }
    }

    if (DotTemplateExp dte = e.isDotTemplateExp())
    {
        exp.e1 = dte.e1; // pull semantic() result

        exp.ti.tempdecl = dte.td;
        if (!exp.ti.semanticTiargs(sc))
            return errorExp();
        if (exp.ti.needsTypeInference(sc))
            return exp;
        exp.ti.dsymbolSemantic(sc);
        if (!exp.ti.inst || exp.ti.errors) // if template failed to expand
            return errorExp();

        if (Declaration v = exp.ti.toAlias().isDeclaration())
        {
            return new DotVarExp(exp.loc, exp.e1, v)
                   .expressionSemantic(sc);
        }
        return new DotExp(exp.loc, exp.e1, new ScopeExp(exp.loc, exp.ti))
               .expressionSemantic(sc);
    }
    else if (e.op == EXP.template_)
    {
        exp.ti.tempdecl = (cast(TemplateExp)e).td;
        return new ScopeExp(exp.loc, exp.ti)
               .expressionSemantic(sc);
    }
    else if (DotExp de = e.isDotExp())
    {
        if (de.e2.op == EXP.overloadSet)
        {
            if (!exp.findTempDecl(sc) || !exp.ti.semanticTiargs(sc))
            {
                return errorExp();
            }
            if (exp.ti.needsTypeInference(sc))
                return exp;
            exp.ti.dsymbolSemantic(sc);
            if (!exp.ti.inst || exp.ti.errors) // if template failed to expand
                return errorExp();

            if (Declaration v = exp.ti.toAlias().isDeclaration())
            {
                if (v.type && !v.type.deco)
                    v.type = v.type.typeSemantic(v.loc, sc);
                return new DotVarExp(exp.loc, exp.e1, v)
                       .expressionSemantic(sc);
            }
            return new DotExp(exp.loc, exp.e1, new ScopeExp(exp.loc, exp.ti))
                   .expressionSemantic(sc);
        }
    }
    else if (OverExp oe = e.isOverExp())
    {
        exp.ti.tempdecl = oe.vars;
        return new ScopeExp(exp.loc, exp.ti)
               .expressionSemantic(sc);
    }

Lerr:
    exp.error("`%s` isn't a template", e.toChars());
    return errorExp();
}

/***************************************
 * If expression is shared, check that we can access it.
 * Give error message if not.
 *
 * Params:
 *      e = expression to check
 *      sc = context
 *      returnRef = Whether this expression is for a `return` statement
 *                  off a `ref` function, in which case a single level
 *                  of dereference is allowed (e.g. `shared(int)*`).
 * Returns:
 *      true on error
 */
bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
{
    if (global.params.noSharedAccess != FeatureState.enabled ||
        sc.intypeof ||
        sc.flags & SCOPE.ctfe)
    {
        return false;
    }

    //printf("checkSharedAccess() `%s` returnRef: %d\n", e.toChars(), returnRef);

    /* In case we don't know which expression triggered it,
     * e.g. for `visit(Type)` overload
     */
    Expression original = e;

    bool check(Expression e, bool allowRef)
    {
        bool sharedError(Expression e)
        {
            // https://dlang.org/phobos/core_atomic.html
            e.error("direct access to shared `%s` is not allowed, see `core.atomic`", e.toChars());
            return true;
        }

        // Error by default
        bool visit(Expression e)
        {
            if (e.type.isShared())
                return sharedError(e);
            return false;
        }

        bool visitNew(NewExp e)
        {
            if (e.thisexp)
                check(e.thisexp, false);
            // Note: This handles things like `new shared(Throwable).msg`,
            // where accessing `msg` would violate `shared`.
            if (e.newtype.isShared())
                return sharedError(original);
            return false;
        }

        bool visitVar(VarExp e)
        {
            // https://issues.dlang.org/show_bug.cgi?id=22626
            // Synchronized functions don't need to use core.atomic
            // when accessing `this`.
            if (sc.func && sc.func.isSynchronized())
            {
                if (e.var.isThisDeclaration())
                    return false;
                else
                    return sharedError(e);
            }
            else if (!allowRef && e.var.type.isShared())
                return sharedError(e);

            return false;
        }

        bool visitAddr(AddrExp e)
        {
            return check(e.e1, true);
        }

        bool visitPtr(PtrExp e)
        {
            if (!allowRef && e.type.isShared())
                return sharedError(e);

            if (e.e1.type.isShared())
                return sharedError(e);

            return check(e.e1, false);
        }

        bool visitThis(ThisExp e)
        {
            if (sc.func && sc.func.isSynchronized())
                return false;

            if (!allowRef && e.type.isShared())
                return sharedError(e);

            return false;
        }

        bool visitDotVar(DotVarExp e)
        {
            //printf("dotvarexp = %s\n", e.toChars());
            auto fd = e.var.isFuncDeclaration();
            const sharedFunc = fd && fd.type.isShared;
            // Allow using `DotVarExp` within value types
            if (!allowRef && e.type.isShared() && !sharedFunc && !(sc.func && sc.func.isSynchronized()))
                return sharedError(e);
            if (e.e1.type.isTypeSArray() || e.e1.type.isTypeStruct())
                return check(e.e1, allowRef);

            // If we end up with a single `VarExp`, it might be a `ref` param
            // `shared ref T` param == `shared(T)*`.
            if (auto ve = e.e1.isVarExp())
            {
                return check(e.e1, allowRef && (ve.var.storage_class & STC.ref_));
            }

            return check(e.e1, false);
        }

        bool visitIndex(IndexExp e)
        {
            if (!allowRef && e.type.isShared())
                return sharedError(e);

            if (e.e1.type.isShared())
                return sharedError(e);

            return check(e.e1, false);
        }

        bool visitComma(CommaExp e)
        {
            // Cannot be `return ref` since we can't use the return,
            // but it's better to show that error than an unrelated `shared` one
            return check(e.e2, true);
        }

        switch (e.op)
        {
            default:              return visit(e);

            // Those have no indirections / can be ignored
            case EXP.call:
            case EXP.error:
            case EXP.complex80:
            case EXP.int64:
            case EXP.null_:       return false;

            case EXP.variable:    return visitVar(e.isVarExp());
            case EXP.new_:        return visitNew(e.isNewExp());
            case EXP.address:     return visitAddr(e.isAddrExp());
            case EXP.star:        return visitPtr(e.isPtrExp());
            case EXP.dotVariable: return visitDotVar(e.isDotVarExp());
            case EXP.index:       return visitIndex(e.isIndexExp());
            case EXP.this_:       return visitThis(e.isThisExp());
        }
    }

    return check(e, returnRef);
}



/****************************************************
 * Determine if `exp`, which gets its address taken, can do so safely.
 * Params:
 *      sc = context
 *      exp = expression having its address taken
 *      v = the variable getting its address taken
 * Returns:
 *      `true` if ok, `false` for error
 */
bool checkAddressVar(Scope* sc, Expression exp, VarDeclaration v)
{
    //printf("checkAddressVar(exp: %s, v: %s)\n", exp.toChars(), v.toChars());
    if (v is null)
        return true;

    if (!v.canTakeAddressOf())
    {
        exp.error("cannot take address of `%s`", exp.toChars());
        return false;
    }
    if (sc.func && !sc.intypeof && !v.isDataseg())
    {
        if (global.params.useDIP1000 != FeatureState.enabled &&
            !(v.storage_class & STC.temp) &&
            sc.setUnsafe(false, exp.loc, "cannot take address of local `%s` in `@safe` function `%s`", v, sc.func))
        {
            return false;
        }
    }
    return true;
}

/**************************************
 * This check ensures that the object in `exp` can have its address taken, or
 * issue a diagnostic error.
 * Params:
 *      e = expression to check
 *      sc = context
 * Returns:
 *      true if the expression is addressable
 */
bool checkAddressable(Expression e, Scope* sc)
{
    Expression ex = e;
    while (true)
    {
        switch (ex.op)
        {
            case EXP.dotVariable:
                // https://issues.dlang.org/show_bug.cgi?id=22749
                // Error about taking address of any bit-field, regardless of
                // whether SCOPE.Cfile is set.
                if (auto bf = ex.isDotVarExp().var.isBitFieldDeclaration())
                {
                    e.error("cannot take address of bit-field `%s`", bf.toChars());
                    return false;
                }
                goto case EXP.cast_;

            case EXP.index:
                ex = ex.isBinExp().e1;
                continue;

            case EXP.address:
            case EXP.array:
            case EXP.cast_:
                ex = ex.isUnaExp().e1;
                continue;

            case EXP.variable:
                if (sc.flags & SCOPE.Cfile)
                {
                    // C11 6.5.3.2: A variable that has its address taken cannot be
                    // stored in a register.
                    // C11 6.3.2.1: An array that has its address computed with `[]`
                    // or cast to an lvalue pointer cannot be stored in a register.
                    if (ex.isVarExp().var.storage_class & STC.register)
                    {
                        if (e.isIndexExp())
                            e.error("cannot index through register variable `%s`", ex.toChars());
                        else
                            e.error("cannot take address of register variable `%s`", ex.toChars());
                        return false;
                    }
                }
                break;

            default:
                break;
        }
        break;
    }
    return true;
}


/*******************************
 * Checks the attributes of a function.
 * Purity (`pure`), safety (`@safe`), no GC allocations(`@nogc`)
 * and usage of `deprecated` and `@disabled`-ed symbols are checked.
 *
 * Params:
 *  exp = expression to check attributes for
 *  sc  = scope of the function
 *  f   = function to be checked
 * Returns: `true` if error occur.
 */
private bool checkFunctionAttributes(Expression exp, Scope* sc, FuncDeclaration f)
{
    with(exp)
    {
        bool error = checkDisabled(sc, f);
        error |= checkDeprecated(sc, f);
        error |= checkPurity(sc, f);
        error |= checkSafety(sc, f);
        error |= checkNogc(sc, f);
        return error;
    }
}

/*******************************
 * Helper function for `getRightThis()`.
 * Gets `this` of the next outer aggregate.
 * Params:
 *      loc = location to use for error messages
 *      sc = context
 *      s = the parent symbol of the existing `this`
 *      ad = struct or class we need the correct `this` for
 *      e1 = existing `this`
 *      t = type of the existing `this`
 *      var = the specific member of ad we're accessing
 *      flag = if true, return `null` instead of throwing an error
 * Returns:
 *      Expression representing the `this` for the var
 */
Expression getThisSkipNestedFuncs(const ref Loc loc, Scope* sc, Dsymbol s, AggregateDeclaration ad, Expression e1, Type t, Dsymbol var, bool flag = false)
{
    int n = 0;
    while (s && s.isFuncDeclaration())
    {
        FuncDeclaration f = s.isFuncDeclaration();
        if (f.vthis)
        {
            n++;
            e1 = new VarExp(loc, f.vthis);
            if (f.hasDualContext())
            {
                // (*__this)[i]
                if (n > 1)
                    e1 = e1.expressionSemantic(sc);
                e1 = new PtrExp(loc, e1);
                uint i = f.followInstantiationContext(ad);
                e1 = new IndexExp(loc, e1, new IntegerExp(i));
                s = f.toParentP(ad);
                continue;
            }
        }
        else
        {
            if (flag)
                return null;
            e1.error("need `this` of type `%s` to access member `%s` from static function `%s`", ad.toChars(), var.toChars(), f.toChars());
            e1 = ErrorExp.get();
            return e1;
        }
        s = s.toParent2();
    }
    if (n > 1 || e1.op == EXP.index)
        e1 = e1.expressionSemantic(sc);
    if (s && e1.type.equivalent(Type.tvoidptr))
    {
        if (auto sad = s.isAggregateDeclaration())
        {
            Type ta = sad.handleType();
            if (ta.ty == Tstruct)
                ta = ta.pointerTo();
            e1.type = ta;
        }
    }
    e1.type = e1.type.addMod(t.mod);
    return e1;
}

/*******************************
 * Make a dual-context container for use as a `this` argument.
 * Params:
 *      loc = location to use for error messages
 *      sc = current scope
 *      fd = target function that will take the `this` argument
 * Returns:
 *      Temporary closure variable.
 * Note:
 *      The function `fd` is added to the nested references of the
 *      newly created variable such that a closure is made for the variable when
 *      the address of `fd` is taken.
 */
VarDeclaration makeThis2Argument(const ref Loc loc, Scope* sc, FuncDeclaration fd)
{
    Type tthis2 = Type.tvoidptr.sarrayOf(2);
    VarDeclaration vthis2 = new VarDeclaration(loc, tthis2, Identifier.generateId("__this"), null);
    vthis2.storage_class |= STC.temp;
    vthis2.dsymbolSemantic(sc);
    vthis2.parent = sc.parent;
    // make it a closure var
    assert(sc.func);
    sc.func.closureVars.push(vthis2);
    // add `fd` to the nested refs
    vthis2.nestedrefs.push(fd);
    return vthis2;
}

/*******************************
 * Make sure that the runtime hook `id` exists.
 * Params:
 *      loc = location to use for error messages
 *      sc = current scope
 *      id = the hook identifier
 *      description = what the hook does
 *      module_ = what module the hook is located in
 * Returns:
 *      a `bool` indicating if the hook is present.
 */
bool verifyHookExist(const ref Loc loc, ref Scope sc, Identifier id, string description, Identifier module_ = Id.object)
{
    auto rootSymbol = sc.search(loc, Id.empty, null);
    if (auto moduleSymbol = rootSymbol.search(loc, module_))
        if (moduleSymbol.search(loc, id))
          return true;
    error(loc, "`%s.%s` not found. The current runtime does not support %.*s, or the runtime is corrupt.", module_.toChars(), id.toChars(), cast(int)description.length, description.ptr);
    return false;
}

/***************************************
 * Fit elements[] to the corresponding types of the `sd`'s fields.
 *
 * Params:
 *      sd = the struct declaration
 *      loc = location to use for error messages
 *      sc = context
 *      elements = explicit arguments used to construct object
 *      stype = the constructed object type.
 * Returns:
 *      false if any errors occur,
 *      otherwise true and elements[] are rewritten for the output.
 */
private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions* elements, Type stype)
{
    if (!elements)
        return true;

    const nfields = sd.nonHiddenFields();
    size_t offset = 0;
    for (size_t i = 0; i < elements.dim; i++)
    {
        Expression e = (*elements)[i];
        if (!e)
            continue;

        e = resolveProperties(sc, e);
        if (i >= nfields)
        {
            if (i < sd.fields.dim && e.op == EXP.null_)
            {
                // CTFE sometimes creates null as hidden pointer; we'll allow this.
                continue;
            }
                .error(loc, "more initializers than fields (%llu) of `%s`", cast(ulong)nfields, sd.toChars());
            return false;
        }
        VarDeclaration v = sd.fields[i];
        if (v.offset < offset)
        {
            .error(loc, "overlapping initialization for `%s`", v.toChars());
            if (!sd.isUnionDeclaration())
            {
                enum errorMsg = "`struct` initializers that contain anonymous unions" ~
                    " must initialize only the first member of a `union`. All subsequent" ~
                    " non-overlapping fields are default initialized";
                .errorSupplemental(loc, errorMsg);
            }
            return false;
        }
        const vsize = v.type.size();
        if (vsize == SIZE_INVALID)
            return false;
        offset = cast(uint)(v.offset + vsize);

        Type t = v.type;
        if (stype)
            t = t.addMod(stype.mod);
        Type origType = t;
        Type tb = t.toBasetype();

        const hasPointers = tb.hasPointers();
        if (hasPointers)
        {
            if ((!stype.alignment.isDefault() && stype.alignment.get() < target.ptrsize ||
                 (v.offset & (target.ptrsize - 1))) &&
                (sc.setUnsafe(false, loc,
                    "field `%s.%s` cannot assign to misaligned pointers in `@safe` code", sd, v)))
            {
                return false;
            }
        }

        /* Look for case of initializing a static array with a too-short
         * string literal, such as:
         *  char[5] foo = "abc";
         * Allow this by doing an explicit cast, which will lengthen the string
         * literal.
         */
        if (e.op == EXP.string_ && tb.ty == Tsarray)
        {
            StringExp se = cast(StringExp)e;
            Type typeb = se.type.toBasetype();
            TY tynto = tb.nextOf().ty;
            if (!se.committed &&
                (typeb.ty == Tarray || typeb.ty == Tsarray) && tynto.isSomeChar &&
                se.numberOfCodeUnits(tynto) < (cast(TypeSArray)tb).dim.toInteger())
            {
                e = se.castTo(sc, t);
                goto L1;
            }
        }

        while (!e.implicitConvTo(t) && tb.ty == Tsarray)
        {
            /* Static array initialization, as in:
             *  T[3][5] = e;
             */
            t = tb.nextOf();
            tb = t.toBasetype();
        }
        if (!e.implicitConvTo(t))
            t = origType; // restore type for better diagnostic

        e = e.implicitCastTo(sc, t);
    L1:
        if (e.op == EXP.error)
            return false;

        (*elements)[i] = doCopyOrMove(sc, e);
    }
    return true;
}


/**
 * Returns `em` as a VariableExp
 * Params:
 *     em = the EnumMember to wrap
 *     loc = location of use of em
 *     sc = scope of use of em
 * Returns:
 *     VarExp referenceing `em` or ErrorExp if `em` if disabled/deprecated
 */
Expression getVarExp(EnumMember em, const ref Loc loc, Scope* sc)
{
    dsymbolSemantic(em, sc);
    if (em.errors)
        return ErrorExp.get();
    em.checkDisabled(loc, sc);

    if (em.depdecl && !em.depdecl._scope)
        em.depdecl._scope = sc;
    em.checkDeprecated(loc, sc);

    if (em.errors)
        return ErrorExp.get();
    Expression e = new VarExp(loc, em);
    e = e.expressionSemantic(sc);
    if (!(sc.flags & SCOPE.Cfile) && em.isCsymbol())
    {
        /* C11 types them as int. But if in D file,
         * type qualified names as the enum
         */
        e.type = em.parent.isEnumDeclaration().type;
        assert(e.type);
    }
    return e;
}


/*****************************
 * Try to treat `exp` as a boolean,
 * Params:
 *     exp = the expression
 *     sc = scope to evalute `exp` in
 * Returns:
 *     Modified expression on success, ErrorExp on error
 */
Expression toBoolean(Expression exp, Scope* sc)
{
    switch(exp.op)
    {
        case EXP.delete_:
            exp.error("`delete` does not give a boolean result");
            return ErrorExp.get();

        case EXP.comma:
            auto ce = exp.isCommaExp();
            auto ex2 = ce.e2.toBoolean(sc);
            if (ex2.op == EXP.error)
                return ex2;
            ce.e2 = ex2;
            ce.type = ce.e2.type;
            return ce;

        case EXP.assign:
        case EXP.construct:
        case EXP.blit:
            if (sc.flags & SCOPE.Cfile)
                return exp;
            // Things like:
            //  if (a = b) ...
            // are usually mistakes.
            exp.error("assignment cannot be used as a condition, perhaps `==` was meant?");
            return ErrorExp.get();

        //LogicalExp
        case EXP.andAnd:
        case EXP.orOr:
            auto le = exp.isLogicalExp();
            auto ex2 = le.e2.toBoolean(sc);
            if (ex2.op == EXP.error)
                return ex2;
            le.e2 = ex2;
            return le;

        case EXP.question:
            auto ce = exp.isCondExp();
            auto ex1 = ce.e1.toBoolean(sc);
            auto ex2 = ce.e2.toBoolean(sc);
            if (ex1.op == EXP.error)
                return ex1;
            if (ex2.op == EXP.error)
                return ex2;
            ce.e1 = ex1;
            ce.e2 = ex2;
            return ce;


        default:
            // Default is 'yes' - do nothing
            Expression e = arrayFuncConv(exp, sc);
            Type t = e.type;
            Type tb = t.toBasetype();
            Type att = null;

            while (1)
            {
                // Structs can be converted to bool using opCast(bool)()
                if (auto ts = tb.isTypeStruct())
                {
                    AggregateDeclaration ad = ts.sym;
                    /* Don't really need to check for opCast first, but by doing so we
                     * get better error messages if it isn't there.
                     */
                    if (Dsymbol fd = search_function(ad, Id._cast))
                    {
                        e = new CastExp(exp.loc, e, Type.tbool);
                        e = e.expressionSemantic(sc);
                        return e;
                    }

                    // Forward to aliasthis.
                    if (ad.aliasthis && !isRecursiveAliasThis(att, tb))
                    {
                        e = resolveAliasThis(sc, e);
                        t = e.type;
                        tb = e.type.toBasetype();
                        continue;
                    }
                }
                break;
            }

            if (!t.isBoolean())
            {
                if (tb != Type.terror)
                    exp.error("expression `%s` of type `%s` does not have a boolean value",
                              exp.toChars(), t.toChars());
                return ErrorExp.get();
            }
            return e;
    }
}
