add enum to address lifetime with colon problem

This commit is contained in:
Kivooeo 2025-11-02 14:43:48 +00:00
parent 73e6c9ebd9
commit 4e17091cf8
3 changed files with 59 additions and 12 deletions

View file

@ -774,20 +774,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// instead we suggest `T: 'a + 'b` in that case.
let hir_generics = self.tcx.hir_get_generics(scope).unwrap();
let sugg_span = match hir_generics.bounds_span_for_suggestions(def_id) {
Some((span, open_paren_sp)) => Some((span, true, open_paren_sp)),
Some((span, open_paren_sp)) => {
Some((span, LifetimeSuggestion::NeedsPlus(open_paren_sp)))
}
// If `param` corresponds to `Self`, no usable suggestion span.
None if generics.has_self && param.index == 0 => None,
None => {
let mut colon_flag = false;
let span = if let Some(param) =
hir_generics.params.iter().find(|param| param.def_id == def_id)
&& let ParamName::Plain(ident) = param.name
{
ident.span.shrink_to_hi()
if let Some(sp) = param.colon_span {
colon_flag = true;
sp.shrink_to_hi()
} else {
ident.span.shrink_to_hi()
}
} else {
let span = self.tcx.def_span(def_id);
span.shrink_to_hi()
};
Some((span, false, None))
match colon_flag {
true => Some((span, LifetimeSuggestion::HasColon)),
false => Some((span, LifetimeSuggestion::NeedsColon)),
}
}
};
(scope, sugg_span)
@ -811,17 +822,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let mut suggs = vec![];
let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs);
if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span
if let Some((sp, suggestion_type)) = type_param_sugg_span
&& suggestion_scope == type_scope
{
let suggestion =
if has_lifetimes { format!(" + {lt_name}") } else { format!(": {lt_name}") };
if let Some(open_paren_sp) = open_paren_sp {
suggs.push((open_paren_sp, "(".to_string()));
suggs.push((sp, format!("){suggestion}")));
} else {
suggs.push((sp, suggestion))
match suggestion_type {
LifetimeSuggestion::NeedsPlus(open_paren_sp) => {
let suggestion = format!(" + {lt_name}");
if let Some(open_paren_sp) = open_paren_sp {
suggs.push((open_paren_sp, "(".to_string()));
suggs.push((sp, format!("){suggestion}")));
} else {
suggs.push((sp, suggestion));
}
}
LifetimeSuggestion::NeedsColon => suggs.push((sp, format!(": {lt_name}"))),
LifetimeSuggestion::HasColon => suggs.push((sp, format!(" {lt_name}"))),
}
} else if let GenericKind::Alias(ref p) = bound_kind
&& let ty::Projection = p.kind(self.tcx)
@ -1056,6 +1071,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}
enum LifetimeSuggestion {
NeedsPlus(Option<Span>),
NeedsColon,
HasColon,
}
pub(super) fn note_and_explain_region<'tcx>(
tcx: TyCtxt<'tcx>,
err: &mut Diag<'_>,

View file

@ -0,0 +1,9 @@
//! Regression test for <https://github.com/rust-lang/rust/issues/144215>
#[rustfmt::skip]
struct S<T:>(&'static T);
//~^ ERROR the parameter type `T` may not live long enough
//~| HELP consider adding an explicit lifetime bound
//~| SUGGESTION 'static
fn main() {}

View file

@ -0,0 +1,17 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/missing-param-but-has-colon-144215.rs:4:14
|
LL | struct S<T:>(&'static T);
| ^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the reference type `&'static T` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound
|
LL | struct S<T: 'static>(&'static T);
| +++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0310`.