-
-
Save davidtwco/9ce3cb7c498d1fbc8a224cdd7f8c472b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs | |
index 327e226a9f1..99430794668 100644 | |
--- a/compiler/rustc_lint/src/types.rs | |
+++ b/compiler/rustc_lint/src/types.rs | |
@@ -940,30 +940,6 @@ pub(crate) fn repr_nullable_ptr<'tcx>( | |
} | |
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { | |
- // Returns `true` if `ty` is a `()`, or a `repr(transparent)` type whose only non-ZST field | |
- // is a generic substituted for `()` - in either case, the type is FFI-safe when used as a | |
- // return type. | |
- pub fn is_unit_or_equivalent(&self, ty: Ty<'tcx>) -> bool { | |
- if ty.is_unit() { | |
- return true; | |
- } | |
- | |
- if let ty::Adt(def, substs) = ty.kind() && def.repr().transparent() { | |
- return def.variants() | |
- .iter() | |
- .filter_map(|variant| transparent_newtype_field(self.cx.tcx, variant)) | |
- .all(|field| { | |
- let field_ty = field.ty(self.cx.tcx, substs); | |
- !field_ty.has_opaque_types() && { | |
- let field_ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, field_ty); | |
- self.is_unit_or_equivalent(field_ty) | |
- } | |
- }); | |
- } | |
- | |
- false | |
- } | |
- | |
/// Check if the type is array and emit an unsafe type lint. | |
fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { | |
if let ty::Array(..) = ty.kind() { | |
@@ -1007,14 +983,19 @@ fn check_variant_for_ffi( | |
use FfiResult::*; | |
let transparent_with_all_zst_fields = if def.repr().transparent() { | |
- // Transparent newtypes have at most one non-ZST field which needs to be checked.. | |
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) { | |
- return self.check_field_type_for_ffi(cache, field, substs); | |
- } | |
+ // Transparent newtypes have at most one non-ZST field which needs to be checked.. | |
+ match self.check_field_type_for_ffi(cache, field, substs) { | |
+ FfiUnsafe { ty, .. } if ty.is_unit() => (), | |
+ r => return r, | |
+ } | |
- // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all | |
- // `PhantomData`). | |
- true | |
+ false | |
+ } else { | |
+ // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all | |
+ // `PhantomData`). | |
+ true | |
+ } | |
} else { | |
false | |
}; | |
@@ -1024,6 +1005,8 @@ fn check_variant_for_ffi( | |
for field in &variant.fields { | |
all_phantom &= match self.check_field_type_for_ffi(cache, &field, substs) { | |
FfiSafe => false, | |
+ // `()` fields are FFI-safe! | |
+ FfiUnsafe { ty, .. } if ty.is_unit() => false, | |
FfiPhantom(..) => true, | |
r @ FfiUnsafe { .. } => return r, | |
} | |
@@ -1246,7 +1229,7 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F | |
} | |
let ret_ty = sig.output(); | |
- if self.is_unit_or_equivalent(ret_ty) { | |
+ if ret_ty.is_unit() { | |
return FfiSafe; | |
} | |
@@ -1371,7 +1354,7 @@ fn check_type_for_ffi_and_report_errors( | |
// Don't report FFI errors for unit return types. This check exists here, and not in | |
// the caller (where it would make more sense) so that normalization has definitely | |
// happened. | |
- if is_return_type && self.is_unit_or_equivalent(ty) { | |
+ if is_return_type && ty.is_unit() { | |
return; | |
} | |
diff --git a/tests/ui/lint/lint-ctypes-113436.rs b/tests/ui/lint/lint-ctypes-113436.rs | |
index d1328af9924..4f733b5bb16 100644 | |
--- a/tests/ui/lint/lint-ctypes-113436.rs | |
+++ b/tests/ui/lint/lint-ctypes-113436.rs | |
@@ -1,3 +1,4 @@ | |
+// check-pass | |
#![deny(improper_ctypes_definitions)] | |
#[repr(C)] | |
@@ -7,20 +8,16 @@ | |
pub struct TransparentWrap<T>(T); | |
pub extern "C" fn f() -> Wrap<()> { | |
- //~^ ERROR `extern` fn uses type `()`, which is not FFI-safe | |
todo!() | |
} | |
const _: extern "C" fn() -> Wrap<()> = f; | |
-//~^ ERROR `extern` fn uses type `()`, which is not FFI-safe | |
pub extern "C" fn ff() -> Wrap<Wrap<()>> { | |
- //~^ ERROR `extern` fn uses type `()`, which is not FFI-safe | |
todo!() | |
} | |
const _: extern "C" fn() -> Wrap<Wrap<()>> = ff; | |
-//~^ ERROR `extern` fn uses type `()`, which is not FFI-safe | |
pub extern "C" fn g() -> TransparentWrap<()> { | |
todo!() | |
diff --git a/tests/ui/lint/lint-ctypes-113436.stderr b/tests/ui/lint/lint-ctypes-113436.stderr | |
deleted file mode 100644 | |
index 72f92c1a49c..00000000000 | |
--- a/tests/ui/lint/lint-ctypes-113436.stderr | |
+++ /dev/null | |
@@ -1,43 +0,0 @@ | |
-error: `extern` fn uses type `()`, which is not FFI-safe | |
- --> $DIR/lint-ctypes-113436.rs:9:26 | |
- | | |
-LL | pub extern "C" fn f() -> Wrap<()> { | |
- | ^^^^^^^^ not FFI-safe | |
- | | |
- = help: consider using a struct instead | |
- = note: tuples have unspecified layout | |
-note: the lint level is defined here | |
- --> $DIR/lint-ctypes-113436.rs:1:9 | |
- | | |
-LL | #![deny(improper_ctypes_definitions)] | |
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
- | |
-error: `extern` fn uses type `()`, which is not FFI-safe | |
- --> $DIR/lint-ctypes-113436.rs:14:10 | |
- | | |
-LL | const _: extern "C" fn() -> Wrap<()> = f; | |
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | |
- | | |
- = help: consider using a struct instead | |
- = note: tuples have unspecified layout | |
- | |
-error: `extern` fn uses type `()`, which is not FFI-safe | |
- --> $DIR/lint-ctypes-113436.rs:17:27 | |
- | | |
-LL | pub extern "C" fn ff() -> Wrap<Wrap<()>> { | |
- | ^^^^^^^^^^^^^^ not FFI-safe | |
- | | |
- = help: consider using a struct instead | |
- = note: tuples have unspecified layout | |
- | |
-error: `extern` fn uses type `()`, which is not FFI-safe | |
- --> $DIR/lint-ctypes-113436.rs:22:10 | |
- | | |
-LL | const _: extern "C" fn() -> Wrap<Wrap<()>> = ff; | |
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | |
- | | |
- = help: consider using a struct instead | |
- = note: tuples have unspecified layout | |
- | |
-error: aborting due to 4 previous errors | |
- | |
diff --git a/tests/ui/repr/repr-transparent-issue-87496.rs b/tests/ui/repr/repr-transparent-issue-87496.rs | |
index 0ce6fb2c19f..a4dd45c63f5 100644 | |
--- a/tests/ui/repr/repr-transparent-issue-87496.rs | |
+++ b/tests/ui/repr/repr-transparent-issue-87496.rs | |
@@ -6,7 +6,7 @@ | |
struct TransparentCustomZst(()); | |
extern "C" { | |
fn good17(p: TransparentCustomZst); | |
- //~^ WARNING: `extern` block uses type `()`, which is not FFI-safe | |
+ //~^ WARNING: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe | |
} | |
fn main() {} | |
diff --git a/tests/ui/repr/repr-transparent-issue-87496.stderr b/tests/ui/repr/repr-transparent-issue-87496.stderr | |
index 03c62f8514e..aee31212b4e 100644 | |
--- a/tests/ui/repr/repr-transparent-issue-87496.stderr | |
+++ b/tests/ui/repr/repr-transparent-issue-87496.stderr | |
@@ -1,11 +1,15 @@ | |
-warning: `extern` block uses type `()`, which is not FFI-safe | |
+warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe | |
--> $DIR/repr-transparent-issue-87496.rs:8:18 | |
| | |
LL | fn good17(p: TransparentCustomZst); | |
| ^^^^^^^^^^^^^^^^^^^^ not FFI-safe | |
| | |
- = help: consider using a struct instead | |
- = note: tuples have unspecified layout | |
+ = note: this struct contains only zero-sized fields | |
+note: the type is defined here | |
+ --> $DIR/repr-transparent-issue-87496.rs:6:1 | |
+ | | |
+LL | struct TransparentCustomZst(()); | |
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
= note: `#[warn(improper_ctypes)]` on by default | |
warning: 1 warning emitted |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment