Skip to content

Commit 4e17091

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

File tree

3 files changed

+59
-12
lines changed

3 files changed

+59
-12
lines changed

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

Lines changed: 33 additions & 12 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)),
800+
false => Some((span, LifetimeSuggestion::NeedsColon)),
801+
}
791802
}
792803
};
793804
(scope, sugg_span)
@@ -811,17 +822,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
811822
let mut suggs = vec![];
812823
let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs);
813824

814-
if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span
825+
if let Some((sp, suggestion_type)) = type_param_sugg_span
815826
&& suggestion_scope == type_scope
816827
{
817-
let suggestion =
818-
if has_lifetimes { format!(" + {lt_name}") } else { format!(": {lt_name}") };
819-
820-
if let Some(open_paren_sp) = open_paren_sp {
821-
suggs.push((open_paren_sp, "(".to_string()));
822-
suggs.push((sp, format!("){suggestion}")));
823-
} else {
824-
suggs.push((sp, suggestion))
828+
match suggestion_type {
829+
LifetimeSuggestion::NeedsPlus(open_paren_sp) => {
830+
let suggestion = format!(" + {lt_name}");
831+
if let Some(open_paren_sp) = open_paren_sp {
832+
suggs.push((open_paren_sp, "(".to_string()));
833+
suggs.push((sp, format!("){suggestion}")));
834+
} else {
835+
suggs.push((sp, suggestion));
836+
}
837+
}
838+
LifetimeSuggestion::NeedsColon => suggs.push((sp, format!(": {lt_name}"))),
839+
LifetimeSuggestion::HasColon => suggs.push((sp, format!(" {lt_name}"))),
825840
}
826841
} else if let GenericKind::Alias(ref p) = bound_kind
827842
&& let ty::Projection = p.kind(self.tcx)
@@ -1056,6 +1071,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
10561071
}
10571072
}
10581073

1074+
enum LifetimeSuggestion {
1075+
NeedsPlus(Option<Span>),
1076+
NeedsColon,
1077+
HasColon,
1078+
}
1079+
10591080
pub(super) fn note_and_explain_region<'tcx>(
10601081
tcx: TyCtxt<'tcx>,
10611082
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)