D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3353 - storage class of a member function is propagated to default arguments
Summary: storage class of a member function is propagated to default arguments
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: patch, rejects-valid
Depends on:
Blocks:
 
Reported: 2009-09-30 13:55 UTC by Rainer Schuetze
Modified: 2015-06-09 01:26 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Rainer Schuetze 2009-09-30 13:55:03 UTC
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
Comment 1 Rainer Schuetze 2009-09-30 14:00:21 UTC
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;
Comment 2 Walter Bright 2009-10-06 02:19:18 UTC
Fixed dmd 1.048 and 2.033