@@ -2038,41 +2038,62 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2038
2038
}
2039
2039
2040
2040
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 ) ,
2045
2042
hir:: ConstArgKind :: Anon ( anon) => Const :: from_anon_const ( tcx, anon. def_id ) ,
2046
2043
}
2047
2044
}
2048
2045
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 > {
2053
2048
let tcx = self . tcx ( ) ;
2054
2049
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
+ }
2060
2076
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) {
2062
2083
Some ( rbv:: ResolvedArg :: EarlyBound ( _) ) => {
2063
2084
// Find the name and index of the const parameter by indexing the generics of
2064
2085
// 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 ) ;
2066
2087
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 ) ;
2069
2090
ty:: Const :: new_param ( tcx, ty:: ParamConst :: new ( index, name) )
2070
2091
}
2071
2092
Some ( rbv:: ResolvedArg :: LateBound ( debruijn, index, _) ) => {
2072
2093
ty:: Const :: new_bound ( tcx, debruijn, ty:: BoundVar :: from_u32 ( index) )
2073
2094
}
2074
2095
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 ) ,
2076
2097
}
2077
2098
}
2078
2099
0 commit comments