Example #1
0
void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
{
    if (sc->incontract && isParameter())
        error(loc, "cannot modify parameter '%s' in contract", toChars());

    if (sc->incontract && isResult())
        error(loc, "cannot modify result '%s' in contract", toChars());

    if (isCtorinit() && !t->isMutable())
    {   // It's only modifiable if inside the right constructor
        Dsymbol *s = sc->func;
        while (1)
        {
            FuncDeclaration *fd = NULL;
            if (s)
                fd = s->isFuncDeclaration();
            if (fd &&
                ((fd->isCtorDeclaration() && storage_class & STCfield) ||
                 (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) &&
                fd->toParent() == toParent()
               )
            {
                VarDeclaration *v = isVarDeclaration();
                assert(v);
                v->ctorinit = 1;
                //printf("setting ctorinit\n");
            }
            else
            {
                if (s)
                {   s = s->toParent2();
                    continue;
                }
                else
                {
                    const char *p = isStatic() ? "static " : "";
                    error(loc, "can only initialize %sconst %s inside %sconstructor",
                        p, toChars(), p);
                }
            }
            break;
        }
    }
    else
    {
        VarDeclaration *v = isVarDeclaration();
        if (v && v->canassign == 0)
        {
            const char *p = NULL;
            if (isConst())
                p = "const";
            else if (isImmutable())
                p = "immutable";
            else if (storage_class & STCmanifest)
                p = "enum";
            else if (!t->isAssignable())
                p = "struct with immutable members";
            if (p)
            {   error(loc, "cannot modify %s", p);
            }
        }
    }
}