@@ -10,7 +10,7 @@ use rustc_errors::{EmissionGuarantee, MultiSpan};
1010use rustc_hir:: def:: { CtorKind , DefKind } ;
1111use rustc_hir:: { LangItem , Node , intravisit} ;
1212use rustc_infer:: infer:: { RegionVariableOrigin , TyCtxtInferExt } ;
13- use rustc_infer:: traits:: { Obligation , ObligationCauseCode } ;
13+ use rustc_infer:: traits:: { Obligation , ObligationCauseCode , WellFormedLoc } ;
1414use 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
3737use super :: compare_impl_item:: check_type_bounds;
3838use 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
4044fn 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
9051077pub ( super ) fn check_on_unimplemented ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) {
0 commit comments