about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Hewson <michael@michaelhewson.ca>2018-10-26 01:09:33 -0400
committerMichael Hewson <michael@michaelhewson.ca>2018-11-01 18:16:59 -0400
commita468da9cfb98df126c0ba709816843115654e3dc (patch)
tree74e513de42f912ddee3f4e8f7f9929412bb1c0fc
parent3db22039dceb36fc15e770c24ec99e2db1ca586d (diff)
downloadrust-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.rs7
-rw-r--r--src/test/ui/invalid_dispatch_from_dyn_impls.rs8
-rw-r--r--src/test/ui/invalid_dispatch_from_dyn_impls.stderr11
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`.