about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/astconv.rs29
-rw-r--r--src/test/ui/associated-types/issue-62200.rs14
-rw-r--r--src/test/ui/associated-types/issue-62200.stderr11
3 files changed, 42 insertions, 12 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 37f48f82ea6..e6d59d30e2f 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1485,28 +1485,33 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
                 for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) {
                     let br_name = match *br {
-                        ty::BrNamed(_, name) => name,
-                        _ => {
-                            span_bug!(
-                                binding.span,
-                                "anonymous bound region {:?} in binding but not trait ref",
-                                br
-                            );
-                        }
+                        ty::BrNamed(_, name) => format!("lifetime `{}`", name),
+                        _ => "an anonymous lifetime".to_string(),
                     };
                     // FIXME: point at the type params that don't have appropriate lifetimes:
                     // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
                     //                         ----  ----     ^^^^^^^
-                    struct_span_err!(
+                    let mut err = struct_span_err!(
                         tcx.sess,
                         binding.span,
                         E0582,
-                        "binding for associated type `{}` references lifetime `{}`, \
+                        "binding for associated type `{}` references {}, \
                          which does not appear in the trait input types",
                         binding.item_name,
                         br_name
-                    )
-                    .emit();
+                    );
+
+                    if let ty::BrAnon(_) = *br {
+                        // The only way for an anonymous lifetime to wind up
+                        // in the return type but **also** be unconstrained is
+                        // if it only appears in "associated types" in the
+                        // input. See #62200 for an example. In this case,
+                        // though we can easily give a hint that ought to be
+                        // relevant.
+                        err.note("lifetimes appearing in an associated type are not considered constrained");
+                    }
+
+                    err.emit();
                 }
             }
         }
diff --git a/src/test/ui/associated-types/issue-62200.rs b/src/test/ui/associated-types/issue-62200.rs
new file mode 100644
index 00000000000..10f06eb26f8
--- /dev/null
+++ b/src/test/ui/associated-types/issue-62200.rs
@@ -0,0 +1,14 @@
+struct S {}
+
+trait T<'a> {
+    type A;
+}
+
+impl T<'_> for S {
+    type A = u32;
+}
+
+fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
+//~^ ERROR binding for associated type `Output` references an anonymous lifetime
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-62200.stderr b/src/test/ui/associated-types/issue-62200.stderr
new file mode 100644
index 00000000000..f14cd81fdfe
--- /dev/null
+++ b/src/test/ui/associated-types/issue-62200.stderr
@@ -0,0 +1,11 @@
+error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
+  --> $DIR/issue-62200.rs:11:39
+   |
+LL | fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
+   |                                       ^^^^^^^^^^^^^^^
+   |
+   = note: lifetimes appearing in an associated type are not considered constrained
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0582`.