Skip to content

Commit 3eef21e

Browse files
committed
additional tests
1 parent f39e2a6 commit 3eef21e

7 files changed

+242
-4
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error[E0716]: temporary value dropped while borrowed
2+
--> $DIR/format-args-temporary-scopes.rs:40:90
3+
|
4+
LL | println!("{:?}{:?}", (), match true { true => &"" as &dyn std::fmt::Debug, false => &temp() });
5+
| ------------------------------------------------------------^^^^^---
6+
| | | |
7+
| | | temporary value is freed at the end of this statement
8+
| | creates a temporary value which is freed while still in use
9+
| borrow later used here
10+
|
11+
= note: consider using a `let` binding to create a longer lived value
12+
13+
error[E0716]: temporary value dropped while borrowed
14+
--> $DIR/format-args-temporary-scopes.rs:33:41
15+
|
16+
LL | println!("{:?}{:?}", (), if true { &format!("") } else { "" });
17+
| -----------^^^^^^^^^^^--------------
18+
| | | |
19+
| | | temporary value is freed at the end of this statement
20+
| | creates a temporary value which is freed while still in use
21+
| borrow later used here
22+
|
23+
= note: consider using a `let` binding to create a longer lived value
24+
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
25+
26+
error[E0716]: temporary value dropped while borrowed
27+
--> $DIR/format-args-temporary-scopes.rs:36:64
28+
|
29+
LL | println!("{:?}{:?}", (), if true { std::convert::identity(&format!("")) } else { "" });
30+
| ----------------------------------^^^^^^^^^^^---------------
31+
| | | |
32+
| | | temporary value is freed at the end of this statement
33+
| | creates a temporary value which is freed while still in use
34+
| borrow later used here
35+
|
36+
= note: consider using a `let` binding to create a longer lived value
37+
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
38+
39+
error: aborting due to 3 previous errors
40+
41+
For more information about this error, try `rustc --explain E0716`.

tests/ui/borrowck/format-args-temporary-scopes.e2024.stderr

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0716]: temporary value dropped while borrowed
2-
--> $DIR/format-args-temporary-scopes.rs:13:25
2+
--> $DIR/format-args-temporary-scopes.rs:12:25
33
|
44
LL | println!("{:?}", { &temp() });
55
| ---^^^^^---
@@ -11,7 +11,19 @@ LL | println!("{:?}", { &temp() });
1111
= note: consider using a `let` binding to create a longer lived value
1212

1313
error[E0716]: temporary value dropped while borrowed
14-
--> $DIR/format-args-temporary-scopes.rs:19:29
14+
--> $DIR/format-args-temporary-scopes.rs:17:48
15+
|
16+
LL | println!("{:?}", { std::convert::identity(&temp()) });
17+
| --------------------------^^^^^^---
18+
| | | |
19+
| | | temporary value is freed at the end of this statement
20+
| | creates a temporary value which is freed while still in use
21+
| borrow later used here
22+
|
23+
= note: consider using a `let` binding to create a longer lived value
24+
25+
error[E0716]: temporary value dropped while borrowed
26+
--> $DIR/format-args-temporary-scopes.rs:23:29
1527
|
1628
LL | println!("{:?}{:?}", { &temp() }, ());
1729
| ---^^^^^---
@@ -22,6 +34,56 @@ LL | println!("{:?}{:?}", { &temp() }, ());
2234
|
2335
= note: consider using a `let` binding to create a longer lived value
2436

