@@ -18,7 +18,7 @@ use rustc_middle::ty::{
18
18
TypeSuperFoldable , TypeVisitableExt , TypingMode , Upcast ,
19
19
} ;
20
20
use rustc_middle:: { bug, span_bug} ;
21
- use rustc_span:: Span ;
21
+ use rustc_span:: { Span , sym } ;
22
22
use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
23
23
use rustc_trait_selection:: infer:: InferCtxtExt ;
24
24
use rustc_trait_selection:: regions:: InferCtxtRegionExt ;
@@ -46,7 +46,9 @@ pub(super) fn compare_impl_item(
46
46
match impl_item. kind {
47
47
ty:: AssocKind :: Fn => compare_impl_method ( tcx, impl_item, trait_item, impl_trait_ref) ,
48
48
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
+ }
50
52
}
51
53
}
52
54
@@ -1769,14 +1771,59 @@ fn compare_generic_param_kinds<'tcx>(
1769
1771
1770
1772
fn compare_impl_const < ' tcx > (
1771
1773
tcx : TyCtxt < ' tcx > ,
1774
+ impl_item_def_id : LocalDefId ,
1772
1775
impl_const_item : ty:: AssocItem ,
1773
1776
trait_const_item : ty:: AssocItem ,
1774
1777
impl_trait_ref : ty:: TraitRef < ' tcx > ,
1775
1778
) -> Result < ( ) , ErrorGuaranteed > {
1776
1779
compare_number_of_generics ( tcx, impl_const_item, trait_const_item, false ) ?;
1777
1780
compare_generic_param_kinds ( tcx, impl_const_item, trait_const_item, false ) ?;
1778
1781
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 ( ) )
1780
1827
}
1781
1828
1782
1829
/// The equivalent of [compare_method_predicate_entailment], but for associated constants
0 commit comments