@@ -215,10 +215,7 @@ impl<'tcx> Const<'tcx> {
215215 }
216216
217217 match const_arg. kind {
218- hir:: ConstArgKind :: Path ( qpath) => {
219- // FIXME(min_generic_const_args): for now only params are lowered to ConstArgKind::Path
220- Self :: from_param ( tcx, qpath, const_arg. hir_id )
221- }
218+ hir:: ConstArgKind :: Path ( qpath) => Self :: from_path ( tcx, qpath, const_arg. hir_id ) ,
222219 hir:: ConstArgKind :: Anon ( anon) => Self :: from_anon_const ( tcx, anon. def_id ) ,
223220 }
224221 }
@@ -240,7 +237,7 @@ impl<'tcx> Const<'tcx> {
240237
241238 let ty = tcx. type_of ( def) . no_bound_vars ( ) . expect ( "const parameter types cannot be generic" ) ;
242239
243- match Self :: try_from_lit_or_param ( tcx, ty, expr) {
240+ match Self :: try_from_lit ( tcx, ty, expr) {
244241 Some ( v) => v,
245242 None => ty:: Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst {
246243 def : def. to_def_id ( ) ,
@@ -249,40 +246,54 @@ impl<'tcx> Const<'tcx> {
249246 }
250247 }
251248
252- /// Lower a const param to a [`Const`].
253- ///
254- /// IMPORTANT: `qpath` must be a const param, otherwise this will panic
255- fn from_param ( tcx : TyCtxt < ' tcx > , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Self {
256- let hir:: QPath :: Resolved ( _, & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , def_id) , .. } ) =
257- qpath
258- else {
259- span_bug ! ( qpath. span( ) , "non-param {qpath:?} passed to Const::from_param" )
260- } ;
249+ fn from_path ( tcx : TyCtxt < ' tcx > , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Self {
250+ match qpath {
251+ hir:: QPath :: Resolved ( _, & path) => match path. res {
252+ Res :: Def ( DefKind :: ConstParam , def_id) => Self :: from_param ( tcx, def_id, hir_id) ,
253+ Res :: Def ( DefKind :: Const , def_id) => {
254+ // FIXME: support parametrized consts (instead of empty list).
255+ let uv = ty:: UnevaluatedConst :: new ( def_id, ty:: List :: empty ( ) ) ;
256+ Self :: new_unevaluated ( tcx, uv)
257+ }
258+ r => Self :: new_error (
259+ tcx,
260+ tcx. dcx ( ) . span_delayed_bug (
261+ tcx. hir ( ) . span ( hir_id) ,
262+ format ! ( "Const::from_path: invalid qpath res: {r:?}" ) ,
263+ ) ,
264+ ) ,
265+ } ,
266+ hir:: QPath :: TypeRelative ( ..) => todo ! ( "associated const paths" ) ,
267+ // FIXME: use span_delayed_bug?
268+ hir:: QPath :: LangItem ( ..) => span_bug ! (
269+ tcx. hir( ) . span( hir_id) ,
270+ "Const::from_path: invalid qpath provided: {qpath:?}"
271+ ) ,
272+ }
273+ }
261274
262- match tcx. named_bound_var ( hir_id) {
275+ /// Lower a const param to a [`Const`]. This is only meant as a helper for [`Self::from_path`].
276+ fn from_param ( tcx : TyCtxt < ' tcx > , param_def_id : DefId , path_hir_id : HirId ) -> Self {
277+ match tcx. named_bound_var ( path_hir_id) {
263278 Some ( rbv:: ResolvedArg :: EarlyBound ( _) ) => {
264279 // Find the name and index of the const parameter by indexing the generics of
265280 // the parent item and construct a `ParamConst`.
266- let item_def_id = tcx. parent ( def_id ) ;
281+ let item_def_id = tcx. parent ( param_def_id ) ;
267282 let generics = tcx. generics_of ( item_def_id) ;
268- let index = generics. param_def_id_to_index [ & def_id ] ;
269- let name = tcx. item_name ( def_id ) ;
283+ let index = generics. param_def_id_to_index [ & param_def_id ] ;
284+ let name = tcx. item_name ( param_def_id ) ;
270285 ty:: Const :: new_param ( tcx, ty:: ParamConst :: new ( index, name) )
271286 }
272287 Some ( rbv:: ResolvedArg :: LateBound ( debruijn, index, _) ) => {
273288 ty:: Const :: new_bound ( tcx, debruijn, ty:: BoundVar :: from_u32 ( index) )
274289 }
275290 Some ( rbv:: ResolvedArg :: Error ( guar) ) => ty:: Const :: new_error ( tcx, guar) ,
276- arg => bug ! ( "unexpected bound var resolution for {:?}: {arg:?}" , hir_id ) ,
291+ arg => bug ! ( "unexpected bound var resolution for {:?}: {arg:?}" , path_hir_id ) ,
277292 }
278293 }
279294
280295 #[ instrument( skip( tcx) , level = "debug" ) ]
281- fn try_from_lit_or_param (
282- tcx : TyCtxt < ' tcx > ,
283- ty : Ty < ' tcx > ,
284- expr : & ' tcx hir:: Expr < ' tcx > ,
285- ) -> Option < Self > {
296+ fn try_from_lit ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , expr : & ' tcx hir:: Expr < ' tcx > ) -> Option < Self > {
286297 // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
287298 // currently have to be wrapped in curly brackets, so it's necessary to special-case.
288299 let expr = match & expr. kind {
0 commit comments