Skip to content

AST, Sema: Teach findProtocolSelfReferences that some stdlib collections preserve variance #34140

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

Merged
merged 3 commits into from
Feb 13, 2021

Conversation

AnthonyLatsis
Copy link
Collaborator

@AnthonyLatsis AnthonyLatsis commented Oct 1, 2020

Extending this to other covariant stdlib collections is problematic due to the Hashable requirement.

@AnthonyLatsis AnthonyLatsis changed the title Coself array AST, Sema: Teach findProtocolSelfReferences that Swift.Array preserves variance of its Element Oct 1, 2020
Copy link
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

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

I think this is big enough of a change to warrant an evolution proposal. I had a brain fart and thought this was about covariance in witness matching and not calling on an existential. Still, we should get a second opinion about the soundness of this.

Does SILGen actually generate the correct conversion from Array<Self> to Array<P> when you call an Array<Self>-returning method on an existential?

@AnthonyLatsis
Copy link
Collaborator Author

Ought the conversion to be special compared to other Array upcasts? The SIL generated for let x = p.foo() looks pretty run-of-the-mill:

// takesP(arg:)
sil hidden [ossa] @$s4test6takesP3argyAA1P_p_tF : $@convention(thin) (@in_guaranteed P) -> () {
// %0 "arg"
bb0(%0 : $*P):
  debug_value_addr %0 : $*P, let, name "arg", argno 1
  %2 = open_existential_addr immutable_access %0 : $*P to $*@opened(X) P
  %3 = witness_method $@opened(X) P, #P.foo {{.*}} : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned Array<τ_0_0>
  %4 = apply %3<@opened(X) P>(%2) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned Array<τ_0_0>
  // function_ref _arrayForceCast<A, B>(_:)
  %5 = function_ref @$ss15_arrayForceCastySayq_GSayxGr0_lF : $@convention(thin) <τ_0_0, τ_0_1> (@guaranteed Array<τ_0_0>) -> @owned Array<τ_0_1>
  %6 = apply %5<@opened(X) P, P>(%4) : $@convention(thin) <τ_0_0, τ_0_1> (@guaranteed Array<τ_0_0>) -> @owned Array<τ_0_1>
  debug_value %6 : $Array<P>, let, name "x"
  destroy_value %4 : $Array<@opened(X) P>
  destroy_value %6 : $Array<P>
  %10 = tuple ()
  return %10 : $()
}

// _arrayForceCast<A, B>(_:)
sil [serialized] @$ss15_arrayForceCastySayq_GSayxGr0_lF : $@convention(thin) <τ_0_0, τ_0_1> (@guaranteed Array<τ_0_0>) -> @owned Array<τ_0_1>

I am always happy to add more tests though!

@AnthonyLatsis AnthonyLatsis changed the title AST, Sema: Teach findProtocolSelfReferences that Swift.Array preserves variance of its Element AST, Sema: Teach findProtocolSelfReferences that some stdlib collections preserve variance Oct 1, 2020
@AnthonyLatsis
Copy link
Collaborator Author

@jckarter ping

@jckarter
Copy link
Contributor

jckarter commented Dec 2, 2020

@swift-ci Please test

@jckarter
Copy link
Contributor

jckarter commented Dec 2, 2020

@swift-ci Please test source compatibility

@swift-ci
Copy link
Contributor

swift-ci commented Dec 2, 2020

Build failed
Swift Test Linux Platform
Git Sha - 87a5d058544c23163561aca14cb438825b8c6efe

@swift-ci
Copy link
Contributor

swift-ci commented Dec 2, 2020

Build failed
Swift Test OS X Platform
Git Sha - 87a5d058544c23163561aca14cb438825b8c6efe

@AnthonyLatsis
Copy link
Collaborator Author

There was a conflict.

@swift-ci please test

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please test source compatibility

@jckarter
Copy link
Contributor

jckarter commented Dec 2, 2020

I think this looks good, as long as there aren't any source compat subtleties.

@swift-ci
Copy link
Contributor

swift-ci commented Dec 2, 2020

Build failed
Swift Test Linux Platform
Git Sha - c691b4f9c5dd0be968eb502c0ae9f344a395db2a

@AnthonyLatsis
Copy link
Collaborator Author

@jckarter Thanks for taking the time to have a look!

@slavapestov Do you have any additional comments?

@swift-ci please test Linux

Copy link
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

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

Looks good. One more thing -- do you mind adding an entry to CHANGELOG.md? You can do that in a separate PR if you like.

…ons preserve variance

* Swift.Array preserves variance in its 'Element' type
* Swift.Dictionary preserves variance in its 'Value' type
@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please test

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please test source compatibility

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please smoke test

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please test source compatibility DEBUG

AnthonyLatsis added a commit to AnthonyLatsis/swift that referenced this pull request Feb 13, 2021
@AnthonyLatsis AnthonyLatsis merged commit a223d37 into swiftlang:main Feb 13, 2021
@AnthonyLatsis AnthonyLatsis deleted the coself-array branch February 13, 2021 16:45
@@ -2931,8 +2931,8 @@ ERROR(dynamic_self_non_method,none,
"%select{global|local}0 function cannot return 'Self'", (bool))

ERROR(dynamic_self_invalid,none,
"covariant 'Self' can only appear as the type of a property, subscript or method result; "
"did you mean '%0'?", (StringRef))
"covariant 'Self' can only appear as the possibly optional type of a "
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this sentence mean simply covariant Self or Self?? I struggle a little with how to parse “possibly optional type.”

Copy link
Collaborator Author

@AnthonyLatsis AnthonyLatsis Feb 13, 2021

Choose a reason for hiding this comment

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

The intention was to convey that both Self and Self? are supported. Do you happen to have a suggestion for a better wording?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps simply: "covariant 'Self' or 'Self?' can only appear as..."

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Heh, indeed. Thank you, I'll take care of this!

AnthonyLatsis added a commit that referenced this pull request Feb 16, 2021
AnthonyLatsis added a commit to AnthonyLatsis/swift that referenced this pull request Sep 3, 2021
… collection

The devirtualizer does not support handling these yet, which wasn't anticipated in swiftlang#34140
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.

6 participants