Skip to content

IRGen: Don't assert on keypaths that use a subclass as root #21592

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

Conversation

aschwaighofer
Copy link
Contributor

class A {
var x : Int = 0
}

class B : A {}

_ = \B.x

rdar://46562046

 class A {
   var x : Int = 0
 }

 class B : A {}

 _ = \B.x

rdar://46562046
@aschwaighofer
Copy link
Contributor Author

@swift-ci Please test

@aschwaighofer aschwaighofer requested a review from jckarter January 2, 2019 19:56
@aschwaighofer
Copy link
Contributor Author

@jckarter Is that the right way to fix this?

@aschwaighofer
Copy link
Contributor Author

getClassFieldAccess expects the class type that contains the field - it does not handle subclasses

}
assert(currentBaseTy->getClassOrBoundGenericClass() == propertyBaseDecl);
loweredBaseTy = IGM.getLoweredType(AbstractionPattern::getOpaque(),
currentBaseTy->getWithoutSpecifierType());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it ever have a specifier type? (inout or lvalue here)? Might be better to assert.

@@ -837,6 +837,21 @@ emitKeyPathComponent(IRGenModule &IGM,
// ObjC-ness and resilience of the class hierarchy, there might be a few
// different ways we need to go about this.
if (loweredBaseTy.getClassOrBoundGenericClass()) {

// Walk up the class hierarchy to find the class decl that matches the
// property's class decl and use this type to determin the field access.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like something SILGen should have already done? CC @jckarter

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That might be cleaner, yeah. Then we can assert the condition in the SILVerifier too.

// property's class decl and use this type to determin the field access.
auto propertyBaseDecl = property->getDeclContext()->getSelfClassDecl();
auto currentBaseTy = loweredBaseTy.getASTType();
while (currentBaseTy->getClassOrBoundGenericClass() != propertyBaseDecl &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop is already encapsulated in TypeBase::getSuperclassForDecl()

@jckarter
Copy link
Contributor

jckarter commented Jan 2, 2019

This SGTM, though I agree with Slava that having SIL always reference the property by its originating superclass is a little bit cleaner.

@aschwaighofer
Copy link
Contributor Author

Consider the following example:

$ cat KP3.swift
class A {
let x : Int = 0
}

class B : A {}

class C {
  let b: B = B()
}

func test() {
 _ = \C.b.x
}

Today the key path is

keypath $KeyPath<C, Int>, (root $C; stored_property #C.b : $B; stored_property #A.x : $Int)

If we change SILGen this would be:

keypath $KeyPath<C, Int>, (root $C; stored_property #C.b : $A; stored_property #A.x : $Int)

Which would seem odd to me that the type for the var decl:#C.b disagrees with the type we assign the component: $A.

@aschwaighofer
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 2, 2019

Build failed
Swift Test Linux Platform
Git Sha - 94a9a9a

@swift-ci
Copy link
Contributor

swift-ci commented Jan 2, 2019

Build failed
Swift Test OS X Platform
Git Sha - 94a9a9a

@jckarter
Copy link
Contributor

jckarter commented Jan 2, 2019

Ah, I misunderstood, I thought that the stored_property key had been ending up as #B.x. In that case, I think your fix is correct.

@aschwaighofer aschwaighofer merged commit a10f65b into swiftlang:master Jan 2, 2019
@slavapestov
Copy link
Contributor

@aschwaighofer Thanks for the cleanup! If this same pattern comes up in more places, we could add a SILType::getSuperclassDecl() variant too, but it's not too bad as-is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants