Skip to content

Commit ade745e

Browse files
authored
Rollup merge of #140593 - m-ou-se:some-temp, r=Nadrieril
Temporary lifetime extension through tuple struct and tuple variant constructors This makes temporary lifetime extension work for tuple struct and tuple variant constructors, such as `Some()`. Before: ```rust let a = &temp(); // Extended let a = Some(&temp()); // Not extended :( let a = Some { 0: &temp() }; // Extended ``` After: ```rust let a = &temp(); // Extended let a = Some(&temp()); // Extended let a = Some { 0: &temp() }; // Extended ``` So, with this change, this works: ```rust let a = Some(&String::from("hello")); // New: String lifetime now extended! println!("{a:?}"); ``` Until now, we did not extend through tuple struct/variant constructors (like `Some`), because they are function calls syntactically, and we do not want to extend the String lifetime in: ```rust let a = some_function(&String::from("hello")); // String not extended! ``` However, it turns out to be very easy to distinguish between regular functions and constructors at the point where we do lifetime extension. In practice, constructors nearly always use UpperCamelCase while regular functions use lower_snake_case, so it should still be easy to for a human programmer at the call site to see whether something qualifies for lifetime extension or not. This needs a lang fcp. --- More examples of what will work after this change: ```rust let x = Person { name: "Ferris", job: Some(&Job { // `Job` now extended! title: "Chief Rustacean", organisation: "Acme Ltd.", }), }; dbg!(x); ``` ```rust let file = if use_stdout { None } else { Some(&File::create("asdf")?) // `File` now extended! }; set_logger(file); ``` ```rust use std::path::Component; let c = Component::Normal(&OsString::from(format!("test-{num}"))); // OsString now extended! assert_eq!(path.components.first().unwrap(), c); ```
2 parents 64033a4 + 855ea48 commit ade745e

14 files changed

+138
-139
lines changed

compiler/rustc_hir_analysis/src/check/region.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::mem;
1010

1111
use rustc_data_structures::fx::FxHashMap;
1212
use rustc_hir as hir;
13+
use rustc_hir::def::{CtorKind, DefKind, Res};
1314
use rustc_hir::def_id::DefId;
1415
use rustc_hir::intravisit::{self, Visitor};
1516
use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt};
@@ -752,13 +753,19 @@ fn resolve_local<'tcx>(
752753
record_rvalue_scope_if_borrow_expr(visitor, arm.body, blk_id);
753754
}
754755
}
755-
hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) => {
756-
// FIXME(@dingxiangfei2009): choose call arguments here
757-
// for candidacy for extended parameter rule application
758-
}
759-
hir::ExprKind::Index(..) => {
760-
// FIXME(@dingxiangfei2009): select the indices
761-
// as candidate for rvalue scope rules
756+
hir::ExprKind::Call(func, args) => {
757+
// Recurse into tuple constructors, such as `Some(&temp())`.
758+
//
759+
// That way, there is no difference between `Some(..)` and `Some { 0: .. }`,
760+
// even though the former is syntactically a function call.
761+
if let hir::ExprKind::Path(path) = &func.kind
762+
&& let hir::QPath::Resolved(None, path) = path
763+
&& let Res::SelfCtor(_) | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) = path.res
764+
{
765+
for arg in args {
766+
record_rvalue_scope_if_borrow_expr(visitor, arg, blk_id);
767+
}
768+
}
762769
}
763770
_ => {}
764771
}

src/tools/tidy/src/issues.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,6 @@ ui/consts/issue-46553.rs
754754
ui/consts/issue-47789.rs
755755
ui/consts/issue-50439.rs
756756
ui/consts/issue-52023-array-size-pointer-cast.rs
757-
ui/consts/issue-54224.rs
758757
ui/consts/issue-54348.rs
759758
ui/consts/issue-54387.rs
760759
ui/consts/issue-54582.rs

tests/ui/consts/const-mut-refs/mut_ref_in_final.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed
1818
const B2: Option<&mut i32> = None;
1919

2020
// Not ok, can't prove that no mutable allocation ends up in final value
21-
const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR temporary value dropped while borrowed
21+
const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR mutable references are not allowed
2222

2323
const fn helper(x: &mut i32) -> Option<&mut i32> { Some(x) }
2424
const B4: Option<&mut i32> = helper(&mut 42); //~ ERROR temporary value dropped while borrowed

tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@ error[E0764]: mutable references are not allowed in the final value of constants
44
LL | const B: *mut i32 = &mut 4;
55
| ^^^^^^
66

7-
error[E0716]: temporary value dropped while borrowed
8-
--> $DIR/mut_ref_in_final.rs:21:40
7+
error[E0764]: mutable references are not allowed in the final value of constants
8+
--> $DIR/mut_ref_in_final.rs:21:35
99
|
1010
LL | const B3: Option<&mut i32> = Some(&mut 42);
11-
| ----------^^-
12-
| | | |
13-
| | | temporary value is freed at the end of this statement
14-
| | creates a temporary value which is freed while still in use
15-
| using this value as a constant requires that borrow lasts for `'static`
11+
| ^^^^^^^
1612

1713
error[E0716]: temporary value dropped while borrowed
1814
--> $DIR/mut_ref_in_final.rs:24:42

tests/ui/consts/issue-54224.rs

Lines changed: 0 additions & 12 deletions
This file was deleted.

tests/ui/consts/issue-54224.stderr

Lines changed: 0 additions & 23 deletions
This file was deleted.

tests/ui/consts/promote-not.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
#![allow(unconditional_panic)]
44

55
use std::cell::Cell;
6+
use std::convert::identity;
67
use std::mem::ManuallyDrop;
78

89
// We do not promote mutable references.
9-
static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]); //~ ERROR temporary value dropped while borrowed
10+
static mut TEST1: &mut [i32] = identity(&mut [1, 2, 3]); //~ ERROR temporary value dropped while borrowed
1011

1112
static mut TEST2: &'static mut [i32] = {
1213
let x = &mut [1,2,3]; //~ ERROR temporary value dropped while borrowed

tests/ui/consts/promote-not.stderr

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
error[E0716]: temporary value dropped while borrowed
2-
--> $DIR/promote-not.rs:9:50
2+
--> $DIR/promote-not.rs:10:46
33
|
4-
LL | static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]);
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-
| using this value as a static requires that borrow lasts for `'static`
4+
LL | static mut TEST1: &mut [i32] = identity(&mut [1, 2, 3]);
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+
| using this value as a static requires that borrow lasts for `'static`
1010

1111
error[E0716]: temporary value dropped while borrowed
12-
--> $DIR/promote-not.rs:12:18
12+
--> $DIR/promote-not.rs:13:18
1313
|
1414
LL | let x = &mut [1,2,3];
1515
| ^^^^^^^ creates a temporary value which is freed while still in use
@@ -19,7 +19,7 @@ LL | };
1919
| - temporary value is freed at the end of this statement
2020

2121
error[E0716]: temporary value dropped while borrowed
22-
--> $DIR/promote-not.rs:34:29
22+
--> $DIR/promote-not.rs:35:29
2323
|
2424
LL | let _x: &'static i32 = &unsafe { U { x: 0 }.x };
2525
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -29,7 +29,7 @@ LL | };
2929
| - temporary value is freed at the end of this statement
3030

3131
error[E0716]: temporary value dropped while borrowed
32-
--> $DIR/promote-not.rs:40:29
32+
--> $DIR/promote-not.rs:41:29
3333
|
3434
LL | let _val: &'static _ = &(Cell::new(1), 2).1;
3535
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -39,7 +39,7 @@ LL | };
3939
| - temporary value is freed at the end of this statement
4040

4141
error[E0493]: destructor of `String` cannot be evaluated at compile-time
42-
--> $DIR/promote-not.rs:47:14
42+
--> $DIR/promote-not.rs:48:14
4343
|
4444
LL | let x = &String::new();
4545
| ^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants
@@ -48,7 +48,7 @@ LL | };
4848
| - value is dropped here
4949

5050
error[E0716]: temporary value dropped while borrowed
51-
--> $DIR/promote-not.rs:59:33
51+
--> $DIR/promote-not.rs:60:33
5252
|
5353
LL | let _x: &'static u32 = &mk_panic();
5454
| ------------ ^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -58,7 +58,7 @@ LL | }
5858
| - temporary value is freed at the end of this statement
5959

