Skip to content
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

Remove default argument from getContextualType #39592

Merged
merged 1 commit into from
Nov 8, 2021

Conversation

Jumhyn
Copy link
Member

@Jumhyn Jumhyn commented Oct 5, 2021

#39412 added a distinction between contextual types as external to the constraint system, and contextual types as they should be used in constraints. We introduced the forConstraint argument with a default value to keep the PR focused on the issue at hand—this followup removes the default argument and audits the other locations where we call getContextualType to make sure that we are using the correct 'version' of the type.

Comment on lines +2077 to +2078
if (auto contextualType =
CS.getContextualType(closure, /*forConstraint=*/false)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

@xedin Most existing uses of getContextualType were just for diagnostic purposes where we don't want opened types. This part in inferClosureType is the only one that seemed questionable but since we only use the result from the contextual type (and do the opening once we have combined with the separately inferred param types) it seemed like we shouldn't get the opened version of the type here directly. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

This type is going to be used by DefaultClosureType constraint in ConstraintGenerator::visitClosureExpr. I'd suggest we actually pass a opened contextual type to inferClosureType and remove replaceInferableTypesWithTypeVars from it and resolveClosure.

Copy link
Member Author

Choose a reason for hiding this comment

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

The use of replaceInferableTypesWithTypeVars in resolveClosure is for a type that comes from an AttachedPropertyWrapperTypeRequest, rather than a contextual type so that may require a different approach (unless I'm confused about what you're thinking).

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 I just got confused thinking about some other stuff related to resolveClosure, please disregard that bit :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Also in inferClosureType we don't use the contextual type info at all to infer the param types, we only look at the declared types. Similarly, we only use the contextual type for the result if we don't have a declared type. So if we passed in the already-opened type then we may end up with orphaned type variables in the event that inferClosureType doesn't end up using the contextual type in the constraint system. 🤔

Copy link
Member Author

@Jumhyn Jumhyn Oct 7, 2021

Choose a reason for hiding this comment

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

We already access the constraint system at that point so I don't think we need the callback, we can just call getContextualType directly:

      Type resultTy = [&] {
           // checks for explicit type
          
           // No explicit result type, let's see if there is a contextual one
           if (CS.getContextualType(closure,
                                    /*forConstraint=*/false)->is<FunctionType>()) {
               auto constraintTy = CS.getContextualType(closure,
                                                        /*forConstraint=*/true);
               return constraintTy->castTo<FunctionType>()->getResult();
           }
           ...
      }();

The problem is that as soon as we call CS.getContextualType(closure, true) to get the proper result type for a constraint we've generated type variables for the parameter type wshich will never get connected to the rest of the system.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think in your example opening would have to happen anyway because contextual type would be used in a contextual conversion constraint.

In that example we don't get the contextual type from getContextualType, we get it from getTypeForPattern via generateInitPatternConstraints, which pulls the type out from the TypedPattern directly and bypasses the contextual type map. So the type variables we end up hooking up to the system are different from the ones that we generate in getContextualType since getTypeForPattern calls replaceInferableTypesWithTypeVars itself.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ugh, this is really-really bad but okay let's keep it the way it is.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I was not excited to discover that 😅

If you're okay with merging this as-is I can next look into whether it would be feasible to use the contextual type directly in generateInitPatternConstraints/getTypeForPattern to avoid this issue, but I suspect that will potentially have wider reaching effects that should be addressed separately from this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I think it's okay to merge it as-is, thank you!

@Jumhyn Jumhyn requested a review from xedin October 5, 2021 21:16
@Jumhyn
Copy link
Member Author

Jumhyn commented Oct 5, 2021

@swift-ci please smoke test

@Jumhyn
Copy link
Member Author

Jumhyn commented Oct 6, 2021

@swift-ci please smoke test Windows Platform

1 similar comment
@Jumhyn
Copy link
Member Author

Jumhyn commented Oct 8, 2021

@swift-ci please smoke test Windows Platform

@Jumhyn
Copy link
Member Author

Jumhyn commented Oct 23, 2021

@swift-ci please smoke test windows platform

1 similar comment
@Jumhyn
Copy link
Member Author

Jumhyn commented Nov 7, 2021

@swift-ci please smoke test windows platform

@Jumhyn
Copy link
Member Author

Jumhyn commented Nov 7, 2021

@xedin Sorry, started a new job and let this one fall off the radar. Still good to merge?

@xedin
Copy link
Contributor

xedin commented Nov 8, 2021

Yeah, let's get this in, thank you, @Jumhyn!

@xedin xedin merged commit 0c70f56 into swiftlang:main Nov 8, 2021
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