ty: simplify transparent_newtype_field
This commit removes the normalization from `transparent_newtype_field` - turns out it wasn't necessary and that makes it a bunch simpler - particularly when handling projections. Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
0cccaa0a27
commit
a730d888ae
@ -627,7 +627,7 @@ fn check_variant_for_ffi(
|
||||
if def.repr.transparent() {
|
||||
// Can assume that only one field is not a ZST, so only check
|
||||
// that field's type for FFI-safety.
|
||||
if let Some(field) = variant.transparent_newtype_field(self.cx.tcx, self.cx.param_env) {
|
||||
if let Some(field) = variant.transparent_newtype_field(self.cx.tcx) {
|
||||
self.check_field_type_for_ffi(cache, field, substs)
|
||||
} else {
|
||||
bug!("malformed transparent type");
|
||||
|
@ -1810,21 +1810,9 @@ pub fn is_field_list_non_exhaustive(&self) -> bool {
|
||||
|
||||
/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
|
||||
/// field.
|
||||
pub fn transparent_newtype_field(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
) -> Option<&FieldDef> {
|
||||
pub fn transparent_newtype_field(&self, tcx: TyCtxt<'tcx>) -> Option<&FieldDef> {
|
||||
for field in &self.fields {
|
||||
let field_ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.def_id));
|
||||
|
||||
// `normalize_erasing_regions` will fail for projections that contain generic
|
||||
// parameters, so check these before normalizing.
|
||||
if field_ty.has_projections() && field_ty.needs_subst() {
|
||||
return Some(field);
|
||||
}
|
||||
|
||||
let field_ty = tcx.normalize_erasing_regions(param_env, field_ty);
|
||||
if !field_ty.is_zst(tcx, self.def_id) {
|
||||
return Some(field);
|
||||
}
|
||||
|
24
src/test/ui/lint/lint-ctypes-73249-4.rs
Normal file
24
src/test/ui/lint/lint-ctypes-73249-4.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// check-pass
|
||||
#![deny(improper_ctypes)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
trait Foo {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl Foo for () {
|
||||
type Assoc = PhantomData<()>;
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct Wow<T> where T: Foo<Assoc = PhantomData<T>> {
|
||||
x: <T as Foo>::Assoc,
|
||||
v: u32,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn test(v: Wow<()>);
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user