Skip to content

[CodeCompletion] Unresolved member completion at type parameter position #21249

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 1 commit into from
Jan 9, 2019

Conversation

rintaro
Copy link
Member

@rintaro rintaro commented Dec 12, 2018

Enable unresolved member completion at generic parameter type context. e.g.

protocol HasStatic {
  static var instance: Self { get }
}

func foo<T: HasStatic>() -> T {
  return .#^HERE^#
}

We need to map GenericTypeParamType to ArchetypeType to lookup its members.

rdar://problem/46657585

@rintaro rintaro requested a review from benlangmuir December 12, 2018 11:24
@rintaro
Copy link
Member Author

rintaro commented Dec 12, 2018

@swift-ci Please smoke test

@@ -3697,8 +3700,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
}

// Otherwise, check the result type matches the contextual type.
auto declTy = getTypeOfMember(VD, T);
if (declTy->hasError())
auto declTy = T->getTypeOfMember(CurrModule, VD);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand what effect this change has. getTypeOfMember in code-completion seems to do a bunch of things that the one on TypeBase doesn't, including eraseArchetypes, and they also use different substitution flags. We currently are trying hard to avoid having archetypes leak into results where they show up badly when printed, per the comment on eraseArchetypes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Are the changes below to mapTypeIntoContext supposed to rectify this? If so, how does that compare to eraseArchetypes?

Copy link
Member Author

@rintaro rintaro Dec 12, 2018

Choose a reason for hiding this comment

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

We want to keep ArchetypeType here because T might be an ArchetypeType and we want to check if result of declTy is convertible to T.

Let's say T is archetype U which conforms to HasStatic protocol and VD is static var instance: Self { get }, getTypeOfMember(VD, T) returns HasStatic protocol, but that is not convertible to archetype U. But T->getTypeOfMember(CurrModule, VD) correctly returns U.

This is just a filtering logic that checks VD can be referenced by "implicit member expression" syntax in T type context. The result of declTy isn't used anywhere else. The type name for completion result is re-constructed by result builder.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, thanks for explaining!

ty = ty->getRValueType();
if (ty->hasTypeParameter())
if (auto env = DC->getGenericEnvironmentOfContext())
ty = env->mapTypeIntoContext(ty);
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 legal to do with any target DeclContext, or is this relying on DC being related to the context we originally got this type from?

Copy link
Member Author

@rintaro rintaro Dec 13, 2018

Choose a reason for hiding this comment

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

To be honest, I'm not sure about this. But I guess the DeclContext should be the context where the parameter is declared. I updated the PR so that it extract decl context from the GenericTypeParamType itself. @slavapestov am I doing the right thing?

Copy link
Contributor

Choose a reason for hiding this comment

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

You want to use the DeclContext of the function itself.

ty = ty->getRValueType();

// Convert 'GenericTypeParamType' to 'ArchetypeType'.
if (ty->hasTypeParameter()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can replace this whole block with DC->mapTypeIntoContext(ty). Please don't use GenericTypeParamType::getDecl().

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! Updated the PR.

@rintaro rintaro force-pushed the ide-completion-rdar46657585 branch from 22f81a0 to aee4b17 Compare December 25, 2018 05:25
@rintaro
Copy link
Member Author

rintaro commented Dec 25, 2018

@swift-ci Please smoke test

@rintaro rintaro force-pushed the ide-completion-rdar46657585 branch from aee4b17 to 62bb886 Compare December 25, 2018 05:53
@rintaro
Copy link
Member Author

rintaro commented Dec 25, 2018

@swift-ci Please smoke test

1 similar comment
@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2019

@swift-ci Please smoke test

We need to map 'GenericTypeParamType' to 'ArchetypeType' to lookup its
members.

rdar://problem/46657585
@rintaro rintaro force-pushed the ide-completion-rdar46657585 branch from 62bb886 to 4b39c20 Compare January 9, 2019 05:45
@rintaro
Copy link
Member Author

rintaro commented Jan 9, 2019

@swift-ci Please smoke test

@rintaro rintaro merged commit 7cb2c9b into swiftlang:master Jan 9, 2019
@rintaro rintaro deleted the ide-completion-rdar46657585 branch January 9, 2019 06:44
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.

3 participants