Skip to content

Improve span for consider adding an explicit lifetime bound suggestions under NLL #96352

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

Merged
merged 3 commits into from
Apr 24, 2022
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
6 changes: 5 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed
use rustc_infer::infer::{
error_reporting::nice_region_error::NiceRegionError,
error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin,
RelateParamBound,
};
use rustc_middle::hir::place::PlaceBase;
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
Expand Down Expand Up @@ -166,11 +167,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let type_test_span = type_test.locations.span(&self.body);

if let Some(lower_bound_region) = lower_bound_region {
let generic_ty = type_test.generic_kind.to_ty(self.infcx.tcx);
let origin = RelateParamBound(type_test_span, generic_ty, None);
self.buffer_error(self.infcx.construct_generic_bound_failure(
type_test_span,
None,
Some(origin),
type_test.generic_kind,
lower_bound_region,
self.body.source.def_id().as_local(),
));
} else {
// FIXME. We should handle this case better. It
Expand Down
53 changes: 25 additions & 28 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{Item, ItemKind, Node};
use rustc_middle::dep_graph::DepContext;
Expand Down Expand Up @@ -2285,7 +2285,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>,
) {
self.construct_generic_bound_failure(span, origin, bound_kind, sub).emit();
let owner =
self.in_progress_typeck_results.map(|typeck_results| typeck_results.borrow().hir_owner);
self.construct_generic_bound_failure(span, origin, bound_kind, sub, owner).emit();
}

