@@ -2038,41 +2038,62 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20382038 }
20392039
20402040 match const_arg. kind {
2041- hir:: ConstArgKind :: Path ( qpath) => {
2042- // FIXME(min_generic_const_args): for now only params are lowered to ConstArgKind::Path
2043- self . lower_const_arg_param ( qpath, const_arg. hir_id )
2044- }
2041+ hir:: ConstArgKind :: Path ( qpath) => self . lower_const_arg_path ( qpath, const_arg. hir_id ) ,
20452042 hir:: ConstArgKind :: Anon ( anon) => Const :: from_anon_const ( tcx, anon. def_id ) ,
20462043 }
20472044 }
20482045
2049- /// Lower a use of a const param to a [`Const`].
2050- ///
2051- /// IMPORTANT: `qpath` must be a const param, otherwise this will panic
2052- fn lower_const_arg_param ( & self , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Const < ' tcx > {
2046+ /// Lower a const path to a [`Const`].
2047+ fn lower_const_arg_path ( & self , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Const < ' tcx > {
20532048 let tcx = self . tcx ( ) ;
20542049
2055- let hir:: QPath :: Resolved ( _, & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , def_id) , .. } ) =
2056- qpath
2057- else {
2058- span_bug ! ( qpath. span( ) , "non-param {qpath:?} passed to Const::from_param" )
2059- } ;
2050+ // TODO: handle path args properly
2051+ match qpath {
2052+ hir:: QPath :: Resolved ( _, & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , did) , .. } ) => {
2053+ self . lower_const_arg_param ( did, hir_id)
2054+ }
2055+ hir:: QPath :: Resolved (
2056+ _,
2057+ & hir:: Path { res : Res :: Def ( DefKind :: Fn | DefKind :: AssocFn , _) , .. } ,
2058+ ) => ty:: Const :: new_error_with_message (
2059+ tcx,
2060+ qpath. span ( ) ,
2061+ "fn's cannot be used as const args" ,
2062+ ) ,
2063+ hir:: QPath :: Resolved ( _, path @ & hir:: Path { res : Res :: Def ( _, did) , .. } ) => {
2064+ let ( item_segment, _) = path. segments . split_last ( ) . unwrap ( ) ;
2065+ let args = self . lower_generic_args_of_path_segment ( path. span , did, item_segment) ;
2066+ ty:: Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( did, args) )
2067+ }
2068+ // TODO: type-relative paths
2069+ _ => ty:: Const :: new_error_with_message (
2070+ tcx,
2071+ qpath. span ( ) ,
2072+ "Const::lower_const_arg_path: invalid qpath" ,
2073+ ) ,
2074+ }
2075+ }
20602076
2061- match tcx. named_bound_var ( hir_id) {
2077+ /// Lower a const param to a [`Const`]. This is only meant as a helper for [`Self::lower_const_arg_path`].
2078+ /// FIXME: dedup with lower_const_param
2079+ fn lower_const_arg_param ( & self , param_def_id : DefId , path_hir_id : HirId ) -> Const < ' tcx > {
2080+ let tcx = self . tcx ( ) ;
2081+
2082+ match tcx. named_bound_var ( path_hir_id) {
20622083 Some ( rbv:: ResolvedArg :: EarlyBound ( _) ) => {
20632084 // Find the name and index of the const parameter by indexing the generics of
20642085 // the parent item and construct a `ParamConst`.
2065- let item_def_id = tcx. parent ( def_id ) ;
2086+ let item_def_id = tcx. parent ( param_def_id ) ;
20662087 let generics = tcx. generics_of ( item_def_id) ;
2067- let index = generics. param_def_id_to_index [ & def_id ] ;
2068- let name = tcx. item_name ( def_id ) ;
2088+ let index = generics. param_def_id_to_index [ & param_def_id ] ;
2089+ let name = tcx. item_name ( param_def_id ) ;
20692090 ty:: Const :: new_param ( tcx, ty:: ParamConst :: new ( index, name) )
20702091 }
20712092 Some ( rbv:: ResolvedArg :: LateBound ( debruijn, index, _) ) => {
20722093 ty:: Const :: new_bound ( tcx, debruijn, ty:: BoundVar :: from_u32 ( index) )
20732094 }
20742095 Some ( rbv:: ResolvedArg :: Error ( guar) ) => ty:: Const :: new_error ( tcx, guar) ,
2075- arg => bug ! ( "unexpected bound var resolution for {:?}: {arg:?}" , hir_id ) ,
2096+ arg => bug ! ( "unexpected bound var resolution for {:?}: {arg:?}" , path_hir_id ) ,
20762097 }
20772098 }
20782099
0 commit comments