6060
error[E0716]: temporary value dropped while borrowed
61-
--> $DIR/promote-not.rs:21:32
61+
--> $DIR/promote-not.rs:22:32
6262
|
6363
LL | let _x: &'static () = &foo();
6464
| ----------- ^^^^^ creates a temporary value which is freed while still in use
@@ -68,7 +68,7 @@ LL | }
6868
| - temporary value is freed at the end of this statement
6969

7070
error[E0716]: temporary value dropped while borrowed
71-
--> $DIR/promote-not.rs:29:29
71+
--> $DIR/promote-not.rs:30:29
7272
|
7373
LL | let _x: &'static i32 = &unsafe { U { x: 0 }.x };
7474
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -78,7 +78,7 @@ LL | }
7878
| - temporary value is freed at the end of this statement
7979

8080
error[E0716]: temporary value dropped while borrowed
81-
--> $DIR/promote-not.rs:65:29
81+
--> $DIR/promote-not.rs:66:29
8282
|
8383
LL | let _val: &'static _ = &(Cell::new(1), 2).0;
8484
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -89,7 +89,7 @@ LL | }
8989
| - temporary value is freed at the end of this statement
9090

9191
error[E0716]: temporary value dropped while borrowed
92-
--> $DIR/promote-not.rs:66:29
92+
--> $DIR/promote-not.rs:67:29
9393
|
9494
LL | let _val: &'static _ = &(Cell::new(1), 2).1;
9595
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -100,7 +100,7 @@ LL | }
100100
| - temporary value is freed at the end of this statement
101101

102102
error[E0716]: temporary value dropped while borrowed
103-
--> $DIR/promote-not.rs:69:29
103+
--> $DIR/promote-not.rs:70:29
104104
|
105105
LL | let _val: &'static _ = &(1/0);
106106
| ---------- ^^^^^ creates a temporary value which is freed while still in use
@@ -111,7 +111,7 @@ LL | }
111111
| - temporary value is freed at the end of this statement
112112

113113
error[E0716]: temporary value dropped while borrowed
114-
--> $DIR/promote-not.rs:70:29
114+
--> $DIR/promote-not.rs:71:29
115115
|
116116
LL | let _val: &'static _ = &(1/(1-1));
117117
| ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -122,7 +122,7 @@ LL | }
122122
| - temporary value is freed at the end of this statement
123123

124124
error[E0716]: temporary value dropped while borrowed
125-
--> $DIR/promote-not.rs:71:29
125+
--> $DIR/promote-not.rs:72:29
126126
|
127127
LL | let _val: &'static _ = &((1+1)/(1-1));
128128
| ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -133,7 +133,7 @@ LL | }
133133
| - temporary value is freed at the end of this statement
134134

135135
error[E0716]: temporary value dropped while borrowed
136-
--> $DIR/promote-not.rs:72:29
136+
--> $DIR/promote-not.rs:73:29
137137
|
138138
LL | let _val: &'static _ = &(i32::MIN/-1);
139139
| ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -144,7 +144,7 @@ LL | }
144144
| - temporary value is freed at the end of this statement
145145

146146
error[E0716]: temporary value dropped while borrowed
147-
--> $DIR/promote-not.rs:73:29
147+
--> $DIR/promote-not.rs:74:29
148148
|
149149
LL | let _val: &'static _ = &(i32::MIN/(0-1));
150150
| ---------- ^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -155,7 +155,7 @@ LL | }
155155
| - temporary value is freed at the end of this statement
156156

157157
error[E0716]: temporary value dropped while borrowed
158-
--> $DIR/promote-not.rs:74:29
158+
--> $DIR/promote-not.rs:75:29
159159
|
160160
LL | let _val: &'static _ = &(-128i8/-1);
161161
| ---------- ^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -166,7 +166,7 @@ LL | }
166166
| - temporary value is freed at the end of this statement
167167

168168
error[E0716]: temporary value dropped while borrowed
169-
--> $DIR/promote-not.rs:75:29
169+
--> $DIR/promote-not.rs:76:29
170170
|
171171
LL | let _val: &'static _ = &(1%0);
172172
| ---------- ^^^^^ creates a temporary value which is freed while still in use
@@ -177,7 +177,7 @@ LL | }
177177
| - temporary value is freed at the end of this statement
178178

179179
error[E0716]: temporary value dropped while borrowed
180-
--> $DIR/promote-not.rs:76:29
180+
--> $DIR/promote-not.rs:77:29
181181
|
182182
LL | let _val: &'static _ = &(1%(1-1));
183183
| ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -188,7 +188,7 @@ LL | }
188188
| - temporary value is freed at the end of this statement
189189

190190
error[E0716]: temporary value dropped while borrowed
191-
--> $DIR/promote-not.rs:77:29
191+
--> $DIR/promote-not.rs:78:29
192192
|
193193
LL | let _val: &'static _ = &([1,2,3][4]+1);
194194
| ---------- ^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -199,7 +199,7 @@ LL | }
199199
| - temporary value is freed at the end of this statement
200200

201201
error[E0716]: temporary value dropped while borrowed
202-
--> $DIR/promote-not.rs:81:29
202+
--> $DIR/promote-not.rs:82:29
203203
|
204204
LL | let _val: &'static _ = &TEST_DROP;
205205
| ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -210,7 +210,7 @@ LL | }
210210
| - temporary value is freed at the end of this statement
211211

212212
error[E0716]: temporary value dropped while borrowed
213-
--> $DIR/promote-not.rs:83:29
213+
--> $DIR/promote-not.rs:84:29
214214
|
215215
LL | let _val: &'static _ = &&TEST_DROP;
216216
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -221,7 +221,7 @@ LL | }
221221
| - temporary value is freed at the end of this statement
222222

223223
error[E0716]: temporary value dropped while borrowed
224-
--> $DIR/promote-not.rs:83:30
224+
--> $DIR/promote-not.rs:84:30
225225
|
226226
LL | let _val: &'static _ = &&TEST_DROP;
227227
| ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -232,7 +232,7 @@ LL | }
232232
| - temporary value is freed at the end of this statement
233233

234234
error[E0716]: temporary value dropped while borrowed
235-
--> $DIR/promote-not.rs:86:29
235+
--> $DIR/promote-not.rs:87:29
236236
|
237237
LL | let _val: &'static _ = &(&TEST_DROP,);
238238
| ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -243,7 +243,7 @@ LL | }
243243
| - temporary value is freed at the end of this statement
244244

245245
error[E0716]: temporary value dropped while borrowed
246-
--> $DIR/promote-not.rs:86:31
246+
--> $DIR/promote-not.rs:87:31
247247
|
248248
LL | let _val: &'static _ = &(&TEST_DROP,);
249249
| ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -254,7 +254,7 @@ LL | }
254254
| - temporary value is freed at the end of this statement
255255

256256
error[E0716]: temporary value dropped while borrowed
257-
--> $DIR/promote-not.rs:89:29
257+
--> $DIR/promote-not.rs:90:29
258258
|
259259
LL | let _val: &'static _ = &[&TEST_DROP; 1];
260260
| ---------- ^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -265,7 +265,7 @@ LL | }
265265
| - temporary value is freed at the end of this statement
266266

267267
error[E0716]: temporary value dropped while borrowed
268-
--> $DIR/promote-not.rs:89:31
268+
--> $DIR/promote-not.rs:90:31
269269
|
270270
LL | let _val: &'static _ = &[&TEST_DROP; 1];
271271
| ---------- ^^^^^^^^^ - temporary value is freed at the end of this statement
@@ -274,7 +274,7 @@ LL | let _val: &'static _ = &[&TEST_DROP; 1];
274274
| type annotation requires that borrow lasts for `'static`
275275

276276
error[E0716]: temporary value dropped while borrowed
277-
--> $DIR/promote-not.rs:98:26
277+
--> $DIR/promote-not.rs:99:26
278278
|
279279
LL | let x: &'static _ = &UnionWithCell { f1: 0 };
280280
| ---------- ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use

tests/ui/coroutine/auto-trait-regions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ fn main() {
4343
// Disallow impls which relates lifetimes in the coroutine interior
4444
let gen = #[coroutine] move || {
4545
let a = A(&mut true, &mut true, No);
46-
//~^ ERROR temporary value dropped while borrowed
47-
//~| ERROR temporary value dropped while borrowed
46+
//~^ ERROR borrow may still be in use when coroutine yields
47+
//~| ERROR borrow may still be in use when coroutine yields
4848
yield;
4949
assert_foo(a);
5050
};

0 commit comments

Comments
 (0)