about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2020-07-24 18:56:32 +0900
committerGitHub <noreply@github.com>2020-07-24 18:56:32 +0900
commit1f6d5ce4ab620d2b843cd0171d0e20ee24ae8c15 (patch)
tree753430a21e794025b53275a410ac74798f78cb82
parenta02aecba211ba82e79350db9e4dcd2675fd79423 (diff)
parentbbaab63f844d64ca726a2a83c18774b3957c7169 (diff)
downloadrust-1f6d5ce4ab620d2b843cd0171d0e20ee24ae8c15.tar.gz
rust-1f6d5ce4ab620d2b843cd0171d0e20ee24ae8c15.zip
Rollup merge of #74665 - smmalis37:issue-62200, r=davidtwco
Don't ICE on unconstrained anonymous lifetimes inside associated types.

Fixes #62200. The change here is inspired (copied) by how this case is handled on bare fns at https://github.com/rust-lang/rust/blob/e8b55a4ad230ebec762fdfc4f241ba98a98560af/src/librustc_typeck/astconv.rs#L3083-L3106.
-rw-r--r--src/librustc_typeck/astconv.rs29
-rw-r--r--src/test/ui/associated-types/issue-62200.rs15
-rw-r--r--src/test/ui/associated-types/issue-62200.stderr11
3 files changed, 43 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..9d18690e960
--- /dev/null
+++ b/src/test/ui/associated-types/issue-62200.rs
@@ -0,0 +1,15 @@
+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
+//~^^ NOTE lifetimes appearing in an associated type are not considered constrained
+
+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`.