diff options
| author | Michael Hewson <michael@michaelhewson.ca> | 2018-10-26 01:09:33 -0400 |
|---|---|---|
| committer | Michael Hewson <michael@michaelhewson.ca> | 2018-11-01 18:16:59 -0400 |
| commit | a468da9cfb98df126c0ba709816843115654e3dc (patch) | |
| tree | 74e513de42f912ddee3f4e8f7f9929412bb1c0fc | |
| parent | 3db22039dceb36fc15e770c24ec99e2db1ca586d (diff) | |
| download | rust-a468da9cfb98df126c0ba709816843115654e3dc.tar.gz rust-a468da9cfb98df126c0ba709816843115654e3dc.zip | |
Add a check for reprs that could change the ABI
disallow `#[repr(C)] and `#[repr(packed)]` on structs implementing DispatchFromDyn because they will change the ABI from Scalar/ScalarPair to Aggregrate, resulting in an ICE during object-safety checks or codegen
| -rw-r--r-- | src/librustc_typeck/coherence/builtin.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/invalid_dispatch_from_dyn_impls.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/invalid_dispatch_from_dyn_impls.stderr | 11 |
3 files changed, 25 insertions, 1 deletions
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index e5a52a1f6ac..99c6ba457fa 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -223,6 +223,13 @@ fn visit_implementation_of_dispatch_from_dyn<'a, 'tcx>( return } + if def_a.repr.c() || def_a.repr.packed() { + create_err( + "structs implementing `DispatchFromDyn` may not have \ + `#[repr(packed)]` or `#[repr(C)]`" + ).emit(); + } + let fields = &def_a.non_enum_variant().fields; let coerced_fields = fields.iter().filter_map(|field| { diff --git a/src/test/ui/invalid_dispatch_from_dyn_impls.rs b/src/test/ui/invalid_dispatch_from_dyn_impls.rs index 101e1eb6e30..1cf5c73ab13 100644 --- a/src/test/ui/invalid_dispatch_from_dyn_impls.rs +++ b/src/test/ui/invalid_dispatch_from_dyn_impls.rs @@ -41,4 +41,12 @@ struct NothingToCoerce<T: ?Sized> { impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {} //~^ ERROR [E0378] +#[repr(C)] +struct HasReprC<T: ?Sized>(Box<T>); + +impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T> +where + T: Unsize<U>, +{} //~^^^ ERROR [E0378] + fn main() {} diff --git a/src/test/ui/invalid_dispatch_from_dyn_impls.stderr b/src/test/ui/invalid_dispatch_from_dyn_impls.stderr index f4affb85514..82186b67d97 100644 --- a/src/test/ui/invalid_dispatch_from_dyn_impls.stderr +++ b/src/test/ui/invalid_dispatch_from_dyn_impls.stderr @@ -27,6 +27,15 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]` + --> $DIR/invalid_dispatch_from_dyn_impls.rs:47:1 + | +LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T> +LL | | where +LL | | T: Unsize<U>, +LL | | {} //~^^^ ERROR [E0378] + | |__^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0378`. |
