-
-
Notifications
You must be signed in to change notification settings - Fork 641
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Issue 22136 - [REG 2.097.1] hashOf failed to compile because of d… #13404
Conversation
Thanks for your pull request and interest in making D better, @edi33416! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "stable + dmd#13404" |
target stable. |
@@ -196,7 +196,8 @@ static assert(is( X!( C***, B*** ) == const(B**)* )); // `B***` | |||
|
|||
static assert(is( X!( C*, I* ) == I* )); | |||
static assert(is( X!( I*, C* ) == I* )); | |||
static assert(Error!( C**, I** )); | |||
//static assert(Error!( C**, I** )); | |||
static assert(is( X!( C**, I** ) == const(I*)* )); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this supposed to be const
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsure about this, but I think so, as this is already true at L313
static assert(is( X!( C*[4], const(B*)[4] ) == const(B*)[] )); // !?
I think you should rebase on top of latest stable to fix the tester issues. |
…ifferent inheritance order
@edi33416 @RazvanN7 Yes! When an interface has multiple parent interfaces one is the "direct parent" that has the same address and the others are at an offset. The following code doesn't compile with DMD 2.098 but in the preview release of DMD 2.099 with this PR it compiles and calls the wrong function: interface IObject
{
string getName() const;
}
interface Dummy { string foo(); }
interface Bug : Dummy, IObject { string bar(); }
interface Ok : IObject, Dummy { string baz(); }
class BugImpl : Bug
{
override string getName() const { return "BugImpl.name"; }
override string foo() { return "BugImpl.foo"; }
override string bar() { return "BugImpl.bar"; }
}
class OkImpl : Ok
{
override string getName() const { return "OkImpl.name"; }
override string foo() { return "OkImpl.foo"; }
override string baz() { return "OkImpl.baz"; }
}
void main()
{
static void printName(const IObject* p)
{
import std.stdio;
writeln(p.getName);
}
Bug bug = new BugImpl();
Ok ok = new OkImpl();
printName(&bug); // On my machine prints BugImpl.foo instead of BugImpl.name!
printName(&ok); // Prints OkImpl.name as expected.
} The specification talks about this at https://dlang.org/spec/abi.html#classes:
|
…use of different inheritance order (dlang#13404)" This reverts commit 646ec17.
I'll add that I missed that same fundamental thing when writing that code. The error was not in DMD but in the "idiom": it incorrectly regards calling
That part isn't a mistake. Consider the difference between |
…ifferent inheritance order Replacement for dlang/dmd#13404
…ifferent inheritance order Replacement for dlang/dmd#13404
…ifferent inheritance order Replacement for dlang/dmd#13404
…ifferent inheritance order Replacement for dlang/dmd#13404
…ifferent inheritance order Replacement for dlang/dmd#13404
…ifferent inheritance order Replacement for dlang/dmd#13404
…ifferent inheritance order Replacement for dlang/dmd#13404
…ifferent inheritance order Replacement for dlang/dmd#13404
@n8sh Thanks a lot for the clarification. I totally missed that |
…ifferent inheritance order
druntime's
hashOf
uses the following "idiom"(?) (extracted only the relavant parts)It seems that it's assuming that if you can access
toHash
through a parentP
, andT*
is not implicitly convertible toP*
then you're accessing
toHash
through analias this
. I'm unsure if this is sound, as the class spec says at point 15.16.2: "A class or struct can be implicitly converted to the AliasThis member.".Either I'm misinterpreting the spec, or the idiom is wrong.
Assuming the idiom is right, the
is(immutable T* : immutable P*)
check fails for the following exampleAs you can see, the order of the interfaces affects the implicit conversion rules.
Before those changes, the implicit conversion check only looked at the declaration (
ClassDeclaration
orInterfaceDeclaration
) at offset 0.I don't understand why we wouldn't want to check against all the interfaces that a type implements.
Am I missing something fundamental?