]> git.lizzy.rs Git - rust.git/commitdiff
Use the span of the user type for `AscribeUserType`
authorMatthew Jasper <mjjasper1@gmail.com>
Tue, 9 Oct 2018 21:59:46 +0000 (22:59 +0100)
committerMatthew Jasper <mjjasper1@gmail.com>
Wed, 10 Oct 2018 10:56:16 +0000 (11:56 +0100)
Also change the order of the fake read for let and the AscribeUserType,
so that we use the better span and message from the fake read in errors.

23 files changed:
src/librustc/mir/mod.rs
src/librustc/mir/visit.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/simplify.rs
src/librustc_mir/hair/cx/block.rs
src/librustc_mir/hair/pattern/mod.rs
src/test/mir-opt/basic_assignment.rs
src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
src/test/ui/nll/user-annotations/patterns.stderr
src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
src/test/ui/regions/regions-addr-of-self.nll.stderr
src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr
src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr
src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr
src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr
src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr
src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr
src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr
src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr
src/test/ui/try-block/try-block-bad-lifetime.stderr
src/test/ui/variance/variance-cell-is-invariant.nll.stderr
src/test/ui/wf/wf-static-method.nll.stderr

index ea4eb761964eb184f0c69b5488331f65ac503cff..2587e19b1cb6255b5aff53965e0493167b505805 100644 (file)
@@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> {
     /// e.g. via `let x: T`, then we carry that type here. The MIR
     /// borrow checker needs this information since it can affect
     /// region inference.
-    pub user_ty: Option<CanonicalTy<'tcx>>,
+    pub user_ty: Option<(CanonicalTy<'tcx>, Span)>,
 
     /// Name of the local, used in debuginfo and pretty-printing.
     ///
index d2b0a6a37a74ac5a6bd8bd31ab275c1c0bd80c9c..920dc88d6a8fc5a01f26d3879faaa79d2ca808b8 100644 (file)
@@ -735,7 +735,7 @@ fn super_local_decl(&mut self,
                     local,
                     source_info: *source_info,
                 });
-                if let Some(user_ty) = user_ty {
+                if let Some((user_ty, _)) = user_ty {
                     self.visit_user_ty(user_ty);
                 }
                 self.visit_source_info(source_info);
index 36eb695186c67da0fc328ca7c2eba9de668a45a1..1f3498b7ae01ac25cbb7532e060966f073a093c1 100644 (file)
@@ -310,12 +310,12 @@ fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
         self.super_local_decl(local, local_decl);
         self.sanitize_type(local_decl, local_decl.ty);
 
-        if let Some(user_ty) = local_decl.user_ty {
+        if let Some((user_ty, span)) = local_decl.user_ty {
             if let Err(terr) = self.cx.relate_type_and_user_type(
                 local_decl.ty,
                 ty::Variance::Invariant,
                 user_ty,
-                Locations::All(local_decl.source_info.span),
+                Locations::All(span),
                 ConstraintCategory::TypeAnnotation,
             ) {
                 span_mirbug!(
index c2a7172d54cca22cf2a105366bf4d27a510d2c67..394fa4e077c1b77af64e2b3c61cb31d7371dd4c8 100644 (file)
@@ -292,30 +292,32 @@ pub fn expr_into_pattern(
                     ..
                 },
                 user_ty: ascription_user_ty,
+                user_ty_span,
             } => {
                 let place =
                     self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard);
                 unpack!(block = self.into(&place, block, initializer));
 
-                let source_info = self.source_info(irrefutable_pat.span);
+                // Inject a fake read, see comments on `FakeReadCause::ForLet`.
+                let pattern_source_info = self.source_info(irrefutable_pat.span);
                 self.cfg.push(
                     block,
                     Statement {
-                        source_info,
-                        kind: StatementKind::AscribeUserType(
-                            place.clone(),
-                            ty::Variance::Invariant,
-                            ascription_user_ty,
-                        ),
+                        source_info: pattern_source_info,
+                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
                     },
                 );
 
-                // Inject a fake read, see comments on `FakeReadCause::ForLet`.
+                let ty_source_info = self.source_info(user_ty_span);
                 self.cfg.push(
                     block,
                     Statement {
-                        source_info,
-                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
+                        source_info: ty_source_info,
+                        kind: StatementKind::AscribeUserType(
+                            place.clone(),
+                            ty::Variance::Invariant,
+                            ascription_user_ty,
+                        ),
                     },
                 );
 
@@ -489,7 +491,7 @@ pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span, for_guard:
     pub fn visit_bindings(
         &mut self,
         pattern: &Pattern<'tcx>,
-        mut pattern_user_ty: Option<CanonicalTy<'tcx>>,
+        mut pattern_user_ty: Option<(CanonicalTy<'tcx>, Span)>,
         f: &mut impl FnMut(
             &mut Self,
             Mutability,
@@ -498,7 +500,7 @@ pub fn visit_bindings(
             NodeId,
             Span,
             Ty<'tcx>,
-            Option<CanonicalTy<'tcx>>,
+            Option<(CanonicalTy<'tcx>, Span)>,
         ),
     ) {
         match *pattern.kind {
@@ -549,16 +551,15 @@ pub fn visit_bindings(
                 // FIXME(#47184): extract or handle `pattern_user_ty` somehow
                 self.visit_bindings(subpattern, None, f);
             }
-            PatternKind::AscribeUserType { ref subpattern, user_ty } => {
+            PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
                 // This corresponds to something like
                 //
                 // ```
-                // let (p1: T1): T2 = ...;
+                // let A::<'a>(_): A<'static> = ...;
                 // ```
                 //
-                // Not presently possible, though maybe someday.
-                assert!(pattern_user_ty.is_none());
-                self.visit_bindings(subpattern, Some(user_ty), f)
+                // FIXME(#47184): handle `pattern_user_ty` somehow
+                self.visit_bindings(subpattern, Some((user_ty, user_ty_span)), f)
             }
             PatternKind::Leaf { ref subpatterns }
             | PatternKind::Variant {
@@ -1469,7 +1470,7 @@ fn declare_binding(
         num_patterns: usize,
         var_id: NodeId,
         var_ty: Ty<'tcx>,
-        user_var_ty: Option<CanonicalTy<'tcx>>,
+        user_var_ty: Option<(CanonicalTy<'tcx>, Span)>,
         has_guard: ArmHasGuard,
         opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
         pat_span: Span,
index 14da8e9083892fb435c743a83573f5fc412f4839..494e7c03c3e68896a23d4cbe16198ca51aa72cf1 100644 (file)
@@ -63,9 +63,9 @@ fn simplify_match_pair<'pat>(&mut self,
                                  candidate: &mut Candidate<'pat, 'tcx>)
                                  -> Result<(), MatchPair<'pat, 'tcx>> {
         match *match_pair.pattern.kind {
-            PatternKind::AscribeUserType { ref subpattern, user_ty } => {
+            PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
                 candidate.ascriptions.push(Ascription {
-                    span: match_pair.pattern.span,
+                    span: user_ty_span,
                     user_ty,
                     source: match_pair.place.clone(),
                 });
index 2ab0a57a855419f23dae98a2d220ebaed70c32ba..022c606a0f819784fcf13b2567dbb44401c79a61 100644 (file)
@@ -92,6 +92,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                                     span: pattern.span,
                                     kind: Box::new(PatternKind::AscribeUserType {
                                         user_ty: *user_ty,
+                                        user_ty_span: ty.span,
                                         subpattern: pattern
                                     })
                                 };
index 04090e5087ffc47c21a579d03e231bc195909447..0238a23895e50f3fec7cfcc2c3eb89cfe1aca6bc 100644 (file)
@@ -71,6 +71,7 @@ pub enum PatternKind<'tcx> {
     AscribeUserType {
         user_ty: CanonicalTy<'tcx>,
         subpattern: Pattern<'tcx>,
+        user_ty_span: Span,
     },
 
     /// x, ref x, x @ P, etc
@@ -692,6 +693,7 @@ fn lower_variant_or_leaf(
             kind = PatternKind::AscribeUserType {
                 subpattern,
                 user_ty,
+                user_ty_span: span,
             };
         }
 
@@ -1015,9 +1017,11 @@ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
             PatternKind::AscribeUserType {
                 ref subpattern,
                 user_ty,
+                user_ty_span,
             } => PatternKind::AscribeUserType {
                 subpattern: subpattern.fold_with(folder),
                 user_ty: user_ty.fold_with(folder),
+                user_ty_span,
             },
             PatternKind::Binding {
                 mutability,
index b474e1a0d6caea16936b8beee92844b2d9e10647..1abe63afa80144228d02b7300117f6901dbe78b0 100644 (file)
@@ -55,8 +55,8 @@ fn main() {
 //        StorageDead(_3);
 //        StorageLive(_4);
 //        _4 = std::option::Option<std::boxed::Box<u32>>::None;
-//        AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
 //        FakeRead(ForLet, _4);
+//        AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
 //        StorageLive(_5);
 //        StorageLive(_6);
 //        _6 = move _4;
index 9a83872b965c9f74db93476f64b543feed6d764a..a4d47eed6fb0a574d40fcbe7cee2e9a85db76683 100644 (file)
@@ -5,10 +5,10 @@ LL |     let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
    |                                                          ^^^^^^^^^
 
 error: higher-ranked subtype error
-  --> $DIR/hr-fn-aaa-as-aba.rs:32:9
+  --> $DIR/hr-fn-aaa-as-aba.rs:32:12
    |
 LL |     let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
-   |         ^
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
index b01dc65fc5f9a905f00731deda1999a1b109776f..0b0848e99137eb3d619633bf201eaa6a85e174bc 100644 (file)
@@ -131,12 +131,12 @@ LL |     y //~ ERROR
    |     ^ returning this value requires that `'a` must outlive `'static`
 
 error: unsatisfied lifetime constraints
-  --> $DIR/patterns.rs:117:9
+  --> $DIR/patterns.rs:117:18
    |
 LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
    |                            -- lifetime `'a` defined here
 LL |     let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR
-   |         ^^^^^^^ type annotation requires that `'a` must outlive `'static`
+   |                  ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
 
 error: aborting due to 14 previous errors
 
index 53d3b2d5323c2488315ef11a505409741f24c7c9..8fd195639fec3b449b9a54995b0a23007202003e 100644 (file)
@@ -1,10 +1,10 @@
 error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/region-object-lifetime-in-coercion.rs:18:9
+  --> $DIR/region-object-lifetime-in-coercion.rs:18:12
    |
 LL | fn a(v: &[u8]) -> Box<Foo + 'static> {
    |         ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
 LL |     let x: Box<Foo + 'static> = Box::new(v);
-   |         ^ lifetime `'static` required
+   |            ^^^^^^^^^^^^^^^^^^ lifetime `'static` required
 
 error[E0621]: explicit lifetime required in the type of `v`
   --> $DIR/region-object-lifetime-in-coercion.rs:24:5
index 0e38abef668cae88084a9039b99cf30deef879ad..1454c856f978586bf0f6ed076d224da72cad2bc8 100644 (file)
@@ -1,10 +1,10 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-self.rs:17:13
+  --> $DIR/regions-addr-of-self.rs:17:16
    |
 LL |     pub fn chase_cat(&mut self) {
    |                      - let's call the lifetime of this reference `'1`
 LL |         let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
-   |             ^ type annotation requires that `'1` must outlive `'static`
+   |                ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
 
 error: aborting due to previous error
 
index fd52494b4994746caedaa6eec7893f712c429bfc..0e48192eaffc82d315766dfa18cfb046c632f7b3 100644 (file)
@@ -1,33 +1,33 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-upvar-self.rs:20:17
+  --> $DIR/regions-addr-of-upvar-self.rs:20:20
    |
 LL |         let _f = || {
    |                  -- lifetime `'1` represents this closure's body
 LL |             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
-   |                 ^ type annotation requires that `'1` must outlive `'static`
+   |                    ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
    |
    = note: closure implements `FnMut`, so references to captured variables can't escape the closure
 
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-upvar-self.rs:20:17
+  --> $DIR/regions-addr-of-upvar-self.rs:20:20
    |
 LL |     pub fn chase_cat(&mut self) {
    |                      --------- lifetime `'2` appears in the type of `self`
 LL |         let _f = || {
    |                  -- lifetime `'1` represents this closure's body
 LL |             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
-   |                 ^ type annotation requires that `'1` must outlive `'2`
+   |                    ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'2`
    |
    = note: closure implements `FnMut`, so references to captured variables can't escape the closure
 
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-upvar-self.rs:20:17
+  --> $DIR/regions-addr-of-upvar-self.rs:20:20
    |
 LL |     pub fn chase_cat(&mut self) {
    |                      - let's call the lifetime of this reference `'1`
 LL |         let _f = || {
 LL |             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
-   |                 ^ type annotation requires that `'1` must outlive `'static`
+   |                    ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
 
 error[E0597]: `self` does not live long enough
   --> $DIR/regions-addr-of-upvar-self.rs:20:46
index 2f3c7166867464f790a68fbe1519022bce047894..aba285d427b47a8f6f89623a938313a1bcd2c4bf 100644 (file)
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-infer-contravariance-due-to-decl.rs:35:9
+  --> $DIR/regions-infer-contravariance-due-to-decl.rs:35:12
    |
 LL | fn use_<'short,'long>(c: Contravariant<'short>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Contravariant<'short>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Contravariant<'long> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
index 835438e9e5d2633978bb4f57d0ae4f9669020413..8bc6d565cf1b20c5ddb27a5d4e23eecc94bac000 100644 (file)
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-infer-covariance-due-to-decl.rs:32:9
+  --> $DIR/regions-infer-covariance-due-to-decl.rs:32:12
    |
 LL | fn use_<'short,'long>(c: Covariant<'long>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Covariant<'long>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Covariant<'short> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
index 706d00a842403ac5d1fd4ab475e477e60888da3c..668b75f5733a21ab079d703d4933167337244149 100644 (file)
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:9
+  --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:12
    |
 LL | fn use_<'short,'long>(c: S<'long, 'short>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: S<'long, 'short>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: S<'long, 'long> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
index 144aa67f9057ad2a1df522c48376154bace70019..5d787e6dab6991b595cdaceaab35453fe433163a 100644 (file)
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-contravariant-use-covariant.rs:33:9
+  --> $DIR/regions-variance-contravariant-use-covariant.rs:33:12
    |
 LL | fn use_<'short,'long>(c: Contravariant<'short>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Contravariant<'short>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Contravariant<'long> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
index c9789f8555e8a209f6319c6083dd7a1ad4aebfd2..3fb290096686d50ffeef723488bf2e3b2899080c 100644 (file)
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-covariant-use-contravariant.rs:33:9
+  --> $DIR/regions-variance-covariant-use-contravariant.rs:33:12
    |
 LL | fn use_<'short,'long>(c: Covariant<'long>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Covariant<'long>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Covariant<'short> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
index 488b70b5f0f801aa1d723d970976bb4ad62e0dc4..fb59ec1ca1008ff7cc4f86042a111c5758612ed9 100644 (file)
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-invariant-use-contravariant.rs:30:9
+  --> $DIR/regions-variance-invariant-use-contravariant.rs:30:12
    |
 LL | fn use_<'short,'long>(c: Invariant<'long>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Invariant<'long>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Invariant<'short> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
index fa7cfc33dc0a909a346021186fd319b277fb56d2..daf6a79136a543ce0841acec7b3fb9ec72be37c5 100644 (file)
@@ -1,11 +1,11 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-variance-invariant-use-covariant.rs:27:9
+  --> $DIR/regions-variance-invariant-use-covariant.rs:27:12
    |
 LL | fn use_<'b>(c: Invariant<'b>) {
    |         -- lifetime `'b` defined here
 ...
 LL |     let _: Invariant<'static> = c; //~ ERROR mismatched types
-   |         ^ type annotation requires that `'b` must outlive `'static`
+   |            ^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'static`
 
 error: aborting due to previous error
 
index ebf56dc9835f4928842586f30424f8f2e8d83e43..061bc19cec9974a1e5a5fa1e4288dfa8985dc7bc 100644 (file)
@@ -2,7 +2,7 @@ error[E0597]: `my_string` does not live long enough
   --> $DIR/try-block-bad-lifetime.rs:25:33
    |
 LL |         let result: Result<(), &str> = try {
-   |             ------ borrow later used here
+   |             ------ borrow later stored here
 LL |             let my_string = String::from("");
 LL |             let my_str: & str = & my_string;
    |                                 ^^^^^^^^^^^ borrowed value does not live long enough
index 0172fcdc8f156715e721657a6ff498d801b3a317..eb01c2bbb05b1029e123ef02d161053232a1c498 100644 (file)
@@ -1,5 +1,5 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/variance-cell-is-invariant.rs:24:9
+  --> $DIR/variance-cell-is-invariant.rs:24:12
    |
 LL | fn use_<'short,'long>(c: Foo<'short>,
    |         ------ ----- lifetime `'long` defined here
@@ -7,7 +7,7 @@ LL | fn use_<'short,'long>(c: Foo<'short>,
    |         lifetime `'short` defined here
 ...
 LL |     let _: Foo<'long> = c; //~ ERROR E0623
-   |         ^ type annotation requires that `'short` must outlive `'long`
+   |            ^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
 
 error: aborting due to previous error
 
index 51aec2a949f998f51d9248a25715443c30ba0035..bfcb16c654ff1d71dcf1c4a10056f44a44689002 100644 (file)
@@ -9,6 +9,17 @@ LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
 LL |         u //~ ERROR E0312
    |         ^ returning this value requires that `'b` must outlive `'a`
 
+error: unsatisfied lifetime constraints
+  --> $DIR/wf-static-method.rs:36:18
+   |
+LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
+   |      --  -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+...
+LL |         let me = Self::make_me(); //~ ERROR lifetime bound not satisfied
+   |                  ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+
 error: unsatisfied lifetime constraints
   --> $DIR/wf-static-method.rs:43:9
    |
@@ -20,5 +31,25 @@ LL |     fn inherent_evil(u: &'b u32) -> &'a u32 {
 LL |         u //~ ERROR E0312
    |         ^ returning this value requires that `'b` must outlive `'a`
 
-error: aborting due to 2 previous errors
+error: unsatisfied lifetime constraints
+  --> $DIR/wf-static-method.rs:51:5
+   |
+LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+   |         --  -- lifetime `'b` defined here
+   |         |
+   |         lifetime `'a` defined here
+LL |     <()>::static_evil(b) //~ ERROR cannot infer an appropriate lifetime
+   |     ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/wf-static-method.rs:55:5
+   |
+LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     <IndirectEvil>::static_evil(b)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
+
+error: aborting due to 5 previous errors