Skip to content

Commit 41d65da

Browse files
committed
add enum to address lifetime with colon problem
1 parent 73e6c9e commit 41d65da

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

compiler/rustc_trait_selection/src/error_reporting/infer/region.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -774,20 +774,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
774774
// instead we suggest `T: 'a + 'b` in that case.
775775
let hir_generics = self.tcx.hir_get_generics(scope).unwrap();
776776
let sugg_span = match hir_generics.bounds_span_for_suggestions(def_id) {
777-
Some((span, open_paren_sp)) => Some((span, true, open_paren_sp)),
777+
Some((span, open_paren_sp)) => {
778+
Some((span, LifetimeSuggestion::NeedsPlus, open_paren_sp))
779+
}
778780
// If `param` corresponds to `Self`, no usable suggestion span.
779781
None if generics.has_self && param.index == 0 => None,
780782
None => {
783+
let mut colon_flag = false;
781784
let span = if let Some(param) =
782785
hir_generics.params.iter().find(|param| param.def_id == def_id)
783786
&& let ParamName::Plain(ident) = param.name
784787
{
785-
ident.span.shrink_to_hi()
788+
if let Some(sp) = param.colon_span {
789+
colon_flag = true;
790+
sp.shrink_to_hi()
791+
} else {
792+
ident.span.shrink_to_hi()
793+
}
786794
} else {
787795
let span = self.tcx.def_span(def_id);
788796
span.shrink_to_hi()
789797
};
790-
Some((span, false, None))
798+
match colon_flag {
799+
true => Some((span, LifetimeSuggestion::HasColon, None)),
800+
false => Some((span, LifetimeSuggestion::NeedsColon, None)),
801+
}
791802
}
792803
};
793804
(scope, sugg_span)
@@ -814,8 +825,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
814825
if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span
815826
&& suggestion_scope == type_scope
816827
{
817-
let suggestion =
818-
if has_lifetimes { format!(" + {lt_name}") } else { format!(": {lt_name}") };
828+
let suggestion = match has_lifetimes {
829+
LifetimeSuggestion::HasColon => format!(" {lt_name}"),
830+
LifetimeSuggestion::NeedsColon => format!(": {lt_name}"),
831+
LifetimeSuggestion::NeedsPlus => format!(" + {lt_name}"),
832+
};
819833

820834
if let Some(open_paren_sp) = open_paren_sp {
821835
suggs.push((open_paren_sp, "(".to_string()));
@@ -1056,6 +1070,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
10561070
}
10571071
}
10581072

1073+
enum LifetimeSuggestion {
1074+
NeedsPlus,
1075+
NeedsColon,
1076+
HasColon,
1077+
}
1078+
10591079
pub(super) fn note_and_explain_region<'tcx>(
10601080
tcx: TyCtxt<'tcx>,
10611081
err: &mut Diag<'_>,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/144215>
2+
3+
#[rustfmt::skip]
4+
struct S<T:>(&'static T);
5+
//~^ ERROR the parameter type `T` may not live long enough
6+
//~| HELP consider adding an explicit lifetime bound
7+
//~| SUGGESTION 'static
8+
9+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0310]: the parameter type `T` may not live long enough
2+
--> $DIR/missing-param-but-has-colon-144215.rs:4:14
3+
|
4+
LL | struct S<T:>(&'static T);
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 S<T: 'static>(&'static T);
13+
| +++++++
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0310`.

0 commit comments

Comments
 (0)