Bug 24520 – [REG] type(value) got a synonym (type)(value)

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2024-04-24T09:19:20Z
Last change time
2024-05-01T09:52:36Z
Keywords
spec
Assigned to
No Owner
Creator
ponce

Comments

Comment #0 by aliloko — 2024-04-24T09:19:20Z
# How to repro Please consider the following file: void main(string[] args) { // 1st change: the ending ';' starts being // accepted in LDC 1.35, before was an error // If that changed silently, then new code breaks in // older compilers, creating disruption. enum { A = 5}; // 2nd change: // This C-style cast starts being accepted in LDC 1.35+ long c; int i = (int) (c % 8); // Note that this cast is always rejected whatever the // compiler version //int j = (int)4; } Some parses that were invalid in LDC 1.34 (DMDFE v2.104.2) became accepted in LDC 1.35 (DMDFE v2.105.2) If new compilers accept invalid code without complaints, it _might_ be intentional and a language change, but please hear me, this is a problem of quality of life in practice for the ecosystem, because then people build with older compiler the code that was produced with new compilers, and it simply breaks there for a lot of people that depend on it. And it's documented nowhere! It's also silent, so would bypass any Edition I guess and break code regardless. https://dlang.org/changelog/2.105.0.html
Comment #1 by aliloko — 2024-04-24T09:22:13Z
Comment #2 by timon.gehr — 2024-04-24T11:22:03Z
https://issues.dlang.org/show_bug.cgi?id=24025 As Steven says: > An alternative to delaying the C style cast to semantic is to just remove the error. > > If a cast from C is desired, then it will work if the type can be constructed with that parameter. > > Back when this error was created, something like `int(5)` was not valid code. Now it is. So most cases of casting will just have a failed implicit cast error. > > Ironically, this error *hurts* porting C code, instead of helping. Therefore, I believe the change in behavior with "casts" is intentional. (int)(c % 8) is just treated as another way to write int(c % 8). Similar to how `(f)(1, 2)` just means `f(1, 2)`. I do appreciate that grammar changes make it harder to write code that is compatible with multiple compiler versions, but I also think testing with different compiler versions cannot be avoided if one wants to support them.
Comment #3 by aliloko — 2024-04-24T11:34:05Z
I get that this is unable to create dysfunction other than "doesn't build". My issue is that a silent language change with no changelog entry and no spec change. This issue is exactly similar with introduction of named arguments. Perhaps yes the language is better afterwards; but since there is no way to know, there is no knowledge one has to test things that worked for a long time under compilers that are a few versions back. If this happen like this, then Editions when compiled with new compilers, won't work in old compilers, somewhat bypassing the advantage of Editions. I develop libraries with users and we do not have the same compilers, so users expect me to test with multiple compilers yes but it is helpful to have a way to track breaking changes or additions like these in changelog. And it's not sure if intentional here.
Comment #4 by dkorpel — 2024-04-24T11:58:35Z
> it is helpful to have a way to track breaking changes or additions like these in changelog It is listed in the changelog of 2.105: > DMD Compiler bug fixes > (...) > 29. Bugzilla 24025: Expressions contained in parentheses should not be assumed to be C casts It doesn't have a spec change because the grammar already allowed calling a parenthesized expression. It's only an implementation bug that it was considered a C-style cast. While breaking changes warrant an explicit changelog entry, fixes for rejects-valid bugs usually only require a bugzilla issue to be closed. Is that something you want to see changed?
Comment #5 by aliloko — 2024-04-24T12:10:34Z
I admit it's not entirely clear to me if the semantics of cast() are the same as implicit conversions. Haven't found a counter-example though, even with alias this.
Comment #6 by aliloko — 2024-04-24T12:14:50Z
In changelog it's in: "DMD Compiler bug fixes" section. But grammar changes are usually language changes, so it could be easier to anticipate if there was a Language Change section (which I will read, more likely that the ~30 items in bug fixes). Thought I understand that in this case it's believed to not change semantics.
Comment #7 by dfj1esp02 — 2024-04-25T10:03:42Z
It's believed that grammar allows this syntax and grammar didn't recently change, therefore it's not a change in grammar, but a compiler bug fix.
Comment #8 by aliloko — 2024-04-25T12:54:55Z
Maybe I was unpleasant to report that, but you can be unpleasant with your real name instead of an anonymous id.
Comment #9 by aliloko — 2024-04-26T12:16:51Z
Comment #10 by nick — 2024-04-29T16:31:21Z
> enum { A = 5}; That was allowed in https://github.com/dlang/dmd/pull/15409. > My issue is that a silent language change with no changelog entry and no spec change Sorry. comment #4: > the grammar already allowed calling a parenthesized expression I don't think (Type) is always an expression - it is when Type is an identifier, but not when (int) or even (int*), and this now works: int i; scope p = (int*)(&i); So unless I missed some part of the grammar, I think the spec needs updating. We can make TypeCtor optional below: PrimaryExpression: TypeCtor ( Type ) ( NamedArgumentListopt ) https://dlang.org/spec/expression.html#primary_expressions
Comment #11 by dlang-bot — 2024-05-01T09:52:36Z
dlang/dlang.org pull request #3819 "[spec] Add grammar for `(Type)(args)` expression" was merged into master: - d9eb8e8511b08fb54b246c82ee60873f92480959 by Nick Treleaven: [spec] Add grammar for `(Type)(args)` Change introduced in https://github.com/dlang/dmd/pull/15377. Fixes Bugzilla 24520 - type(value) got a synonym (type)(value) Also combine 2 other PrimaryExpression rules with `TypeCtor? (Type).Identifier`. https://github.com/dlang/dlang.org/pull/3819