Do not default to 'static for trait object lifetimes

We lack trait object default lifetime elision, so `'static` can be wrong at times, confusing the user
This commit is contained in:
Lukas Wirth 2025-06-18 14:28:04 +02:00
parent df50136c23
commit 2b05bd7d7e
12 changed files with 70 additions and 70 deletions

View file

@ -711,7 +711,7 @@ impl<'a> TyLoweringContext<'a> {
.unwrap_or(it), .unwrap_or(it),
None => it, None => it,
}, },
None => static_lifetime(), None => error_lifetime(),
}, },
}) })
.intern(Interner) .intern(Interner)

View file

@ -561,7 +561,7 @@ trait Foo {}
fn test(f: impl Foo, g: &(impl Foo + ?Sized)) { fn test(f: impl Foo, g: &(impl Foo + ?Sized)) {
let _: &dyn Foo = &f; let _: &dyn Foo = &f;
let _: &dyn Foo = g; let _: &dyn Foo = g;
//^ expected &'? (dyn Foo + 'static), got &'? impl Foo + ?Sized //^ expected &'? (dyn Foo + '?), got &'? impl Foo + ?Sized
} }
"#, "#,
); );

View file

@ -67,11 +67,11 @@ trait B: A {}
fn test<'a>( fn test<'a>(
_: &(dyn A<Assoc = ()> + Send), _: &(dyn A<Assoc = ()> + Send),
//^ &(dyn A<Assoc = ()> + Send + 'static) //^ &(dyn A<Assoc = ()> + Send)
_: &'a (dyn Send + A<Assoc = ()>), _: &'a (dyn Send + A<Assoc = ()>),
//^ &'a (dyn A<Assoc = ()> + Send + 'static) //^ &'a (dyn A<Assoc = ()> + Send)
_: &dyn B<Assoc = ()>, _: &dyn B<Assoc = ()>,
//^ &(dyn B<Assoc = ()> + 'static) //^ &(dyn B<Assoc = ()>)
) {} ) {}
"#, "#,
); );
@ -85,7 +85,7 @@ fn render_dyn_for_ty() {
trait Foo<'a> {} trait Foo<'a> {}
fn foo(foo: &dyn for<'a> Foo<'a>) {} fn foo(foo: &dyn for<'a> Foo<'a>) {}
// ^^^ &(dyn Foo<'?> + 'static) // ^^^ &dyn Foo<'?>
"#, "#,
); );
} }

View file

@ -1153,9 +1153,9 @@ fn dyn_trait_super_trait_not_in_scope() {
51..55 'self': &'? Self 51..55 'self': &'? Self
64..69 '{ 0 }': u32 64..69 '{ 0 }': u32
66..67 '0': u32 66..67 '0': u32
176..177 'd': &'? (dyn Trait + 'static) 176..177 'd': &'? (dyn Trait + '?)
191..207 '{ ...o(); }': () 191..207 '{ ...o(); }': ()
197..198 'd': &'? (dyn Trait + 'static) 197..198 'd': &'? (dyn Trait + '?)
197..204 'd.foo()': u32 197..204 'd.foo()': u32
"#]], "#]],
); );
@ -2019,10 +2019,10 @@ impl dyn Error + Send {
/// Attempts to downcast the box to a concrete type. /// Attempts to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> { pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
let err: Box<dyn Error> = self; let err: Box<dyn Error> = self;
// ^^^^ expected Box<dyn Error + 'static>, got Box<dyn Error + Send + 'static> // ^^^^ expected Box<dyn Error + '?>, got Box<dyn Error + Send + '?>
// FIXME, type mismatch should not occur // FIXME, type mismatch should not occur
<dyn Error>::downcast(err).map_err(|_| loop {}) <dyn Error>::downcast(err).map_err(|_| loop {})
//^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + 'static>) -> Result<Box<{unknown}>, Box<dyn Error + 'static>> //^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + '?>) -> Result<Box<{unknown}>, Box<dyn Error + '?>>
} }
} }
"#, "#,

View file

