diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2020-07-14 13:19:39 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-14 13:19:39 -0700 |
| commit | dbe7ed33cd14166ed52ff02f4db145e199c348cd (patch) | |
| tree | 873851698947a162abdd85a971618981b1e19b2a /src | |
| parent | c4fcf5a7a4e70073e2229641fedfd57a63f3dfed (diff) | |
| parent | cccc3109ffc61a742bcaa9241e457ceadb96ce95 (diff) | |
| download | rust-dbe7ed33cd14166ed52ff02f4db145e199c348cd.tar.gz rust-dbe7ed33cd14166ed52ff02f4db145e199c348cd.zip | |
Rollup merge of #74340 - davidtwco:issue-73747-improper-ctypes-defns-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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_lint/types.rs | 32 | ||||
| -rw-r--r-- | src/test/ui/lint/lint-ctypes-73747.rs | 14 |
2 files changed, 30 insertions, 16 deletions
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index b3015dcc2ae..46741fcf2ba 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 00000000000..293ffd5c28e --- /dev/null +++ b/src/test/ui/lint/lint-ctypes-73747.rs @@ -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() {} |
