Skip to content

Commit

Permalink
Rollup merge of #74340 - davidtwco:issue-73747-improper-ctypes-defns-…
Browse files Browse the repository at this point in the history
…is-zst-with-params, r=pnkfelix

lint: use `transparent_newtype_field` to avoid ICE

Fixes #73747.

This PR 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.
  • Loading branch information
Manishearth authored Jul 14, 2020
2 parents c4fcf5a + cccc310 commit dbe7ed3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
32 changes: 16 additions & 16 deletions src/librustc_lint/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/lint/lint-ctypes-73747.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit dbe7ed3

Please sign in to comment.