@@ -10,7 +10,7 @@ use rustc_errors::{EmissionGuarantee, MultiSpan};
10
10
use rustc_hir:: def:: { CtorKind , DefKind } ;
11
11
use rustc_hir:: { LangItem , Node , intravisit} ;
12
12
use rustc_infer:: infer:: { RegionVariableOrigin , TyCtxtInferExt } ;
13
- use rustc_infer:: traits:: { Obligation , ObligationCauseCode } ;
13
+ use rustc_infer:: traits:: { Obligation , ObligationCauseCode , WellFormedLoc } ;
14
14
use rustc_lint_defs:: builtin:: {
15
15
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS , UNSUPPORTED_CALLING_CONVENTIONS ,
16
16
} ;
@@ -36,6 +36,10 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir};
36
36
37
37
use super :: compare_impl_item:: check_type_bounds;
38
38
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
+ } ;
39
43
40
44
fn add_abi_diag_help < T : EmissionGuarantee > ( abi : ExternAbi , diag : & mut Diag < ' _ , T > ) {
41
45
if let ExternAbi :: Cdecl { unwind } = abi {
@@ -729,7 +733,8 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
729
733
}
730
734
}
731
735
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 ( ( ) ) ;
733
738
let generics = tcx. generics_of ( def_id) ;
734
739
735
740
for param in & generics. own_params {
@@ -754,15 +759,39 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
754
759
}
755
760
756
761
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
+ }
760
780
}
761
- DefKind :: Const => { }
762
781
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 ( ) ) ;
763
786
check_enum ( tcx, def_id) ;
787
+ check_variances_for_type_defn ( tcx, def_id) ;
764
788
}
765
789
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) ;
766
795
if let Some ( i) = tcx. intrinsic ( def_id) {
767
796
intrinsic:: check_intrinsic_type (
768
797
tcx,
@@ -773,17 +802,31 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
773
802
}
774
803
}
775
804
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) ;
776
810
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.
782
820
check_impl_items_against_trait ( tcx, def_id, impl_trait_header) ;
783
821
}
784
822
}
785
823
}
786
824
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) ;
787
830
let assoc_items = tcx. associated_items ( def_id) ;
788
831
check_on_unimplemented ( tcx, def_id) ;
789
832
@@ -802,11 +845,33 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
802
845
}
803
846
}
804
847
}
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) ;
807
853
}
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) ;
810
875
}
811
876
DefKind :: OpaqueTy => {
812
877
check_opaque_precise_captures ( tcx, def_id) ;
@@ -831,14 +896,37 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
831
896
tcx. ensure_ok ( ) . explicit_implied_const_bounds ( def_id) ;
832
897
tcx. ensure_ok ( ) . const_conditions ( def_id) ;
833
898
}
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;
834
904
}
835
905
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) ;
836
909
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
+ }
837
925
}
838
926
DefKind :: ForeignMod => {
839
927
let it = tcx. hir_expect_item ( def_id) ;
840
928
let hir:: ItemKind :: ForeignMod { abi, items } = it. kind else {
841
- return ;
929
+ return Ok ( ( ) ) ;
842
930
} ;
843
931
844
932
check_abi ( tcx, it. hir_id ( ) , it. span , abi) ;
@@ -877,15 +965,23 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
877
965
}
878
966
879
967
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 ) ;
882
979
require_c_abi_if_c_variadic ( tcx, sig. decl , abi, item. span ) ;
883
980
}
884
981
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 ) ;
887
983
}
888
- _ => { }
984
+ _ => ( ) ,
889
985
}
890
986
}
891
987
}
@@ -897,9 +993,85 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
897
993
// We do not call `type_of` for closures here as that
898
994
// depends on typecheck and would therefore hide
899
995
// 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;
900
1037
}
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,
901
1066
_ => { }
902
1067
}
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
+ } )
903
1075
}
904
1076
905
1077
pub ( super ) fn check_on_unimplemented ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) {
0 commit comments