Skip to content

[NFC] More InOut Cleanup #12559

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 2 commits into from
Oct 22, 2017
Merged

[NFC] More InOut Cleanup #12559

merged 2 commits into from
Oct 22, 2017

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Oct 22, 2017

Trying to do two things here (and do them without hurting anything)

  • Remove more uses of <InOutType>()
  • Make coercing patterns stop resetting specifiers on variables - this was just for a diagnostic anyways.
    - Teach CSBindings what to do with declrefs for closure parameters.

@CodaFi CodaFi requested a review from xedin October 22, 2017 06:04
@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 22, 2017

@swift-ci please test

@@ -400,6 +400,11 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) {
if (type->hasError())
continue;

// If we're not allowed to bind to an InOut type, try to bind to the
// underlying type instead.
if (!typeVar->getImpl().canBindToInOut() && typeVar->getImpl().canBindToLValue())
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems wrong...

Copy link
Contributor Author

@CodaFi CodaFi Oct 22, 2017

Choose a reason for hiding this comment

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

Oddly enough, it does the right thing. For this, the alternative is to let the binding through: Then we bind x to inout Int transitively and matchTypes never has a chance to suggest the fix.

func f0(_ : inout Int) {}
let g = { x in f0(x) }

Copy link
Contributor Author

@CodaFi CodaFi Oct 22, 2017

Choose a reason for hiding this comment

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

Which is a symptom of inout inference being a thing at all with closures. It's not valid in general to propagate from the declref back to the parameter if there's an intervening inout. We should instead be trying to bind the parameter from the closure to the call's parameter but that's a larger change.

Copy link
Contributor

@slavapestov slavapestov Oct 22, 2017

Choose a reason for hiding this comment

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

Closures already use separate type variables for the 'external' parameter type and 'internal' parameter type. For example, if the 'external' type is inout T, the 'internal' type is @lvalue T. They are related with a BindParam constraint.

Maybe this is not plumbed all the way through.

In your example, getOpenedTypeOfReference() should return a type variable, say $T1, for x. The type of the closure expression as generated by CSGen should involve a different type variable, $T0. There should be a BindParam constraint between $T0 and $T1.

Am I thinking of something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Closure inference specifically does not open the type of the declref for closure parameters and throws in its own BindParam constraint.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's just the part where we create a second 'internal' type variable and relate it with the original 'external' type variable via a BindParam constraint, which is what I was talking about above.

Copy link
Contributor

Choose a reason for hiding this comment

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

so, can you figure out what's going wrong here? :-) I'm not convinced your change is the correct fix for the problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well that constraint is the root of all this trouble. I'll revert the last commit and come up with something more clever

Copy link
Contributor

Choose a reason for hiding this comment

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

Could it be that 'edge contraction' or some other optimization pass is performing an invalid transformation on the constraint graph before the solver runs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought @xedin stopped that kind of contraction from being performed a while ago.

@@ -2180,6 +2180,27 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
auto resultTy = typeCheckExpression(initializer, DC, contextualType,
contextualPurpose, flags, &listener);
if (resultTy) {
// If we detected that the initializer would
Copy link
Contributor

Choose a reason for hiding this comment

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

Incomplete comment

@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 22, 2017

@swift-ci please test source compatibility

Move this from the validation phase into the phase where we check the
binding.  The type checker no longer has to reset the specifier for
VarDecls.
@CodaFi
Copy link
Contributor Author

CodaFi commented Oct 22, 2017

Scaled back to trivial changes

@swift-ci please smoke test and merge

@swift-ci swift-ci merged commit e4ddd56 into swiftlang:master Oct 22, 2017
@CodaFi CodaFi deleted the inouthouse branch October 22, 2017 09:13
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