Skip to content

[Diagnostics] Type-check return of the multi-statement closure without applying solutions #6481

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 3 commits into from
Jan 4, 2017

Conversation

xedin
Copy link
Contributor

@xedin xedin commented Dec 23, 2016

Obtain type of the result expression without applying solutions,
because otherwise this might result in leaking of type variables,
since we are not reseting result statement and if expression is
sucessfully type-checked it's type cleanup is going to be disabled
(we are allowing unresolved types), and as a side-effect it might
also be transformed e.g. OverloadedDeclRefExpr -> DeclRefExpr.

@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

/cc @rudkx @DougGregor @slavapestov

Resolves 8 related crashers.

@slavapestov
Copy link
Contributor

You're a beast!

@slavapestov
Copy link
Contributor

@swift-ci Please smoke test

// Obtain type of the result expression without applying solutions,
// because otherwise this might result in leaking of type variables,
// since we are not reseting result statement and if expression is
// sucessfully type-checked it's type cleanup is going to be disabled
Copy link
Contributor

Choose a reason for hiding this comment

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

it's -> its

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, i just can't spell... :(

@xedin xedin force-pushed the diagnose-closure-return branch from 0702cb1 to 7e9af10 Compare December 23, 2016 08:01
…t apply solutions

Obtain type of the result expression without applying solutions,
because otherwise this might result in leaking of type variables,
since we are not reseting result statement and if expression is
sucessfully type-checked its type cleanup is going to be disabled
(we are allowing unresolved types), and as a side-effect it might
also be transformed e.g. OverloadedDeclRefExpr -> DeclRefExpr.
@xedin xedin force-pushed the diagnose-closure-return branch from 7e9af10 to f42fa36 Compare December 23, 2016 08:02
@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

@slavapestov @erg Fixed typo, sorry about that...

@slavapestov
Copy link
Contributor

I just let @practicalswift fix all my typos

@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

@slavapestov That sounds great! :) Can you please re-trigger tests, since I had to push force?...

@rudkx
Copy link
Contributor

rudkx commented Dec 23, 2016

@swift-ci Please smoke test

@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

Thanks, @rudkx!

@rudkx
Copy link
Contributor

rudkx commented Dec 23, 2016

@xedin I think this is a fine fix but a bit of a buzzkill since my (mostly but not totally complete) changes for keeping a separate side map for types in the constraint system would have fixed these! :)

@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

@rudkx ah, I can close this and wait for your changes, that's totally fine

@rudkx
Copy link
Contributor

rudkx commented Dec 23, 2016

@xedin Ha no, let's let this go through. My changes will potentially fix other cases and keep these from leaking in the future.

@slavapestov
Copy link
Contributor

CI is down right now. I'll trigger tests tomorrow.

@slavapestov
Copy link
Contributor

@rudkx Does your change make CSApple completely idempotent or does it still insert expressions for conversions? If the latter then not applying the solution unnecessarily when all you need is a type still makes sense IMO.

@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

@rudkx Sounds good! And I actually didn't expect that there are going to be so many crashers fixed by this... :)

@slavapestov thanks!

@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

@slavapestov I think that one of the biggest problems with diagnostics right now is that typeCheckChildIndendently and friends are mutating AST, it makes (at least) diagnosing of ApplyExpr way harder than it could be, because sometimes you need to have original expression as well as mutated expression like in case of contextual conversion diagnostics...

@slavapestov
Copy link
Contributor

Yeah. Also another big issue is that lazy vars without a declared type have the initializer type checker twice, once to determine the type and another time when they're re-parented into the getter. I added a hack recently to fix one common crash but I still haven't figured out a better solution. Two ideas so far:

  • Emit trivial accessors in SILGen, just like we do with materializeForSet. This might be independently good, since it's simpler, less memory usage, etc. SILGen already knows how to emit a reference to a variable initializer.

  • Figure out a way to infer the type of a variable from an initializer without applying a solution to the initializer. Then we can special case lazy to do that since the solution is applied as part of type checking the getter.

I think we might want both for independent reasons. Thoughts?

@rudkx
Copy link
Contributor

rudkx commented Dec 23, 2016

@slavapestov Yes, that's one of the reasons I still think we should take this (although it's not just CSApply that modifies expressions - that can happen for things that fail to type check as well).

@slavapestov
Copy link
Contributor

But with the side table we should be able to get the type of something without mutating it right?

Also it's not clear to me if CSApply can fail even after the solver succeeds. I know of one case where we don't implement a tuple conversion, and a few random cases can fail when stdlib declarations are missing, but we should tighten this up as much as possible.

@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

@slavapestov I think I know exactly what you are talking about (I mentioned that I the other issue):

protocol A {
   func foo()
}

struct B {
  lazy var a = A.foo
}

@slavapestov
Copy link
Contributor

That's a nice reduction!

@slavapestov
Copy link
Contributor

Well, A.foo is broken for other reasons too. It's missing SILGen support to generate the right thunk that opens the 'self' parameter when A is a protocol. Maybe a good project if you want to get into SILGen :-)

@xedin
Copy link
Contributor Author

xedin commented Dec 23, 2016

