Bug 21740 – Typeof mixin regression with v2.096

Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-03-21T12:51:51Z
Last change time
2021-03-21T20:07:29Z
Assigned to
No Owner
Creator
kinke

Comments

Comment #0 by kinke — 2021-03-21T12:51:51Z
void foo() {} pragma(msg, typeof(mixin(foo()))); * Output with v2.095: bla.d-mixin-2(2): Error: expression expected, not < _error_ * Output with v2.096: void
Comment #1 by moonlightsentinel — 2021-03-21T15:08:08Z
Comment #2 by kinke — 2021-03-21T16:38:54Z
Thx for digging. Just in case, the problem isn't the pragma(msg), but that `static assert(!is(typeof(mixin(foo()))));` newly fails.
Comment #3 by moonlightsentinel — 2021-03-21T16:45:35Z
Indeed but bisection yields the same commit for your example.
Comment #4 by boris2.9 — 2021-03-21T16:53:03Z
Regression? I would call it 'progression', the behavior is totally more consistent now. --- void foo() {} pragma(msg, typeof(foo())); pragma(msg, typeof(mixin("foo()"))); pragma(msg, typeof(mixin(foo()))); pragma(msg, typeof(mixin(foo().stringof))); static assert(is(typeof(foo()) == void)); static assert(is(typeof(mixin("foo()")) == void)); static assert(is(typeof(mixin(foo())) == void)); static assert(is(typeof(mixin(foo().stringof)) == void)); ---
Comment #5 by moonlightsentinel — 2021-03-21T16:56:15Z
(In reply to Boris Carvajal from comment #4) > Regression? > > I would call it 'progression', the behavior is totally more consistent now. > > --- > pragma(msg, typeof(mixin(foo()))); > --- So the behaviour of this snippet now depends on the return type of foo AFAICT (CTFE vs. implicit .stringof). Doesn't seem consistent to me.
Comment #6 by moonlightsentinel — 2021-03-21T16:59:16Z
Assume pragma(msg, typeof(mixin(foo()))); void foo() {} => void string foo() { return "foo"; } => string() // function type
Comment #7 by boris2.9 — 2021-03-21T17:40:08Z
The 'typeof' of any void expression should be 'void'. The second case looks like another bug, why is the call expression "foo()", of void value, changing to a function symbol.
Comment #8 by moonlightsentinel — 2021-03-21T17:53:17Z
(In reply to Boris Carvajal from comment #7) > The second case looks like another bug, why is the call expression "foo()", > of void value, changing to a function symbol. You misunderstood my second example, it changes foo to return a string. Slightly modified example that should be less confusing: ---------------------------------------- string foo() { return "bar"; } int bar; pragma(msg, typeof(mixin(foo()))); ---------------------------------------- =(CTFE)=> pragma(msg, typeof(mixin("bar"))); // int
Comment #9 by kinke — 2021-03-21T19:18:57Z
No idea what the spec says, but I expected `mixin(foo())`, i.e., `mixin(void)` to fail, and only string expressions to be allowed - `mixin("1 + 2")`, `mixin(q{1 + 2})` and `mixin((() => "1")() ~ " + " ~ 2.stringof)`.
Comment #10 by boris2.9 — 2021-03-21T19:32:19Z
(In reply to moonlightsentinel from comment #8) > You misunderstood my second example, it changes foo to return a string. Yep, now I get it, my bad. I shouldn't have put the example, just think it doesn't exist. So all it's reduced to whether mixin should be able to parse a void expression or not. (In reply to kinke from comment #9) > No idea what the spec says, but I expected `mixin(foo())`, i.e., > `mixin(void)` to fail Yep, though this '(void)' was always something more, before there was no way to express it but the new 'cast(void)0' thing took over and now it's working.
Comment #11 by kinke — 2021-03-21T19:39:18Z
Ah, so the point is to allow stuff like `mixin((() => "1")(), " + ", 2)` too: https://dlang.org/spec/expression.html#mixin_expressions So with void expressions now being represented as "cast(void)0" strings instead of "<void>", there's a chance that a previously invalid mixin with some void expression argument doesn't fail anymore. Do type arguments make a lot of sense for mixin expressions? `mixin("int") d = 3;` works fine; `mixin(int) d = 3;` yields: Error: found `)` when expecting `.` following int Error: found `;` when expecting `)` Error: no identifier for declarator `mixin((int).d = 3)`
Comment #12 by kinke — 2021-03-21T19:59:40Z
Scratch the type thing above, I wasn't thinking clearly. (In reply to Boris Carvajal from comment #10) > So all it's reduced to whether mixin should be able to parse a void > expression or not. Yes, but I'm not sure it's worth it, as the new behaviour seems indeed consistent. FWIW, this 'issue' newly manifested in https://github.com/dlang/dmd/blob/98ec2d4946f69c74d008e2a97c3a9e7252da9a1e/test/runnable/test42.d#L2776 for LDC when merging 2.096, i.e., some edge-case test and no 'real' code. (Still works with DMD for another, possibly invalid reason apparently.) Closing.
Comment #13 by moonlightsentinel — 2021-03-21T20:07:29Z
Fair enough, it's fine as long as both examples are run via CTFE (which dmd actually does for the `void` version)