about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2020-01-04 13:08:17 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2020-01-05 18:13:01 +0000
commit5e92625004546005c3bc59351dd6c5132312f0f7 (patch)
tree670312e3dd9915f8f88a3040506d4fb5f03f961c
parentc5840f9d252c2f5cc16698dbf385a29c5de3ca07 (diff)
downloadrust-5e92625004546005c3bc59351dd6c5132312f0f7.tar.gz
rust-5e92625004546005c3bc59351dd6c5132312f0f7.zip
Correctly check for opaque types in `assoc_ty_def`
-rw-r--r--src/librustc/traits/project.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr23
3 files changed, 40 insertions, 1 deletions
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index c604bf59cbd..5ac31fafd9f 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -1461,7 +1461,7 @@ fn assoc_ty_def(
     // cycle error if the specialization graph is currently being built.
     let impl_node = specialization_graph::Node::Impl(impl_def_id);
     for item in impl_node.items(tcx) {
-        if item.kind == ty::AssocKind::Type
+        if matches!(item.kind, ty::AssocKind::Type | ty::AssocKind::OpaqueTy)
             && tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id)
         {
             return specialization_graph::NodeItem {
diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs
new file mode 100644
index 00000000000..c46c4715924
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs
@@ -0,0 +1,16 @@
+// Regression test for issue 67856
+
+#![feature(unboxed_closures)]
+#![feature(type_alias_impl_trait)]
+#![feature(fn_traits)]
+
+trait MyTrait {}
+impl MyTrait for () {}
+
+impl<F> FnOnce<()> for &F {
+    //~^ ERROR conflicting implementations
+    //~| ERROR type parameter `F` must be used
+    type Output = impl MyTrait;
+    extern "rust-call" fn call_once(self, _: ()) -> Self::Output {}
+}
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr
new file mode 100644
index 00000000000..f8e1e55f23f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr
@@ -0,0 +1,23 @@
+error[E0119]: conflicting implementations of trait `std::ops::FnOnce<()>` for type `&_`:
+  --> $DIR/incoherent-assoc-imp-trait.rs:10:1
+   |
+LL | impl<F> FnOnce<()> for &F {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<A, F> std::ops::FnOnce<A> for &F
+             where F: std::ops::Fn<A>, F: ?Sized;
+
+error[E0210]: type parameter `F` must be used as the type parameter for some local type (e.g., `MyStruct<F>`)
+  --> $DIR/incoherent-assoc-imp-trait.rs:10:6
+   |
+LL | impl<F> FnOnce<()> for &F {
+   |      ^ type parameter `F` must be used as the type parameter for some local type
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
+   = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0210.
+For more information about an error, try `rustc --explain E0119`.