Skip to content

Commit 4174600

Browse files
committed
place explicit lifetime bound after generic param
1 parent 21e6de7 commit 4174600

File tree

3 files changed

+151
-3
lines changed

3 files changed

+151
-3
lines changed

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

+15-3
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ use rustc_errors::{
6363
codes::*, pluralize, struct_span_code_err, Applicability, Diag, DiagCtxt, DiagStyledString,
6464
ErrorGuaranteed, IntoDiagArg, StringPart,
6565
};
66-
use rustc_hir as hir;
6766
use rustc_hir::def::DefKind;
6867
use rustc_hir::def_id::{DefId, LocalDefId};
6968
use rustc_hir::intravisit::Visitor;
7069
use rustc_hir::lang_items::LangItem;
70+
use rustc_hir::{self as hir, ParamName};
7171
use rustc_macros::extension;
7272
use rustc_middle::bug;
7373
use rustc_middle::dep_graph::DepContext;
@@ -2379,7 +2379,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23792379
let (type_scope, type_param_sugg_span) = match bound_kind {
23802380
GenericKind::Param(param) => {
23812381
let generics = self.tcx.generics_of(generic_param_scope);
2382-
let def_id = generics.type_param(param, self.tcx).def_id.expect_local();
2382+
let type_param = generics.type_param(param, self.tcx);
2383+
let def_id = type_param.def_id.expect_local();
23832384
let scope = self.tcx.local_def_id_to_hir_id(def_id).owner.def_id;
23842385
// Get the `hir::Param` to verify whether it already has any bounds.
23852386
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
@@ -2389,7 +2390,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23892390
Some((span, open_paren_sp)) => Some((span, true, open_paren_sp)),
23902391
// If `param` corresponds to `Self`, no usable suggestion span.
23912392
None if generics.has_self && param.index == 0 => None,
2392-
None => Some((self.tcx.def_span(def_id).shrink_to_hi(), false, None)),
2393+
None => {
2394+
let span = if let Some(param) =
2395+
hir_generics.params.iter().find(|param| param.def_id == def_id)
2396+
&& let ParamName::Plain(ident) = param.name
2397+
{
2398+
ident.span.shrink_to_hi()
2399+
} else {
2400+
let span = self.tcx.def_span(def_id);
2401+
span.shrink_to_hi()
2402+
};
2403+
Some((span, false, None))
2404+
}
23932405
};
23942406
(scope, sugg_span)
23952407
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 T);
16+
//~^ ERROR: the parameter type `T` may not live long enough
17+
18+
struct Far<T
19+
= i32>(&'static T);
20+
//~^ ERROR: the parameter type `T` may not live long enough
21+
22+
struct S<'a, K: 'a = i32>(&'static K);
23+
//~^ ERROR: lifetime parameter `'a` is never used
24+
//~| ERROR: the parameter type `K` may not live long enough
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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 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 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 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[E0310]: the parameter type `K` may not live long enough
86+
--> $DIR/static-lifetime-tip-with-default-type.rs:22:27
87+
|
88+
LL | struct S<'a, K: 'a = i32>(&'static K);
89+
| ^^^^^^^^^^
90+
| |
91+
| the parameter type `K` must be valid for the static lifetime...
92+
| ...so that the reference type `&'static K` does not outlive the data it points at
93+
|
94+
help: consider adding an explicit lifetime bound
95+
|
96+
LL | struct S<'a, K: 'a + 'static = i32>(&'static K);
97+
| +++++++++
98+
99+
error[E0392]: lifetime parameter `'a` is never used
100+
--> $DIR/static-lifetime-tip-with-default-type.rs:22:10
101+
|
102+
LL | struct S<'a, K: 'a = i32>(&'static K);
103+
| ^^ unused lifetime parameter
104+
|
105+
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
106+
107+
error: aborting due to 8 previous errors
108+
109+
Some errors have detailed explanations: E0310, E0392.
110+
For more information about an error, try `rustc --explain E0310`.

0 commit comments

Comments
 (0)