about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs28
-rw-r--r--compiler/rustc_middle/src/ty/context.rs36
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs20
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr4
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr32
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr4
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.stderr8
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-2.stderr4
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-4.stderr4
-rw-r--r--src/test/ui/regions/regions-proc-bound-capture.stderr4
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr16
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr4
12 files changed, 85 insertions, 79 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 34015b97e3c..80bdccd4f2c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -10,7 +10,8 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor};
 use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind};
 use rustc_middle::ty::{
-    self, AssocItemContainer, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor,
+    self, AssocItemContainer, RegionKind, StaticLifetimeVisitor, Ty, TyCtxt, TypeFoldable,
+    TypeVisitor,
 };
 use rustc_span::symbol::Ident;
 use rustc_span::{MultiSpan, Span};
@@ -186,10 +187,27 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                 let parent_id = tcx.hir().get_parent_item(*hir_id);
                 if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id) {
                     let mut span: MultiSpan = fn_decl.output.span().into();
-                    span.push_span_label(
-                        fn_decl.output.span(),
-                        "requirement introduced by this return type".to_string(),
-                    );
+                    let mut add_label = true;
+                    if let hir::FnRetTy::Return(ty) = fn_decl.output {
+                        let mut v = StaticLifetimeVisitor(vec![], tcx.hir());
+                        v.visit_ty(ty);
+                        if !v.0.is_empty() {
+                            span = v.0.clone().into();
+                            for sp in v.0 {
+                                span.push_span_label(
+                                    sp,
+                                    "`'static` requirement introduced here".to_string(),
+                                );
+                            }
+                            add_label = false;
+                        }
+                    }
+                    if add_label {
+                        span.push_span_label(
+                            fn_decl.output.span(),
+                            "requirement introduced by this return type".to_string(),
+                        );
+                    }
                     span.push_span_label(
                         cause.span,
                         "because of this returned expression".to_string(),
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 275a2128c45..0bf457ca8a8 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1481,40 +1481,8 @@ impl<'tcx> TyCtxt<'tcx> {
         scope_def_id: LocalDefId,
     ) -> Vec<&'tcx hir::Ty<'tcx>> {
         let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
-        let hir_output = match self.hir().get(hir_id) {
-            Node::Item(hir::Item {
-                kind:
-                    ItemKind::Fn(
-                        hir::FnSig {
-                            decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
-                            ..
-                        },
-                        ..,
-                    ),
-                ..
-            })
-            | Node::ImplItem(hir::ImplItem {
-                kind:
-                    hir::ImplItemKind::Fn(
-                        hir::FnSig {
-                            decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
-                            ..
-                        },
-                        _,
-                    ),
-                ..
-            })
-            | Node::TraitItem(hir::TraitItem {
-                kind:
-                    hir::TraitItemKind::Fn(
-                        hir::FnSig {
-                            decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
-                            ..
-                        },
-                        _,
-                    ),
-                ..
-            }) => ty,
+        let hir_output = match self.hir().fn_decl_by_hir_id(hir_id) {
+            Some(hir::FnDecl { output: hir::FnRetTy::Return(ty), .. }) => ty,
             _ => return vec![],
         };
 
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 8803370251b..1acb3ec57de 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -6,6 +6,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate};
+use rustc_span::Span;
 
 impl<'tcx> TyS<'tcx> {
     /// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive.
@@ -432,3 +433,22 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
         hir::intravisit::walk_ty(self, ty);
     }
 }
+
+/// Collect al types that have an implicit `'static` obligation that we could suggest `'_` for.
+pub struct StaticLifetimeVisitor<'tcx>(pub Vec<Span>, pub crate::hir::map::Map<'tcx>);
+
+impl<'v> hir::intravisit::Visitor<'v> for StaticLifetimeVisitor<'v> {
+    type Map = rustc_hir::intravisit::ErasedMap<'v>;
+
+    fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
+        hir::intravisit::NestedVisitorMap::None
+    }
+
+    fn visit_lifetime(&mut self, lt: &'v hir::Lifetime) {
+        if let hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static =
+            lt.name
+        {
+            self.0.push(lt.span);
+        }
+    }
+}
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
index 49264ae2505..628023ad471 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
@@ -8,10 +8,10 @@ LL |     bar(foo, x)
    |         ^^^  - ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/project-fn-ret-invariant.rs:45:32
