about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2021-09-01 09:23:28 +0200
committerGitHub <noreply@github.com>2021-09-01 09:23:28 +0200
commitbbc94ed32982eb4a12a0778837e17581e885d59e (patch)
tree29a182b19b20ce3f0d544eabda13e6af00c9083d
parent75b2ae5ec50a3fb3cadd297b7d524935afa9faad (diff)
parent6e70678f7d93ad777297c865e35e005520a4eefb (diff)
downloadrust-bbc94ed32982eb4a12a0778837e17581e885d59e.tar.gz
rust-bbc94ed32982eb4a12a0778837e17581e885d59e.zip
Rollup merge of #88525 - notriddle:notriddle/coherence-dyn-auto-trait, r=petrochenkov
fix(rustc_typeck): produce better errors for dyn auto trait

Fixes #85026
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0785.md30
-rw-r--r--compiler/rustc_typeck/src/coherence/inherent_impls.rs11
-rw-r--r--src/test/ui/coherence/issue-85026.rs10
-rw-r--r--src/test/ui/coherence/issue-85026.stderr19
5 files changed, 71 insertions, 0 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index c2e62328cb1..45d91c2047d 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -480,6 +480,7 @@ E0781: include_str!("./error_codes/E0781.md"),
 E0782: include_str!("./error_codes/E0782.md"),
 E0783: include_str!("./error_codes/E0783.md"),
 E0784: include_str!("./error_codes/E0784.md"),
+E0785: include_str!("./error_codes/E0785.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
diff --git a/compiler/rustc_error_codes/src/error_codes/E0785.md b/compiler/rustc_error_codes/src/error_codes/E0785.md
new file mode 100644
index 00000000000..373320539ef
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0785.md
@@ -0,0 +1,30 @@
+An inherent `impl` was written on a dyn auto trait.
+
+Erroneous code example:
+
+```compile_fail,E0785
+#![feature(auto_traits)]
+
+auto trait AutoTrait {}
+
+impl dyn AutoTrait {}
+```
+
+Dyn objects allow any number of auto traits, plus at most one non-auto trait.
+The non-auto trait becomes the "principal trait".
+
+When checking if an impl on a dyn trait is coherent, the principal trait is
+normally the only one considered. Since the erroneous code has no principal
+trait, it cannot be implemented at all.
+
+Working example:
+
+```
+#![feature(auto_traits)]
+
+trait PrincipalTrait {}
+
+auto trait AutoTrait {}
+
+impl dyn PrincipalTrait + AutoTrait + Send {}
+```
diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
index 51698437a30..c7be9e21235 100644
--- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
@@ -60,6 +60,17 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
             ty::Dynamic(ref data, ..) if data.principal_def_id().is_some() => {
                 self.check_def_id(item, data.principal_def_id().unwrap());
             }
+            ty::Dynamic(..) => {
+                struct_span_err!(
+                    self.tcx.sess,
+                    ty.span,
+                    E0785,
+                    "cannot define inherent `impl` for a dyn auto trait"
+                )
+                .span_label(ty.span, "impl requires at least one non-auto trait")
+                .note("define and implement a new trait or type instead")
+                .emit();
+            }
             ty::Bool => {
                 self.check_primitive_impl(
                     item.def_id,
diff --git a/src/test/ui/coherence/issue-85026.rs b/src/test/ui/coherence/issue-85026.rs
new file mode 100644
index 00000000000..8b116545aa6
--- /dev/null
+++ b/src/test/ui/coherence/issue-85026.rs
@@ -0,0 +1,10 @@
+#![feature(auto_traits)]
+auto trait AutoTrait {}
+
+// You cannot impl your own `dyn AutoTrait`.
+impl dyn AutoTrait {} //~ERROR E0785
+
+// You cannot impl someone else's `dyn AutoTrait`
+impl dyn Unpin {} //~ERROR E0785
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-85026.stderr b/src/test/ui/coherence/issue-85026.stderr
new file mode 100644
index 00000000000..a5da19bbfaa
--- /dev/null
+++ b/src/test/ui/coherence/issue-85026.stderr
@@ -0,0 +1,19 @@
+error[E0785]: cannot define inherent `impl` for a dyn auto trait
+  --> $DIR/issue-85026.rs:5:6
+   |
+LL | impl dyn AutoTrait {}
+   |      ^^^^^^^^^^^^^ impl requires at least one non-auto trait
+   |
+   = note: define and implement a new trait or type instead
+
+error[E0785]: cannot define inherent `impl` for a dyn auto trait
+  --> $DIR/issue-85026.rs:8:6
+   |
+LL | impl dyn Unpin {}
+   |      ^^^^^^^^^ impl requires at least one non-auto trait
+   |
+   = note: define and implement a new trait or type instead
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0785`.