about summary refs log tree commit diff
diff options
context:
space:
mode:
authormarmeladema <xademax@gmail.com>2022-04-24 00:17:33 +0200
committermarmeladema <xademax@gmail.com>2022-04-24 09:34:50 +0200
commit7b0db3e7c81c36d2ec623849d17d9df4858abca1 (patch)
tree6b4452c04270e18addefc4f26c2b02c24ae27803
parent6b4563bf93f4b103ed22507ed825008b89e4f5d9 (diff)
downloadrust-7b0db3e7c81c36d2ec623849d17d9df4858abca1.tar.gz
rust-7b0db3e7c81c36d2ec623849d17d9df4858abca1.zip
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.
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs53
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr5
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr10
-rw-r--r--src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr10
-rw-r--r--src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr5
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr10
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr9
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn.stderr10
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr4
13 files changed, 69 insertions, 60 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 5fd9ecf4513..be715505d81 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -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
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index f2dd4f5d5cb..f9273cc50b7 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -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;
@@ -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(
@@ -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
@@ -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:
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
index 4b860a55057..5a382ded70b 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
@@ -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 | |
@@ -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
 
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
index 31ee540cce9..d303b8c84c1 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
+++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
@@ -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
 
diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
index 9f0c60c1e17..faa90e3e564 100644
--- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
@@ -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
 
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
index 2513b0bfccb..cec1c277e7f 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
@@ -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
@@ -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
diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr
index 8175c302155..ad2571e44f5 100644
--- a/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr
@@ -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
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index baf223b786b..1f232f35043 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -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
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
index 88d73e7a729..7b1f8192cb6 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
@@ -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
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
index 5b175aac1e1..eaa536ec3a4 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
@@ -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 | |
@@ -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
@@ -121,6 +121,9 @@ 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 | |
@@ -128,8 +131,6 @@ 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
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
index 9a023a0e58e..3cfc23ffcfd 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
@@ -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
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr
index 8c8529620d5..981d3d03b82 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-fn.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr
@@ -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
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr
index db771d21132..a0b955112d2 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr
@@ -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