+  --> $DIR/project-fn-ret-invariant.rs:45:37
    |
 LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
-   |                                ^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                     ^^^^^^^ `'static` requirement introduced here
 ...
 LL |     bar(foo, x)
    |     ----------- because of this returned expression
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index d0d9ed8923d..bf1f93aebd5 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -141,12 +141,12 @@ LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
    |               this data with an anonymous lifetime `'_`...
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/must_outlive_least_region_or_bound.rs:14:24
+  --> $DIR/must_outlive_least_region_or_bound.rs:14:28
    |
 LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
-   |                        ^^^^^^^^^^^^^^   ----------- because of this returned expression
-   |                        |
-   |                        requirement introduced by this return type
+   |                            ^^^^^^^^^    ----------- because of this returned expression
+   |                            |
+   |                            `'static` requirement introduced here
 help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
    |
 LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
@@ -161,12 +161,12 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
    |                     this data with lifetime `'a`...
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/must_outlive_least_region_or_bound.rs:16:33
+  --> $DIR/must_outlive_least_region_or_bound.rs:16:37
    |
 LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
-   |                                 ^^^^^^^^^^^^^^   ----------- because of this returned expression
-   |                                 |
-   |                                 requirement introduced by this return type
+   |                                     ^^^^^^^^^    ----------- because of this returned expression
+   |                                     |
+   |                                     `'static` requirement introduced here
 help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
    |
 LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
@@ -181,12 +181,12 @@ LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |               this data with an anonymous lifetime `'_`...
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/must_outlive_least_region_or_bound.rs:18:24
+  --> $DIR/must_outlive_least_region_or_bound.rs:18:40
    |
 LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-   |                        ^^^^^^^^^^^^^^^^^^^^^^^^   ----------- because of this returned expression