pub fn construct_generic_bound_failure(
Expand All @@ -2294,31 +2296,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
origin: Option<SubregionOrigin<'tcx>>,
bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>,
owner: Option<LocalDefId>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let hir = self.tcx.hir();
// Attempt to obtain the span of the parameter so we can
// suggest adding an explicit lifetime bound to it.
let generics = self
.in_progress_typeck_results
.map(|typeck_results| typeck_results.borrow().hir_owner)
.map(|owner| {
let hir_id = hir.local_def_id_to_hir_id(owner);
let parent_id = hir.get_parent_item(hir_id);
(
// Parent item could be a `mod`, so we check the HIR before calling:
if let Some(Node::Item(Item {
kind: ItemKind::Trait(..) | ItemKind::Impl { .. },
..
})) = hir.find_by_def_id(parent_id)
{
Some(self.tcx.generics_of(parent_id))
} else {
None
},
self.tcx.generics_of(owner.to_def_id()),
hir.span(hir_id),
)
});
let generics = owner.map(|owner| {
let hir_id = hir.local_def_id_to_hir_id(owner);
let parent_id = hir.get_parent_item(hir_id);
(
// Parent item could be a `mod`, so we check the HIR before calling:
if let Some(Node::Item(Item {
kind: ItemKind::Trait(..) | ItemKind::Impl { .. },
..
})) = hir.find_by_def_id(parent_id)
{
Some(self.tcx.generics_of(parent_id))
} else {
None
},
self.tcx.generics_of(owner.to_def_id()),
hir.span(hir_id),
)
});

let span = match generics {
// This is to get around the trait identity obligation, that has a `DUMMY_SP` as signal
Expand Down Expand Up @@ -2606,11 +2606,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
None,
);
if let Some(infer::RelateParamBound(_, t, _)) = origin {
let return_impl_trait = self
.in_progress_typeck_results
.map(|typeck_results| typeck_results.borrow().hir_owner)
.and_then(|owner| self.tcx.return_type_impl_trait(owner))
.is_some();
let return_impl_trait =
owner.and_then(|owner| self.tcx.return_type_impl_trait(owner)).is_some();
let t = self.resolve_vars_if_possible(t);
match t.kind() {
// We've got:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/must_outlive_least_region_or_bound.rs:41:5
|
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
| -- help: consider adding an explicit lifetime bound...: `T: 'static +`
...
LL | x
| ^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
| ^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to 9 previous errors

Expand Down
7 changes: 4 additions & 3 deletions src/test/ui/impl-trait/type_parameters_captured.nll.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/type_parameters_captured.rs:10:5
|
LL | fn foo<T>(x: T) -> impl Any + 'static {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
...
LL | x
| ^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
| ^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to previous error

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/issue_74400.rs:12:5
|
LL | fn g<T>(data: &[T]) {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | f(data, identity)
| ^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
| ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0308]: mismatched types
--> $DIR/issue_74400.rs:12:5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/propagate-from-trait-match.rs:32:36
|
LL | fn supply<'a, T>(value: T)
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | establish_relationships(value, |value| {
| ____________________________________^
LL | |
Expand All @@ -44,9 +47,7 @@ LL | | // This function call requires that
... |
LL | | require(value);
LL | | });
| |_____^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| |_____^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to previous error

Expand Down
14 changes: 8 additions & 6 deletions src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/impl-trait-outlives.rs:11:5
|
LL | fn no_region<'a, T>(x: Box<T>) -> impl Debug + 'a
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | x
| ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| ^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/impl-trait-outlives.rs:26:5
|
LL | fn wrong_region<'a, 'b, T>(x: Box<T>) -> impl Debug + 'a
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | x
| ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| ^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to 2 previous errors

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/projection-implied-bounds.rs:30:18
|
LL | fn generic2<T: Iterator>(value: T) {
| -- help: consider adding an explicit lifetime bound...: `T: 'static +`
LL | twice(value, |value_ref, item| invoke2(value_ref, item));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ LL | with_signature(x, |mut y| Box::new(y.next()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`...
= note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds

note: external requirements
--> $DIR/projection-no-regions-closure.rs:34:23
Expand Down Expand Up @@ -96,6 +97,7 @@ LL | with_signature(x, |mut y| Box::new(y.next()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`...
= note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds

note: external requirements
--> $DIR/projection-no-regions-closure.rs:52:23
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | Box::new(x.next())
| ^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`...
= note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds

error[E0309]: the associated type `<T as Iterator>::Item` may not live long enough
--> $DIR/projection-no-regions-fn.rs:28:5
Expand All @@ -13,6 +14,7 @@ LL | Box::new(x.next())
| ^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`...
= note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds

error: aborting due to 2 previous errors

Expand Down
14 changes: 8 additions & 6 deletions src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/projection-one-region-closure.rs:45:29
|
LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error: lifetime may not live long enough
--> $DIR/projection-one-region-closure.rs:45:39
Expand Down Expand Up @@ -81,10 +82,11 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/projection-one-region-closure.rs:56:29
|
LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error: lifetime may not live long enough
--> $DIR/projection-one-region-closure.rs:56:39
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType: 'a`...
= note: ...so that the type `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType` will meet its required lifetime bounds

note: external requirements
--> $DIR/projection-two-region-trait-bound-closure.rs:48:29
Expand Down Expand Up @@ -70,6 +71,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: 'a`...
= note: ...so that the type `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType` will meet its required lifetime bounds

note: external requirements
--> $DIR/projection-two-region-trait-bound-closure.rs:61:29
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | bar::<T::Output>()
| ^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as MyTrait<'_>>::Output: 'a`...
= note: ...so that the type `<T as MyTrait<'_>>::Output` will meet its required lifetime bounds

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | bar::<<T as MyTrait<'a>>::Output>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as MyTrait<'_>>::Output: 'a`...
= note: ...so that the type `<T as MyTrait<'_>>::Output` will meet its required lifetime bounds

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/projection-where-clause-none.rs:16:5
|
LL | fn foo<'a, T>() -> &'a ()
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | bar::<T::Output>()
| ^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-closure-approximate-lower-bound.rs:29:24
|
LL | fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | twice(cell, value, |a, b| invoke(a, b));
| ^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| ^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,20 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-closure-outlives-from-return-type.rs:26:23
|
LL | fn no_region<'a, T>(x: Box<T>) -> Box<dyn Debug + 'a>
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | with_signature(x, |y| y)
| ^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| ^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-closure-outlives-from-return-type.rs:41:5
|
LL | fn wrong_region<'a, 'b, T>(x: Box<T>) -> Box<Debug + 'a>
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | x
| ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
| ^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to 2 previous errors

Expand Down
Loading