@@ -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 ;
1010use rustc_type_ir:: { self as ir, TypeFlags , WithCachedTypeInfo } ;
@@ -179,6 +179,39 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
179179}
180180
181181impl < ' tcx > Const < ' tcx > {
182+ /// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self).
183+ ///
184+ /// `param_def_id` is the [`DefId`] of the declared param that this [`ConstArg`] is being
185+ /// supplied to. We need this in case this `ConstArg` is a [`ConstArgKind::Anon`]
186+ /// so we can tell the [`AnonConst`] what type it should be.
187+ pub fn from_const_arg (
188+ tcx : TyCtxt < ' tcx > ,
189+ const_arg : & ' tcx hir:: ConstArg < ' tcx > ,
190+ param_def_id : DefId ,
191+ ) -> Self {
192+ if let hir:: ConstArgKind :: Anon ( anon) = & const_arg. kind {
193+ tcx. feed_anon_const_type ( anon. def_id , tcx. type_of ( param_def_id) ) ;
194+ }
195+ Self :: from_const_arg_without_feeding ( tcx, const_arg)
196+ }
197+
198+ /// Convert a [`hir::ConstArg`] to a [`ty::Const`](Self), without feeding it its expected type.
199+ ///
200+ /// This distinction is only relevant for [`hir::ConstArgKind::Anon`];
201+ /// see [`Self::from_const_arg_without_feeding`].
202+ pub fn from_const_arg_without_feeding (
203+ tcx : TyCtxt < ' tcx > ,
204+ const_arg : & ' tcx hir:: ConstArg < ' tcx > ,
205+ ) -> Self {
206+ match const_arg. kind {
207+ hir:: ConstArgKind :: Path ( qpath) => {
208+ // FIXME(min_generic_const_exprs): for now only params are lowered to ConstArgKind::Path
209+ Self :: from_param ( tcx, qpath, const_arg. hir_id )
210+ }
211+ hir:: ConstArgKind :: Anon ( anon) => Self :: from_anon_const ( tcx, anon. def_id ) ,
212+ }
213+ }
214+
182215 /// Literals and const generic parameters are eagerly converted to a constant, everything else
183216 /// becomes `Unevaluated`.
184217 #[ instrument( skip( tcx) , level = "debug" ) ]
@@ -212,7 +245,7 @@ impl<'tcx> Const<'tcx> {
212245 /// Lower a const param to a [`Const`].
213246 ///
214247 /// IMPORTANT: `qpath` must be a const param, otherwise this will panic
215- pub fn from_param ( tcx : TyCtxt < ' tcx > , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Self {
248+ fn from_param ( tcx : TyCtxt < ' tcx > , qpath : hir:: QPath < ' tcx > , hir_id : HirId ) -> Self {
216249 // FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
217250 // does not provide the parents generics to anonymous constants. We still allow generic const
218251 // parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
@@ -274,6 +307,21 @@ impl<'tcx> Const<'tcx> {
274307 }
275308 }
276309 }
310+
311+ // FIXME: this shouldn't panic, it's just temporary code
312+ match expr. kind {
313+ hir:: ExprKind :: Path ( hir:: QPath :: Resolved (
314+ _,
315+ & hir:: Path { res : Res :: Def ( DefKind :: ConstParam , _) , .. } ,
316+ ) ) => {
317+ span_bug ! (
318+ expr. span,
319+ "try_from_lit: received const param which shouldn't be possible"
320+ )
321+ }
322+ _ => { }
323+ }
324+
277325 None
278326 }
279327
0 commit comments