Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layout error instead of an ICE for packed and aligned types #83319

Merged
merged 1 commit into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
let dl = self.data_layout();
let pack = repr.pack;
if pack.is_some() && repr.align.is_some() {
bug!("struct cannot be packed and aligned");
self.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned");
return Err(LayoutError::Unknown(ty));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it correct for this and below to return LayoutError::Unknown? Is the idea that it doesn't matter because an error will have already been emitted and the Unknown will never be emitted to the user?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conceptually returning LayoutError::Unknown does seems correct to me. At the same time it wouldn't be exactly the kind of error we would like to emit, given that it is relatively uninformative.

The general idea is that the incorrect use of packed & aligned will diagnosed elsewhere, before we reach any code that is in position to assume that failure to compute layout is an error or a bug (like codegen does assume).

}

let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
Expand Down Expand Up @@ -808,7 +809,11 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {

if def.is_union() {
if def.repr.pack.is_some() && def.repr.align.is_some() {
bug!("union cannot be packed and aligned");
self.tcx.sess.delay_span_bug(
tcx.def_span(def.did),
"union cannot be packed and aligned",
);
return Err(LayoutError::Unknown(ty));
}

let mut align =
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/conflicting-repr-hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,15 @@ union Z {
i: i32,
}

#[repr(packed, align(0x100))]
pub struct S(u16); //~ ERROR type has conflicting packed and align representation hints

#[repr(packed, align(0x100))]
pub union U { //~ ERROR type has conflicting packed and align representation hints
u: u16
}

static B: U = U { u: 0 };
static A: S = S(0);

fn main() {}
16 changes: 15 additions & 1 deletion src/test/ui/conflicting-repr-hints.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,21 @@ LL | | i: i32,
LL | | }
| |_^

error: aborting due to 10 previous errors
error[E0587]: type has conflicting packed and align representation hints
--> $DIR/conflicting-repr-hints.rs:70:1
|
LL | pub struct S(u16);
| ^^^^^^^^^^^^^^^^^^

error[E0587]: type has conflicting packed and align representation hints
--> $DIR/conflicting-repr-hints.rs:73:1
|
LL | / pub union U {
LL | | u: u16
LL | | }
| |_^

error: aborting due to 12 previous errors

Some errors have detailed explanations: E0566, E0587, E0634.
For more information about an error, try `rustc --explain E0566`.