Skip to content

Commit ac6f3a3

Browse files
committed
Auto merge of #143328 - oli-obk:ty-decl-wf-check, r=cjgillot
Avoid loading HIR for check_well_formed on type declarations r? @compiler-errors
2 parents 39ec825 + ed579db commit ac6f3a3

4 files changed

Lines changed: 62 additions & 70 deletions

File tree

compiler/rustc_hir/src/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5253,6 +5253,7 @@ impl<'hir> Node<'hir> {
52535253
GenericParamKind::Type { default, .. } => default,
52545254
GenericParamKind::Const { ty, .. } => Some(ty),
52555255
},
5256+
Node::Field(f) => Some(f.ty),
52565257
_ => None,
52575258
}
52585259
}

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use ty::TypingMode;
3535
use super::compare_impl_item::check_type_bounds;
3636
use super::*;
3737
use crate::check::wfcheck::{
38-
check_associated_item, check_trait_item, check_variances_for_type_defn, check_where_clauses,
39-
enter_wf_checking_ctxt,
38+
check_associated_item, check_trait_item, check_type_defn, check_variances_for_type_defn,
39+
check_where_clauses, enter_wf_checking_ctxt,
4040
};
4141

4242
fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) {
@@ -103,7 +103,7 @@ pub fn check_custom_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, fn_sig: FnSig<'_>,
103103
}
104104
}
105105

106-
fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
106+
fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
107107
let def = tcx.adt_def(def_id);
108108
let span = tcx.def_span(def_id);
109109
def.destructor(tcx); // force the destructor to be evaluated
@@ -116,15 +116,17 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
116116

117117
check_transparent(tcx, def);
118118
check_packed(tcx, span, def);
119+
check_type_defn(tcx, def_id, false)
119120
}
120121

121-
fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
122+
fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
122123
let def = tcx.adt_def(def_id);
123124
let span = tcx.def_span(def_id);
124125
def.destructor(tcx); // force the destructor to be evaluated
125126
check_transparent(tcx, def);
126127
check_union_fields(tcx, span, def_id);
127128
check_packed(tcx, span, def);
129+
check_type_defn(tcx, def_id, true)
128130
}
129131

130132
fn allowed_union_or_unsafe_field<'tcx>(
@@ -805,9 +807,12 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
805807
tcx.ensure_ok().generics_of(def_id);
806808
tcx.ensure_ok().type_of(def_id);
807809
tcx.ensure_ok().predicates_of(def_id);
808-
crate::collect::lower_enum_variant_types(tcx, def_id);
810+
crate::collect::check_enum_variant_types(tcx, def_id);
809811
check_enum(tcx, def_id);
810812
check_variances_for_type_defn(tcx, def_id);
813+
res = res.and(check_type_defn(tcx, def_id, true));
814+
// enums are fully handled by the type based check and have no hir wfcheck logic
815+
return res;
811816
}
812817
DefKind::Fn => {
813818
tcx.ensure_ok().generics_of(def_id);
@@ -865,12 +870,19 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
865870
_ => {}
866871
}
867872
}
873+
res = res.and(wfcheck::check_trait(tcx, def_id));
874+
wfcheck::check_gat_where_clauses(tcx, def_id);
875+
// Trait aliases do not have hir checks anymore
876+
return res;
868877
}
869878
DefKind::TraitAlias => {
870879
tcx.ensure_ok().generics_of(def_id);
871880
tcx.ensure_ok().explicit_implied_predicates_of(def_id);
872881
tcx.ensure_ok().explicit_super_predicates_of(def_id);
873882
tcx.ensure_ok().predicates_of(def_id);
883+
res = res.and(wfcheck::check_trait(tcx, def_id));
884+
// Trait aliases do not have hir checks anymore
885+
return res;
874886
}
875887
def_kind @ (DefKind::Struct | DefKind::Union) => {
876888
tcx.ensure_ok().generics_of(def_id);
@@ -885,14 +897,16 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
885897
}
886898

887899
if let Some((_, ctor_def_id)) = adt.ctor {
888-
crate::collect::lower_variant_ctor(tcx, ctor_def_id.expect_local());
900+
crate::collect::check_ctor(tcx, ctor_def_id.expect_local());
889901
}
890-
match def_kind {
902+
check_variances_for_type_defn(tcx, def_id);
903+
res = res.and(match def_kind {
891904
DefKind::Struct => check_struct(tcx, def_id),
892905
DefKind::Union => check_union(tcx, def_id),
893906
_ => unreachable!(),
894-
}
895-
check_variances_for_type_defn(tcx, def_id);
907+
});
908+
// structs and enums are fully handled by the type based check and have no hir wfcheck logic
909+
return res;
896910
}
897911
DefKind::OpaqueTy => {
898912
check_opaque_precise_captures(tcx, def_id);
@@ -1073,6 +1087,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
10731087
_ => (),
10741088
}
10751089
}
1090+
// Doesn't have any hir based checks
1091+
return res;
10761092
}
10771093
DefKind::Closure => {
10781094
// This is guaranteed to be called by metadata encoding,
@@ -1152,10 +1168,14 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
11521168
return res;
11531169
}
11541170

1155-
// Only `Node::Item` and `Node::ForeignItem` still have HIR based
1156-
// checks. Returning early here does not miss any checks and
1157-
// avoids this query from having a direct dependency edge on the HIR
1158-
DefKind::AnonConst | DefKind::InlineConst => return res,
1171+
// These have no wf checks
1172+
DefKind::AnonConst
1173+
| DefKind::InlineConst
1174+
| DefKind::ExternCrate
1175+
| DefKind::Macro(..)
1176+
| DefKind::Use
1177+
| DefKind::GlobalAsm
1178+
| DefKind::Mod => return res,
11591179
_ => {}
11601180
}
11611181
let node = tcx.hir_node_by_def_id(def_id);

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 25 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ use rustc_middle::mir::interpret::ErrorHandled;
2222
use rustc_middle::traits::solve::NoSolution;
2323
use rustc_middle::ty::trait_def::TraitSpecializationKind;
2424
use rustc_middle::ty::{
25-
self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags,
26-
TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
27-
Unnormalized, Upcast,
25+
self, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags, TypeFoldable,
26+
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized,
27+
Upcast,
2828
};
2929
use rustc_middle::{bug, span_bug};
3030
use rustc_session::errors::feature_err;
@@ -324,12 +324,8 @@ pub(super) fn check_item<'tcx>(
324324
res
325325
}
326326
hir::ItemKind::Fn { sig, .. } => check_item_fn(tcx, def_id, sig.decl),
327-
hir::ItemKind::Struct(..) => check_type_defn(tcx, item, false),
328-
hir::ItemKind::Union(..) => check_type_defn(tcx, item, true),
329-
hir::ItemKind::Enum(..) => check_type_defn(tcx, item, true),
330-
hir::ItemKind::Trait { .. } => check_trait(tcx, item),
331-
hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
332-
_ => Ok(()),
327+
// Note: do not add new entries to this match. Instead add all new logic in `check_item_type`
328+
_ => span_bug!(item.span, "should have been handled by the type based wf check: {item:?}"),
333329
}
334330
}
335331

@@ -381,7 +377,7 @@ pub(crate) fn check_trait_item<'tcx>(
381377
/// fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
382378
/// }
383379
/// ```
384-
fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
380+
pub(crate) fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
385381
// Associates every GAT's def_id to a list of possibly missing bounds detected by this lint.
386382
let mut required_bounds_by_item = FxIndexMap::default();
387383
let associated_items = tcx.associated_items(trait_def_id);
@@ -1036,15 +1032,15 @@ pub(crate) fn check_associated_item(
10361032
}
10371033

10381034
/// In a type definition, we check that to ensure that the types of the fields are well-formed.
1039-
fn check_type_defn<'tcx>(
1035+
pub(crate) fn check_type_defn<'tcx>(
10401036
tcx: TyCtxt<'tcx>,
1041-
item: &hir::Item<'tcx>,
1037+
item: LocalDefId,
10421038
all_sized: bool,
10431039
) -> Result<(), ErrorGuaranteed> {
1044-
tcx.ensure_ok().check_representability(item.owner_id.def_id);
1045-
let adt_def = tcx.adt_def(item.owner_id);
1040+
tcx.ensure_ok().check_representability(item);
1041+
let adt_def = tcx.adt_def(item);
10461042

1047-
enter_wf_checking_ctxt(tcx, item.owner_id.def_id, |wfcx| {
1043+
enter_wf_checking_ctxt(tcx, item, |wfcx| {
10481044
let variants = adt_def.variants();
10491045
let packed = adt_def.repr().packed();
10501046

@@ -1057,6 +1053,7 @@ fn check_type_defn<'tcx>(
10571053
// FIXME(generic_const_exprs, default_field_values): this is a hack and needs to
10581054
// be refactored to check the instantiate-ability of the code better.
10591055
if let Some(def_id) = def_id.as_local()
1056+
&& let DefKind::AnonConst = tcx.def_kind(def_id)
10601057
&& let hir::Node::AnonConst(anon) = tcx.hir_node_by_def_id(def_id)
10611058
&& let expr = &tcx.hir_body(anon.body).value
10621059
&& let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
@@ -1071,26 +1068,21 @@ fn check_type_defn<'tcx>(
10711068
}
10721069
}
10731070
let field_id = field.did.expect_local();
1074-
let hir::FieldDef { ty: hir_ty, .. } =
1075-
tcx.hir_node_by_def_id(field_id).expect_field();
1071+
let span = tcx.ty_span(field_id);
10761072
let ty = wfcx.deeply_normalize(
1077-
hir_ty.span,
1073+
span,
10781074
None,
10791075
tcx.type_of(field.did).instantiate_identity(),
10801076
);
1081-
wfcx.register_wf_obligation(
1082-
hir_ty.span,
1083-
Some(WellFormedLoc::Ty(field_id)),
1084-
ty.into(),
1085-
);
1077+
wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(field_id)), ty.into());
10861078

10871079
if matches!(ty.kind(), ty::Adt(def, _) if def.repr().scalable())
10881080
&& !matches!(adt_def.repr().scalable, Some(ScalableElt::Container))
10891081
{
10901082
// Scalable vectors can only be fields of structs if the type has a
10911083
// `rustc_scalable_vector` attribute w/out specifying an element count
10921084
tcx.dcx().span_err(
1093-
hir_ty.span,
1085+
span,
10941086
format!(
10951087
"scalable vectors cannot be fields of a {}",
10961088
adt_def.variant_descr()
@@ -1116,35 +1108,21 @@ fn check_type_defn<'tcx>(
11161108
variant.fields.raw[..variant.fields.len() - unsized_len].iter().enumerate()
11171109
{
11181110
let last = idx == variant.fields.len() - 1;
1119-
let field_id = field.did.expect_local();
1120-
let hir::FieldDef { ty: hir_ty, .. } =
1121-
tcx.hir_node_by_def_id(field_id).expect_field();
1122-
let ty = wfcx.normalize(
1123-
hir_ty.span,
1124-
None,
1125-
tcx.type_of(field.did).instantiate_identity(),
1126-
);
1111+
let span = tcx.ty_span(field.did.expect_local());
1112+
let ty = wfcx.normalize(span, None, tcx.type_of(field.did).instantiate_identity());
11271113
wfcx.register_bound(
11281114
traits::ObligationCause::new(
1129-
hir_ty.span,
1115+
span,
11301116
wfcx.body_def_id,
11311117
ObligationCauseCode::FieldSized {
1132-
adt_kind: match &item.kind {
1133-
ItemKind::Struct(..) => AdtKind::Struct,
1134-
ItemKind::Union(..) => AdtKind::Union,
1135-
ItemKind::Enum(..) => AdtKind::Enum,
1136-
kind => span_bug!(
1137-
item.span,
1138-
"should be wfchecking an ADT, got {kind:?}"
1139-
),
1140-
},
1141-
span: hir_ty.span,
1118+
adt_kind: adt_def.adt_kind(),
1119+
span,
11421120
last,
11431121
},
11441122
),
11451123
wfcx.param_env,
11461124
ty,
1147-
tcx.require_lang_item(LangItem::Sized, hir_ty.span),
1125+
tcx.require_lang_item(LangItem::Sized, span),
11481126
);
11491127
}
11501128

@@ -1160,16 +1138,13 @@ fn check_type_defn<'tcx>(
11601138
}
11611139
}
11621140

1163-
check_where_clauses(wfcx, item.owner_id.def_id);
1141+
check_where_clauses(wfcx, item);
11641142
Ok(())
11651143
})
11661144
}
11671145

1168-
#[instrument(skip(tcx, item))]
1169-
fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuaranteed> {
1170-
debug!(?item.owner_id);
1171-
1172-
let def_id = item.owner_id.def_id;
1146+
#[instrument(skip(tcx))]
1147+
pub(crate) fn check_trait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
11731148
if tcx.is_lang_item(def_id.into(), LangItem::PointeeSized) {
11741149
// `PointeeSized` is removed during lowering.
11751150
return Ok(());
@@ -1195,10 +1170,6 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuarant
11951170
Ok(())
11961171
});
11971172

1198-
// Only check traits, don't check trait aliases
1199-
if let hir::ItemKind::Trait { .. } = item.kind {
1200-
check_gat_where_clauses(tcx, item.owner_id.def_id);
1201-
}
12021173
res
12031174
}
12041175

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,13 +630,13 @@ fn get_new_lifetime_name<'tcx>(
630630
(1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap()
631631
}
632632

633-
pub(super) fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
633+
pub(super) fn check_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
634634
tcx.ensure_ok().generics_of(def_id);
635635
tcx.ensure_ok().type_of(def_id);
636636
tcx.ensure_ok().predicates_of(def_id);
637637
}
638638

639-
pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) {
639+
pub(super) fn check_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) {
640640
struct ReprCIssue {
641641
msg: &'static str,
642642
}
@@ -718,7 +718,7 @@ pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) {
718718

719719
// Lower the ctor, if any. This also registers the variant as an item.
720720
if let Some(ctor_def_id) = variant.ctor_def_id() {
721-
lower_variant_ctor(tcx, ctor_def_id.expect_local());
721+
check_ctor(tcx, ctor_def_id.expect_local());
722722
}
723723
}
724724
}

0 commit comments

Comments
 (0)