25-
error: aborting due to 2 previous errors
37+
error[E0716]: temporary value dropped while borrowed
38+
--> $DIR/format-args-temporary-scopes.rs:26:52
39+
|
40+
LL | println!("{:?}{:?}", { std::convert::identity(&temp()) }, ());
41+
| --------------------------^^^^^^---
42+
| | | |
43+
| | | temporary value is freed at the end of this statement
44+
| | creates a temporary value which is freed while still in use
45+
| borrow later used here
46+
|
47+
= note: consider using a `let` binding to create a longer lived value
48+
49+
error[E0716]: temporary value dropped while borrowed
50+
--> $DIR/format-args-temporary-scopes.rs:40:90
51+
|
52+
LL | println!("{:?}{:?}", (), match true { true => &"" as &dyn std::fmt::Debug, false => &temp() });
53+
| ------------------------------------------------------------^^^^^---
54+
| | | |
55+
| | | temporary value is freed at the end of this statement
56+
| | creates a temporary value which is freed while still in use
57+
| borrow later used here
58+
|
59+
= note: consider using a `let` binding to create a longer lived value
60+
61+
error[E0716]: temporary value dropped while borrowed
62+
--> $DIR/format-args-temporary-scopes.rs:33:41
63+
|
64+
LL | println!("{:?}{:?}", (), if true { &format!("") } else { "" });
65+
| -^^^^^^^^^^-
66+
| || |
67+
| || temporary value is freed at the end of this statement
68+
| |creates a temporary value which is freed while still in use
69+
| borrow later used here
70+
|
71+
= note: consider using a `let` binding to create a longer lived value
72+
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
73+
74+
error[E0716]: temporary value dropped while borrowed
75+
--> $DIR/format-args-temporary-scopes.rs:36:64
76+
|
77+
LL | println!("{:?}{:?}", (), if true { std::convert::identity(&format!("")) } else { "" });
78+
| ------------------------^^^^^^^^^^^-
79+
| | | |
80+
| | | temporary value is freed at the end of this statement
81+
| | creates a temporary value which is freed while still in use
82+
| borrow later used here
83+
|
84+
= note: consider using a `let` binding to create a longer lived value
85+
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
86+
87+
error: aborting due to 7 previous errors
2688

2789
For more information about this error, try `rustc --explain E0716`.

tests/ui/borrowck/format-args-temporary-scopes.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Test for #145784 as it relates to format arguments: arguments to macros such as `println!`
22
//! should obey normal temporary scoping rules.
33
//@ revisions: e2021 e2024
4-
//@ [e2021] check-pass
54
//@ [e2021] edition: 2021
65
//@ [e2024] edition: 2024
76

