diff options
| author | David Wood <david@davidtw.co> | 2020-07-14 19:26:34 +0100 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2020-08-07 11:54:30 -0400 |
| commit | 34c9ac319282f93e148df27db030a99f5a9402f0 (patch) | |
| tree | 04fc459d7571a98cfe2a7a1988ecf8128dca2db1 | |
| parent | 1a2f6d5d6fd46054f59852c052d12f2f3711e5b8 (diff) | |
| download | rust-34c9ac319282f93e148df27db030a99f5a9402f0.tar.gz rust-34c9ac319282f93e148df27db030a99f5a9402f0.zip | |
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>
| -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() {} |
