From 026322c34b2ae68af15b59df69a121209c8364f1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 30 Aug 2021 22:11:25 -0700 Subject: [PATCH 1/3] fix(rustc_typeck): produce better errors for dyn auto trait Fixes #85026 --- compiler/rustc_error_codes/src/error_codes.rs | 1 + .../src/error_codes/E0785.md | 30 +++++++++++++++++++ .../src/coherence/inherent_impls.rs | 11 +++++++ src/test/ui/coherence/issue-85026.rs | 10 +++++++ src/test/ui/coherence/issue-85026.stderr | 19 ++++++++++++ 5 files changed, 71 insertions(+) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0785.md create mode 100644 src/test/ui/coherence/issue-85026.rs create mode 100644 src/test/ui/coherence/issue-85026.stderr diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index c2e62328cb151..45d91c2047d41 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 0000000000000..b8a03cd109d87 --- /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 51698437a305b..05d7dfb9c8ffa 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 a principal 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 0000000000000..8b116545aa696 --- /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 0000000000000..cf9cd52d2bfdd --- /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 a principal 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 a principal 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`. From 435cdd0f9ab2cb02bb475415279f9542efa449a1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 30 Aug 2021 22:18:55 -0700 Subject: [PATCH 2/3] Update E0785.md --- compiler/rustc_error_codes/src/error_codes/E0785.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0785.md b/compiler/rustc_error_codes/src/error_codes/E0785.md index b8a03cd109d87..373320539ef64 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0785.md +++ b/compiler/rustc_error_codes/src/error_codes/E0785.md @@ -26,5 +26,5 @@ trait PrincipalTrait {} auto trait AutoTrait {} -impl dyn (PrincipalTrait + AutoTrait + Send) {} +impl dyn PrincipalTrait + AutoTrait + Send {} ``` From 6e70678f7d93ad777297c865e35e005520a4eefb Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 31 Aug 2021 08:52:19 -0700 Subject: [PATCH 3/3] Change wording to less jaron-y "non-auto trait" Co-authored-by: Vadim Petrochenkov --- compiler/rustc_typeck/src/coherence/inherent_impls.rs | 2 +- src/test/ui/coherence/issue-85026.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs index 05d7dfb9c8ffa..c7be9e2123512 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs @@ -67,7 +67,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { E0785, "cannot define inherent `impl` for a dyn auto trait" ) - .span_label(ty.span, "impl requires a principal trait") + .span_label(ty.span, "impl requires at least one non-auto trait") .note("define and implement a new trait or type instead") .emit(); } diff --git a/src/test/ui/coherence/issue-85026.stderr b/src/test/ui/coherence/issue-85026.stderr index cf9cd52d2bfdd..a5da19bbfaa47 100644 --- a/src/test/ui/coherence/issue-85026.stderr +++ b/src/test/ui/coherence/issue-85026.stderr @@ -2,7 +2,7 @@ error[E0785]: cannot define inherent `impl` for a dyn auto trait --> $DIR/issue-85026.rs:5:6 | LL | impl dyn AutoTrait {} - | ^^^^^^^^^^^^^ impl requires a principal trait + | ^^^^^^^^^^^^^ impl requires at least one non-auto trait | = note: define and implement a new trait or type instead @@ -10,7 +10,7 @@ error[E0785]: cannot define inherent `impl` for a dyn auto trait --> $DIR/issue-85026.rs:8:6 | LL | impl dyn Unpin {} - | ^^^^^^^^^ impl requires a principal trait + | ^^^^^^^^^ impl requires at least one non-auto trait | = note: define and implement a new trait or type instead