-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Implement repr(transparent) #47158
Implement repr(transparent) #47158
Conversation
let mut all_phantom = true; | ||
for field in &def.struct_variant().fields { | ||
let field_ty = cx.fully_normalize_associated_types_in( | ||
&field.ty(cx, substs) | ||
); | ||
// repr(transparent) types are allowed to have arbitrary ZSTs, not just | ||
// PhantomData -- skip checking all ZST fields |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could restrict it to PhantomData
, didn't know the lint was special-casing that already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm torn. Supporting only PhantomData
would be the more conservative option and I don't have a use case for other ZSTs at hand. OTOH repr(transparent)
is explicitly ignoring all ZSTs, so it makes sense to allow them for C interop too even though repr(C)
warns about other ZSTs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I meant also changing rustc_typeck
, not just this check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. The RFC says all ZSTs are fine, and that seems nicer to me than special casing PhantomData, but being conservative and following the precedent of the improper-ctypes lint also makes sense. If anyone has a preference for starting out accepting only PhantomData, I'll implement that. Otherwise, well, it's not exactly a burden to support other ZSTs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, if the RFC says all ZSTs, I'm fine with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't allowing all ZSTs could change the size and alignment, making it not really transparent?
#[repr(transparent)]
struct U8 {
a: u8,
not_really: [u32; 0],
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kennytm A good point, but this was already brought up in the RFC discussion, with the proposed solution (that I implemented) being to prohibit ZSTs with alignment > 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rkuppe thanks, found the check in check_transparent
@@ -416,7 +416,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { | |||
} | |||
match def.adt_kind() { | |||
AdtKind::Struct => { | |||
if !def.repr.c() { | |||
if !def.repr.c() && !def.repr.transparent() { | |||
return FfiUnsafe("found struct without foreign-function-safe \ | |||
representation annotation in foreign module, \ | |||
consider adding a #[repr(C)] attribute to the type"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe change this message to refer to #[repr(transparent)]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly. The message is already too long IMHO. Maybe this lint should use a help
diagnostic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll do this in a follow-up PR.
let is_zst = (cx, cx.param_env(field.did)) | ||
.layout_of(field_ty) | ||
.map(|layout| layout.is_zst()) | ||
.unwrap_or(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can write this with map_or
fwiw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
layout_of
returns Result
, map_or
only exists on Option
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, didn't know that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But you can call ok()
first before calling map_or()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess, but it doesn't look any nicer than this IMO.
7bbb3d6
to
c2ec5d1
Compare
@rust-lang/docs r=me on the implementation side. |
docs look good to me! though travis found some doctest errors that should be addressed before approving |
c2ec5d1
to
d62764d
Compare
Doc tests should be fixed. |
d62764d
to
697c390
Compare
@bors r=eddyb |
📌 Commit 697c390 has been approved by |
☔ The latest upstream changes (presumably #47156) made this pull request unmergeable. Please resolve the merge conflicts. |
697c390
to
4e1d212
Compare
@bors r=eddyb |
📌 Commit 4e1d212 has been approved by |
⌛ Testing commit 4e1d2122bc7d09bb5fa8b05c558d4e8bf481e0c2 with merge 78e7563b1b9088a9295d3325670d7aee376d3100... |
💔 Test failed - status-travis |
Test failed on i686-musl, the type is not transparent 🤔
|
Nah, it works just fine, that's just how newtypes around aggregates are currently handled. I just had a brainfart in the |
4e1d212
to
6a005eb
Compare
@bors r=eddyb |
7456fe1
to
46dad65
Compare
@bors r=eddyb |
📌 Commit 46dad65 has been approved by |
⌛ Testing commit 46dad65f90ce9cff0ae84c1337f7f7718bc05e4b with merge b08302f63c3dca543fb9b5180f4cf2b697990cb4... |
💔 Test failed - status-travis |
46dad65
to
2be697b
Compare
@bors r=eddyb |
📌 Commit 2be697b has been approved by |
⌛ Testing commit 2be697b with merge 3f82c9163c4728c7f540ca89c4cedb35ce13804b... |
💔 Test failed - status-appveyor |
@bors retry |
@bors clean retry |
☀️ Test successful - status-appveyor, status-travis |
Slightly more complicated: also give them appropriate names that somewhat describe the cases they are trying to cover, using information from PR chatter in rust-lang#47158
r? @eddyb for the functional changes. The bulk of the PR is error messages and docs, might be good to have a doc person look over those.
cc #43036
cc @nox