@@ -2010,41 +2010,62 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20102010 }
20112011
20122012 match const_arg. kind {
2013- hir:: ConstArgKind :: Path ( qpath) => {
2014- // FIXME(min_generic_const_args): for now only params are lowered to ConstArgKind::Path
2015- self . lower_const_arg_param ( qpath, const_arg. hir_id )
2016- }
2013+ hir:: ConstArgKind :: Path ( qpath) => self . lower_const_arg_path ( qpath, const_arg. hir_id ) ,
20172014 hir:: ConstArgKind :: Anon ( anon) => Const :: from_anon_const ( tcx, anon. def_id ) ,
20182015 }
20192016 }
20202017
2021- /// Lower a use of a const param to a [`Const`].
2022- ///
2023- /// IMPORTANT: `qpath` must be a const param, otherwise this will panic
2024- fn lower_const_arg_param ( & self , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Const < ' tcx > {
2018+ /// Lower a const path to a [`Const`].
2019+ fn lower_const_arg_path ( & self , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Const < ' tcx > {
20252020 let tcx = self . tcx ( ) ;
20262021
2027- let hir:: QPath :: Resolved ( _, & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , def_id) , .. } ) =
2028- qpath
2029- else {
2030- span_bug ! ( qpath. span( ) , "non-param {qpath:?} passed to Const::from_param" )
2031- } ;
2022+ // TODO: handle path args properly
2023+ match qpath {
2024+ hir:: QPath :: Resolved ( _, & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , did) , .. } ) => {
2025+ self . lower_const_arg_param ( did, hir_id)
2026+ }
2027+ hir:: QPath :: Resolved (
2028+ _,
2029+ & hir:: Path { res : Res :: Def ( DefKind :: Fn | DefKind :: AssocFn , _) , .. } ,
2030+ ) => ty:: Const :: new_error_with_message (
2031+ tcx,
2032+ qpath. span ( ) ,
2033+ "fn's cannot be used as const args" ,
2034+ ) ,
2035+ hir:: QPath :: Resolved ( _, path @ & hir:: Path { res : Res :: Def ( _, did) , .. } ) => {
2036+ let ( item_segment, _) = path. segments . split_last ( ) . unwrap ( ) ;
2037+ let args = self . lower_generic_args_of_path_segment ( path. span , did, item_segment) ;
2038+ ty:: Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( did, args) )
2039+ }
2040+ // TODO: type-relative paths
2041+ _ => ty:: Const :: new_error_with_message (
2042+ tcx,
2043+ qpath. span ( ) ,
2044+ "Const::lower_const_arg_path: invalid qpath" ,
2045+ ) ,
2046+ }
2047+ }
20322048
2033- match tcx. named_bound_var ( hir_id) {
2049+ /// Lower a const param to a [`Const`]. This is only meant as a helper for [`Self::lower_const_arg_path`].
2050+ /// FIXME: dedup with lower_const_param
2051+ fn lower_const_arg_param ( & self , param_def_id : DefId , path_hir_id : HirId ) -> Const < ' tcx > {
2052+ let tcx = self . tcx ( ) ;
2053+
2054+ match tcx. named_bound_var ( path_hir_id) {
20342055 Some ( rbv:: ResolvedArg :: EarlyBound ( _) ) => {
20352056 // Find the name and index of the const parameter by indexing the generics of
20362057 // the parent item and construct a `ParamConst`.
2037- let item_def_id = tcx. parent ( def_id ) ;
2058+ let item_def_id = tcx. parent ( param_def_id ) ;
20382059 let generics = tcx. generics_of ( item_def_id) ;
2039- let index = generics. param_def_id_to_index [ & def_id ] ;
2040- let name = tcx. item_name ( def_id ) ;
2060+ let index = generics. param_def_id_to_index [ & param_def_id ] ;
2061+ let name = tcx. item_name ( param_def_id ) ;
20412062 ty:: Const :: new_param ( tcx, ty:: ParamConst :: new ( index, name) )
20422063 }
20432064 Some ( rbv:: ResolvedArg :: LateBound ( debruijn, index, _) ) => {
20442065 ty:: Const :: new_bound ( tcx, debruijn, ty:: BoundVar :: from_u32 ( index) )
20452066 }
20462067 Some ( rbv:: ResolvedArg :: Error ( guar) ) => ty:: Const :: new_error ( tcx, guar) ,
2047- arg => bug ! ( "unexpected bound var resolution for {:?}: {arg:?}" , hir_id ) ,
2068+ arg => bug ! ( "unexpected bound var resolution for {:?}: {arg:?}" , path_hir_id ) ,
20482069 }
20492070 }
20502071
0 commit comments