@@ -232,12 +232,12 @@ impl AssocItemQSelf {
232232/// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
233233/// desired behavior.
234234#[ derive( Debug , Clone , Copy ) ]
235- pub enum FeedConstTy {
235+ pub enum FeedConstTy < ' a , ' tcx > {
236236 /// Feed the type.
237237 ///
238238 /// The `DefId` belongs to the const param that we are supplying
239239 /// this (anon) const arg to.
240- Param ( DefId ) ,
240+ Param ( DefId , & ' a [ ty :: GenericArg < ' tcx > ] ) ,
241241 /// Don't feed the type.
242242 No ,
243243}
@@ -298,6 +298,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
298298
299299 fn provided_kind (
300300 & mut self ,
301+ preceding_args : & [ ty:: GenericArg < ' tcx > ] ,
301302 param : & ty:: GenericParamDef ,
302303 arg : & GenericArg < ' tcx > ,
303304 ) -> ty:: GenericArg < ' tcx > ;
@@ -481,6 +482,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
481482
482483 fn provided_kind (
483484 & mut self ,
485+ preceding_args : & [ ty:: GenericArg < ' tcx > ] ,
484486 param : & ty:: GenericParamDef ,
485487 arg : & GenericArg < ' tcx > ,
486488 ) -> ty:: GenericArg < ' tcx > {
@@ -526,7 +528,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
526528 ( GenericParamDefKind :: Const { .. } , GenericArg :: Const ( ct) ) => self
527529 . lowerer
528530 // Ambig portions of `ConstArg` are handled in the match arm below
529- . lower_const_arg ( ct. as_unambig_ct ( ) , FeedConstTy :: Param ( param. def_id ) )
531+ . lower_const_arg (
532+ ct. as_unambig_ct ( ) ,
533+ FeedConstTy :: Param ( param. def_id , preceding_args) ,
534+ )
530535 . into ( ) ,
531536 ( & GenericParamDefKind :: Const { .. } , GenericArg :: Infer ( inf) ) => {
532537 self . lowerer . ct_infer ( Some ( param) , inf. span ) . into ( )
@@ -582,8 +587,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
582587 let ty = tcx
583588 . at ( self . span )
584589 . type_of ( param. def_id )
585- . no_bound_vars ( )
586- . expect ( "const parameter types cannot be generic" ) ;
590+ . instantiate ( tcx, preceding_args) ;
587591 if let Err ( guar) = ty. error_reported ( ) {
588592 return ty:: Const :: new_error ( tcx, guar) . into ( ) ;
589593 }
@@ -2107,14 +2111,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21072111 pub fn lower_const_arg (
21082112 & self ,
21092113 const_arg : & hir:: ConstArg < ' tcx > ,
2110- feed : FeedConstTy ,
2114+ feed : FeedConstTy < ' _ , ' tcx > ,
21112115 ) -> Const < ' tcx > {
21122116 let tcx = self . tcx ( ) ;
21132117
2114- if let FeedConstTy :: Param ( param_def_id) = feed
2118+ if let FeedConstTy :: Param ( param_def_id, args ) = feed
21152119 && let hir:: ConstArgKind :: Anon ( anon) = & const_arg. kind
21162120 {
2117- tcx. feed_anon_const_type ( anon. def_id , tcx. type_of ( param_def_id) ) ;
2121+ let anon_const_type = tcx. type_of ( param_def_id) . instantiate ( tcx, args) ;
2122+
2123+ // We must error if the instantiated type has any inference variables as we will
2124+ // use this type to feed the `type_of` and query results must not contain inference
2125+ // variables otherwise we will ICE.
2126+ //
2127+ // FIXME(generic_const_parameter_types): Ideally we remove this one day when we
2128+ // have the ability to intermix typeck of anon const const args with the parent
2129+ // bodies typeck.
2130+ if anon_const_type. has_infer ( ) {
2131+ let e =
2132+ tcx. dcx ( ) . span_err ( const_arg. span ( ) , "Type of const argument is uninferred" ) ;
2133+ tcx. feed_anon_const_type ( anon. def_id , ty:: EarlyBinder :: bind ( Ty :: new_error ( tcx, e) ) ) ;
2134+ return ty:: Const :: new_error ( tcx, e) ;
2135+ }
2136+
2137+ tcx. feed_anon_const_type (
2138+ anon. def_id ,
2139+ ty:: EarlyBinder :: bind ( tcx. type_of ( param_def_id) . instantiate ( tcx, args) ) ,
2140+ ) ;
21182141 }
21192142
21202143 let hir_id = const_arg. hir_id ;
@@ -2230,10 +2253,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22302253 let expr = & tcx. hir_body ( anon. body ) . value ;
22312254 debug ! ( ?expr) ;
22322255
2233- let ty = tcx
2234- . type_of ( anon . def_id )
2235- . no_bound_vars ( )
2236- . expect ( "const parameter types cannot be generic" ) ;
2256+ // FIXME(generic_const_parameter_types): We should use the proper generic args
2257+ // here. It's only used as a hint for literals so doesn't matter too much to use the right
2258+ // generic arguments, just weaker type inference.
2259+ let ty = tcx . type_of ( anon . def_id ) . instantiate_identity ( ) ;
22372260
22382261 match self . try_lower_anon_const_lit ( ty, expr) {
22392262 Some ( v) => v,
0 commit comments