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

Because NLL borrowck is run after typeck, `in_progress_typeck_results`
was always `None` which was preventing the retrieval of the span to which
the suggestion is suppose to add the lifetime bound.

We now manually pass the `LocalDefId` owner to `construct_generic_bound_failure`
so that under NLL, we give the owner id of the current body.
This commit is contained in:
marmeladema 2022-04-24 00:17:33 +02:00
parent 6b4563bf93
commit 7b0db3e7c8
13 changed files with 69 additions and 60 deletions

View file

@ -171,6 +171,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
None, None,
type_test.generic_kind, type_test.generic_kind,
lower_bound_region, lower_bound_region,
self.body.source.def_id().as_local(),
)); ));
} else { } else {
// FIXME. We should handle this case better. It // FIXME. We should handle this case better. It

View file

@ -61,7 +61,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan};
use rustc_hir as hir; 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::lang_items::LangItem;
use rustc_hir::{Item, ItemKind, Node}; use rustc_hir::{Item, ItemKind, Node};
use rustc_middle::dep_graph::DepContext; use rustc_middle::dep_graph::DepContext;
@ -2285,7 +2285,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
bound_kind: GenericKind<'tcx>, bound_kind: GenericKind<'tcx>,
sub: Region<'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( pub fn construct_generic_bound_failure(
@ -2294,14 +2296,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
origin: Option<SubregionOrigin<'tcx>>, origin: Option<SubregionOrigin<'tcx>>,
bound_kind: GenericKind<'tcx>, bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>, sub: Region<'tcx>,
owner: Option<LocalDefId>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let hir = self.tcx.hir(); let hir = self.tcx.hir();
// Attempt to obtain the span of the parameter so we can // Attempt to obtain the span of the parameter so we can
// suggest adding an explicit lifetime bound to it. // suggest adding an explicit lifetime bound to it.
let generics = self let generics = owner.map(|owner| {
.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 hir_id = hir.local_def_id_to_hir_id(owner);
let parent_id = hir.get_parent_item(hir_id); let parent_id = hir.get_parent_item(hir_id);
( (
@ -2606,11 +2606,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
None, None,
); );
if let Some(infer::RelateParamBound(_, t, _)) = origin { if let Some(infer::RelateParamBound(_, t, _)) = origin {
let return_impl_trait = self let return_impl_trait =
.in_progress_typeck_results owner.and_then(|owner| self.tcx.return_type_impl_trait(owner)).is_some();
.map(|typeck_results| typeck_results.borrow().hir_owner)
.and_then(|owner| self.tcx.return_type_impl_trait(owner))
.is_some();
let t = self.resolve_vars_if_possible(t); let t = self.resolve_vars_if_possible(t);
match t.kind() { match t.kind() {
// We've got: // We've got:

View file

@ -36,6 +36,9 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/propagate-from-trait-match.rs:32:36 --> $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 | establish_relationships(value, |value| {
| ____________________________________^ | ____________________________________^
LL | | LL | |
@ -45,8 +48,6 @@ LL | | // This function call requires that
LL | | require(value); LL | | require(value);
LL | | }); LL | | });
| |_____^ | |_____^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,18 +1,20 @@
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/impl-trait-outlives.rs:11:5 --> $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 LL | x
| ^ | ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/impl-trait-outlives.rs:26:5 --> $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 LL | x
| ^ | ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,10 +1,10 @@
error[E0310]: the parameter type `T` may not live long enough error[E0310]: the parameter type `T` may not live long enough
--> $DIR/projection-implied-bounds.rs:30:18 --> $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)); LL | twice(value, |value_ref, item| invoke2(value_ref, item));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
error: aborting due to previous error error: aborting due to previous error

View file

@ -31,10 +31,11 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/projection-one-region-closure.rs:45:29 --> $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)); LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/projection-one-region-closure.rs:45:39 --> $DIR/projection-one-region-closure.rs:45:39
@ -81,10 +82,11 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/projection-one-region-closure.rs:56:29 --> $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)); LL | with_signature(cell, t, |cell, t| require(cell, t));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/projection-one-region-closure.rs:56:39 --> $DIR/projection-one-region-closure.rs:56:39

View file

@ -1,10 +1,11 @@
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/projection-where-clause-none.rs:16:5 --> $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>() LL | bar::<T::Output>()
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: aborting due to previous error error: aborting due to previous error

View file

@ -52,10 +52,10 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-closure-approximate-lower-bound.rs:29:24 --> $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)); LL | twice(cell, value, |a, b| invoke(a, b));
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: aborting due to previous error error: aborting due to previous error

View file

@ -29,18 +29,20 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-closure-outlives-from-return-type.rs:26:23 --> $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) LL | with_signature(x, |y| y)
| ^^^^^ | ^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-closure-outlives-from-return-type.rs:41:5 --> $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 LL | x
| ^ | ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -37,6 +37,8 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:27:26 --> $DIR/ty-param-closure-outlives-from-where-clause.rs:27:26
| |
LL | fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | with_signature(a, b, |x, y| { LL | with_signature(a, b, |x, y| {
| __________________________^ | __________________________^
LL | | LL | |
@ -46,8 +48,6 @@ LL | | // See `correct_region`, which explains the point of this
LL | | require(&x, &y) LL | | require(&x, &y)
LL | | }) LL | | })
| |_____^ | |_____^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
note: external requirements note: external requirements
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26 --> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26
@ -121,6 +121,9 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:64:26 --> $DIR/ty-param-closure-outlives-from-where-clause.rs:64:26
| |
LL | fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | with_signature(a, b, |x, y| { LL | with_signature(a, b, |x, y| {
| __________________________^ | __________________________^
LL | | LL | |
@ -128,8 +131,6 @@ LL | | // See `correct_region`
LL | | require(&x, &y) LL | | require(&x, &y)
LL | | }) LL | | })
| |_____^ | |_____^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
note: external requirements note: external requirements
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26 --> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26

View file

@ -1,10 +1,10 @@
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-fn-body.rs:19:5 --> $DIR/ty-param-fn-body.rs:19:5
| |
LL | fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | outlives(cell, t) LL | outlives(cell, t)
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,18 +1,20 @@
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-fn.rs:11:5 --> $DIR/ty-param-fn.rs:11:5
| |
LL | fn no_region<'a, T>(x: Box<T>) -> Box<Debug + 'a>
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | x LL | x
| ^ | ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error[E0309]: the parameter type `T` may not live long enough error[E0309]: the parameter type `T` may not live long enough
--> $DIR/ty-param-fn.rs:26:5 --> $DIR/ty-param-fn.rs:26: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 LL | x
| ^ | ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -19,10 +19,10 @@ LL | type WrongGeneric<T> = impl 'static;
error[E0310]: the parameter type `T` may not live long enough error[E0310]: the parameter type `T` may not live long enough
--> $DIR/generic_type_does_not_live_long_enough.rs:18:5 --> $DIR/generic_type_does_not_live_long_enough.rs:18:5
| |
LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | t LL | t
| ^ | ^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
error: aborting due to 3 previous errors error: aborting due to 3 previous errors