@@ -13,9 +12,31 @@ fn main() {
1312
println!("{:?}", { &temp() });
1413
//[e2024]~^ ERROR: temporary value dropped while borrowed [E0716]
1514

15+
// Arguments to function calls aren't extending expressions, so `temp()` is dropped at the end
16+
// of the block in Rust 2024.
17+
println!("{:?}", { std::convert::identity(&temp()) });
18+
//[e2024]~^ ERROR: temporary value dropped while borrowed [E0716]
19+
1620
// In Rust 1.89, `format_args!` extended the lifetime of all extending expressions in its
1721
// arguments when provided with two or more arguments. This caused the result of `temp()` to
1822
// outlive the result of the block, making this compile.
1923
println!("{:?}{:?}", { &temp() }, ());
2024
//[e2024]~^ ERROR: temporary value dropped while borrowed [E0716]
25+
26+
println!("{:?}{:?}", { std::convert::identity(&temp()) }, ());
27+
//[e2024]~^ ERROR: temporary value dropped while borrowed [E0716]
28+
29+
// In real-world projects, this typically appeared in `if` expressions with a `&str` in one
30+
// branch and a reference to a `String` temporary in the other. Since the consequent and `else`
31+
// blocks of `if` expressions are temporary scopes in all editions, this affects Rust 2021 and
32+
// earlier as well.
33+
println!("{:?}{:?}", (), if true { &format!("") } else { "" });
34+
//~^ ERROR: temporary value dropped while borrowed [E0716]
35+
36+
println!("{:?}{:?}", (), if true { std::convert::identity(&format!("")) } else { "" });
37+
//~^ ERROR: temporary value dropped while borrowed [E0716]
38+
39+
// This has likewise occurred with `match`, affecting all editions.
40+
println!("{:?}{:?}", (), match true { true => &"" as &dyn std::fmt::Debug, false => &temp() });
41+
//~^ ERROR: temporary value dropped while borrowed [E0716]
2142
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//! Test that `super let` bindings in `if` expressions' blocks have the same scope as the result
2+
//! of the block.
3+
#![feature(super_let)]
4+
5+
fn main() {
6+
// For `super let` in an extending `if`, the binding `temp` should live in the scope of the
7+
// outer `let` statement.
8+
let x = if true {
9+
super let temp = ();
10+
&temp
11+
} else {
12+
super let temp = ();
13+
&temp
14+
};
15+
x;
16+
17+
// For `super let` in non-extending `if`, the binding `temp` should live in the temporary scope
18+
// the `if` expression is in.
19+
// TODO: make this not an error
20+
std::convert::identity(if true {
21+
super let temp = ();
22+
&temp
23+
//~^ ERROR `temp` does not live long enough
24+
} else {
25+
super let temp = ();
26+
&temp
27+
//~^ ERROR `temp` does not live long enough
28+
});
29+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0597]: `temp` does not live long enough
2+
--> $DIR/super-let-in-if-block.rs:22:9
3+
|
4+
LL | std::convert::identity(if true {
5+
| ---------------------- borrow later used by call
6+
LL | super let temp = ();
7+
| ---- binding `temp` declared here
8+
LL | &temp
9+
| ^^^^^ borrowed value does not live long enough
10+
LL |
11+
LL | } else {
12+
| - `temp` dropped here while still borrowed
13+
14+
error[E0597]: `temp` does not live long enough
15+
--> $DIR/super-let-in-if-block.rs:26:9
16+
|
17+
LL | std::convert::identity(if true {
18+
| ---------------------- borrow later used by call
19+
...
20+
LL | super let temp = ();
21+
| ---- binding `temp` declared here
22+
LL | &temp
23+
| ^^^^^ borrowed value does not live long enough
24+
LL |
25+
LL | });
26+
| - `temp` dropped here while still borrowed
27+
28+
error: aborting due to 2 previous errors
29+
30+
For more information about this error, try `rustc --explain E0597`.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//! Demonstrates a case where `{ super let x = temp(); &x }` =/= `&temp()`, a variant of which is
2+
//! observable on stable Rust via the `pin!` macro: `pin!($EXPR)` and `&mut $EXPR` may use different
3+
//! scopes for their temporaries.
4+
5+
#![feature(super_let)]
6+
7+
use std::pin::pin;
8+
9+
fn temp() {}
10+
11+
fn main() {
12+
// This is fine, since the temporary is extended to the end of the block:
13+
let a = &*&temp();
14+
a;
15+
let b = &mut *&mut temp();
16+
b;
17+
18+
// The temporary is dropped at the end of the outer `let` initializer:
19+
let c = &*{ super let x = temp(); &x };
20+
//~^ ERROR `x` does not live long enough
21+
c;
22+
let d = &mut *pin!(temp());
23+
//~^ ERROR temporary value dropped while borrowed
24+
d;
25+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0597]: `x` does not live long enough
2+
--> $DIR/super-let-projection-extension.rs:19:39
3+
|
4+
LL | let c = &*{ super let x = temp(); &x };
5+
| - ^^ - `x` dropped here while still borrowed
6+
| | |
7+
| | borrowed value does not live long enough
8+
| binding `x` declared here
9+
LL |
10+
LL | c;
11+
| - borrow later used here
12+
13+
error[E0716]: temporary value dropped while borrowed
14+
--> $DIR/super-let-projection-extension.rs:22:19
15+
|
16+
LL | let d = &mut *pin!(temp());
17+
| ^^^^^^^^^^^^- temporary value is freed at the end of this statement
18+
| |
19+
| creates a temporary value which is freed while still in use
20+
LL |
21+
LL | d;
22+
| - borrow later used here
23+
|
24+
= note: consider using a `let` binding to create a longer lived value
25+
= note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)
26+
27+
error: aborting due to 2 previous errors
28+
29+
Some errors have detailed explanations: E0597, E0716.
30+
For more information about an error, try `rustc --explain E0597`.

0 commit comments

Comments
 (0)