Skip to content

Sema: Arrange TypeCheckType to open unbound generics on the fly #32116

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
Jul 8, 2020

Conversation

AnthonyLatsis
Copy link
Collaborator

@AnthonyLatsis AnthonyLatsis commented Jun 1, 2020

Lays the groundwork for sinking UnboundGenericType to unblock #31895. The idea was put forth by Slava over here. NFC expected, because for now the "opener" is used as intended only where unbound generics were already being handled in-place; the remaining type resolution sites that allow unbound generics to escape are now marked with FIXMEs. With this much we are safe to nuke TypeResolutionFlags::AllowUnboundGenerics and start addressing these FIXMEs incrementally.

@AnthonyLatsis
Copy link
Collaborator Author

@davidungar This change uncovered what looks like an ASTScope expansion bug:

class Outer {
  class Inner {}
}

extension Outer.Inner {
  func foo(arg: Inner) {} // Could not find `Inner` in scope
}

My prints are telling me that name lookup is hopping straight to file scope from the extension. Could you offer me some guidance here? Where exactly is the parent scope decided upon?

Type parentType =
resolveTypeReferenceInExpression(enumPattern->getParentType());
Type parentType = resolveTypeReferenceInExpression(
enumPattern->getParentType(), [](auto unboundTy) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We oughta make a functor for the no-op case a default argument to both functions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The no-op is a temporary hack. I figured writing them out explicitly with FIXMEs is a good idea, rather than defaulting the parameter.

if (isSILMode) {
options |= TypeResolutionFlags::SILMode;
}
if (isSILType)
options |= TypeResolutionFlags::SILType;

auto resolution = TypeResolution::forContextual(DC, GenericEnv, options);
const auto resolution =
TypeResolution::forContextual(DC, GenericEnv, options,
Copy link
Contributor

Choose a reason for hiding this comment

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

Another candidate for a default

Copy link
Contributor

@CodaFi CodaFi left a comment

Choose a reason for hiding this comment

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

The approach here looks fine, just picking around the edges mostly. We can take the simpler changes to TypeCheckType (removal of dead parameters and such) now if you would like to split them.

@CodaFi
Copy link
Contributor

CodaFi commented Jun 1, 2020

My prints are telling me that name lookup is hopping straight to file scope from the extension. Could you offer me some guidance here? Where exactly is the parent scope decided upon?

You don't have to worry about that - it's a pre-existing limitation of name lookup in extensions of nested types.

@AnthonyLatsis
Copy link
Collaborator Author

AnthonyLatsis commented Jun 1, 2020

We can take the simpler changes to TypeCheckType (removal of dead parameters and such) now if you would like to split them.

Thanks for taking a look! I was able to remove the isSpecialized parameter by encapsulating and moving generic argument inference out of resolveTypeInContext, but there are still a couple of annoying test failures due to this. Anything else like the removal of a factory constructor on TypeResolution is fairly minor and can wait.

@AnthonyLatsis AnthonyLatsis marked this pull request as ready for review June 2, 2020 05:53
@AnthonyLatsis AnthonyLatsis force-pushed the eliminate-unbound branch 4 times, most recently from ecf74a5 to 33fe6d0 Compare June 11, 2020 13:22
@AnthonyLatsis AnthonyLatsis changed the title Sema: Allow TypeResolution to accept a callback for opening unbound generics Sema: Arrange TypeCheckType to open unbound generics on the fly Jun 11, 2020
@AnthonyLatsis AnthonyLatsis force-pushed the eliminate-unbound branch 3 times, most recently from 9b37bcc to 2ace225 Compare June 11, 2020 19:16
@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please smoke test

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please test source compatibility release

@AnthonyLatsis
Copy link
Collaborator Author

Alright, this is now ready for review.

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please smoke test macOS

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please smoke test

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please test source compatibility release

@CodaFi CodaFi requested review from xedin and CodaFi June 12, 2020 22:57
Copy link
Contributor

@CodaFi CodaFi left a comment

Choose a reason for hiding this comment

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

This looks a lot better, thanks! Let’s see what Slava and Pavel have to say.

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 for the underlying type of a type alias, the right way to handle it is to desugar the typealias into a generic one. Eg,

typealias Foo = Array

is really the same as

typealias Foo<Element> = Array<Element>

TypeResolution::forContextual(
CS.DC, None,
// FIXME: Should we really unconditionally complain
// about unbound generics here?
Copy link
Contributor

Choose a reason for hiding this comment

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

if they're truly invalid, then instead of complaining, we should be ensuring that the TypeResolution's context kind and so on doesn't allow them in the first place.

Copy link
Collaborator Author

@AnthonyLatsis AnthonyLatsis Jun 16, 2020

Choose a reason for hiding this comment

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

Perhaps the sentence is flawed. What I meant to convey is that we may want to someday reconsider complaining about unbound generics here (we do complain today). For example:

let foo: [Array<Float>] = [[3], [4], [5]] as [Array] // error

@AnthonyLatsis
Copy link
Collaborator Author

@xedin ping

@slavapestov
Copy link
Contributor

@AnthonyLatsis IMO this is ready to merge.

@AnthonyLatsis
Copy link
Collaborator Author

@slavapestov recd. Needs another rebase though.

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please smoke test and merge

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please smoke test and merge

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please smoke test

@AnthonyLatsis AnthonyLatsis merged commit f558eb3 into swiftlang:master Jul 8, 2020
@AnthonyLatsis AnthonyLatsis deleted the eliminate-unbound branch July 8, 2020 14:28
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