Skip to content

Commit

Permalink
Improve span for consider adding an explicit lifetime bound suggest…
Browse files Browse the repository at this point in the history
…ions 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.
  • Loading branch information
marmeladema committed Apr 24, 2022
1 parent 6b4563b commit 7b0db3e
Show file tree
Hide file tree
Showing 13 changed files with 69 additions and 60 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
None,
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 @@ -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 @@ -45,8 +48,6 @@ LL | | // This function call requires that
LL | | require(value);
LL | | });
| |_____^
|
= help: consider adding an explicit lifetime bound `T: 'a`...

error: aborting due to previous error

Expand Down
10 changes: 6 additions & 4 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`...

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`...

error: aborting due to 2 previous errors

Expand Down
4 changes: 2 additions & 2 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`...

error: aborting due to previous error

Expand Down
10 changes: 6 additions & 4 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`...

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`...

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
@@ -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`...

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`...

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`...

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`...

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough
--> $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 | |
Expand All @@ -46,8 +48,6 @@ LL | | // See `correct_region`, which explains the point of this
LL | | require(&x, &y)
LL | | })
| |_____^
|
= help: consider adding an explicit lifetime bound `T: 'a`...

note: external requirements
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26
Expand Down Expand Up @@ -121,15 +121,16 @@ LL | | }
error[E0309]: the parameter type `T` may not live long enough
--> $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 | |
LL | | // See `correct_region`
LL | | require(&x, &y)
LL | | })
| |_____^
|
= help: consider adding an explicit lifetime bound `T: 'a`...

note: external requirements
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0309]: the parameter type `T` may not live long enough
--> $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)
| ^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...

error: aborting due to previous error

Expand Down
10 changes: 6 additions & 4 deletions src/test/ui/nll/ty-outlives/ty-param-fn.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/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
| ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...

error[E0309]: the parameter type `T` may not live long enough
--> $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
| ^
|
= help: consider adding an explicit lifetime bound `T: 'a`...

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ LL | type WrongGeneric<T> = impl 'static;
error[E0310]: the parameter type `T` may not live long enough
--> $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
| ^
|
= help: consider adding an explicit lifetime bound `T: 'static`...

error: aborting due to 3 previous errors

Expand Down

0 comments on commit 7b0db3e

Please sign in to comment.