Skip to content

Commit 6429d91

Browse files
authored
Merge 4e97337 into 076a0a2
2 parents 076a0a2 + 4e97337 commit 6429d91

File tree

124 files changed

+1149
-1012
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+1149
-1012
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4834,6 +4834,10 @@ impl<'hir> Node<'hir> {
48344834
ImplItemKind::Type(ty) => Some(ty),
48354835
_ => None,
48364836
},
4837+
Node::ForeignItem(it) => match it.kind {
4838+
ForeignItemKind::Static(ty, ..) => Some(ty),
4839+
_ => None,
4840+
},
48374841
_ => None,
48384842
}
48394843
}

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 193 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_errors::{EmissionGuarantee, MultiSpan};
1010
use rustc_hir::def::{CtorKind, DefKind};
1111
use rustc_hir::{LangItem, Node, intravisit};
1212
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
13-
use rustc_infer::traits::{Obligation, ObligationCauseCode};
13+
use rustc_infer::traits::{Obligation, ObligationCauseCode, WellFormedLoc};
1414
use rustc_lint_defs::builtin::{
1515
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS,
1616
};
@@ -36,6 +36,10 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir};
3636

3737
use super::compare_impl_item::check_type_bounds;
3838
use super::*;
39+
use crate::check::wfcheck::{
40+
check_associated_item, check_trait_item, check_variances_for_type_defn, check_where_clauses,
41+
enter_wf_checking_ctxt,
42+
};
3943

4044
fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) {
4145
if let ExternAbi::Cdecl { unwind } = abi {
@@ -729,7 +733,8 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
729733
}
730734
}
731735

732-
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
736+
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
737+
let mut res = Ok(());
733738
let generics = tcx.generics_of(def_id);
734739

735740
for param in &generics.own_params {
@@ -754,15 +759,39 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
754759
}
755760

