D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7653 - remove "function literals cannot be class members" annoyance
Summary: remove "function literals cannot be class members" annoyance
Status: RESOLVED DUPLICATE of issue 12288
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-05 15:12 UTC by timon.gehr
Modified: 2014-03-02 13:16 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 timon.gehr 2012-03-05 15:12:19 UTC
class C{
    mixin({
        string r;
        foreach(x;["a","b","c"]) r~="int "~x~";";
        return r;
    }());
}

Error: delegate tt.C.__lambda1 function literals cannot be class members
       called from here: (*delegate _error_()
{
string r;
foreach (x; ["a","b","c"])
{
r ~= "int " ~ x ~ ";";
}
return r;
}
)()

This is one of the most annoying limitations of the current compiler implementation. (Making the function literal static results in an even more massive error message).
Comment 1 Vladimir Panteleev 2014-02-03 05:58:53 UTC
Another test case:

enum x = { return 5; }; // allowed

struct S
{
	enum y = { return 5; }; // forbidden
}

Looking at the compiler code and its history, it looks like an artificial limitation left in the code from ancient times (dmd 0.90).
Comment 2 Vladimir Panteleev 2014-02-03 06:08:25 UTC
Sorry, that's not right. I forgot the parens.

enum x = { return 5; }(); // allowed

struct S
{
	enum y = { return 5; }(); // forbidden
}
Comment 3 Kenji Hara 2014-02-03 06:29:34 UTC

*** This issue has been marked as a duplicate of issue 11545 ***
Comment 4 timon.gehr 2014-03-02 12:38:17 UTC
Not a duplicate!
Comment 5 Vladimir Panteleev 2014-03-02 12:40:18 UTC
Regardless of whether the two issues describe different problems, the pull in issue 11545 fixes compilation of the code in this issue as well.
Comment 6 timon.gehr 2014-03-02 12:48:10 UTC
(In reply to comment #5)
> Regardless of whether the two issues describe different problems, the pull in
> issue 11545 fixes compilation of the code in this issue as well.

1. There are no tests for the case without explicit 'function'.

2. Does it fix the following as well?

class C{
    mixin(delegate{
        string r;
        foreach(x;["a","b","c"]) r~="int "~x~";";
        return r;
    }());
}

template ID(alias a){ alias ID=a; }
class C{
    int x=3;
    alias a = ID!(()=>x);
}
static assert(new C().a()==3);
Comment 7 Vladimir Panteleev 2014-03-02 12:51:56 UTC
No. But I think that is a separate issue. Your original report and test code only concerned functions, which did not require a context.
Comment 8 timon.gehr 2014-03-02 12:53:21 UTC
(In reply to comment #7)
> No. But I think that is a separate issue. Your original report and test code
> only concerned functions, which did not require a context.

Well, the title of this issue is 'remove "function literals cannot be class members" annoyance'.
Comment 9 Vladimir Panteleev 2014-03-02 12:53:58 UTC
Yes. And function literals are now allowed. But not delegate literals.
Comment 10 timon.gehr 2014-03-02 12:59:25 UTC
(In reply to comment #9)
> Yes. And function literals are now allowed. But not delegate literals.

$ git clone https://github.com/D-Programming-Language/dmd.git
$ cd dmd/src
$ grep "function literals cannot be" *.c
func.c:                error("function literals cannot be class members");
Comment 11 Vladimir Panteleev 2014-03-02 13:00:57 UTC
The pull isn't merged yet.
Comment 12 timon.gehr 2014-03-02 13:06:00 UTC
(In reply to comment #11)
> The pull isn't merged yet.

I am sorry I was not making myself very clear, but surely the right way to get rid of the "function literals cannot be class members" annoyance is not to just fix the diagnostic message? It's a quotation. This error is displayed for any function/delegate literal.
Comment 13 Vladimir Panteleev 2014-03-02 13:12:36 UTC
Sorry, there does appear to be a misunderstanding.

I am referring to the code in the issue description:

(In reply to comment #0)
> class C{
>     mixin({
>         string r;
>         foreach(x;["a","b","c"]) r~="int "~x~";";
>         return r;
>     }());
> }

With Kenji's pull from issue 11545, this code compiles and works fine.

This code does not need an instance of C to work, thus it does not have a context pointer, and so I've referred to it as a "function literal" in my last comment.

The two examples you posted earlier do have a context pointer:

(In reply to comment #6)
> class C{
>     mixin(delegate{
>         string r;
>         foreach(x;["a","b","c"]) r~="int "~x~";";
>         return r;
>     }());
> }

Here, although the code does not refer to C fields or methods, it is explicitly declared as a delegate.

> template ID(alias a){ alias ID=a; }
> class C{
>     int x=3;
>     alias a = ID!(()=>x);
> }
> static assert(new C().a()==3);

Here it refers to x, and thus needs a context pointer.
Comment 14 timon.gehr 2014-03-02 13:16:43 UTC
Well, I guess it's easiest to just do it this way.

*** This issue has been marked as a duplicate of issue 12288 ***