Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,8 @@ fn resolve_local<'tcx>(
/// | [ ..., E&, ... ]
/// | ( ..., E&, ... )
/// | {...; E&}
/// | if _ { ...; E& } else { ...; E& }
/// | match _ { ..., _ => E&, ... }
/// | box E&
/// | E& as ...
/// | ( E& )
Expand Down Expand Up @@ -727,6 +729,17 @@ fn resolve_local<'tcx>(
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
}
}
hir::ExprKind::If(_, then_block, else_block) => {
record_rvalue_scope_if_borrow_expr(visitor, then_block, blk_id);
if let Some(else_block) = else_block {
record_rvalue_scope_if_borrow_expr(visitor, else_block, blk_id);
}
}
hir::ExprKind::Match(_, arms, _) => {
for arm in arms {
record_rvalue_scope_if_borrow_expr(visitor, arm.body, blk_id);
}
}
hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) => {
// FIXME(@dingxiangfei2009): choose call arguments here
// for candidacy for extended parameter rule application
Expand Down
30 changes: 18 additions & 12 deletions tests/ui/borrowck/let_underscore_temporary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ fn let_underscore(string: &Option<&str>, mut num: Option<i32>) {
*s += 1;
s
} else {
&mut 0
//~^ ERROR temporary value dropped while borrowed
let a = 0;
&a
//~^ ERROR does not live long enough
};
let _ = if let Some(ref s) = num { s } else { &0 };
let _ = if let Some(mut s) = num {
Expand All @@ -21,8 +22,9 @@ fn let_underscore(string: &Option<&str>, mut num: Option<i32>) {
*s += 1;
s
} else {
&mut 0
//~^ ERROR temporary value dropped while borrowed
let a = 0;
&a
//~^ ERROR does not live long enough
};
}

Expand All @@ -33,8 +35,9 @@ fn let_ascribe(string: &Option<&str>, mut num: Option<i32>) {
*s += 1;
s
} else {
&mut 0
//~^ ERROR temporary value dropped while borrowed
let a = 0;
&a
//~^ ERROR does not live long enough
};
let _: _ = if let Some(ref s) = num { s } else { &0 };
let _: _ = if let Some(mut s) = num {
Expand All @@ -47,8 +50,9 @@ fn let_ascribe(string: &Option<&str>, mut num: Option<i32>) {
*s += 1;
s
} else {
&mut 0
//~^ ERROR temporary value dropped while borrowed
let a = 0;
&a
//~^ ERROR does not live long enough
};
}

Expand All @@ -63,8 +67,9 @@ fn matched(string: &Option<&str>, mut num: Option<i32>) {
*s += 1;
s
} else {
&mut 0
//~^ ERROR temporary value dropped while borrowed
let a = 0;
&a
//~^ ERROR does not live long enough
} {
_ => {}
};
Expand All @@ -83,8 +88,9 @@ fn matched(string: &Option<&str>, mut num: Option<i32>) {
*s += 1;
s
} else {
&mut 0
//~^ ERROR temporary value dropped while borrowed
let a = 0;
&a
//~^ ERROR does not live long enough
} {
_ => {}
};
Expand Down
158 changes: 55 additions & 103 deletions tests/ui/borrowck/let_underscore_temporary.stderr
Original file line number Diff line number Diff line change
@@ -1,117 +1,69 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/let_underscore_temporary.rs:10:14
error[E0597]: `a` does not live long enough
--> $DIR/let_underscore_temporary.rs:11:9
|
LL | let _ = if let Some(s) = &mut num {
| _____________-
LL | | *s += 1;
LL | | s
LL | | } else {
LL | | &mut 0
| | ^ creates a temporary value which is freed while still in use
LL | |
LL | | };
| | -
| | |
| |_____temporary value is freed at the end of this statement
| borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
LL | let a = 0;
| - binding `a` declared here
LL | &a
| ^^ borrowed value does not live long enough
LL |
LL | };
| - `a` dropped here while still borrowed