756761
match tcx.def_kind(def_id) {
757-
DefKind::Static { .. } => {
758-
check_static_inhabited(tcx, def_id);
759-
check_static_linkage(tcx, def_id);
762+
def_kind @ (DefKind::Static { .. } | DefKind::Const) => {
763+
tcx.ensure_ok().generics_of(def_id);
764+
tcx.ensure_ok().type_of(def_id);
765+
tcx.ensure_ok().predicates_of(def_id);
766+
match def_kind {
767+
DefKind::Static { .. } => {
768+
check_static_inhabited(tcx, def_id);
769+
check_static_linkage(tcx, def_id);
770+
res = res.and(wfcheck::check_static_item(tcx, def_id));
771+
772+
// Only `Node::Item` and `Node::ForeignItem` still have HIR based
773+
// checks. Returning early here does not miss any checks and
774+
// avoids this query from having a direct dependency edge on the HIR
775+
return res;
776+
}
777+
DefKind::Const => {}
778+
_ => unreachable!(),
779+
}
760780
}
761-
DefKind::Const => {}
762781
DefKind::Enum => {
782+
tcx.ensure_ok().generics_of(def_id);
783+
tcx.ensure_ok().type_of(def_id);
784+
tcx.ensure_ok().predicates_of(def_id);
785+
crate::collect::lower_enum_variant_types(tcx, def_id.to_def_id());
763786
check_enum(tcx, def_id);
787+
check_variances_for_type_defn(tcx, def_id);
764788
}
765789
DefKind::Fn => {
790+
tcx.ensure_ok().generics_of(def_id);
791+
tcx.ensure_ok().type_of(def_id);
792+
tcx.ensure_ok().predicates_of(def_id);
793+
tcx.ensure_ok().fn_sig(def_id);
794+
tcx.ensure_ok().codegen_fn_attrs(def_id);
766795
if let Some(i) = tcx.intrinsic(def_id) {
767796
intrinsic::check_intrinsic_type(
768797
tcx,
@@ -773,17 +802,31 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
773802
}
774803
}
775804
DefKind::Impl { of_trait } => {
805+
tcx.ensure_ok().generics_of(def_id);
806+
tcx.ensure_ok().type_of(def_id);
807+
tcx.ensure_ok().impl_trait_header(def_id);
808+
tcx.ensure_ok().predicates_of(def_id);
809+
tcx.ensure_ok().associated_items(def_id);
776810
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
777-
if tcx
778-
.ensure_ok()
779-
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)
780-
.is_ok()
781-
{
811+
res = res.and(
812+
tcx.ensure_ok()
813+
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id),
814+
);
815+
816+
if res.is_ok() {
817+
// Checking this only makes sense if the all trait impls satisfy basic
818+
// requirements (see `coherent_trait` query), otherwise
819+
// we run into infinite recursions a lot.
782820
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
783821
}
784822
}
785823
}
786824
DefKind::Trait => {
825+
tcx.ensure_ok().generics_of(def_id);
826+
tcx.ensure_ok().trait_def(def_id);
827+
tcx.ensure_ok().explicit_super_predicates_of(def_id);
828+
tcx.ensure_ok().predicates_of(def_id);
829+
tcx.ensure_ok().associated_items(def_id);
787830
let assoc_items = tcx.associated_items(def_id);
788831
check_on_unimplemented(tcx, def_id);
789832

@@ -802,11 +845,33 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
802845
}
803846
}
804847
}
805-
DefKind::Struct => {
806-
check_struct(tcx, def_id);
848+
DefKind::TraitAlias => {
849+
tcx.ensure_ok().generics_of(def_id);
850+
tcx.ensure_ok().explicit_implied_predicates_of(def_id);
851+
tcx.ensure_ok().explicit_super_predicates_of(def_id);
852+
tcx.ensure_ok().predicates_of(def_id);
807853
}
808-
DefKind::Union => {
809-
check_union(tcx, def_id);
854+
def_kind @ (DefKind::Struct | DefKind::Union) => {
855+
tcx.ensure_ok().generics_of(def_id);
856+
tcx.ensure_ok().type_of(def_id);
857+
tcx.ensure_ok().predicates_of(def_id);
858+
859+
let adt = tcx.adt_def(def_id).non_enum_variant();
860+
for f in adt.fields.iter() {
861+
tcx.ensure_ok().generics_of(f.did);
862+
tcx.ensure_ok().type_of(f.did);
863+
tcx.ensure_ok().predicates_of(f.did);
864+
}
865+
866+
if let Some((_, ctor_def_id)) = adt.ctor {
867+
crate::collect::lower_variant_ctor(tcx, ctor_def_id.expect_local());
868+
}
869+
match def_kind {
870+
DefKind::Struct => check_struct(tcx, def_id),
871+
DefKind::Union => check_union(tcx, def_id),
872+
_ => unreachable!(),
873+
}
874+
check_variances_for_type_defn(tcx, def_id);
810875
}
811876
DefKind::OpaqueTy => {
812877
check_opaque_precise_captures(tcx, def_id);
@@ -831,14 +896,37 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
831896
tcx.ensure_ok().explicit_implied_const_bounds(def_id);
832897
tcx.ensure_ok().const_conditions(def_id);
833898
}
899+
900+
// Only `Node::Item` and `Node::ForeignItem` still have HIR based
901+
// checks. Returning early here does not miss any checks and
902+
// avoids this query from having a direct dependency edge on the HIR
903+
return res;
834904
}
835905
DefKind::TyAlias => {
906+
tcx.ensure_ok().generics_of(def_id);
907+
tcx.ensure_ok().type_of(def_id);
908+
tcx.ensure_ok().predicates_of(def_id);
836909
check_type_alias_type_params_are_used(tcx, def_id);
910+
if tcx.type_alias_is_lazy(def_id) {
911+
res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
912+
let ty = tcx.type_of(def_id).instantiate_identity();
913+
let span = tcx.def_span(def_id);
914+
let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty);
915+
wfcx.register_wf_obligation(
916+
span,
917+
Some(WellFormedLoc::Ty(def_id)),
918+
item_ty.into(),
919+
);
920+
check_where_clauses(wfcx, def_id);
921+
Ok(())
922+
}));
923+
check_variances_for_type_defn(tcx, def_id);
924+
}
837925
}
838926
DefKind::ForeignMod => {
839927
let it = tcx.hir_expect_item(def_id);
840928
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
841-
return;
929+
return Ok(());
842930
};
843931

844932
check_abi(tcx, it.hir_id(), it.span, abi);
@@ -877,15 +965,23 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
877965
}
878966

