Skip to content

[CodeCompletion] Use GenericSignature methods to get 'associatedtype' requirements #29086

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

Conversation

rintaro
Copy link
Member

@rintaro rintaro commented Jan 9, 2020

instead of AssociatedTypeDecl::getInherited() when checking if the return type should be suggested as "opaque result type" in override completion.

AssociatedTypeDecl::getInherited() is not serialized. So if the protocol is declared in a module, it was never suggested as some result.

rdar://problem/57245073

Also, stop suggesting opaque result type for generic requirements:
SE-244 explicitly states that the following example cannot infer the associatedtype. So we can't use some here.

protocol P {
  associatedtype A: P
  func foo<T: P>(x: T) -> A
}

struct Foo: P {
  func foo<T: P>(x: T) -> some P {
    return x
  }
}

@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2020

@swift-ci Please smoke test

@rintaro rintaro requested a review from slavapestov January 9, 2020 01:31
…tRequirementSignature()

instead of AssociatedTypeDecl::getInherited() when checking if the
return type should be suggested as "opaque result type" in override
completion.

AssociatedTypeDecl::getInherited() is not serialized. So if the protocol
is declared in a module, it was never suggested as 'some' result.

rdar://problem/57245073
in override completion. As per SE-0244:

> Associated type inference can only infer an opaque result type for a
> non-generic requirement, because the opaque type is parameterized by
> the function's own generic arguments
@rintaro rintaro force-pushed the ide-completion-opaqueresult-rdar57245073 branch from db8a312 to 1dd6fe5 Compare January 9, 2020 01:37
@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2020

@swift-ci Please smoke test


SmallVector<Type, 2> opaqueTypes;
bool hasExplicitAnyObject = false;
for (auto req : protoD->getRequirementSignature()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of looking at the requirement signature, can you do this instead?

proto->getGenericSignature()->getConformsTo(ResultT)
proto->getGenericSignature()->getSuperclassBound(ResultT)
proto->getGenericSignature()->getLayoutConstraint(ResultT)

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks! I wasn't aware of these methods. Updated.

@rintaro rintaro force-pushed the ide-completion-opaqueresult-rdar57245073 branch from ca42ef8 to f0434f1 Compare January 9, 2020 05:03
@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2020

@swift-ci Please smoke test

@rintaro rintaro changed the title [CodeCompletion] Get associatedtype constraints from ProtocolDecl::getRequirementSignature() [CodeCompletion] Use GenericSignature methods to get 'associatedtype' requirements Jan 9, 2020
if (auto *FD = dyn_cast<FuncDecl>(VD))
if (auto *FD = dyn_cast<FuncDecl>(VD)) {
if (FD->getGenericParams()) {
// Generic function cannot have opaque result type.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this really the case? This seems to type check and compile just fine:

func foo<T>(_ t: T) -> some Any {
  return t
}

Copy link
Member Author

@rintaro rintaro Jan 9, 2020

Choose a reason for hiding this comment

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

This code is only for conformance completion.

protocol MyProtocol {}
class C: MyProtocol {}

protocol P {
  associatedtype Assoc : MyProtocol
  func foo<T>(x: T) -> Assoc
}
struct S: P {
  func foo<T>(x: T) -> some MyProtocol { return C() }
}

This S.foo(x:) cannot be used to infer S.Assoc. Even if the user explicitly adds, for instance, typealias Assoc = C, func foo<T>(x: T) -> some MyProtocol doesn't satisfy the requirement.
So we can't use some MyProtocol as a conformance completion.

else if (auto *SD = dyn_cast<SubscriptDecl>(VD))
} else if (auto *SD = dyn_cast<SubscriptDecl>(VD)) {
if (SD->getGenericParams()) {
// Generic subscript cannot have opaque result type.
Copy link
Contributor

Choose a reason for hiding this comment

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

This also works fine for me:

struct S<T> {
  subscript<U>(_ u: U) -> some Any {
    return u
  }
}

// If resolved print it.
return nullptr;

return assocTyD->getInherited()[0];
GenericSignature sig = ResultT->castTo<DependentMemberType>()
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this just VD->getDeclContext()->getGenericSignatureOfContext()?

@rintaro rintaro force-pushed the ide-completion-opaqueresult-rdar57245073 branch from f0434f1 to b9f1e58 Compare January 9, 2020 05:41
@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2020

@swift-ci Please smoke test

@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2020

@swift-ci Please smoke test Linux

2 similar comments
@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2020

@swift-ci Please smoke test Linux

@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2020

@swift-ci Please smoke test Linux

@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2020

Slava approved in person. Merging

@rintaro rintaro merged commit 90d94c8 into swiftlang:master Jan 9, 2020
@rintaro rintaro deleted the ide-completion-opaqueresult-rdar57245073 branch January 9, 2020 22:27
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.

2 participants