1616
1717use std:: cell:: Cell ;
1818use std:: iter;
19- use std:: ops:: Bound ;
19+ use std:: ops:: { Bound , ControlFlow } ;
2020
2121use rustc_abi:: { ExternAbi , Size } ;
2222use rustc_ast:: Recovered ;
@@ -26,12 +26,13 @@ use rustc_errors::{
2626 Applicability , Diag , DiagCtxtHandle , E0228 , ErrorGuaranteed , StashKey , struct_span_code_err,
2727} ;
2828use rustc_hir:: attrs:: AttributeKind ;
29- use rustc_hir:: def:: DefKind ;
29+ use rustc_hir:: def:: { DefKind , Res } ;
3030use rustc_hir:: def_id:: { DefId , LocalDefId } ;
31- use rustc_hir:: intravisit:: { InferKind , Visitor , VisitorExt } ;
31+ use rustc_hir:: intravisit:: { self , InferKind , Visitor , VisitorExt } ;
3232use rustc_hir:: { self as hir, GenericParamKind , HirId , Node , PreciseCapturingArgKind , find_attr} ;
3333use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
3434use rustc_infer:: traits:: { DynCompatibilityViolation , ObligationCause } ;
35+ use rustc_middle:: hir:: nested_filter;
3536use rustc_middle:: query:: Providers ;
3637use rustc_middle:: ty:: util:: { Discr , IntTypeExt } ;
3738use rustc_middle:: ty:: {
@@ -1511,6 +1512,20 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
15111512 let parent_hir_node = tcx. hir_node ( tcx. parent_hir_id ( const_arg_id) ) ;
15121513 if tcx. features ( ) . generic_const_exprs ( ) {
15131514 ty:: AnonConstKind :: GCE
1515+ } else if tcx. features ( ) . opaque_generic_const_args ( ) {
1516+ // Only anon consts that are the RHS of a const item can be OGCA.
1517+ // Note: We can't just check tcx.parent because it needs to be EXACTLY
1518+ // the RHS, not just part of the RHS.
1519+ if !is_anon_const_rhs_of_const_item ( tcx, def) {
1520+ return ty:: AnonConstKind :: MCG ;
1521+ }
1522+
1523+ let body = tcx. hir_body_owned_by ( def) ;
1524+ let mut visitor = OGCAParamVisitor ( tcx) ;
1525+ match visitor. visit_body ( body) {
1526+ ControlFlow :: Break ( UsesParam ) => ty:: AnonConstKind :: OGCA ,
1527+ ControlFlow :: Continue ( ( ) ) => ty:: AnonConstKind :: MCG ,
1528+ }
15141529 } else if tcx. features ( ) . min_generic_const_args ( ) {
15151530 ty:: AnonConstKind :: MCG
15161531 } else if let hir:: Node :: Expr ( hir:: Expr {
@@ -1528,6 +1543,49 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
15281543 }
15291544}
15301545
1546+ fn is_anon_const_rhs_of_const_item < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId ) -> bool {
1547+ let hir_id = tcx. local_def_id_to_hir_id ( def_id) ;
1548+ let Some ( ( _, grandparent_node) ) = tcx. hir_parent_iter ( hir_id) . nth ( 1 ) else { return false } ;
1549+ let ( Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Const ( _, _, _, ct_rhs) , .. } )
1550+ | Node :: ImplItem ( hir:: ImplItem { kind : hir:: ImplItemKind :: Const ( _, ct_rhs) , .. } )
1551+ | Node :: TraitItem ( hir:: TraitItem {
1552+ kind : hir:: TraitItemKind :: Const ( _, Some ( ct_rhs) ) , ..
1553+ } ) ) = grandparent_node
1554+ else {
1555+ return false ;
1556+ } ;
1557+ let hir:: ConstItemRhs :: TypeConst ( hir:: ConstArg {
1558+ kind : hir:: ConstArgKind :: Anon ( rhs_anon) , ..
1559+ } ) = ct_rhs
1560+ else {
1561+ return false ;
1562+ } ;
1563+ def_id == rhs_anon. def_id
1564+ }
1565+
1566+ struct OGCAParamVisitor < ' tcx > ( TyCtxt < ' tcx > ) ;
1567+
1568+ struct UsesParam ;
1569+
1570+ impl < ' tcx > Visitor < ' tcx > for OGCAParamVisitor < ' tcx > {
1571+ type NestedFilter = nested_filter:: OnlyBodies ;
1572+ type Result = ControlFlow < UsesParam > ;
1573+
1574+ fn maybe_tcx ( & mut self ) -> TyCtxt < ' tcx > {
1575+ self . 0
1576+ }
1577+
1578+ fn visit_path ( & mut self , path : & hir:: Path < ' tcx > , _id : HirId ) -> ControlFlow < UsesParam > {
1579+ if let Res :: Def ( DefKind :: TyParam | DefKind :: ConstParam | DefKind :: LifetimeParam , _) =
1580+ path. res
1581+ {
1582+ return ControlFlow :: Break ( UsesParam ) ;
1583+ }
1584+
1585+ intravisit:: walk_path ( self , path)
1586+ }
1587+ }
1588+
15311589#[ instrument( level = "debug" , skip( tcx) , ret) ]
15321590fn const_of_item < ' tcx > (
15331591 tcx : TyCtxt < ' tcx > ,
0 commit comments