@@ -4,7 +4,7 @@ use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisita
44use rustc_data_structures:: intern:: Interned ;
55use rustc_error_messages:: MultiSpan ;
66use rustc_hir:: def:: { DefKind , Res } ;
7- use rustc_hir:: def_id:: LocalDefId ;
7+ use rustc_hir:: def_id:: { DefId , LocalDefId } ;
88use rustc_hir:: { self as hir, HirId } ;
99use rustc_macros:: { HashStable , TyDecodable , TyEncodable } ;
1010use rustc_type_ir:: { self as ir, TypeFlags , WithCachedTypeInfo } ;
@@ -216,6 +216,39 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
216216}
217217
218218impl < ' tcx > Const < ' tcx > {
219+ /// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self).
220+ ///
221+ /// `param_def_id` is the [`DefId`] of the declared param that this [`ConstArg`] is being
222+ /// supplied to. We need this in case this `ConstArg` is a [`ConstArgKind::Anon`]
223+ /// so we can tell the [`AnonConst`] what type it should be.
224+ pub fn from_const_arg (
225+ tcx : TyCtxt < ' tcx > ,
226+ const_arg : & ' tcx hir:: ConstArg < ' tcx > ,
227+ param_def_id : DefId ,
228+ ) -> Self {
229+ if let hir:: ConstArgKind :: Anon ( anon) = & const_arg. kind {
230+ tcx. feed_anon_const_type ( anon. def_id , tcx. type_of ( param_def_id) ) ;
231+ }
232+ Self :: from_const_arg_without_feeding ( tcx, const_arg)
233+ }
234+
235+ /// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self), without feeding it its expected type.
236+ ///
237+ /// This distinction is only relevant for [`hir::ConstArgKind::Anon`];
238+ /// see [`Self::from_const_arg_without_feeding`].
239+ pub fn from_const_arg_without_feeding (
240+ tcx : TyCtxt < ' tcx > ,
241+ const_arg : & ' tcx hir:: ConstArg < ' tcx > ,
242+ ) -> Self {
243+ match const_arg. kind {
244+ hir:: ConstArgKind :: Path ( qpath) => {
245+ // FIXME(min_generic_const_exprs): for now only params are lowered to ConstArgKind::Path
246+ Self :: from_param ( tcx, qpath, const_arg. hir_id )
247+ }
248+ hir:: ConstArgKind :: Anon ( anon) => Self :: from_anon_const ( tcx, anon. def_id ) ,
249+ }
250+ }
251+
219252 /// Literals and const generic parameters are eagerly converted to a constant, everything else
220253 /// becomes `Unevaluated`.
221254 #[ instrument( skip( tcx) , level = "debug" ) ]
@@ -250,7 +283,7 @@ impl<'tcx> Const<'tcx> {
250283 /// Lower a const param to a [`Const`].
251284 ///
252285 /// IMPORTANT: `qpath` must be a const param, otherwise this will panic
253- pub fn from_param ( tcx : TyCtxt < ' tcx > , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Self {
286+ fn from_param ( tcx : TyCtxt < ' tcx > , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Self {
254287 // FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
255288 // does not provide the parents generics to anonymous constants. We still allow generic const
256289 // parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
@@ -315,6 +348,21 @@ impl<'tcx> Const<'tcx> {
315348 }
316349 }
317350 }
351+
352+ // FIXME: this shouldn't panic, it's just temporary code
353+ match expr. kind {
354+ hir:: ExprKind :: Path ( hir:: QPath :: Resolved (
355+ _,
356+ & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , _) , .. } ,
357+ ) ) => {
358+ span_bug ! (
359+ expr. span,
360+ "try_from_lit: received const param which shouldn't be possible"
361+ )
362+ }
363+ _ => { }
364+ }
365+
318366 None
319367 }
320368
0 commit comments