@@ -18,7 +18,7 @@ use rustc_middle::ty::{
1818 TypeSuperFoldable , TypeVisitableExt , TypingMode , Upcast ,
1919} ;
2020use rustc_middle:: { bug, span_bug} ;
21- use rustc_span:: Span ;
21+ use rustc_span:: { Span , sym } ;
2222use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
2323use rustc_trait_selection:: infer:: InferCtxtExt ;
2424use rustc_trait_selection:: regions:: InferCtxtRegionExt ;
@@ -46,7 +46,9 @@ pub(super) fn compare_impl_item(
4646 match impl_item. kind {
4747 ty:: AssocKind :: Fn => compare_impl_method ( tcx, impl_item, trait_item, impl_trait_ref) ,
4848 ty:: AssocKind :: Type => compare_impl_ty ( tcx, impl_item, trait_item, impl_trait_ref) ,
49- ty:: AssocKind :: Const => compare_impl_const ( tcx, impl_item, trait_item, impl_trait_ref) ,
49+ ty:: AssocKind :: Const => {
50+ compare_impl_const ( tcx, impl_item_def_id, impl_item, trait_item, impl_trait_ref)
51+ }
5052 }
5153}
5254
@@ -1769,14 +1771,59 @@ fn compare_generic_param_kinds<'tcx>(
17691771
17701772fn compare_impl_const < ' tcx > (
17711773 tcx : TyCtxt < ' tcx > ,
1774+ impl_item_def_id : LocalDefId ,
17721775 impl_const_item : ty:: AssocItem ,
17731776 trait_const_item : ty:: AssocItem ,
17741777 impl_trait_ref : ty:: TraitRef < ' tcx > ,
17751778) -> Result < ( ) , ErrorGuaranteed > {
17761779 compare_number_of_generics ( tcx, impl_const_item, trait_const_item, false ) ?;
17771780 compare_generic_param_kinds ( tcx, impl_const_item, trait_const_item, false ) ?;
17781781 check_region_bounds_on_impl_item ( tcx, impl_const_item, trait_const_item, false ) ?;
1779- compare_const_predicate_entailment ( tcx, impl_const_item, trait_const_item, impl_trait_ref)
1782+ compare_const_predicate_entailment ( tcx, impl_const_item, trait_const_item, impl_trait_ref) ?;
1783+ check_type_const_satisfied ( tcx, impl_item_def_id, trait_const_item)
1784+ }
1785+
1786+ fn check_type_const_satisfied < ' tcx > (
1787+ tcx : TyCtxt < ' tcx > ,
1788+ impl_item_def_id : LocalDefId ,
1789+ trait_ct : ty:: AssocItem ,
1790+ ) -> Result < ( ) , ErrorGuaranteed > {
1791+ // Only need to check if mgca is enabled.
1792+ // Only need to check it if the trait const was actually marked with the attr.
1793+ if !tcx. features ( ) . min_generic_const_args ( ) || !tcx. has_attr ( trait_ct. def_id , sym:: type_const) {
1794+ return Ok ( ( ) ) ;
1795+ }
1796+
1797+ let ( _, ct_body, ct_arg) =
1798+ tcx. hir_node_by_def_id ( impl_item_def_id) . expect_impl_item ( ) . expect_const ( ) ;
1799+ if let Some ( ct_arg) = ct_arg {
1800+ match ct_arg {
1801+ hir:: ConstArg { kind : hir:: ConstArgKind :: Path ( ..) , .. } => return Ok ( ( ) ) ,
1802+ _ => unreachable ! ( "only const paths are created here currently" ) ,
1803+ }
1804+ }
1805+
1806+ let body = tcx. hir_body ( ct_body) ;
1807+ let hir:: ExprKind :: ConstBlock ( ct_block) = body. value . kind else {
1808+ unreachable ! ( "always lowered to const block" )
1809+ } ;
1810+ let generics = tcx. generics_of ( ct_block. def_id ) ;
1811+ // FIXME(mgca): we exclude own params since they include synthetic params created for the const's type
1812+ // but are there cases where own params could exist that would be a problem?
1813+ if generics. parent_count == 0 {
1814+ return Ok ( ( ) ) ;
1815+ }
1816+
1817+ let mut diag = tcx. dcx ( ) . struct_span_err (
1818+ tcx. def_span ( ct_block. def_id ) ,
1819+ "assoc const body is not safe for type system usage" ,
1820+ ) ;
1821+ diag. note ( format ! ( "the body uses generic parameters in nontrivial computations" ) ) ;
1822+ diag. span_note (
1823+ tcx. def_span ( trait_ct. def_id ) ,
1824+ "the `#[type_const]` declaration in the trait required this" ,
1825+ ) ;
1826+ Err ( diag. emit ( ) )
17801827}
17811828
17821829/// The equivalent of [compare_method_predicate_entailment], but for associated constants
0 commit comments