about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Kuber <esteban@kuber.com.ar>2021-10-12 09:52:32 +0000
committerEsteban Kuber <esteban@kuber.com.ar>2021-12-10 03:08:23 +0000
commitee0fd105d86f4998a341b9a819735f1087423492 (patch)
tree9715be7f48e25a6c5e36637d09a1175995e161f3
parent09dbf37213a5462c08e5e62e931aabc2fb3b92e4 (diff)
downloadrust-ee0fd105d86f4998a341b9a819735f1087423492.tar.gz
rust-ee0fd105d86f4998a341b9a819735f1087423492.zip
Point at return type when it introduces `'static` obligation
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs20
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr9
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr28
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr8
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.stderr15
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-2.stderr7
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-4.stderr7
-rw-r--r--src/test/ui/regions/regions-proc-bound-capture.stderr8
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr32
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr8
10 files changed, 142 insertions, 0 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 daeb406a839..34015b97e3c 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
@@ -181,6 +181,26 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin {
             err.span_note(*bound, "`'static` lifetime requirement introduced by this bound");
         }
+        if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin {
+            if let ObligationCauseCode::BlockTailExpression(hir_id) = &cause.code {
+                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(),
+                    );
+                    span.push_span_label(
+                        cause.span,
+                        "because of this returned expression".to_string(),
+                    );
+                    err.span_note(
+                        span,
+                        "`'static` lifetime requirement introduced by the return type",
+                    );
+                }
+            }
+        }
 
         let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
 
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 eb81da7852d..49264ae2505 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
@@ -6,6 +6,15 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
 ...
 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
+   |
+LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
+   |                                ^^^^^^^^^^^^^ requirement introduced by this return type
+...
+LL |     bar(foo, x)
+   |     ----------- because of this returned expression
 
 error: aborting due to previous error
 
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 e80372766dc..d0d9ed8923d 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
@@ -140,6 +140,13 @@ 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
+   |
+LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
+   |                        ^^^^^^^^^^^^^^   ----------- because of this returned expression
+   |                        |
+   |                        requirement introduced by this return type
 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) }
@@ -153,6 +160,13 @@ 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
+   |
+LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
+   |                                 ^^^^^^^^^^^^^^   ----------- because of this returned expression
+   |                                 |
+   |                                 requirement introduced by this return type
 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) }
@@ -166,6 +180,13 @@ 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
+   |
+LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^   ----------- because of this returned expression
+   |                        |
+   |                        requirement introduced by this return type
 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) }
@@ -181,6 +202,13 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime
 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
+   |
+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
 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 e0a8534cd28..c882e3c9d06 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
@@ -7,6 +7,14 @@ LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
 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
+   |
+LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
+   |                                 ^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+...
+LL |     ss.r
+   |     ---- because of this returned expression
 help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound
    |
 LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {
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 9eb24c1bd37..45a3c801a38 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -23,6 +23,13 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
 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
+   |
+LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
+   |                   ^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+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`
    |
 LL | fn b(v: &[u8]) -> Box<dyn Foo + '_> {
@@ -41,6 +48,14 @@ LL | fn c(v: &[u8]) -> Box<dyn Foo> {
 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
+   |
+LL | fn c(v: &[u8]) -> Box<dyn Foo> {
+   |                   ^^^^^^^^^^^^ requirement introduced by this return type
+...
+LL |     Box::new(v)
+   |     ----------- because of this returned expression
 help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound
    |
 LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {
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 9c803d4e1d4..a924fbc5bf7 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
@@ -6,6 +6,13 @@ LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
 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
+   |
+LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
+   |                                                ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+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`
    |
 LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'a> {
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 27bb19a89df..969222068ee 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
@@ -6,6 +6,13 @@ LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
 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
+   |
+LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
+   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+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`
    |
 LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'a> {
diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr
index a257576e5d1..3bbbf00d5e7 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.stderr
+++ b/src/test/ui/regions/regions-proc-bound-capture.stderr
@@ -7,6 +7,14 @@ LL |     // This is illegal, because the region bound on `proc` is 'static.
 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
+   |
+LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+LL |     // This is illegal, because the region bound on `proc` is 'static.
+LL |     Box::new(move || { *x })
+   |     ------------------------ because of this returned expression
 help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
    |
 LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + '_> {
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 3d6308a0825..c06943c0874 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
@@ -46,6 +46,14 @@ 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
+   |
+LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+...
+LL |     y.get_b() // ERROR
+   |     --------- because of this returned expression
 
 error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/type-checking-test-4.rs:33:5
@@ -54,6 +62,14 @@ LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
    |                       ------------ this data with lifetime `'a`...
 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
+   |
+LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+LL |     <_ as Bar>::get_b(x) // ERROR
+   |     -------------------- because of this returned expression
 
 error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/type-checking-test-4.rs:38:15
@@ -62,6 +78,14 @@ LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
    |                       ------------ this data with lifetime `'a`...
 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
+   |
+LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+LL |     <_ as Bar<'_, '_>>::get_b(x) // ERROR
+   |     ---------------------------- because of this returned expression
 
 error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/type-checking-test-4.rs:43:27
@@ -84,6 +108,14 @@ 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
+   |
+LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+   |                                        ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+...
+LL |     z.get_b() // ERROR
+   |     --------- because of this returned expression
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
index da0f6d0ecde..3fed7ba6c49 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -9,6 +9,14 @@ 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
+   |
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
+LL |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
+LL |     Box::new(items.iter())
+   |     ---------------------- because of this returned expression
 help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound
    |
 LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {