Skip to content

Commit 0f2bd56

Browse files
committed
lint/ty: move fns to avoid abstraction violation
This commit moves `transparent_newtype_field` and `is_zst` to `LateContext` where they are used, rather than being on the `VariantDef` and `TyS` types. Signed-off-by: David Wood <david@davidtw.co>
1 parent 85fbf49 commit 0f2bd56

File tree

4 files changed

+27
-25
lines changed

4 files changed

+27
-25
lines changed

compiler/rustc_lint/src/builtin.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
//! `late_lint_methods!` invocation in `lib.rs`.
2222
2323
use crate::{
24-
types::CItemKind, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
24+
types::{transparent_newtype_field, CItemKind},
25+
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
2526
};
2627
use rustc_ast::attr::{self, HasAttrs};
2728
use rustc_ast::tokenstream::{TokenStream, TokenTree};
@@ -2180,8 +2181,7 @@ impl ClashingExternDeclarations {
21802181
if is_transparent && !is_non_null {
21812182
debug_assert!(def.variants.len() == 1);
21822183
let v = &def.variants[VariantIdx::new(0)];
2183-
ty = v
2184-
.transparent_newtype_field(tcx)
2184+
ty = transparent_newtype_field(tcx, v)
21852185
.expect(
21862186
"single-variant transparent structure with zero-sized field",
21872187
)

compiler/rustc_lint/src/types.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,26 @@ crate fn nonnull_optimization_guaranteed<'tcx>(tcx: TyCtxt<'tcx>, def: &ty::AdtD
533533
.any(|a| tcx.sess.check_name(a, sym::rustc_nonnull_optimization_guaranteed))
534534
}
535535

536+
/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
537+
/// field.
538+
pub fn transparent_newtype_field<'a, 'tcx>(
539+
tcx: TyCtxt<'tcx>,
540+
variant: &'a ty::VariantDef,
541+
) -> Option<&'a ty::FieldDef> {
542+
let param_env = tcx.param_env(variant.def_id);
543+
for field in &variant.fields {
544+
let field_ty = tcx.type_of(field.did);
545+
let is_zst =
546+
tcx.layout_of(param_env.and(field_ty)).map(|layout| layout.is_zst()).unwrap_or(false);
547+
548+
if !is_zst {
549+
return Some(field);
550+
}
551+
}
552+
553+
None
554+
}
555+
536556
/// Is type known to be non-null?
537557
crate fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKind) -> bool {
538558
let tcx = cx.tcx;
@@ -548,7 +568,7 @@ crate fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: C
548568
}
549569

550570
for variant in &def.variants {
551-
if let Some(field) = variant.transparent_newtype_field(tcx) {
571+
if let Some(field) = transparent_newtype_field(cx.tcx, variant) {
552572
if ty_is_known_nonnull(cx, field.ty(tcx, substs), mode) {
553573
return true;
554574
}
@@ -569,7 +589,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
569589
ty::Adt(field_def, field_substs) => {
570590
let inner_field_ty = {
571591
let first_non_zst_ty =
572-
field_def.variants.iter().filter_map(|v| v.transparent_newtype_field(tcx));
592+
field_def.variants.iter().filter_map(|v| transparent_newtype_field(cx.tcx, v));
573593
debug_assert_eq!(
574594
first_non_zst_ty.clone().count(),
575595
1,
@@ -710,7 +730,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
710730
if def.repr.transparent() {
711731
// Can assume that only one field is not a ZST, so only check
712732
// that field's type for FFI-safety.
713-
if let Some(field) = variant.transparent_newtype_field(self.cx.tcx) {
733+
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
714734
self.check_field_type_for_ffi(cache, field, substs)
715735
} else {
716736
bug!("malformed transparent type");

compiler/rustc_middle/src/ty/mod.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -2005,7 +2005,7 @@ pub struct VariantDef {
20052005
flags: VariantFlags,
20062006
}
20072007

2008-
impl<'tcx> VariantDef {
2008+
impl VariantDef {
20092009
/// Creates a new `VariantDef`.
20102010
///
20112011
/// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
@@ -2071,19 +2071,6 @@ impl<'tcx> VariantDef {
20712071
pub fn is_recovered(&self) -> bool {
20722072
self.flags.intersects(VariantFlags::IS_RECOVERED)
20732073
}
2074-
2075-
/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
2076-
/// field.
2077-
pub fn transparent_newtype_field(&self, tcx: TyCtxt<'tcx>) -> Option<&FieldDef> {
2078-
for field in &self.fields {
2079-
let field_ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.def_id));
2080-
if !field_ty.is_zst(tcx, self.def_id) {
2081-
return Some(field);
2082-
}
2083-
}
2084-
2085-
None
2086-
}
20872074
}
20882075

20892076
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]

compiler/rustc_middle/src/ty/sty.rs

-5
Original file line numberDiff line numberDiff line change
@@ -2280,9 +2280,4 @@ impl<'tcx> TyS<'tcx> {
22802280
}
22812281
}
22822282
}
2283-
2284-
/// Is this a zero-sized type?
2285-
pub fn is_zst(&'tcx self, tcx: TyCtxt<'tcx>, did: DefId) -> bool {
2286-
tcx.layout_of(tcx.param_env(did).and(self)).map(|layout| layout.is_zst()).unwrap_or(false)
2287-
}
22882283
}

0 commit comments

Comments
 (0)