@@ -6,10 +6,11 @@ use rustc_abi::ExternAbi;
66use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
77use rustc_errors:: codes:: * ;
88use rustc_errors:: { Applicability , ErrorGuaranteed , pluralize, struct_span_code_err} ;
9+ use rustc_hir:: attrs:: AttributeKind ;
910use rustc_hir:: def:: { DefKind , Res } ;
1011use rustc_hir:: def_id:: { DefId , LocalDefId } ;
1112use rustc_hir:: lang_items:: LangItem ;
12- use rustc_hir:: { AmbigArg , ItemKind } ;
13+ use rustc_hir:: { AmbigArg , ItemKind , find_attr } ;
1314use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
1415use rustc_infer:: infer:: { self , InferCtxt , SubregionOrigin , TyCtxtInferExt } ;
1516use rustc_lint_defs:: builtin:: SUPERTRAIT_ITEM_SHADOWING_DEFINITION ;
@@ -925,11 +926,11 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
925926#[ instrument( level = "debug" , skip( tcx) ) ]
926927pub ( crate ) fn check_associated_item (
927928 tcx : TyCtxt < ' _ > ,
928- item_id : LocalDefId ,
929+ def_id : LocalDefId ,
929930) -> Result < ( ) , ErrorGuaranteed > {
930- let loc = Some ( WellFormedLoc :: Ty ( item_id ) ) ;
931- enter_wf_checking_ctxt ( tcx, item_id , |wfcx| {
932- let item = tcx. associated_item ( item_id ) ;
931+ let loc = Some ( WellFormedLoc :: Ty ( def_id ) ) ;
932+ enter_wf_checking_ctxt ( tcx, def_id , |wfcx| {
933+ let item = tcx. associated_item ( def_id ) ;
933934
934935 // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
935936 // other `Foo` impls are incoherent.
@@ -942,36 +943,45 @@ pub(crate) fn check_associated_item(
942943 }
943944 } ;
944945
945- let span = tcx. def_span ( item_id ) ;
946+ let span = tcx. def_span ( def_id ) ;
946947
947948 match item. kind {
948949 ty:: AssocKind :: Const { .. } => {
949- let ty = tcx. type_of ( item . def_id ) . instantiate_identity ( ) ;
950- let ty = wfcx. deeply_normalize ( span, Some ( WellFormedLoc :: Ty ( item_id ) ) , ty) ;
950+ let ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
951+ let ty = wfcx. deeply_normalize ( span, Some ( WellFormedLoc :: Ty ( def_id ) ) , ty) ;
951952 wfcx. register_wf_obligation ( span, loc, ty. into ( ) ) ;
952- check_sized_if_body (
953- wfcx,
954- item. def_id . expect_local ( ) ,
955- ty,
956- Some ( span) ,
957- ObligationCauseCode :: SizedConstOrStatic ,
958- ) ;
953+
954+ let has_value = item. defaultness ( tcx) . has_value ( ) ;
955+ if find_attr ! ( tcx. get_all_attrs( def_id) , AttributeKind :: TypeConst ( _) ) {
956+ check_type_const ( wfcx, def_id, ty, has_value) ?;
957+ }
958+
959+ if has_value {
960+ let code = ObligationCauseCode :: SizedConstOrStatic ;
961+ wfcx. register_bound (
962+ ObligationCause :: new ( span, def_id, code) ,
963+ wfcx. param_env ,
964+ ty,
965+ tcx. require_lang_item ( LangItem :: Sized , span) ,
966+ ) ;
967+ }
968+
959969 Ok ( ( ) )
960970 }
961971 ty:: AssocKind :: Fn { .. } => {
962- let sig = tcx. fn_sig ( item . def_id ) . instantiate_identity ( ) ;
972+ let sig = tcx. fn_sig ( def_id) . instantiate_identity ( ) ;
963973 let hir_sig =
964- tcx. hir_node_by_def_id ( item_id ) . fn_sig ( ) . expect ( "bad signature for method" ) ;
965- check_fn_or_method ( wfcx, sig, hir_sig. decl , item_id ) ;
974+ tcx. hir_node_by_def_id ( def_id ) . fn_sig ( ) . expect ( "bad signature for method" ) ;
975+ check_fn_or_method ( wfcx, sig, hir_sig. decl , def_id ) ;
966976 check_method_receiver ( wfcx, hir_sig, item, self_ty)
967977 }
968978 ty:: AssocKind :: Type { .. } => {
969979 if let ty:: AssocContainer :: Trait = item. container {
970980 check_associated_type_bounds ( wfcx, item, span)
971981 }
972982 if item. defaultness ( tcx) . has_value ( ) {
973- let ty = tcx. type_of ( item . def_id ) . instantiate_identity ( ) ;
974- let ty = wfcx. deeply_normalize ( span, Some ( WellFormedLoc :: Ty ( item_id ) ) , ty) ;
983+ let ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
984+ let ty = wfcx. deeply_normalize ( span, Some ( WellFormedLoc :: Ty ( def_id ) ) , ty) ;
975985 wfcx. register_wf_obligation ( span, loc, ty. into ( ) ) ;
976986 }
977987 Ok ( ( ) )
@@ -1222,28 +1232,36 @@ pub(crate) fn check_static_item<'tcx>(
12221232 } )
12231233}
12241234
1225- pub ( crate ) fn check_const_item ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> Result < ( ) , ErrorGuaranteed > {
1226- enter_wf_checking_ctxt ( tcx, def_id, |wfcx| {
1227- let ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
1228- let ty_span = tcx. ty_span ( def_id) ;
1229- let ty = wfcx. deeply_normalize ( ty_span, Some ( WellFormedLoc :: Ty ( def_id) ) , ty) ;
1235+ #[ instrument( level = "debug" , skip( wfcx) ) ]
1236+ pub ( super ) fn check_type_const < ' tcx > (
1237+ wfcx : & WfCheckingCtxt < ' _ , ' tcx > ,
1238+ def_id : LocalDefId ,
1239+ item_ty : Ty < ' tcx > ,
1240+ has_value : bool ,
1241+ ) -> Result < ( ) , ErrorGuaranteed > {
1242+ let tcx = wfcx. tcx ( ) ;
1243+ let span = tcx. def_span ( def_id) ;
12301244
1231- wfcx. register_wf_obligation ( ty_span, Some ( WellFormedLoc :: Ty ( def_id) ) , ty. into ( ) ) ;
1232- wfcx. register_bound (
1233- traits:: ObligationCause :: new (
1234- ty_span,
1235- wfcx. body_def_id ,
1236- ObligationCauseCode :: SizedConstOrStatic ,
1237- ) ,
1238- wfcx. param_env ,
1239- ty,
1240- tcx. require_lang_item ( LangItem :: Sized , ty_span) ,
1241- ) ;
1245+ wfcx. register_bound (
1246+ ObligationCause :: new ( span, def_id, ObligationCauseCode :: ConstParam ( item_ty) ) ,
1247+ wfcx. param_env ,
1248+ item_ty,
1249+ tcx. require_lang_item ( LangItem :: ConstParamTy , span) ,
1250+ ) ;
12421251
1243- check_where_clauses ( wfcx, def_id) ;
1252+ if has_value {
1253+ let raw_ct = tcx. const_of_item ( def_id) . instantiate_identity ( ) ;
1254+ let norm_ct = wfcx. deeply_normalize ( span, Some ( WellFormedLoc :: Ty ( def_id) ) , raw_ct) ;
1255+ wfcx. register_wf_obligation ( span, Some ( WellFormedLoc :: Ty ( def_id) ) , norm_ct. into ( ) ) ;
12441256
1245- Ok ( ( ) )
1246- } )
1257+ wfcx. register_obligation ( Obligation :: new (
1258+ tcx,
1259+ ObligationCause :: new ( span, def_id, ObligationCauseCode :: WellFormed ( None ) ) ,
1260+ wfcx. param_env ,
1261+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: ConstArgHasType ( norm_ct, item_ty) ) ,
1262+ ) ) ;
1263+ }
1264+ Ok ( ( ) )
12471265}
12481266
12491267#[ instrument( level = "debug" , skip( tcx, impl_) ) ]
@@ -1583,33 +1601,16 @@ fn check_fn_or_method<'tcx>(
15831601 }
15841602
15851603 // If the function has a body, additionally require that the return type is sized.
1586- check_sized_if_body (
1587- wfcx,
1588- def_id,
1589- sig. output ( ) ,
1590- match hir_decl. output {
1591- hir:: FnRetTy :: Return ( ty) => Some ( ty. span ) ,
1592- hir:: FnRetTy :: DefaultReturn ( _) => None ,
1593- } ,
1594- ObligationCauseCode :: SizedReturnType ,
1595- ) ;
1596- }
1597-
1598- fn check_sized_if_body < ' tcx > (
1599- wfcx : & WfCheckingCtxt < ' _ , ' tcx > ,
1600- def_id : LocalDefId ,
1601- ty : Ty < ' tcx > ,
1602- maybe_span : Option < Span > ,
1603- code : ObligationCauseCode < ' tcx > ,
1604- ) {
1605- let tcx = wfcx. tcx ( ) ;
16061604 if let Some ( body) = tcx. hir_maybe_body_owned_by ( def_id) {
1607- let span = maybe_span. unwrap_or ( body. value . span ) ;
1605+ let span = match hir_decl. output {
1606+ hir:: FnRetTy :: Return ( ty) => ty. span ,
1607+ hir:: FnRetTy :: DefaultReturn ( _) => body. value . span ,
1608+ } ;
16081609
16091610 wfcx. register_bound (
1610- ObligationCause :: new ( span, def_id, code ) ,
1611+ ObligationCause :: new ( span, def_id, ObligationCauseCode :: SizedReturnType ) ,
16111612 wfcx. param_env ,
1612- ty ,
1613+ sig . output ( ) ,
16131614 tcx. require_lang_item ( LangItem :: Sized , span) ,
16141615 ) ;
16151616 }
0 commit comments