error[E0716]: temporary value dropped while borrowed
--> $DIR/let_underscore_temporary.rs:24:14
|
LL | let _ = if let Some(ref mut s) = num {
| _____________-
LL | | *s += 1;
LL | | s
LL | | } else {
LL | | &mut 0
| | ^ creates a temporary value which is freed while still in use
LL | |
LL | | };
| | -
| | |
| |_____temporary value is freed at the end of this statement
| borrow later used here
error[E0597]: `a` does not live long enough
--> $DIR/let_underscore_temporary.rs:26:9
|
= note: consider using a `let` binding to create a longer lived value
LL | let a = 0;
| - binding `a` declared here
LL | &a
| ^^ borrowed value does not live long enough
LL |
LL | };
| - `a` dropped here while still borrowed

error[E0716]: temporary value dropped while borrowed
--> $DIR/let_underscore_temporary.rs:36:14
|
LL | let _: _ = if let Some(s) = &mut num {
| ________________-
LL | | *s += 1;
LL | | s
LL | | } else {
LL | | &mut 0
| | ^ creates a temporary value which is freed while still in use
LL | |
LL | | };
| | -
| | |
| |_____temporary value is freed at the end of this statement
| borrow later used here
error[E0597]: `a` does not live long enough
--> $DIR/let_underscore_temporary.rs:39:9
|
= note: consider using a `let` binding to create a longer lived value
LL | let a = 0;
| - binding `a` declared here
LL | &a
| ^^ borrowed value does not live long enough
LL |
LL | };
| - `a` dropped here while still borrowed

error[E0716]: temporary value dropped while borrowed
--> $DIR/let_underscore_temporary.rs:50:14
error[E0597]: `a` does not live long enough
--> $DIR/let_underscore_temporary.rs:54:9
|
LL | let _: _ = if let Some(ref mut s) = num {
| ________________-
LL | | *s += 1;
LL | | s
LL | | } else {
LL | | &mut 0
| | ^ creates a temporary value which is freed while still in use
LL | |
LL | | };
| | -
| | |
| |_____temporary value is freed at the end of this statement
| borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
LL | let a = 0;
| - binding `a` declared here
LL | &a
| ^^ borrowed value does not live long enough
LL |
LL | };
| - `a` dropped here while still borrowed

error[E0716]: temporary value dropped while borrowed
--> $DIR/let_underscore_temporary.rs:66:14
|
LL | match if let Some(s) = &mut num {
| ___________-
LL | | *s += 1;
LL | | s
LL | | } else {
LL | | &mut 0
| | ^ creates a temporary value which is freed while still in use
LL | |
LL | | } {
| | -
| | |
| |_____temporary value is freed at the end of this statement
| borrow later used here
error[E0597]: `a` does not live long enough
--> $DIR/let_underscore_temporary.rs:71:9
|
= note: consider using a `let` binding to create a longer lived value
LL | let a = 0;
| - binding `a` declared here
LL | &a
| ^^ borrowed value does not live long enough
LL |
LL | } {
| - `a` dropped here while still borrowed

error[E0716]: temporary value dropped while borrowed
--> $DIR/let_underscore_temporary.rs:86:14
|
LL | match if let Some(ref mut s) = num {
| ___________-
LL | | *s += 1;
LL | | s
LL | | } else {
LL | | &mut 0
| | ^ creates a temporary value which is freed while still in use
LL | |
LL | | } {
| | -
| | |
| |_____temporary value is freed at the end of this statement
| borrow later used here
error[E0597]: `a` does not live long enough
--> $DIR/let_underscore_temporary.rs:92:9
|
= note: consider using a `let` binding to create a longer lived value
LL | let a = 0;
| - binding `a` declared here
LL | &a
| ^^ borrowed value does not live long enough
LL |
LL | } {
| - `a` dropped here while still borrowed

error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0716`.
For more information about this error, try `rustc --explain E0597`.
33 changes: 33 additions & 0 deletions tests/ui/lifetimes/temporary-lifetime-extension.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//@ check-pass

fn temp() -> (String, i32) {
(String::from("Hello"), 1)
}

fn main() {
let a = &temp();
let b = [(&temp(),)];
let c = &temp().0;
let d = &temp().0[..];
let e = {
let _ = 123;
&(*temp().0)[..]
};
let f = if true {
&temp()
} else {
&temp()
};
let g = match true {
true => &temp(),
false => {
let _ = 123;
&temp()
}
};
let h = match temp() {
// The {} moves the value, making a new temporary.
owned_non_temporary => &{ owned_non_temporary },
};
println!("{a:?} {b:?} {c:?} {d:?} {e:?} {f:?} {g:?} {h:?}");
}