Bug 9051 – Passing an immutable global with post-blit to a CTFE function

Status
RESOLVED
Resolution
WONTFIX
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-11-20T12:50:42Z
Last change time
2021-03-16T11:03:31Z
Keywords
diagnostic
Assigned to
No Owner
Creator
Dmitry Olshansky

Comments

Comment #0 by dmitry.olsh — 2012-11-20T12:50:42Z
I'm wondering if this is supposed to work. By all means I don't see why it has to try this(this) in this case (and moreover fail). struct Set{ uint[] arr; this(this){ } //comment out to make it compile } pure auto getMeASet(uint[] arr) { return Set(arr); } immutable set = getMeASet([1,2,3,4]); pure auto getSecond(in Set set) { return set.arr[1]; } pragma(msg, getSecond(set)); And the diagnostic spits all kinds of nonsense: D:\D\ctfe_glob.d(20): Error: variable ctfe_glob.__cpcttmp6 of type struct const(Set) uses this(this), which is not allowed in static initialization D:\D\ctfe_glob.d(20): while evaluating pragma(msg, getSecond((const const(Set) __cpcttmp6 = Set([1u, 2u, 3u, 4u]); , __cpcttmp6)))
Comment #1 by clugdbug — 2012-11-21T02:13:04Z
The error message is not coming from CTFE. Here's a simple case from a comment in the compiler source code (declaration.c): /* The problem is the following code: * struct CopyTest { * double x; * this(double a) { x = a * 10.0;} * this(this) { x += 2.0; } * } * const CopyTest z = CopyTest(5.3); // ok * const CopyTest w = z; // not ok, postblit not run * static assert(w.x == 55.0); * because the postblit doesn't get run on the initialization of w. */ I think that if we didn't call this(this), wrong code would result. There is at least a diagnostic bug here - if it must behave this way, the code that creates the comma expression should be issuing the error. Interestingly, if you move it inside a function, the result is different: void foo() { pragma(msg, getSecond(set)); } qqq.d(19): Error: static variable set cannot be referenced at compile time qqq.d(19): called from here: __cpcttmp6.__cpctor(set) qqq.d(19): called from here: getSecond((const const(Set) __cpcttmp6 = __cpcttmp6.__cpctor(set); , __cpcttmp6))
Comment #2 by dmitry.olsh — 2012-11-21T10:49:17Z
(In reply to comment #1) > The error message is not coming from CTFE. Here's a simple case from a comment > in the compiler source code (declaration.c): > > /* The problem is the following code: > * struct CopyTest { > * double x; > * this(double a) { x = a * 10.0;} > * this(this) { x += 2.0; } > * } > * const CopyTest z = CopyTest(5.3); // ok > * const CopyTest w = z; // not ok, postblit not run > * static assert(w.x == 55.0); > * because the postblit doesn't get run on the initialization of w. > */ > > I think that if we didn't call this(this), wrong code would result. I agree in general. And But given that getMeASet(uint[] arr) is an r-value. Surely the result of it should be just moved? The other thought is: can't this(this) be run at compile-time then? What are limitations? > There is at least a diagnostic bug here - if it must behave this way, the code > that creates the comma expression should be issuing the error. > > Interestingly, if you move it inside a function, the result is different: > The same thing happens if you try passing set by reference be it const or otherwise. > void foo() > { > pragma(msg, getSecond(set)); > } > > qqq.d(19): Error: static variable set cannot be referenced at compile time > qqq.d(19): called from here: __cpcttmp6.__cpctor(set) > qqq.d(19): called from here: getSecond((const const(Set) __cpcttmp6 = > __cpcttmp6.__cpctor(set); > , __cpcttmp6))
Comment #3 by clugdbug — 2012-11-26T00:56:22Z
(In reply to comment #2) > (In reply to comment #1) > > The error message is not coming from CTFE. Here's a simple case from a comment > > in the compiler source code (declaration.c): > > > > /* The problem is the following code: > > * struct CopyTest { > > * double x; > > * this(double a) { x = a * 10.0;} > > * this(this) { x += 2.0; } > > * } > > * const CopyTest z = CopyTest(5.3); // ok > > * const CopyTest w = z; // not ok, postblit not run > > * static assert(w.x == 55.0); > > * because the postblit doesn't get run on the initialization of w. > > */ > > > > I think that if we didn't call this(this), wrong code would result. > > I agree in general. And But given that getMeASet(uint[] arr) is an r-value. > Surely the result of it should be just moved? > > The other thought is: can't this(this) be run at compile-time then? What are > limitations? Yeah, that's kind of like bug 7988. The calling of this(this) should be part of the CTFE'd bit. CTFE could cope with it, no problem, it just doesn't get a chance. BTW if we moved the this(this) into CTFE, the example I posted would also work!
Comment #4 by razvan.nitu1305 — 2021-03-16T11:03:31Z
The postblit should not be used as it has impossible to fix flaws. Development for it has halted. The code works if the copy constructor is used: struct Set{ uint[] arr; this(const ref Set) {} //comment out to make it compile } pure auto getMeASet(uint[] arr) { return Set(arr); } immutable set = getMeASet([1,2,3,4]); pure auto getSecond(in Set set) { return set.arr[1]; } pragma(msg, getSecond(set)); I'm gonna close this as WONTFIX.