Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

place explicit lifetime bound after generic param #124884

Merged
merged 1 commit into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diag, DiagCtxt, DiagStyledString,
ErrorGuaranteed, IntoDiagArg, StringPart,
};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{self as hir, ParamName};
use rustc_macros::extension;
use rustc_middle::bug;
use rustc_middle::dep_graph::DepContext;
Expand Down Expand Up @@ -2379,7 +2379,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let (type_scope, type_param_sugg_span) = match bound_kind {
GenericKind::Param(param) => {
let generics = self.tcx.generics_of(generic_param_scope);
let def_id = generics.type_param(param, self.tcx).def_id.expect_local();
let type_param = generics.type_param(param, self.tcx);
let def_id = type_param.def_id.expect_local();
let scope = self.tcx.local_def_id_to_hir_id(def_id).owner.def_id;
// Get the `hir::Param` to verify whether it already has any bounds.
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
Expand All @@ -2389,7 +2390,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
Some((span, open_paren_sp)) => Some((span, true, open_paren_sp)),
// If `param` corresponds to `Self`, no usable suggestion span.
None if generics.has_self && param.index == 0 => None,
None => Some((self.tcx.def_span(def_id).shrink_to_hi(), false, None)),
None => {
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()
} else {
let span = self.tcx.def_span(def_id);
span.shrink_to_hi()
Comment on lines +2400 to +2401
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, is there any case where this can be reached?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think no cases can reach this branch, but using unreachable!() here seems unnecessary...

};
Some((span, false, None))
}
};
(scope, sugg_span)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@ error-pattern: r#T: 'static
//@ error-pattern: r#K: 'static
//@ error-pattern: T: 'static=

bvanjoi marked this conversation as resolved.
Show resolved Hide resolved
// https://github.com/rust-lang/rust/issues/124785

struct Foo<T, K = i32>(&'static T, &'static K);
//~^ ERROR: the parameter type `T` may not live long enough
//~| ERROR: the parameter type `K` may not live long enough

struct Bar<r#T, r#K = i32>(&'static r#T, &'static r#K);
//~^ ERROR: the parameter type `T` may not live long enough
//~| ERROR: the parameter type `K` may not live long enough

struct Boo<T= i32>(&'static T);
//~^ ERROR: the parameter type `T` may not live long enough

struct Far<T
= i32>(&'static T);
//~^ ERROR: the parameter type `T` may not live long enough

struct S<'a, K: 'a = i32>(&'static K);
//~^ ERROR: lifetime parameter `'a` is never used
//~| ERROR: the parameter type `K` may not live long enough

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/static-lifetime-tip-with-default-type.rs:7:24
|
LL | struct Foo<T, K = i32>(&'static T, &'static K);
| ^^^^^^^^^^
| |
| 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 Foo<T: 'static, K = i32>(&'static T, &'static K);
| +++++++++

error[E0310]: the parameter type `K` may not live long enough
--> $DIR/static-lifetime-tip-with-default-type.rs:7:36
|
LL | struct Foo<T, K = i32>(&'static T, &'static K);
| ^^^^^^^^^^
| |
| the parameter type `K` must be valid for the static lifetime...
| ...so that the reference type `&'static K` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound
|
LL | struct Foo<T, K: 'static = i32>(&'static T, &'static K);
| +++++++++

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/static-lifetime-tip-with-default-type.rs:11:28
|
LL | struct Bar<r#T, r#K = i32>(&'static r#T, &'static r#K);
| ^^^^^^^^^^^^
| |
| 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 Bar<r#T: 'static, r#K = i32>(&'static r#T, &'static r#K);
| +++++++++

error[E0310]: the parameter type `K` may not live long enough
--> $DIR/static-lifetime-tip-with-default-type.rs:11:42
|
LL | struct Bar<r#T, r#K = i32>(&'static r#T, &'static r#K);
| ^^^^^^^^^^^^
| |
| the parameter type `K` must be valid for the static lifetime...
| ...so that the reference type `&'static K` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound
|
LL | struct Bar<r#T, r#K: 'static = i32>(&'static r#T, &'static r#K);
| +++++++++

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/static-lifetime-tip-with-default-type.rs:15:20
|
LL | struct Boo<T= i32>(&'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 Boo<T: 'static= i32>(&'static T);
| +++++++++

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/static-lifetime-tip-with-default-type.rs:19:8
|
LL | = i32>(&'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 Far<T: 'static
| +++++++++

error[E0310]: the parameter type `K` may not live long enough
--> $DIR/static-lifetime-tip-with-default-type.rs:22:27
|
LL | struct S<'a, K: 'a = i32>(&'static K);
| ^^^^^^^^^^
| |
| the parameter type `K` must be valid for the static lifetime...
| ...so that the reference type `&'static K` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound
|
LL | struct S<'a, K: 'a + 'static = i32>(&'static K);
| +++++++++

error[E0392]: lifetime parameter `'a` is never used
--> $DIR/static-lifetime-tip-with-default-type.rs:22:10
|
LL | struct S<'a, K: 'a = i32>(&'static K);
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

error: aborting due to 8 previous errors

Some errors have detailed explanations: E0310, E0392.
For more information about an error, try `rustc --explain E0310`.
Loading