Bug 5363 – const + alias this = wrong code

Status
NEW
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-12-21T19:30:58Z
Last change time
2024-12-15T19:40:13Z
Keywords
bounty, patch, wrong-code
Assigned to
No Owner
Creator
David Simcha
See also
https://issues.dlang.org/show_bug.cgi?id=6777, https://issues.dlang.org/show_bug.cgi?id=9274
Moved to GitHub: dmd#18323 →

Comments

Comment #0 by dsimcha — 2010-12-21T19:30:58Z
Happens on at least 2.050, 2.051. import core.stdc.stdio; // Pollutes asm less than std.stdio. struct Foo { uint dummy = 0; uint k = 0; alias dummy this; // Yes, this line is necessary for reproducing the bug. // This needs to be a function to reproduce the bug. Setting k directly // doesn't cut it. void put(uint element) { k += element; } // rhs must be const to reproduce the bug. void put(const Foo rhs) { k += rhs.k; } } void main() { Foo foo1, foo2; foo1.put(10); foo2.put(42); foo1.put(foo2); printf("%d\n", foo1.k); // 10, should be 52 }
Comment #1 by k.hara.pg — 2011-06-21T19:36:13Z
More simple case: ---- struct S { int dummy; alias dummy this; } int foo(int){ return 1; } int foo(const(S)){ return 2; } void main() { S s; assert(foo(s) == 2); } ---- It is the reason of this problem that the type matching levels through normal and alias this have same basis.
Comment #2 by k.hara.pg — 2011-07-14T04:31:02Z
Comment #3 by lovelydear — 2012-04-22T09:30:41Z
Bug still here in 2.059. Kenji, what happened to your pull ?
Comment #4 by jens.k.mueller — 2012-11-13T02:36:38Z
Today I ran into this bug. Unfortunately it tooks quite some time until I had a minimal example that exemplified the problem. Then I could search the database to find this report here. I leave my minimal example here for reference. struct A { B b; alias b this; } struct B { static struct Value { } Value value; B[] bs; alias value this; bool opEquals(ref const B rhs) const // remove const in front of B and it works { return this.bs == rhs.bs; } } unittest { A a; a.bs ~= B.init; B b; b.bs ~= B.init; assert(b.opEquals(a)); // fails } This is Linux and dmd2.060. This issue is a blocker for me because I can't use const and alias this anymore. I have to remove the const which makes my code error-prone.
Comment #5 by k.hara.pg — 2014-02-09T23:10:13Z
*** Issue 12117 has been marked as a duplicate of this issue. ***
Comment #6 by schuetzm — 2014-07-22T17:52:03Z
Just tested with latest DMD git. Jens Mueller's example passes now, but the other ones still fail.
Comment #7 by taylorh140 — 2016-03-24T19:48:07Z
Still fails on DMD 2.070.2 ( 2.070.2 ) http://dpaste.dzfl.pl/1da91ec34a86
Comment #8 by razvan.nitu1305 — 2018-09-18T22:22:00Z
*** Issue 9354 has been marked as a duplicate of this issue. ***
Comment #9 by bugzilla — 2018-10-06T09:08:57Z
I simplified it a bit more, so it happens at compile time: struct S { int dummy; alias dummy this; } int foo(int){ return 1; } int foo(const(S)){ return 2; } void test() { static assert(foo(cast(const)S.init) == 2); // pass static assert(foo(S.init) == 2); // fail } Here's the trouble. With alias this, the conversion of S to int is considered an 'exact' match, while the conversion of S to const is considered a 'constant' match, which is not as good as 'exact'. Hence, the 'exact' is selected and foo(int) is called. The levels of conversion are: nomatch convert constant exact We could change an alias this conversion to a 'convert' match, but it is unknown how much breakage this will cause. It seems to be a rather drastic change. The compiler source code is the TypeStruct.implicitConvTo() function in mtype.d.
Comment #10 by razvan.nitu1305 — 2018-10-08T10:55:12Z
Comment #11 by robert.schadek — 2024-12-13T17:54:34Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18323 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB
Comment #12 by dlang-bugzilla — 2024-12-15T19:40:13Z
aoeu