Bug 21780 – alias this preferred over immutable conversion even if alias this is deprecated and de is on

Status
NEW
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-03-29T07:48:37Z
Last change time
2024-12-13T19:15:36Z
Assigned to
No Owner
Creator
FeepingCreature
Moved to GitHub: dmd#19900 →

Comments

Comment #0 by default_357-line — 2021-03-29T07:48:37Z
Consider the following code: immutable struct S { } struct Nullable { S get_() { return S.init; } deprecated alias get_ this; } void foo(immutable Nullable) { } void foo(immutable S) { } void main() { foo(Nullable()); } So `Nullable()` is implicitly convertible to `immutable Nullable` without hitting the "alias this". And yet, DMD will prefer the deprecated conversion even if `-de` is on, erroring with Deprecation: `alias get_ this` is deprecated This despite the fact that removing the `alias get_ this` will allow the code to compile. Marked as trivial because as you can guess from the struct name, this issue will solve itself "naturally" when 2.097 releases. :)
Comment #1 by moonlightsentinel — 2021-03-29T08:12:00Z
This is actually a regression. Extending your example with appropriate puts("Nullable") / puts("S") yields: Up to 2.060 : Success with output: Nullable 2.061 to 2.075.1: <Doesn't compile due to overload resolution error> 2.076.1 to 2.087.1: Success with output: S Since 2.088.1: Success with output: ----- onlineapp.d(14): Deprecation: `alias get_ this` is deprecated S -----
Comment #2 by default_357-line — 2021-03-29T14:01:28Z
That's not really a "regression" - well, it is a regression, but it's an expected regression, because Nullable's alias get this is in the process of being deprecated and has been removed in master. A deprecation is functionally equivalent to a regression, that's why there was a year of warning messages.
Comment #3 by default_357-line — 2021-03-29T14:05:11Z
Oh wait you're right! I thought you were talking about std.typecons.Nullable for a second. It's still not a regression - it's a bugfix: https://issues.dlang.org/show_bug.cgi?id=20033 , I believe.
Comment #4 by moonlightsentinel — 2021-03-29T14:09:03Z
(In reply to FeepingCreature from comment #2) > That's not really a "regression" - well, it is a regression, but it's an This is still a regression. DMD should prefer const-conversions over implicit conversions (e.g. alias this). This extends example exhibits wrong behaviour since 2.061 : (Unless i misunderstood the rules for overload matching) extern(C) void puts(const scope char*); immutable struct S { } struct Nullable { S get_() { return S.init; } deprecated alias get_ this; } void foo(immutable Nullable) { puts("Nullable"); } void foo(immutable S) { puts("S"); } void main() { foo(Nullable()); // prints "S" }
Comment #5 by moonlightsentinel — 2021-03-29T14:11:38Z
The regression refers to the change which overload is called, not the deprecation message.
Comment #6 by moonlightsentinel — 2021-03-29T14:20:09Z
Even worse when removing the immutable from S and using const parameters: extern(C) void puts(const scope char*); struct S { } struct Nullable { S get_() { return S.init; } deprecated alias get_ this; } void foo(const Nullable) { puts("Nullable"); } void foo(const S) { puts("S"); } void main() { foo(Nullable()); // fails due to ambiguity }
Comment #7 by robert.schadek — 2024-12-13T19:15:36Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19900 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB