@@ -2054,41 +2054,62 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20542054 }
20552055
20562056 match const_arg. kind {
2057- hir:: ConstArgKind :: Path ( qpath) => {
2058- // FIXME(min_generic_const_args): for now only params are lowered to ConstArgKind::Path
2059- self . lower_const_arg_param ( qpath, const_arg. hir_id )
2060- }
2057+ hir:: ConstArgKind :: Path ( qpath) => self . lower_const_arg_path ( qpath, const_arg. hir_id ) ,
20612058 hir:: ConstArgKind :: Anon ( anon) => Const :: from_anon_const ( tcx, anon. def_id ) ,
20622059 }
20632060 }
20642061
2065- /// Lower a use of a const param to a [`Const`].
2066- ///
2067- /// IMPORTANT: `qpath` must be a const param, otherwise this will panic
2068- fn lower_const_arg_param ( & self , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Const < ' tcx > {
2062+ /// Lower a const path to a [`Const`].
2063+ fn lower_const_arg_path ( & self , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Const < ' tcx > {
20692064 let tcx = self . tcx ( ) ;
20702065
2071- let hir:: QPath :: Resolved ( _, & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , def_id) , .. } ) =
2072- qpath
2073- else {
2074- span_bug ! ( qpath. span( ) , "non-param {qpath:?} passed to Const::from_param" )
2075- } ;
2066+ // TODO: handle path args properly
2067+ match qpath {
2068+ hir:: QPath :: Resolved ( _, & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , did) , .. } ) => {
2069+ self . lower_const_arg_param ( did, hir_id)
2070+ }
2071+ hir:: QPath :: Resolved (
2072+ _,
2073+ & hir:: Path { res : Res :: Def ( DefKind :: Fn | DefKind :: AssocFn , _) , .. } ,
2074+ ) => ty:: Const :: new_error_with_message (
2075+ tcx,
2076+ qpath. span ( ) ,
2077+ "fn's cannot be used as const args" ,
2078+ ) ,
2079+ hir:: QPath :: Resolved ( _, path @ & hir:: Path { res : Res :: Def ( _, did) , .. } ) => {
2080+ let ( item_segment, _) = path. segments . split_last ( ) . unwrap ( ) ;
2081+ let args = self . lower_generic_args_of_path_segment ( path. span , did, item_segment) ;
2082+ ty:: Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( did, args) )
2083+ }
2084+ // TODO: type-relative paths
2085+ _ => ty:: Const :: new_error_with_message (
2086+ tcx,
2087+ qpath. span ( ) ,
2088+ "Const::lower_const_arg_path: invalid qpath" ,
2089+ ) ,
2090+ }
2091+ }
20762092
2077- match tcx. named_bound_var ( hir_id) {
2093+ /// Lower a const param to a [`Const`]. This is only meant as a helper for [`Self::lower_const_arg_path`].
2094+ /// FIXME: dedup with lower_const_param
2095+ fn lower_const_arg_param ( & self , param_def_id : DefId , path_hir_id : HirId ) -> Const < ' tcx > {
2096+ let tcx = self . tcx ( ) ;
2097+
2098+ match tcx. named_bound_var ( path_hir_id) {
20782099 Some ( rbv:: ResolvedArg :: EarlyBound ( _) ) => {
20792100 // Find the name and index of the const parameter by indexing the generics of
20802101 // the parent item and construct a `ParamConst`.
2081- let item_def_id = tcx. parent ( def_id ) ;
2102+ let item_def_id = tcx. parent ( param_def_id ) ;
20822103 let generics = tcx. generics_of ( item_def_id) ;
2083- let index = generics. param_def_id_to_index [ & def_id ] ;
2084- let name = tcx. item_name ( def_id ) ;
2104+ let index = generics. param_def_id_to_index [ & param_def_id ] ;
2105+ let name = tcx. item_name ( param_def_id ) ;
20852106 ty:: Const :: new_param ( tcx, ty:: ParamConst :: new ( index, name) )
20862107 }
20872108 Some ( rbv:: ResolvedArg :: LateBound ( debruijn, index, _) ) => {
20882109 ty:: Const :: new_bound ( tcx, debruijn, ty:: BoundVar :: from_u32 ( index) )
20892110 }
20902111 Some ( rbv:: ResolvedArg :: Error ( guar) ) => ty:: Const :: new_error ( tcx, guar) ,
2091- arg => bug ! ( "unexpected bound var resolution for {:?}: {arg:?}" , hir_id ) ,
2112+ arg => bug ! ( "unexpected bound var resolution for {:?}: {arg:?}" , path_hir_id ) ,
20922113 }
20932114 }
20942115
0 commit comments