Skip to content

Commit 1b679e7

Browse files
committed
Only allow ZSTs with 1 byte alignment
1 parent abf73a6 commit 1b679e7

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

src/librustc_typeck/coherence/builtin.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ fn visit_implementation_of_dispatch_from_dyn<'a, 'tcx>(
227227
let ty_b = field.ty(tcx, substs_b);
228228

229229
if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
230-
if layout.is_zst() {
231-
// ignore ZST fields
230+
if layout.is_zst() && layout.details.align.abi.bytes() == 1 {
231+
// ignore ZST fields with alignment of 1 byte
232232
return None;
233233
}
234234
}
@@ -238,7 +238,7 @@ fn visit_implementation_of_dispatch_from_dyn<'a, 'tcx>(
238238
create_err(
239239
"the trait `DispatchFromDyn` may only be implemented \
240240
for structs containing the field being coerced, \
241-
ZST fields, and nothing else"
241+
ZST fields with 1 byte alignment, and nothing else"
242242
).note(
243243
&format!(
244244
"extra field `{}` of type `{}` is not allowed",

src/test/ui/invalid_dispatch_from_dyn_impls.rs

+9
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,13 @@ where
3939
T: Unsize<U>,
4040
{} //~^^^ ERROR [E0378]
4141

42+
#[repr(align(64))]
43+
struct OverAlignedZst;
44+
struct OverAligned<T: ?Sized>(Box<T>, OverAlignedZst);
45+
46+
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
47+
where
48+
T: Unsize<U>,
49+
{} //~^^^ ERROR [E0378]
50+
4251
fn main() {}

src/test/ui/invalid_dispatch_from_dyn_impls.stderr

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields, and nothing else
1+
error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
22
--> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1
33
|
44
LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
@@ -36,6 +36,17 @@ LL | | T: Unsize<U>,
3636
LL | | {}
3737
| |__^
3838

39-
error: aborting due to 4 previous errors
39+
error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
40+
--> $DIR/invalid_dispatch_from_dyn_impls.rs:46:1
41+
|
42+
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
43+
LL | | where
44+
LL | | T: Unsize<U>,
45+
LL | | {}
46+
| |__^
47+
|
48+
= note: extra field `1` of type `OverAlignedZst` is not allowed
49+
50+
error: aborting due to 5 previous errors
4051

4152
For more information about this error, try `rustc --explain E0378`.

0 commit comments

Comments
 (0)