Skip to content

Commit

Permalink
fix(rustc_typeck): produce better errors for dyn auto trait
Browse files Browse the repository at this point in the history
Fixes #85026
  • Loading branch information
notriddle committed Aug 31, 2021
1 parent 56ea5e0 commit 026322c
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 30 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0785.md
Original file line number Diff line number Diff line change
@@ -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) {}
```
11 changes: 11 additions & 0 deletions compiler/rustc_typeck/src/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/coherence/issue-85026.rs
Original file line number Diff line number Diff line change
@@ -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() {}
19 changes: 19 additions & 0 deletions src/test/ui/coherence/issue-85026.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 026322c

Please sign in to comment.