879967
let item = tcx.hir_foreign_item(item.id);
880-
match &item.kind {
881-
hir::ForeignItemKind::Fn(sig, _, _) => {
968+
tcx.ensure_ok().generics_of(item.owner_id);
969+
tcx.ensure_ok().type_of(item.owner_id);
970+
tcx.ensure_ok().predicates_of(item.owner_id);
971+
if tcx.is_conditionally_const(def_id) {
972+
tcx.ensure_ok().explicit_implied_const_bounds(def_id);
973+
tcx.ensure_ok().const_conditions(def_id);
974+
}
975+
match item.kind {
976+
hir::ForeignItemKind::Fn(sig, ..) => {
977+
tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
978+
tcx.ensure_ok().fn_sig(item.owner_id);
882979
require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
883980
}
884981
hir::ForeignItemKind::Static(..) => {
885-
check_static_inhabited(tcx, def_id);
886-
check_static_linkage(tcx, def_id);
982+
tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
887983
}
888-
_ => {}
984+
_ => (),
889985
}
890986
}
891987
}
@@ -897,9 +993,85 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
897993
// We do not call `type_of` for closures here as that
898994
// depends on typecheck and would therefore hide
899995
// any further errors in case one typeck fails.
996+
997+
// Only `Node::Item` and `Node::ForeignItem` still have HIR based
998+
// checks. Returning early here does not miss any checks and
999+
// avoids this query from having a direct dependency edge on the HIR
1000+
return res;
1001+
}
1002+
DefKind::AssocFn => {
1003+
tcx.ensure_ok().codegen_fn_attrs(def_id);
1004+
tcx.ensure_ok().type_of(def_id);
1005+
tcx.ensure_ok().fn_sig(def_id);
1006+
tcx.ensure_ok().predicates_of(def_id);
1007+
res = res.and(check_associated_item(tcx, def_id));
1008+
let assoc_item = tcx.associated_item(def_id);
1009+
match assoc_item.container {
1010+
ty::AssocItemContainer::Impl => {}
1011+
ty::AssocItemContainer::Trait => {
1012+
res = res.and(check_trait_item(tcx, def_id));
1013+
}
1014+
}
1015+
1016+
// Only `Node::Item` and `Node::ForeignItem` still have HIR based
1017+
// checks. Returning early here does not miss any checks and
1018+
// avoids this query from having a direct dependency edge on the HIR
1019+
return res;
1020+
}
1021+
DefKind::AssocConst => {
1022+
tcx.ensure_ok().type_of(def_id);
1023+
tcx.ensure_ok().predicates_of(def_id);
1024+
res = res.and(check_associated_item(tcx, def_id));
1025+
let assoc_item = tcx.associated_item(def_id);
1026+
match assoc_item.container {
1027+
ty::AssocItemContainer::Impl => {}
1028+
ty::AssocItemContainer::Trait => {
1029+
res = res.and(check_trait_item(tcx, def_id));
1030+
}
1031+
}
1032+
1033+
// Only `Node::Item` and `Node::ForeignItem` still have HIR based
1034+
// checks. Returning early here does not miss any checks and
1035+
// avoids this query from having a direct dependency edge on the HIR
1036+
return res;
9001037
}
1038+
DefKind::AssocTy => {
1039+
tcx.ensure_ok().predicates_of(def_id);
1040+
res = res.and(check_associated_item(tcx, def_id));
1041+
1042+
let assoc_item = tcx.associated_item(def_id);
1043+
let has_type = match assoc_item.container {
1044+
ty::AssocItemContainer::Impl => true,
1045+
ty::AssocItemContainer::Trait => {
1046+
tcx.ensure_ok().item_bounds(def_id);
1047+
tcx.ensure_ok().item_self_bounds(def_id);
1048+
res = res.and(check_trait_item(tcx, def_id));
1049+
assoc_item.defaultness(tcx).has_value()
1050+
}
1051+
};
1052+
if has_type {
1053+
tcx.ensure_ok().type_of(def_id);
1054+
}
1055+
1056+
// Only `Node::Item` and `Node::ForeignItem` still have HIR based
1057+
// checks. Returning early here does not miss any checks and
1058+
// avoids this query from having a direct dependency edge on the HIR
1059+
return res;
1060+
}
1061+
1062+
// Only `Node::Item` and `Node::ForeignItem` still have HIR based
1063+
// checks. Returning early here does not miss any checks and
1064+
// avoids this query from having a direct dependency edge on the HIR
1065+
DefKind::AnonConst | DefKind::InlineConst => return res,
9011066
_ => {}
9021067
}
1068+
let node = tcx.hir_node_by_def_id(def_id);
1069+
res.and(match node {
1070+
hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
1071+
hir::Node::Item(item) => wfcheck::check_item(tcx, item),
1072+
hir::Node::ForeignItem(item) => wfcheck::check_foreign_item(tcx, item),
1073+
_ => unreachable!("{node:?}"),
1074+
})
9031075
}
9041076

9051077
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, def_id: LocalDefId) {

0 commit comments

Comments
 (0)