@ -629,7 +629,7 @@ fn issue_4053_diesel_where_clauses() {
488..522 '{ ... }': () 488..522 '{ ... }': ()
498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> 498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
498..508 'self.order': O 498..508 'self.order': O
498..515 'self.o...into()': dyn QueryFragment<DB> + 'static 498..515 'self.o...into()': dyn QueryFragment<DB> + '?
"#]], "#]],
); );
} }
@ -773,7 +773,7 @@ fn issue_4800() {
"#, "#,
expect![[r#" expect![[r#"
379..383 'self': &'? mut PeerSet<D> 379..383 'self': &'? mut PeerSet<D>
401..424 '{ ... }': dyn Future<Output = ()> + 'static 401..424 '{ ... }': dyn Future<Output = ()> + '?
411..418 'loop {}': ! 411..418 'loop {}': !
416..418 '{}': () 416..418 '{}': ()
575..579 'self': &'? mut Self 575..579 'self': &'? mut Self

View file

@ -2741,11 +2741,11 @@ impl B for Astruct {}
715..744 '#[rust...1i32])': Box<[i32; 1], Global> 715..744 '#[rust...1i32])': Box<[i32; 1], Global>
737..743 '[1i32]': [i32; 1] 737..743 '[1i32]': [i32; 1]
738..742 '1i32': i32 738..742 '1i32': i32
755..756 'v': Vec<Box<dyn B + 'static, Global>, Global> 755..756 'v': Vec<Box<dyn B + '?, Global>, Global>
776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B + 'static, Global>, Global>(Box<[Box<dyn B + 'static, Global>], Global>) -> Vec<Box<dyn B + 'static, Global>, Global> 776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B + '?, Global>, Global>(Box<[Box<dyn B + '?, Global>], Global>) -> Vec<Box<dyn B + '?, Global>, Global>
776..850 '<[_]> ...ct)]))': Vec<Box<dyn B + 'static, Global>, Global> 776..850 '<[_]> ...ct)]))': Vec<Box<dyn B + '?, Global>, Global>
794..849 '#[rust...uct)])': Box<[Box<dyn B + 'static, Global>; 1], Global> 794..849 '#[rust...uct)])': Box<[Box<dyn B + '?, Global>; 1], Global>
816..848 '[#[rus...ruct)]': [Box<dyn B + 'static, Global>; 1] 816..848 '[#[rus...ruct)]': [Box<dyn B + '?, Global>; 1]
817..847 '#[rust...truct)': Box<Astruct, Global> 817..847 '#[rust...truct)': Box<Astruct, Global>
839..846 'Astruct': Astruct 839..846 'Astruct': Astruct
"#]], "#]],

View file

@ -1475,26 +1475,26 @@ fn test(x: Box<dyn Trait<u64>>, y: &dyn Trait<u64>) {
expect![[r#" expect![[r#"
29..33 'self': &'? Self 29..33 'self': &'? Self
54..58 'self': &'? Self 54..58 'self': &'? Self
198..200 '{}': Box<dyn Trait<u64> + 'static> 198..200 '{}': Box<dyn Trait<u64> + '?>
210..211 'x': Box<dyn Trait<u64> + 'static> 210..211 'x': Box<dyn Trait<u64> + '?>
234..235 'y': &'? (dyn Trait<u64> + 'static) 234..235 'y': &'? (dyn Trait<u64> + '?)
254..371 '{ ...2(); }': () 254..371 '{ ...2(); }': ()
260..261 'x': Box<dyn Trait<u64> + 'static> 260..261 'x': Box<dyn Trait<u64> + '?>
267..268 'y': &'? (dyn Trait<u64> + 'static) 267..268 'y': &'? (dyn Trait<u64> + '?)
278..279 'z': Box<dyn Trait<u64> + 'static> 278..279 'z': Box<dyn Trait<u64> + '?>
282..285 'bar': fn bar() -> Box<dyn Trait<u64> + 'static> 282..285 'bar': fn bar() -> Box<dyn Trait<u64> + '?>
282..287 'bar()': Box<dyn Trait<u64> + 'static> 282..287 'bar()': Box<dyn Trait<u64> + '?>
293..294 'x': Box<dyn Trait<u64> + 'static> 293..294 'x': Box<dyn Trait<u64> + '?>
293..300 'x.foo()': u64 293..300 'x.foo()': u64
306..307 'y': &'? (dyn Trait<u64> + 'static) 306..307 'y': &'? (dyn Trait<u64> + '?)
306..313 'y.foo()': u64 306..313 'y.foo()': u64
319..320 'z': Box<dyn Trait<u64> + 'static> 319..320 'z': Box<dyn Trait<u64> + '?>
319..326 'z.foo()': u64 319..326 'z.foo()': u64
332..333 'x': Box<dyn Trait<u64> + 'static> 332..333 'x': Box<dyn Trait<u64> + '?>
332..340 'x.foo2()': i64 332..340 'x.foo2()': i64
346..347 'y': &'? (dyn Trait<u64> + 'static) 346..347 'y': &'? (dyn Trait<u64> + '?)
346..354 'y.foo2()': i64 346..354 'y.foo2()': i64
360..361 'z': Box<dyn Trait<u64> + 'static> 360..361 'z': Box<dyn Trait<u64> + '?>
360..368 'z.foo2()': i64 360..368 'z.foo2()': i64
"#]], "#]],
); );
@ -1523,14 +1523,14 @@ fn test(s: S<u32, i32>) {
expect![[r#" expect![[r#"
32..36 'self': &'? Self 32..36 'self': &'? Self
102..106 'self': &'? S<T, U> 102..106 'self': &'? S<T, U>
128..139 '{ loop {} }': &'? (dyn Trait<T, U> + 'static) 128..139 '{ loop {} }': &'? (dyn Trait<T, U> + '?)
130..137 'loop {}': ! 130..137 'loop {}': !
135..137 '{}': () 135..137 '{}': ()
175..179 'self': &'? Self 175..179 'self': &'? Self
251..252 's': S<u32, i32> 251..252 's': S<u32, i32>
267..289 '{ ...z(); }': () 267..289 '{ ...z(); }': ()
273..274 's': S<u32, i32> 273..274 's': S<u32, i32>
273..280 's.bar()': &'? (dyn Trait<u32, i32> + 'static) 273..280 's.bar()': &'? (dyn Trait<u32, i32> + '?)
273..286 's.bar().baz()': (u32, i32) 273..286 's.bar().baz()': (u32, i32)
"#]], "#]],
); );
@ -1556,20 +1556,20 @@ fn test(x: Trait, y: &Trait) -> u64 {
}"#, }"#,
expect![[r#" expect![[r#"
26..30 'self': &'? Self 26..30 'self': &'? Self
60..62 '{}': dyn Trait + 'static 60..62 '{}': dyn Trait + '?
72..73 'x': dyn Trait + 'static 72..73 'x': dyn Trait + '?
82..83 'y': &'? (dyn Trait + 'static) 82..83 'y': &'? (dyn Trait + '?)
100..175 '{ ...o(); }': u64 100..175 '{ ...o(); }': u64
106..107 'x': dyn Trait + 'static 106..107 'x': dyn Trait + '?
113..114 'y': &'? (dyn Trait + 'static) 113..114 'y': &'? (dyn Trait + '?)
124..125 'z': dyn Trait + 'static 124..125 'z': dyn Trait + '?
128..131 'bar': fn bar() -> dyn Trait + 'static 128..131 'bar': fn bar() -> dyn Trait + '?
128..133 'bar()': dyn Trait + 'static 128..133 'bar()': dyn Trait + '?
139..140 'x': dyn Trait + 'static 139..140 'x': dyn Trait + '?
139..146 'x.foo()': u64 139..146 'x.foo()': u64
152..153 'y': &'? (dyn Trait + 'static) 152..153 'y': &'? (dyn Trait + '?)
152..159 'y.foo()': u64 152..159 'y.foo()': u64
165..166 'z': dyn Trait + 'static 165..166 'z': dyn Trait + '?
165..172 'z.foo()': u64 165..172 'z.foo()': u64
"#]], "#]],
); );
@ -1589,10 +1589,10 @@ fn main() {
expect![[r#" expect![[r#"
31..35 'self': &'? S 31..35 'self': &'? S
37..39 '{}': () 37..39 '{}': ()
47..48 '_': &'? (dyn Fn(S) + 'static) 47..48 '_': &'? (dyn Fn(S) + '?)
58..60 '{}': () 58..60 '{}': ()
71..105 '{ ...()); }': () 71..105 '{ ...()); }': ()
77..78 'f': fn f(&'? (dyn Fn(S) + 'static)) 77..78 'f': fn f(&'? (dyn Fn(S) + '?))
77..102 'f(&|nu...foo())': () 77..102 'f(&|nu...foo())': ()
79..101 '&|numb....foo()': &'? impl Fn(S) 79..101 '&|numb....foo()': &'? impl Fn(S)
80..101 '|numbe....foo()': impl Fn(S) 80..101 '|numbe....foo()': impl Fn(S)
@ -2927,13 +2927,13 @@ fn test(x: &dyn Foo) {
foo(x); foo(x);
}"#, }"#,
expect![[r#" expect![[r#"
21..22 'x': &'? (dyn Foo + 'static) 21..22 'x': &'? (dyn Foo + '?)
34..36 '{}': () 34..36 '{}': ()
46..47 'x': &'? (dyn Foo + 'static) 46..47 'x': &'? (dyn Foo + '?)
59..74 '{ foo(x); }': () 59..74 '{ foo(x); }': ()
65..68 'foo': fn foo(&'? (dyn Foo + 'static)) 65..68 'foo': fn foo(&'? (dyn Foo + '?))
65..71 'foo(x)': () 65..71 'foo(x)': ()
69..70 'x': &'? (dyn Foo + 'static) 69..70 'x': &'? (dyn Foo + '?)
"#]], "#]],
); );
} }
@ -3210,13 +3210,13 @@ fn foo() {
218..324 '{ ...&s); }': () 218..324 '{ ...&s); }': ()
228..229 's': Option<i32> 228..229 's': Option<i32>
232..236 'None': Option<i32> 232..236 'None': Option<i32>
246..247 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static> 246..247 'f': Box<dyn FnOnce(&'? Option<i32>) + '?>
281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>) + 'static> 281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>) + '?>
294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'? Option<i32>) 294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'? Option<i32>)
300..307 '|ps| {}': impl FnOnce(&'? Option<i32>) 300..307 '|ps| {}': impl FnOnce(&'? Option<i32>)
301..303 'ps': &'? Option<i32> 301..303 'ps': &'? Option<i32>
305..307 '{}': () 305..307 '{}': ()
316..317 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static> 316..317 'f': Box<dyn FnOnce(&'? Option<i32>) + '?>
316..321 'f(&s)': () 316..321 'f(&s)': ()
318..320 '&s': &'? Option<i32> 318..320 '&s': &'? Option<i32>
319..320 's': Option<i32> 319..320 's': Option<i32>
@ -4252,9 +4252,9 @@ fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) {
"#, "#,
expect![[r#" expect![[r#"
90..94 'self': &'? Self 90..94 'self': &'? Self
127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static) 127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + '?)
164..195 '{ ...f(); }': () 164..195 '{ ...f(); }': ()
170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static) 170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + '?)
170..184 'v.get::<i32>()': &'? i32 170..184 'v.get::<i32>()': &'? i32
170..192 'v.get:...eref()': &'? i32 170..192 'v.get:...eref()': &'? i32
"#]], "#]],

View file

@ -429,18 +429,18 @@ trait Tr<T> {
impl Tr<$0 impl Tr<$0
"#, "#,
expect![[r#" expect![[r#"
en Enum Enum en Enum Enum
ma makro!() macro_rules! makro ma makro!() macro_rules! makro
md module md module
sp Self dyn Tr<{unknown}> + 'static sp Self dyn Tr<{unknown}>
st Record Record st Record Record
st S S st S S
st Tuple Tuple st Tuple Tuple
st Unit Unit st Unit Unit
tt Tr tt Tr
tt Trait tt Trait
un Union Union un Union Union
bt u32 u32 bt u32 u32
kw crate:: kw crate::
kw self:: kw self::
"#]], "#]],

View file

@ -1171,7 +1171,7 @@ trait B {}
fn test(a: &dyn A) -> &dyn B { fn test(a: &dyn A) -> &dyn B {
a a
//^ error: expected &(dyn B + 'static), found &(dyn A + 'static) //^ error: expected &dyn B, found &dyn A
} }
"#, "#,
); );

View file

@ -380,9 +380,9 @@ fn main() {
let foo = foo3(); let foo = foo3();
// ^^^ impl Fn(f64, f64) -> u32 // ^^^ impl Fn(f64, f64) -> u32
let foo = foo4(); let foo = foo4();
// ^^^ &'static (dyn Fn(f64, f64) -> u32 + 'static) // ^^^ &'static dyn Fn(f64, f64) -> u32
let foo = foo5(); let foo = foo5();
// ^^^ &'static (dyn Fn(&(dyn Fn(f64, f64) -> u32 + 'static), f64) -> u32 + 'static) // ^^^ &'static dyn Fn(&dyn Fn(f64, f64) -> u32, f64) -> u32
let foo = foo6(); let foo = foo6();
// ^^^ impl Fn(f64, f64) -> u32 // ^^^ impl Fn(f64, f64) -> u32
let foo = foo7(); let foo = foo7();
@ -413,7 +413,7 @@ fn main() {
let foo = foo3(); let foo = foo3();
// ^^^ impl Fn(f64, f64) -> u32 // ^^^ impl Fn(f64, f64) -> u32
let foo = foo4(); let foo = foo4();
// ^^^ &'static (dyn Fn(f64, f64) -> u32 + 'static) // ^^^ &'static dyn Fn(f64, f64) -> u32
let foo = foo5(); let foo = foo5();
let foo = foo6(); let foo = foo6();
let foo = foo7(); let foo = foo7();

View file

@ -193,7 +193,7 @@ impl Tr for () {
//^ impl Tr for () //^ impl Tr for ()
impl dyn Tr { impl dyn Tr {
} }
//^ impl dyn Tr + 'static //^ impl dyn Tr
static S0: () = 0; static S0: () = 0;
static S1: () = {}; static S1: () = {};

View file

@ -1588,7 +1588,7 @@ fn add_target_crate_root(
None => Err("proc-macro crate build data is missing dylib path".to_owned()), None => Err("proc-macro crate build data is missing dylib path".to_owned()),
} }
} }
None => Err("proc-macro crate is missing its build data".to_owned()), None => Err("build scripts have not been built".to_owned()),
}; };
proc_macros.insert(crate_id, proc_macro); proc_macros.insert(crate_id, proc_macro);
} }