-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Guarantee result nonzero for FFI #110968
Guarantee result nonzero for FFI #110968
Conversation
Implements the required comipler changes for result_ffi_guarantees (rust-lang#3391) Allows `Result<T, E>` to be used in extern "C" functions where one of (T, E) is a non-zero type and one of (T, E) is a zero sized type. e.g. `Result<NonZeroI32, ()>` Adds test cases to ensure that the abi for Result and Option types with nonzero representation remains consistent
r? @jackh726 (rustbot has picked a reviewer for you, use r? to override) |
r? compiler |
let is_zst = |field: &FieldDef, variant: &VariantDef| { | ||
let param_env = cx.tcx.param_env(variant.def_id); | ||
let field_ty = field.ty(cx.tcx, substs); | ||
cx.tcx | ||
.layout_of(param_env.and(field_ty)) | ||
.map_or(false, |layout| layout.is_zst()) | ||
}; |
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.
This is not sufficient, see the RFC:
Result<T, E>
where eitherT
orE
meet all of the following conditions:
- Is a zero-sized type with alignment 1 (a "1-ZST").
- Has no fields.
- Does not have the
#[non_exhaustive]
attribute.
(emph. mine)
@@ -770,8 +773,26 @@ pub(crate) fn repr_nullable_ptr<'tcx>( | |||
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty); |
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.
Please also update the documentation comment on this function.
) -> FfiResult<'tcx> { | ||
let field_ty = field.ty(self.cx.tcx, substs); | ||
if field_ty.has_opaque_types() { | ||
if field_ty.is_unit() && allow_unit_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.
This only checks for unit, shouldn't it be the same check as above? (ZST + no fields + exhaustive)
@@ -770,8 +773,26 @@ pub(crate) fn repr_nullable_ptr<'tcx>( | |||
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty); |
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.
Also, the doc comment seems to suggest we have similar code in codegen, but I don't see it changed in this PR.
cc @Lokathor |
☔ The latest upstream changes (presumably #113591) made this pull request unmergeable. Please resolve the merge conflicts. |
@zacklukem FYI: when a PR is ready for review, send a message containing |
([], [field]) | ([field], []) => field.ty(cx.tcx, substs), | ||
// If one variant has a ZST and the other has a single field (e.g. Result<T, ()> or Result<(), T>) |
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.
All of these uses of "ZST" here should become "1-ZST" -- it is quite important that we exclude ZST with alignment requirements. There now is a layout.is_1zst
method that can and should be used here.
Closing this as inactive. Feel free to reöpen this pr or create a new pr if you get the time to work on this. Thanks |
Implements the required comipler changes for result_ffi_guarantees (rust-lang/rfcs#3391)
Allows
Result<T, E>
to be used inextern "C"
functions where one of (T, E) is a non-zero type and one of (T, E) is a zero sized type. e.g.Result<NonZeroI32, ()>
Adds test cases to ensure that the abi for Result and Option types with nonzero representation remains consistent
tracking issue: #110503