Bug 7653 – remove "function literals cannot be class members" annoyance
Status
RESOLVED
Resolution
DUPLICATE
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-03-05T15:12:00Z
Last change time
2014-03-02T13:16:43Z
Assigned to
nobody
Creator
timon.gehr
Comments
Comment #0 by timon.gehr — 2012-03-05T15:12:19Z
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 by dlang-bugzilla — 2014-02-03T05:58:53Z
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 by dlang-bugzilla — 2014-02-03T06:08:25Z
Sorry, that's not right. I forgot the parens.
enum x = { return 5; }(); // allowed
struct S
{
enum y = { return 5; }(); // forbidden
}
Comment #3 by k.hara.pg — 2014-02-03T06:29:34Z
*** This issue has been marked as a duplicate of issue 11545 ***
Comment #4 by timon.gehr — 2014-03-02T12:38:17Z
Not a duplicate!
Comment #5 by dlang-bugzilla — 2014-03-02T12:40:18Z
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 by timon.gehr — 2014-03-02T12:48:10Z
(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 by dlang-bugzilla — 2014-03-02T12:51:56Z
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 by timon.gehr — 2014-03-02T12:53:21Z
(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 by dlang-bugzilla — 2014-03-02T12:53:58Z
Yes. And function literals are now allowed. But not delegate literals.
Comment #10 by timon.gehr — 2014-03-02T12:59:25Z
(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 by dlang-bugzilla — 2014-03-02T13:00:57Z
The pull isn't merged yet.
Comment #12 by timon.gehr — 2014-03-02T13:06:00Z
(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 by dlang-bugzilla — 2014-03-02T13:12:36Z
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 by timon.gehr — 2014-03-02T13:16:43Z
Well, I guess it's easiest to just do it this way.
*** This issue has been marked as a duplicate of issue 12288 ***