Compiling the module test.d: public struct foo { public this(real aleft) { } } class bar { final void fun(foo arg = foo(0.)) { } } produces: test.d(11): Error: variable test.bar.__ctmp1 final cannot be applied to variable
This happens, because the default argument is evaluated in the same scope as the function. The following patch opens a new scope for argument semantics, clearing the storage class (maybe some flags should be kept?): Index: mtype.c =================================================================== --- mtype.c (revision 196) +++ mtype.c (working copy) @@ -4065,11 +4065,14 @@ if (tf->parameters) { size_t dim = Argument::dim(tf->parameters); + Scope* argsc = sc->push(); // arguments must be evaluated in a different scope + argsc->stc = STCundefined; // as we don't want to inherit storage class from the function + for (size_t i = 0; i < dim; i++) { Argument *arg = Argument::getNth(tf->parameters, i); tf->inuse++; - arg->type = arg->type->semantic(loc,sc); + arg->type = arg->type->semantic(loc,argsc); if (tf->inuse == 1) tf->inuse--; arg->type = arg->type->addStorageClass(arg->storageClass); @@ -4094,9 +4097,9 @@ if (arg->defaultArg) { - arg->defaultArg = arg->defaultArg->semantic(sc); - arg->defaultArg = resolveProperties(sc, arg->defaultArg); - arg->defaultArg = arg->defaultArg->implicitCastTo(sc, arg->type); + arg->defaultArg = arg->defaultArg->semantic(argsc); + arg->defaultArg = resolveProperties(argsc, arg->defaultArg); + arg->defaultArg = arg->defaultArg->implicitCastTo(argsc, arg->type); } /* If arg turns out to be a tuple, the number of parameters may @@ -4107,6 +4110,7 @@ i--; } } + argsc->pop(); } if (tf->next) tf->deco = tf->merge()->deco;
Fixed dmd 1.048 and 2.033