From a468da9cfb98df126c0ba709816843115654e3dc Mon Sep 17 00:00:00 2001 From: Michael Hewson Date: Fri, 26 Oct 2018 01:09:33 -0400 Subject: [PATCH] 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 --- src/librustc_typeck/coherence/builtin.rs | 7 +++++++ src/test/ui/invalid_dispatch_from_dyn_impls.rs | 8 ++++++++ src/test/ui/invalid_dispatch_from_dyn_impls.stderr | 11 ++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index e5a52a1f6ac6..99c6ba457faa 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 101e1eb6e307..1cf5c73ab138 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 { impl DispatchFromDyn> for NothingToCoerce {} //~^ ERROR [E0378] +#[repr(C)] +struct HasReprC(Box); + +impl DispatchFromDyn> for HasReprC +where + T: Unsize, +{} //~^^^ 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 f4affb855146..82186b67d97f 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 DispatchFromDyn> for NothingToCoerce {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -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 DispatchFromDyn> for HasReprC +LL | | where +LL | | T: Unsize, +LL | | {} //~^^^ ERROR [E0378] + | |__^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0378`.