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

Ban registering obligations during InferCtxt snapshots. #41325

Merged
merged 6 commits into from
Apr 19, 2017

Conversation

eddyb
Copy link
Member

@eddyb eddyb commented Apr 15, 2017

Back in #33852, a flag was added to InferCtxt to prevent rolling back a snapshot if obligations were added to some FulfillmentContext during the snapshot, to prevent leaking fresh inference variables (created during that snapshot, so their indices would get reused) in obligations, which could ICE or worse.

But that isn't enough in the long run, as type-checking ends up relying on success implying that eager side-effects are fine, and while stray obligations do get caught nowadays, those errors prevent, e.g. the speculative coercions from #37658, which have to be rolled back even if they succeed.

We can't just allow those obligations to stay around though, because we end up, again, in ICEs or worse.
Instead, this PR modifies lookup_method_in_trait_adjusted to return InferOk containing the obligations that Autoderef::finalize_as_infer_ok can propagate to deref coercions.

As there shouldn't be anything left that registers obligations during snapshots, it's completely banned.

r? @nikomatsakis @arielb1

@eddyb eddyb added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 15, 2017
//
// HOWEVER, in some cases the flag is wrong. In particular, we
Copy link
Contributor

@arielb1 arielb1 Apr 15, 2017

Choose a reason for hiding this comment

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

Maybe it's better to have a within_snapshot boolean on FulfillmentCx that disables the check?

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 it's not super clear what the best option is. It's probably a good idea to tie fulfillment contexts to inference contexts (through lifetimes?) and maybe have a snapshot depth... or maybe an "epoch"?

Copy link
Contributor

Choose a reason for hiding this comment

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

Longer term, I have been hoping to just get rid of the notion of snapshots except for very short-term (e.g., to make a unification operation atomic) and then create nested fulfillment contexts for "probing sessions".

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, maybe that's not a complete answer. Still, I guess I hope that we can move things into nested contexts and generally remove the need for snapshots.

@GuillaumeGomez GuillaumeGomez mentioned this pull request Apr 15, 2017
@eddyb
Copy link
Member Author

eddyb commented Apr 16, 2017

Crater run has found one root regression.

EDIT: reproduced it (looks like obligations need to be selected eagerly for binops - Travis failure is similar):

fn main() {
    let mut s = String::new();
    s += {&String::new()};
//        ^^^^^^^^^^^^^^ expected str, found struct `std::string::String`
// note: expected type `&str`
//          found type `&std::string::String`
}  

EDIT2: pushed a fix.

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

Looks good to me, do we want to do a crater run or anything like that? I could imagine some subtle effects (as evidenced by the last commit).

@nikomatsakis
Copy link
Contributor

Ah, I see @eddyb is ahead of me here. Very good.

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Apr 17, 2017

📌 Commit cd64ff9 has been approved by nikomatsakis

@nikomatsakis
Copy link
Contributor

@bors r-

@nikomatsakis
Copy link
Contributor

Actually, @arielb1, were you satisfied? (If so, feel free to r=me, or you :)

@arielb1
Copy link
Contributor

arielb1 commented Apr 18, 2017

@bors r+

@bors
Copy link
Contributor

bors commented Apr 18, 2017

📌 Commit cd64ff9 has been approved by arielb1

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Apr 18, 2017
…=arielb1

Ban registering obligations during InferCtxt snapshots.

Back in rust-lang#33852, a flag was added to `InferCtxt` to prevent rolling back a snapshot if obligations were added to some `FulfillmentContext` during the snapshot, to prevent leaking fresh inference variables (created during that snapshot, so their indices would get reused) in obligations, which could ICE or worse.

But that isn't enough in the long run, as type-checking ends up relying on success implying that eager side-effects are fine, and while stray obligations *do* get caught nowadays, those errors prevent, e.g. the speculative coercions from rust-lang#37658, which *have to* be rolled back *even* if they succeed.

We can't just allow those obligations to stay around though, because we end up, again, in ICEs or worse.
Instead, this PR modifies `lookup_method_in_trait_adjusted` to return `InferOk` containing the obligations that `Autoderef::finalize_as_infer_ok` can propagate to deref coercions.

As there shouldn't be *anything* left that registers obligations during snapshots, it's completely banned.

r? @nikomatsakis @arielb1
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Apr 18, 2017
…=arielb1

Ban registering obligations during InferCtxt snapshots.

Back in rust-lang#33852, a flag was added to `InferCtxt` to prevent rolling back a snapshot if obligations were added to some `FulfillmentContext` during the snapshot, to prevent leaking fresh inference variables (created during that snapshot, so their indices would get reused) in obligations, which could ICE or worse.

But that isn't enough in the long run, as type-checking ends up relying on success implying that eager side-effects are fine, and while stray obligations *do* get caught nowadays, those errors prevent, e.g. the speculative coercions from rust-lang#37658, which *have to* be rolled back *even* if they succeed.

We can't just allow those obligations to stay around though, because we end up, again, in ICEs or worse.
Instead, this PR modifies `lookup_method_in_trait_adjusted` to return `InferOk` containing the obligations that `Autoderef::finalize_as_infer_ok` can propagate to deref coercions.

As there shouldn't be *anything* left that registers obligations during snapshots, it's completely banned.

r? @nikomatsakis @arielb1
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Apr 18, 2017
…=arielb1

Ban registering obligations during InferCtxt snapshots.

Back in rust-lang#33852, a flag was added to `InferCtxt` to prevent rolling back a snapshot if obligations were added to some `FulfillmentContext` during the snapshot, to prevent leaking fresh inference variables (created during that snapshot, so their indices would get reused) in obligations, which could ICE or worse.

But that isn't enough in the long run, as type-checking ends up relying on success implying that eager side-effects are fine, and while stray obligations *do* get caught nowadays, those errors prevent, e.g. the speculative coercions from rust-lang#37658, which *have to* be rolled back *even* if they succeed.

We can't just allow those obligations to stay around though, because we end up, again, in ICEs or worse.
Instead, this PR modifies `lookup_method_in_trait_adjusted` to return `InferOk` containing the obligations that `Autoderef::finalize_as_infer_ok` can propagate to deref coercions.

As there shouldn't be *anything* left that registers obligations during snapshots, it's completely banned.

r? @nikomatsakis @arielb1
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Apr 18, 2017
…=arielb1

Ban registering obligations during InferCtxt snapshots.

Back in rust-lang#33852, a flag was added to `InferCtxt` to prevent rolling back a snapshot if obligations were added to some `FulfillmentContext` during the snapshot, to prevent leaking fresh inference variables (created during that snapshot, so their indices would get reused) in obligations, which could ICE or worse.

But that isn't enough in the long run, as type-checking ends up relying on success implying that eager side-effects are fine, and while stray obligations *do* get caught nowadays, those errors prevent, e.g. the speculative coercions from rust-lang#37658, which *have to* be rolled back *even* if they succeed.

We can't just allow those obligations to stay around though, because we end up, again, in ICEs or worse.
Instead, this PR modifies `lookup_method_in_trait_adjusted` to return `InferOk` containing the obligations that `Autoderef::finalize_as_infer_ok` can propagate to deref coercions.

As there shouldn't be *anything* left that registers obligations during snapshots, it's completely banned.

r? @nikomatsakis @arielb1
@bors
Copy link
Contributor

bors commented Apr 19, 2017

⌛ Testing commit cd64ff9 with merge 467aaab...

bors added a commit that referenced this pull request Apr 19, 2017
Ban registering obligations during InferCtxt snapshots.

Back in #33852, a flag was added to `InferCtxt` to prevent rolling back a snapshot if obligations were added to some `FulfillmentContext` during the snapshot, to prevent leaking fresh inference variables (created during that snapshot, so their indices would get reused) in obligations, which could ICE or worse.

But that isn't enough in the long run, as type-checking ends up relying on success implying that eager side-effects are fine, and while stray obligations *do* get caught nowadays, those errors prevent, e.g. the speculative coercions from #37658, which *have to* be rolled back *even* if they succeed.

We can't just allow those obligations to stay around though, because we end up, again, in ICEs or worse.
Instead, this PR modifies `lookup_method_in_trait_adjusted` to return `InferOk` containing the obligations that `Autoderef::finalize_as_infer_ok` can propagate to deref coercions.

As there shouldn't be *anything* left that registers obligations during snapshots, it's completely banned.

r? @nikomatsakis @arielb1
@bors
Copy link
Contributor

bors commented Apr 19, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: arielb1
Pushing 467aaab to master...

@bors bors merged commit cd64ff9 into rust-lang:master Apr 19, 2017
@eddyb eddyb deleted the isolate-snapshots-for-good branch April 19, 2017 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants