diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index b3015dcc2aee..46741fcf2ba0 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -531,23 +531,23 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { match ty.kind { ty::FnPtr(_) => true, ty::Ref(..) => true, - ty::Adt(field_def, substs) if field_def.repr.transparent() && !field_def.is_union() => { - for field in field_def.all_fields() { - let field_ty = self.cx.tcx.normalize_erasing_regions( - self.cx.param_env, - field.ty(self.cx.tcx, substs), - ); - if field_ty.is_zst(self.cx.tcx, field.did) { - continue; - } + ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => { + let guaranteed_nonnull_optimization = self + .cx + .tcx + .get_attrs(def.did) + .iter() + .any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed)); + + if guaranteed_nonnull_optimization { + return true; + } - let attrs = self.cx.tcx.get_attrs(field_def.did); - if attrs - .iter() - .any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed)) - || self.ty_is_known_nonnull(field_ty) - { - return true; + for variant in &def.variants { + if let Some(field) = variant.transparent_newtype_field(self.cx.tcx) { + if self.ty_is_known_nonnull(field.ty(self.cx.tcx, substs)) { + return true; + } } } diff --git a/src/test/ui/lint/lint-ctypes-73747.rs b/src/test/ui/lint/lint-ctypes-73747.rs new file mode 100644 index 000000000000..293ffd5c28e1 --- /dev/null +++ b/src/test/ui/lint/lint-ctypes-73747.rs @@ -0,0 +1,14 @@ +// check-pass + +#[repr(transparent)] +struct NonNullRawComPtr { + inner: std::ptr::NonNull<::VTable>, +} + +trait ComInterface { + type VTable; +} + +extern "C" fn invoke(_: Option>) {} + +fn main() {}