---- struct S() { shared(int)* method() { return ptr; } shared(int)* ptr; } void main() { S!() s; int* foo = s.method(); /* accepted; should be rejected */ } ---- These variations are correctly rejected: ---- auto foo = s.method(); int* bar = foo; // rejected as expected int* baz = s.ptr; // ditto ----
The reason for the bug is that there are different overloads in dcast.d for implicitConvTo for CallExp (int* foo = s.method() falling here) and Expression (where the other examples in this issue go). https://github.com/dlang/dmd/blob/master/src/ddmd/dcast.d#L179 Expression: https://github.com/dlang/dmd/blob/master/src/ddmd/dcast.d#L194 CallExp: https://github.com/dlang/dmd/blob/master/src/ddmd/dcast.d#L809 For: int* foo = s.method(); Code goes into visit(CallExp) and calls visit(Expression) which defaults to NOMATCH(false). https://github.com/dlang/dmd/blob/master/src/ddmd/dcast.d#L817 On NOMATCH, the checks continue in visit(CallExp) and if nothing is found, it dafaults to success (true). https://github.com/dlang/dmd/blob/master/src/ddmd/dcast.d#L940 Everything else hits the default in visit(Expression) which is NOMATCH - hence the rejecting. Now I have a fix here disallowing pointer conversions from shared to nonshared https://github.com/somzzz/dmd/commit/6fdead01822071b464016f1c0313358f40494de2 But DIP29 allows this kind of conversions as long as the pointers are unique. https://wiki.dlang.org/DIP29 This results in my fix breaking the following compiler tests for DIP29: https://github.com/dlang/dmd/blob/master/test/runnable/implicit.d#L217 I'm not sure how to check if the pointer is unique. Also, are there any other subtleties related to DIP29 that these changes could be disregarding?
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19306 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB