Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign uprefactor autoderef to avoid prematurely registering obligations #33852
Conversation
rust-highfive
assigned
eddyb
May 24, 2016
arielb1
changed the title
refactor autoderef to avoid registering obligations
refactor autoderef to avoid prematurely registering obligations
May 24, 2016
eddyb
reviewed
May 24, 2016
| let mut autoderef = self.autoderef(callee_expr.span, original_callee_ty); | ||
| let result = autoderef.by_ref().flat_map(|(adj_ty, idx)| { | ||
| self.try_overloaded_call_step(call_expr, callee_expr, adj_ty, idx) | ||
| }).next(); |
This comment has been minimized.
This comment has been minimized.
eddyb
reviewed
May 24, 2016
| None | ||
| } | ||
| }).2.is_some() | ||
| self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty)) |
This comment has been minimized.
This comment has been minimized.
eddyb
reviewed
May 24, 2016
| @@ -99,7 +99,7 @@ fn assign_field1<'a>(x: Own<Point>) { | |||
| } | |||
|
|
|||
| fn assign_field2<'a>(x: &'a Own<Point>) { | |||
| x.y = 3; //~ ERROR cannot assign | |||
| x.y = 3; //~ ERROR cannot borrow | |||
This comment has been minimized.
This comment has been minimized.
eddyb
May 24, 2016
Member
Is this change a bug-fix?
It seems to typeck as (*DerefMut::deref_mut(&mut *x)).y = 3; where previously it was (*Deref::deref(&*x)).y = 3;.
This comment has been minimized.
This comment has been minimized.
arielb1
May 25, 2016
Author
Contributor
Both cases are fine. The special casing that caused Deref::deref to be chosen is just plain unnecessary.
eddyb
reviewed
May 24, 2016
| None => { | ||
| let err = first_error.expect("coerce_borrowed_pointer had no error"); | ||
| debug!("coerce_borrowed_pointer: failed with err = {:?}", err); | ||
| return Err(err); | ||
| } | ||
| }; | ||
|
|
||
| autoderef.finalize(LvaluePreference::from_mutbl(mt_b.mutbl), exprs()); |
This comment has been minimized.
This comment has been minimized.
eddyb
May 24, 2016
Member
Could use a comment here explaining that this is only correct because nothing can later fail, i.e. we're guaranteed a successful coercion at this point.
eddyb
reviewed
May 24, 2016
| } | ||
|
|
||
| for obligation in self.obligations { | ||
| self.fcx.register_predicate(obligation); |
This comment has been minimized.
This comment has been minimized.
eddyb
May 24, 2016
Member
Would it be possible to make rolling back a snapshot in which obligations have been registered, into an ICE?
To prevent future misuse, I mean, you seem to have covered the existing problems.
This comment has been minimized.
This comment has been minimized.
|
#27631 is already closed btw, should it be in the description? I've noticed an observed change in behavior (picking mutable over immutable on field assignment, even through an immutable reference), and there's also the question of potentially hardening the system we have so obscure index out of bounds errors do not happen in the future. But other than that, it looks like a very nice refactoring, r=me with nits/questions addressed. |
This comment has been minimized.
This comment has been minimized.
|
updated |
This comment has been minimized.
This comment has been minimized.
|
@bors r+ |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
cc me |
nikomatsakis
reviewed
May 26, 2016
| @@ -463,24 +448,10 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { | |||
| /////////////////////////////////////////////////////////////////////////// | |||
| // RECONCILIATION | |||
|
|
|||
| /// When we select a method with an `&mut self` receiver, we have to go convert any | |||
| /// When we select a method with a mutable autoref, we have to go convert any | |||
This comment has been minimized.
This comment has been minimized.
nikomatsakis
May 26, 2016
•
Contributor
Nit: I think this comment is not as good as the one before, even if it is potentially more precise (at least in the future...). I always like to see concrete Rust code examples, particularly as our terminology tends to drift over time. :) "a mutable autoref (e.g., &mut self)" would be better, for example.
Edit: tweaked wording.
nikomatsakis
reviewed
May 26, 2016
| // e.g. `Deref` to `DerefMut` in overloaded derefs and so on). | ||
| self.fixup_derefs_on_method_receiver_if_necessary(&callee); | ||
|
|
||
| if let Some(hir::MutMutable) = pick.autoref { |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
May 26, 2016
Contributor
Nit: Sad to lose the comment here. I realize it overlaps with convert_lvalue_derefs_to_mutable, but still seems like it will it easier for readers to follow.
nikomatsakis
reviewed
May 26, 2016
| match result { | ||
| Some(r) => r, | ||
| None => { | ||
| // FIXME: this feels, like, super dubious |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
May 26, 2016
Contributor
Nit: This comment is not particularly specific... it'd be good to elaborate what you think is dubious about it :)
This comment has been minimized.
This comment has been minimized.
|
(The nits I noted aren't worth stopping bors, btw.) |
This comment has been minimized.
This comment has been minimized.
|
So, just to be sure I'm following along: the ICEs here were caused by obligations that were being registered by the autoderef code, which were then in the fulfillcx but referencing type variables added in the snapshot -- thus when we rolled back, the variables leaked out, right? Hence this fixes it by just not registering any obligations during the snapshot. This seems good -- and in general I am trying to move us more towards returning obligations back up the stack vs registering them eagerly -- though I do wonder if we will encounter problems at some point where e.g. the type that we |
eddyb
referenced this pull request
May 27, 2016
Closed
Type Checker getting confused with constraints + ICE #33904
Manishearth
added a commit
to Manishearth/rust
that referenced
this pull request
May 28, 2016
bors
added a commit
that referenced
this pull request
May 28, 2016
Manishearth
added a commit
to Manishearth/rust
that referenced
this pull request
May 28, 2016
bors
added a commit
that referenced
this pull request
May 28, 2016
bors
merged commit 040fc94
into
rust-lang:master
May 28, 2016
1 check passed
arielb1
added
the
beta-nominated
label
May 28, 2016
This comment has been minimized.
This comment has been minimized.
|
Beta-nominating for being a very annoying ICE. |
nikomatsakis
removed
the
beta-nominated
label
Jun 2, 2016
This comment has been minimized.
This comment has been minimized.
|
In @rust-lang/compiler meeting, decided not to backport:
|
arielb1 commentedMay 24, 2016
Refactor
FnCtxt::autoderefto use an external iterator and to notregister any obligation from the main autoderef loop, but rather to
register them after (and if) the loop successfully completes.
Fixes #24819
Fixes #25801
Fixes #27631
Fixes #31258
Fixes #31964
Fixes #32320
Fixes #33515
Fixes #33755
r? @eddyb