-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[CodeCompletion] Don’t report a call pattern as convertible if its result type doesn’t match #72568
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
[CodeCompletion] Don’t report a call pattern as convertible if its result type doesn’t match #72568
Conversation
…nction that takes a parameter pack The issue here was that we inferred the contextual type of the `Mixer` call to be the following, inferred from the result type of the partial call to the initializer of `Mixer` ``` (bound_generic_struct_type decl="swift_ide_test.(file).Mixer@/Users/alex/src/swift/test/IDE/complete_parameter_pack_as_call_argument.swift:3:8" (pack_type num_elements=1 (pack_expansion_type (pattern=unresolved_type) (count=unresolved_type)))) ``` Technically, the contextual type that we should have here should be `Any` (from `print`) but getting that information out of the constraint system turns out to be quite hard. swiftlang#72568 makes some improvements in this area but in general the constraint system does not contain enough information to figure out the contextual type of an arbitrary expression. The important thing right now is that the unresolved type in here trips the constraint system over when comparing types of code completion results with the contextual type. To prevent the crash for now, reset the expected call type if the computed type contains an unresolved type. rdar://124166587 Co-authored-by: Pavel Yaskevich <[email protected]>
…nction that takes a parameter pack The issue here was that we inferred the contextual type of the `Mixer` call to be the following, inferred from the result type of the partial call to the initializer of `Mixer` ``` (bound_generic_struct_type decl="swift_ide_test.(file).Mixer@/Users/alex/src/swift/test/IDE/complete_parameter_pack_as_call_argument.swift:3:8" (pack_type num_elements=1 (pack_expansion_type (pattern=unresolved_type) (count=unresolved_type)))) ``` Technically, the contextual type that we should have here should be `Any` (from `print`) but getting that information out of the constraint system turns out to be quite hard. swiftlang#72568 makes some improvements in this area but in general the constraint system does not contain enough information to figure out the contextual type of an arbitrary expression. The important thing right now is that the unresolved type in here trips the constraint system over when comparing types of code completion results with the contextual type. To prevent the crash for now, reset the expected call type if the computed type contains an unresolved type. rdar://124166587 Co-authored-by: Pavel Yaskevich <[email protected]>
@swift-ci Please smoke test |
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.
Looks reasonable
e703ba6
to
29b7947
Compare
@swift-ci Please smoke test |
lib/Sema/CSSimplify.cpp
Outdated
bool isSynthesizedArg = arg->isImplicit() && isa<DeclRefExpr>(arg); | ||
if (!isSynthesizedArg && containsIDEInspectionTarget(arg) && | ||
!lhs->isVoid() && !lhs->isUninhabited()) | ||
fixBehavior = FixBehavior::Suppress; |
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.
I replied about this in the other PR, I think we need a better way here.
…sult type doesn’t match To compute the expected type of a call pattern (which is the return type of the function if that call pattern is being used), we called `getTypeForCompletion` for the entire call, in the same way that we do for the code completion token. However, this pattern does not generally work. For the code completion token it worked because the code completion expression doesn’t have an inherent type and it inherits the type solely from its context. Calls, however, have an inherent return type and that type gets assigned as the `typeForCompletion`. Implement targeted checks for the two most common cases where an expected type exists: If the call that we suggest call patterns for is itself an argument to another function or if it is used in a place that has a contextual type in the constraint system (eg. a variable binding or a `return` statement). This means that we no longer return `Convertible` for call patterns in some more complex scenarios. But given that this information was computed based on incorrect results and that in those cases all call patterns had a `Convertible` type relation, I think that’s acceptable. Fixing this would require recording more information in the constraints system, which is out-of-scope for now.
29b7947
to
278ecef
Compare
@swift-ci Please smoke test |
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.
we no longer return Convertible for call patterns in some more complex scenarios.
let's improve this in follow-ups
…nction that takes a parameter pack The issue here was that we inferred the contextual type of the `Mixer` call to be the following, inferred from the result type of the partial call to the initializer of `Mixer` ``` (bound_generic_struct_type decl="swift_ide_test.(file).Mixer@/Users/alex/src/swift/test/IDE/complete_parameter_pack_as_call_argument.swift:3:8" (pack_type num_elements=1 (pack_expansion_type (pattern=unresolved_type) (count=unresolved_type)))) ``` Technically, the contextual type that we should have here should be `Any` (from `print`) but getting that information out of the constraint system turns out to be quite hard. swiftlang#72568 makes some improvements in this area but in general the constraint system does not contain enough information to figure out the contextual type of an arbitrary expression. The important thing right now is that the unresolved type in here trips the constraint system over when comparing types of code completion results with the contextual type. To prevent the crash for now, reset the expected call type if the computed type contains an unresolved type. rdar://124166587 Co-authored-by: Pavel Yaskevich <[email protected]>
…nction that takes a parameter pack The issue here was that we inferred the contextual type of the `Mixer` call to be the following, inferred from the result type of the partial call to the initializer of `Mixer` ``` (bound_generic_struct_type decl="swift_ide_test.(file).Mixer@/Users/alex/src/swift/test/IDE/complete_parameter_pack_as_call_argument.swift:3:8" (pack_type num_elements=1 (pack_expansion_type (pattern=unresolved_type) (count=unresolved_type)))) ``` Technically, the contextual type that we should have here should be `Any` (from `print`) but getting that information out of the constraint system turns out to be quite hard. swiftlang#72568 makes some improvements in this area but in general the constraint system does not contain enough information to figure out the contextual type of an arbitrary expression. The important thing right now is that the unresolved type in here trips the constraint system over when comparing types of code completion results with the contextual type. To prevent the crash for now, reset the expected call type if the computed type contains an unresolved type. rdar://124166587 Co-authored-by: Pavel Yaskevich <[email protected]>
…nction that takes a parameter pack The issue here was that we inferred the contextual type of the `Mixer` call to be the following, inferred from the result type of the partial call to the initializer of `Mixer` ``` (bound_generic_struct_type decl="swift_ide_test.(file).Mixer@/Users/alex/src/swift/test/IDE/complete_parameter_pack_as_call_argument.swift:3:8" (pack_type num_elements=1 (pack_expansion_type (pattern=unresolved_type) (count=unresolved_type)))) ``` Technically, the contextual type that we should have here should be `Any` (from `print`) but getting that information out of the constraint system turns out to be quite hard. swiftlang#72568 makes some improvements in this area but in general the constraint system does not contain enough information to figure out the contextual type of an arbitrary expression. The important thing right now is that the unresolved type in here trips the constraint system over when comparing types of code completion results with the contextual type. To prevent the crash for now, reset the expected call type if the computed type contains an unresolved type. rdar://124166587 Co-authored-by: Pavel Yaskevich <[email protected]>
To compute the expected type of a call pattern (which is the return type of the function if that call pattern is being used), we called
getTypeForCompletion
for the entire call, in the same way that we do for the code completion token. However, this pattern does not generally work. For the code completion token it worked because the code completion expression doesn’t have an inherent type and it inherits the type solely from its context. Calls, however, have an inherent return type and that type gets assigned as thetypeForCompletion
.Implement targeted checks for the two most common cases where an expected type exists: If the call that we suggest call patterns for is itself an argument to another function or if it is used in a place that has a contextual type in the constraint system (eg. a variable binding or a
return
statement). This means that we no longer returnConvertible
for call patterns in some more complex scenarios. But given that this information was computed based on incorrect results and that in those cases all call patterns had aConvertible
type relation, I think that’s acceptable. Fixing this would require recording more information in the constraints system, which is out-of-scope for now.