-   |                        |
-   |                        requirement introduced by this return type
+   |                                        ^^^^^^^    ----------- because of this returned expression
+   |                                        |
+   |                                        `'static` requirement introduced here
 help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
    |
 LL | fn elided4(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
@@ -203,12 +203,12 @@ LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |                     ------- this data with lifetime `'a`...         ^ ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/must_outlive_least_region_or_bound.rs:20:33
+  --> $DIR/must_outlive_least_region_or_bound.rs:20:49
    |
 LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^   ----------- because of this returned expression
-   |                                 |
-   |                                 requirement introduced by this return type
+   |                                                 ^^^^^^^    ----------- because of this returned expression
+   |                                                 |
+   |                                                 `'static` requirement introduced here
 help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
    |
 LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
index c882e3c9d06..0308ecf8f64 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
@@ -8,10 +8,10 @@ LL |     ss.r
    |     ^^^^ ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/object-lifetime-default-from-box-error.rs:14:33
+  --> $DIR/object-lifetime-default-from-box-error.rs:14:37
    |
 LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
-   |                                 ^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                     ^^^^^^^^^^^^^ `'static` requirement introduced here
 ...
 LL |     ss.r
    |     ---- because of this returned expression
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index 45a3c801a38..74683f1439a 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -24,10 +24,10 @@ LL |     Box::new(v)
    |              ^ ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/region-object-lifetime-in-coercion.rs:12:19
+  --> $DIR/region-object-lifetime-in-coercion.rs:12:33
    |
 LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
-   |                   ^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                 ^^^^^^^ `'static` requirement introduced here
 LL |     Box::new(v)
    |     ----------- because of this returned expression
 help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
@@ -49,10 +49,10 @@ LL |     Box::new(v)
    |              ^ ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/region-object-lifetime-in-coercion.rs:16:19
+  --> $DIR/region-object-lifetime-in-coercion.rs:16:23
    |
 LL | fn c(v: &[u8]) -> Box<dyn Foo> {
-   |                   ^^^^^^^^^^^^ requirement introduced by this return type
+   |                       ^^^^^^^ `'static` requirement introduced here
 ...
 LL |     Box::new(v)
    |     ----------- because of this returned expression
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr
index a924fbc5bf7..c914d91306c 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr
@@ -7,10 +7,10 @@ LL |     Box::new(B(&*v)) as Box<dyn X>
    |                ^^^ ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/regions-close-object-into-object-2.rs:8:48
+  --> $DIR/regions-close-object-into-object-2.rs:8:60
    |
 LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
-   |                                                ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                                            ^^^^^^^ `'static` requirement introduced here
 LL |     Box::new(B(&*v)) as Box<dyn X>
    |     ------------------------------ because of this returned expression
 help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr
index 969222068ee..1f68db023a9 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr
@@ -7,10 +7,10 @@ LL |     Box::new(B(&*v)) as Box<dyn X>
    |                ^^^ ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/regions-close-object-into-object-4.rs:8:40
+  --> $DIR/regions-close-object-into-object-4.rs:8:52
    |
 LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
-   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                                    ^^^^^^^ `'static` requirement introduced here
 LL |     Box::new(B(&*v)) as Box<dyn X>
    |     ------------------------------ because of this returned expression
 help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr
index 3bbbf00d5e7..99657632035 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.stderr
+++ b/src/test/ui/regions/regions-proc-bound-capture.stderr
@@ -8,10 +8,10 @@ LL |     Box::new(move || { *x })
    |              ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/regions-proc-bound-capture.rs:7:30
+  --> $DIR/regions-proc-bound-capture.rs:7:59
    |
 LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                                           ^^^^^^^ `'static` requirement introduced here
 LL |     // This is illegal, because the region bound on `proc` is 'static.
 LL |     Box::new(move || { *x })
    |     ------------------------ because of this returned expression
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
index c06943c0874..42230ddd695 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
@@ -47,10 +47,10 @@ note: ...and is required to live as long as `'static` here
 LL |     y.get_b() // ERROR
    |     ^^^^^^^^^
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/type-checking-test-4.rs:26:40
+  --> $DIR/type-checking-test-4.rs:26:48
    |
 LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
-   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                                ^^^^^^^ `'static` requirement introduced here
 ...
 LL |     y.get_b() // ERROR
    |     --------- because of this returned expression
@@ -64,10 +64,10 @@ LL |     <_ as Bar>::get_b(x) // ERROR
    |     ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/type-checking-test-4.rs:32:40
+  --> $DIR/type-checking-test-4.rs:32:48
    |
 LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
-   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                                ^^^^^^^ `'static` requirement introduced here
 LL |     <_ as Bar>::get_b(x) // ERROR
    |     -------------------- because of this returned expression
 
@@ -80,10 +80,10 @@ LL |     <_ as Bar<'_, '_>>::get_b(x) // ERROR
    |     ----------^^------------- ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/type-checking-test-4.rs:37:40
+  --> $DIR/type-checking-test-4.rs:37:48
    |
 LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
-   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                                ^^^^^^^ `'static` requirement introduced here
 LL |     <_ as Bar<'_, '_>>::get_b(x) // ERROR
    |     ---------------------------- because of this returned expression
 
@@ -109,10 +109,10 @@ note: ...and is required to live as long as `'static` here
 LL |     z.get_b() // ERROR
    |     ^^^^^^^^^
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/type-checking-test-4.rs:42:40
+  --> $DIR/type-checking-test-4.rs:42:48
    |
 LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
-   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                                                ^^^^^^^ `'static` requirement introduced here
 ...
 LL |     z.get_b() // ERROR
    |     --------- because of this returned expression
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
index 3fed7ba6c49..b8552c872c1 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -10,10 +10,10 @@ LL |     Box::new(items.iter())
    |              ...is captured and required to live as long as `'static` here
    |
 note: `'static` lifetime requirement introduced by the return type
-  --> $DIR/dyn-trait-underscore.rs:6:25
+  --> $DIR/dyn-trait-underscore.rs:6:29
    |
 LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+   |                             ^^^^^^^^^^^^^^^^^^^^^ `'static` requirement introduced here
 LL |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
 LL |     Box::new(items.iter())
    |     ---------------------- because of this returned expression