@slavapestov I can definitely take a look at that! Another question I have is should we be producing diagnostic in this case, which says something like - "cannot use result of assignment operation as a value"?

var x = 0
x = x = 42

Because that is completely broken for closure parameters e.g.

{ $0 = $0 = 0}

Because $0 are marked as equivalent in type system, and my old friend computeAssignDestType makes a binding Lvalue type variable it erases connections in the constraint system...

@practicalswift
Copy link
Contributor

Good stuff! The number of unresolved crashers are quickly approaching zero.

Must scale up my fuzzing efforts to dig deeper! :-)

@xedin
Copy link
Contributor Author

xedin commented Dec 24, 2016

@slavapestov @rudkx Looks like there were 7 more tests which this change fixed, which were marked as 'REQUIRES: deterministic-behavior' (all related to return statement type-checking), I've marked all of them as fixed in separate commit.

@xedin xedin force-pushed the diagnose-closure-return branch from 9e9cadd to 546a8f5 Compare December 24, 2016 11:34
@xedin xedin force-pushed the diagnose-closure-return branch from 546a8f5 to 3a61fba Compare December 24, 2016 11:34
@practicalswift
Copy link
Contributor

@xedin That's great! The non-deterministic crashers are the worst!

@rudkx
Copy link
Contributor

rudkx commented Dec 24, 2016

@xedin Yeah that's not too surprising. All of the ones I had looked at were leaking type variables.

@slavapestov
Copy link
Contributor

Awesome!

@slavapestov
Copy link
Contributor

Hey @xedin, two fun ones are 28594 and 28501. In both cases, we have an erroneously-placed _=nil expression, and we fail to produce a diagnostic, which triggers verifier asserts (we get a decl with an ErrorType and an UnresolvedDeclRefExpr, respectively). Since you're getting pretty good at CSDiag, do you want to take a look?

@xedin
Copy link
Contributor Author

xedin commented Dec 24, 2016

@slavapestov I will work on that next then, thanks!

… unresolved parameters

If return expression uses closure parameters, which have/are
type variables, such means that we won't be be able to
type-check result correctly and, unfornutately,
we are going to leak type variables from the parent
constraint system through declaration types.
@xedin
Copy link
Contributor Author

xedin commented Dec 28, 2016

@slavapestov I've fixed two more crashers in context of this PR (pushed a separate commit) - 28449 and 28473, short story is - trying to type-check return expression which involves closure parameters is going to leak type variables from the parent system in some cases...

@xedin
Copy link
Contributor Author

xedin commented Jan 3, 2017

@slavapestov @rudkx Looks like CI is back in business, can you please trigger it?

@slavapestov
Copy link
Contributor

You can't merge yet... let's wait for the more important fixes to go in before we deal with the crasher-fix-backlog :-)

@xedin
Copy link
Contributor Author

xedin commented Jan 3, 2017

@slavapestov Absolutely and sorry...

@slavapestov
Copy link
Contributor

No worries! Just give us a couple of hours to clean up.

@slavapestov
Copy link
Contributor

@swift-ci Please smoke test

@xedin
Copy link
Contributor Author

xedin commented Jan 4, 2017

@slavapestov I didn't report any test failures but build-script itself failed without any details on Linux :(

@slavapestov
Copy link
Contributor

@swift-ci Please smoke test Linux

@slavapestov slavapestov self-assigned this Jan 4, 2017
@slavapestov slavapestov merged commit 5da7e10 into swiftlang:master Jan 4, 2017
@DougGregor
Copy link
Member

This is fantastic, thanks!

@rudkx
Copy link
Contributor

rudkx commented Jan 5, 2017

@xedin I wonder if this might have fixed some of the crashers currently marked non-deterministic. E.g. I cannot seem to reproduce the crash in validation-test/compiler_crashers/28447-result-case-not-implemented-failed.swift.

Does anybody want to volunteer to try to re-enable all those tests and run through them N times (where N is high enough that we don't accidentally break CI) before submitting a PR to move the ones that appear fixed to compiler_crashers_fixed?

@xedin
Copy link
Contributor Author

xedin commented Jan 5, 2017

@rudkx I thought I got most of the ones marked as non-deterministic but apparently not :) I'll have another go through all of the remaining crashers, thanks!

@xedin
Copy link
Contributor Author

xedin commented Jan 9, 2017

@rudkx I've tried all three remaining tests marked as "deterministic-behavior" and they seem legit.

@rudkx
Copy link
Contributor

rudkx commented Jan 9, 2017

@xedin You mean legitimately non-deterministic?

@xedin
Copy link
Contributor Author

xedin commented Jan 9, 2017

@rudkx Yes, I run them in the loop 50 times, sometimes they fail with escaped type var or invalid declaration, or segfault and sometimes not at all. The one you mentioned - 28447 - was marked resolved by @practicalswift in separate commit, that's why I didn't include it...

@rudkx
Copy link
Contributor

rudkx commented Jan 9, 2017

@xedin Ah, thanks for the clarification!

@xedin
Copy link
Contributor Author

xedin commented Jan 9, 2017

@rudkx No problem! :)

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.

6 participants