mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
rustc: use more correct span data in for loop desugaring
Before: help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped | LL | for x in DroppingSlice(&*v).iter(); { | + After: help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped | LL | }; | + This seems like a reasonable fix: since the desugared "expr_drop_temps_mut" contains the entire desugared loop construct, its span should contain the entire loop construct as well.
This commit is contained in:
parent
9583fd1bdd
commit
fe1a7f71fb
@ -1401,8 +1401,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
)
|
||||
};
|
||||
|
||||
// #82462: to correctly diagnose borrow errors, the block that contains
|
||||
// the iter expr needs to have a span that covers the loop body.
|
||||
let desugared_full_span =
|
||||
self.mark_span_with_reason(DesugaringKind::ForLoop(ForLoopLoc::Head), e.span, None);
|
||||
|
||||
let match_expr = self.arena.alloc(self.expr_match(
|
||||
desugared_span,
|
||||
desugared_full_span,
|
||||
into_iter_expr,
|
||||
arena_vec![self; iter_arm],
|
||||
hir::MatchSource::ForLoopDesugar,
|
||||
@ -1416,7 +1421,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// surrounding scope of the `match` since the `match` is not a terminating scope.
|
||||
//
|
||||
// Also, add the attributes to the outer returned expr node.
|
||||
self.expr_drop_temps_mut(desugared_span, match_expr, attrs.into())
|
||||
self.expr_drop_temps_mut(desugared_full_span, match_expr, attrs.into())
|
||||
}
|
||||
|
||||
/// Desugar `ExprKind::Try` from: `<expr>?` into:
|
||||
|
@ -80,7 +80,7 @@
|
||||
- StorageDead(_7); // scope 3 at $DIR/remove_storage_markers.rs:8:18: 8:19
|
||||
- StorageDead(_6); // scope 2 at $DIR/remove_storage_markers.rs:10:5: 10:6
|
||||
- StorageDead(_4); // scope 1 at $DIR/remove_storage_markers.rs:10:5: 10:6
|
||||
- StorageDead(_2); // scope 1 at $DIR/remove_storage_markers.rs:8:18: 8:19
|
||||
- StorageDead(_2); // scope 1 at $DIR/remove_storage_markers.rs:10:5: 10:6
|
||||
- StorageDead(_1); // scope 0 at $DIR/remove_storage_markers.rs:11:1: 11:2
|
||||
return; // scope 0 at $DIR/remove_storage_markers.rs:11:2: 11:2
|
||||
}
|
||||
|
22
src/test/ui/borrowck/issue-82462.nll.stderr
Normal file
22
src/test/ui/borrowck/issue-82462.nll.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/issue-82462.rs:18:9
|
||||
|
|
||||
LL | for x in DroppingSlice(&*v).iter() {
|
||||
| ------------------
|
||||
| | |
|
||||
| | immutable borrow occurs here
|
||||
| a temporary with access to the immutable borrow is created here ...
|
||||
LL | v.push(*x);
|
||||
| ^ mutable borrow occurs here
|
||||
LL | break;
|
||||
LL | }
|
||||
| - ... and the immutable borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DroppingSlice`
|
||||
|
|
||||
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
|
||||
|
|
||||
LL | };
|
||||
| +
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0502`.
|
21
src/test/ui/borrowck/issue-82462.rs
Normal file
21
src/test/ui/borrowck/issue-82462.rs
Normal file
@ -0,0 +1,21 @@
|
||||
struct DroppingSlice<'a>(&'a [i32]);
|
||||
|
||||
impl Drop for DroppingSlice<'_> {
|
||||
fn drop(&mut self) {
|
||||
println!("hi from slice");
|
||||
}
|
||||
}
|
||||
|
||||
impl DroppingSlice<'_> {
|
||||
fn iter(&self) -> std::slice::Iter<'_, i32> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut v = vec![1, 2, 3, 4];
|
||||
for x in DroppingSlice(&*v).iter() {
|
||||
v.push(*x); //~ERROR
|
||||
break;
|
||||
}
|
||||
}
|
22
src/test/ui/borrowck/issue-82462.stderr
Normal file
22
src/test/ui/borrowck/issue-82462.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/issue-82462.rs:18:9
|
||||
|
|
||||
LL | for x in DroppingSlice(&*v).iter() {
|
||||
| ------------------
|
||||
| | |
|
||||
| | immutable borrow occurs here
|
||||
| a temporary with access to the immutable borrow is created here ...
|
||||
LL | v.push(*x);
|
||||
| ^^^^^^^^^^ mutable borrow occurs here
|
||||
LL | break;
|
||||
LL | }
|
||||
| - ... and the immutable borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DroppingSlice`
|
||||
|
|
||||
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
|
||||
|
|
||||
LL | };
|
||||
| +
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0502`.
|
Loading…
Reference in New Issue
Block a user