1
Fork 0

lint: use transparent_newtype_field to avoid ICE

This commit re-uses the `transparent_newtype_field` function instead of
manually calling `is_zst` on normalized fields to determine which field
in a transparent type is the non-zero-sized field, thus avoiding an ICE.

Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
David Wood 2020-07-14 19:26:34 +01:00
parent c724b67e1b
commit cccc3109ff
No known key found for this signature in database
GPG key ID: 2592E76C87381FD9
2 changed files with 30 additions and 16 deletions

View file

@ -531,23 +531,23 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
match ty.kind { match ty.kind {
ty::FnPtr(_) => true, ty::FnPtr(_) => true,
ty::Ref(..) => true, ty::Ref(..) => true,
ty::Adt(field_def, substs) if field_def.repr.transparent() && !field_def.is_union() => { ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => {
for field in field_def.all_fields() { let guaranteed_nonnull_optimization = self
let field_ty = self.cx.tcx.normalize_erasing_regions( .cx
self.cx.param_env, .tcx
field.ty(self.cx.tcx, substs), .get_attrs(def.did)
); .iter()
if field_ty.is_zst(self.cx.tcx, field.did) { .any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed));
continue;
}
let attrs = self.cx.tcx.get_attrs(field_def.did); if guaranteed_nonnull_optimization {
if attrs return true;
.iter() }
.any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed))
|| self.ty_is_known_nonnull(field_ty) for variant in &def.variants {
{ if let Some(field) = variant.transparent_newtype_field(self.cx.tcx) {
return true; if self.ty_is_known_nonnull(field.ty(self.cx.tcx, substs)) {
return true;
}
} }
} }

View file

@ -0,0 +1,14 @@
// check-pass
#[repr(transparent)]
struct NonNullRawComPtr<T: ComInterface> {
inner: std::ptr::NonNull<<T as ComInterface>::VTable>,
}
trait ComInterface {
type VTable;
}
extern "C" fn invoke<T: ComInterface>(_: Option<NonNullRawComPtr<T>>) {}
fn main() {}