Skip to content

Commit c3a73dc

Browse files
committed
place explicit lifetime bound after generic param
1 parent 87293c9 commit c3a73dc

File tree

3 files changed

+128
-2
lines changed

3 files changed

+128
-2
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -2374,7 +2374,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23742374
let (type_scope, type_param_sugg_span) = match bound_kind {
23752375
GenericKind::Param(param) => {
23762376
let generics = self.tcx.generics_of(generic_param_scope);
2377-
let def_id = generics.type_param(param, self.tcx).def_id.expect_local();
2377+
let type_param = generics.type_param(param, self.tcx);
2378+
let def_id = type_param.def_id.expect_local();
23782379
let scope = self.tcx.local_def_id_to_hir_id(def_id).owner.def_id;
23792380
// Get the `hir::Param` to verify whether it already has any bounds.
23802381
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
@@ -2384,7 +2385,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23842385
Some((span, open_paren_sp)) => Some((span, true, open_paren_sp)),
23852386
// If `param` corresponds to `Self`, no usable suggestion span.
23862387
None if generics.has_self && param.index == 0 => None,
2387-
None => Some((self.tcx.def_span(def_id).shrink_to_hi(), false, None)),
2388+
None => {
2389+
let span = self.tcx.def_span(def_id);
2390+
let span = if type_param.default_value(self.tcx).is_some() {
2391+
let start = span.shrink_to_lo();
2392+
self.tcx
2393+
.sess
2394+
.source_map()
2395+
.span_extend_while(start, |char| {
2396+
!char.is_whitespace() && char != '='
2397+
})
2398+
.unwrap()
2399+
.shrink_to_hi()
2400+
} else {
2401+
span.shrink_to_hi()
2402+
};
2403+
Some((span, false, None))
2404+
}
23882405
};
23892406
(scope, sugg_span)
23902407
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ error-pattern: r#T: 'static
2+
//@ error-pattern: r#K: 'static
3+
//@ error-pattern: T: 'static=
4+
5+
// https://github.com/rust-lang/rust/issues/124785
6+
7+
struct Foo<T, K = i32>(&'static T, &'static K);
8+
//~^ ERROR: the parameter type `T` may not live long enough
9+
//~| ERROR: the parameter type `K` may not live long enough
10+
11+
struct Bar<r#T, r#K = i32>(&'static r#T, &'static r#K);
12+
//~^ ERROR: the parameter type `T` may not live long enough
13+
//~| ERROR: the parameter type `K` may not live long enough
14+
15+
struct Boo<T= i32>(&'static r#T);
16+
//~^ ERROR: the parameter type `T` may not live long enough
17+
18+
struct Far<T
19+
= i32>(&'static r#T);
20+
//~^ ERROR: the parameter type `T` may not live long enough
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
error[E0310]: the parameter type `T` may not live long enough
2+
--> $DIR/static-lifetime-tip-with-default-type.rs:7:24
3+
|
4+
LL | struct Foo<T, K = i32>(&'static T, &'static K);
5+
| ^^^^^^^^^^
6+
| |
7+
| the parameter type `T` must be valid for the static lifetime...
8+
| ...so that the reference type `&'static T` does not outlive the data it points at
9+
|
10+
help: consider adding an explicit lifetime bound
11+
|
12+
LL | struct Foo<T: 'static, K = i32>(&'static T, &'static K);
13+
| +++++++++
14+
15+
error[E0310]: the parameter type `K` may not live long enough
16+
--> $DIR/static-lifetime-tip-with-default-type.rs:7:36
17+
|
18+
LL | struct Foo<T, K = i32>(&'static T, &'static K);
19+
| ^^^^^^^^^^
20+
| |
21+
| the parameter type `K` must be valid for the static lifetime...
22+
| ...so that the reference type `&'static K` does not outlive the data it points at
23+
|
24+
help: consider adding an explicit lifetime bound
25+
|
26+
LL | struct Foo<T, K: 'static = i32>(&'static T, &'static K);
27+
| +++++++++
28+
29+
error[E0310]: the parameter type `T` may not live long enough
30+
--> $DIR/static-lifetime-tip-with-default-type.rs:11:28
31+
|
32+
LL | struct Bar<r#T, r#K = i32>(&'static r#T, &'static r#K);
33+
| ^^^^^^^^^^^^
34+
| |
35+
| the parameter type `T` must be valid for the static lifetime...
36+
| ...so that the reference type `&'static T` does not outlive the data it points at
37+
|
38+
help: consider adding an explicit lifetime bound
39+
|
40+
LL | struct Bar<r#T: 'static, r#K = i32>(&'static r#T, &'static r#K);
41+
| +++++++++
42+
43+
error[E0310]: the parameter type `K` may not live long enough
44+
--> $DIR/static-lifetime-tip-with-default-type.rs:11:42
45+
|
46+
LL | struct Bar<r#T, r#K = i32>(&'static r#T, &'static r#K);
47+
| ^^^^^^^^^^^^
48+
| |
49+
| the parameter type `K` must be valid for the static lifetime...
50+
| ...so that the reference type `&'static K` does not outlive the data it points at
51+
|
52+
help: consider adding an explicit lifetime bound
53+
|
54+
LL | struct Bar<r#T, r#K: 'static = i32>(&'static r#T, &'static r#K);
55+
| +++++++++
56+
57+
error[E0310]: the parameter type `T` may not live long enough
58+
--> $DIR/static-lifetime-tip-with-default-type.rs:15:20
59+
|
60+
LL | struct Boo<T= i32>(&'static r#T);
61+
| ^^^^^^^^^^^^
62+
| |
63+
| the parameter type `T` must be valid for the static lifetime...
64+
| ...so that the reference type `&'static T` does not outlive the data it points at
65+
|
66+
help: consider adding an explicit lifetime bound
67+
|
68+
LL | struct Boo<T: 'static= i32>(&'static r#T);
69+
| +++++++++
70+
71+
error[E0310]: the parameter type `T` may not live long enough
72+
--> $DIR/static-lifetime-tip-with-default-type.rs:19:8
73+
|
74+
LL | = i32>(&'static r#T);
75+
| ^^^^^^^^^^^^
76+
| |
77+
| the parameter type `T` must be valid for the static lifetime...
78+
| ...so that the reference type `&'static T` does not outlive the data it points at
79+
|
80+
help: consider adding an explicit lifetime bound
81+
|
82+
LL | struct Far<T: 'static
83+
| +++++++++
84+
85+
error: aborting due to 6 previous errors
86+
87+
For more information about this error, try `rustc --explain E0310`.

0 commit comments

Comments
 (0)