@@ -232,12 +232,15 @@ 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+ ///
241+ /// The list of generic args is used to instantiate the parameters
242+ /// used by the type of the const param specified by `DefId`.
243+ Param ( DefId , & ' a [ ty:: GenericArg < ' tcx > ] ) ,
241244 /// Don't feed the type.
242245 No ,
243246}
@@ -298,6 +301,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
298301
299302 fn provided_kind (
300303 & mut self ,
304+ preceding_args : & [ ty:: GenericArg < ' tcx > ] ,
301305 param : & ty:: GenericParamDef ,
302306 arg : & GenericArg < ' tcx > ,
303307 ) -> ty:: GenericArg < ' tcx > ;
@@ -481,6 +485,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
481485
482486 fn provided_kind (
483487 & mut self ,
488+ preceding_args : & [ ty:: GenericArg < ' tcx > ] ,
484489 param : & ty:: GenericParamDef ,
485490 arg : & GenericArg < ' tcx > ,
486491 ) -> ty:: GenericArg < ' tcx > {
@@ -526,7 +531,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
526531 ( GenericParamDefKind :: Const { .. } , GenericArg :: Const ( ct) ) => self
527532 . lowerer
528533 // Ambig portions of `ConstArg` are handled in the match arm below
529- . lower_const_arg ( ct. as_unambig_ct ( ) , FeedConstTy :: Param ( param. def_id ) )
534+ . lower_const_arg (
535+ ct. as_unambig_ct ( ) ,
536+ FeedConstTy :: Param ( param. def_id , preceding_args) ,
537+ )
530538 . into ( ) ,
531539 ( & GenericParamDefKind :: Const { .. } , GenericArg :: Infer ( inf) ) => {
532540 self . lowerer . ct_infer ( Some ( param) , inf. span ) . into ( )
@@ -582,8 +590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
582590 let ty = tcx
583591 . at ( self . span )
584592 . type_of ( param. def_id )
585- . no_bound_vars ( )
586- . expect ( "const parameter types cannot be generic" ) ;
593+ . instantiate ( tcx, preceding_args) ;
587594 if let Err ( guar) = ty. error_reported ( ) {
588595 return ty:: Const :: new_error ( tcx, guar) . into ( ) ;
589596 }
@@ -2107,14 +2114,50 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21072114 pub fn lower_const_arg (
21082115 & self ,
21092116 const_arg : & hir:: ConstArg < ' tcx > ,
2110- feed : FeedConstTy ,
2117+ feed : FeedConstTy < ' _ , ' tcx > ,
21112118 ) -> Const < ' tcx > {
21122119 let tcx = self . tcx ( ) ;
21132120
2114- if let FeedConstTy :: Param ( param_def_id) = feed
2121+ if let FeedConstTy :: Param ( param_def_id, args ) = feed
21152122 && let hir:: ConstArgKind :: Anon ( anon) = & const_arg. kind
21162123 {
2117- tcx. feed_anon_const_type ( anon. def_id , tcx. type_of ( param_def_id) ) ;
2124+ let anon_const_type = tcx. type_of ( param_def_id) . instantiate ( tcx, args) ;
2125+
2126+ // We must error if the instantiated type has any inference variables as we will
2127+ // use this type to feed the `type_of` and query results must not contain inference
2128+ // variables otherwise we will ICE.
2129+ //
2130+ // We also error if the type contains any regions as effectively any region will wind
2131+ // up as a region variable in mir borrowck. It would also be somewhat concerning if
2132+ // hir typeck was using equality but mir borrowck wound up using subtyping as that could
2133+ // result in a non-infer in hir typeck but a region variable in borrowck.
2134+ //
2135+ // FIXME(generic_const_parameter_types): Ideally we remove these errors one day when
2136+ // we have the ability to intermix typeck of anon const const args with the parent
2137+ // bodies typeck.
2138+ if tcx. features ( ) . generic_const_parameter_types ( )
2139+ && ( anon_const_type. has_free_regions ( ) || anon_const_type. has_erased_regions ( ) )
2140+ {
2141+ let e = tcx. dcx ( ) . span_err (
2142+ const_arg. span ( ) ,
2143+ "anonymous constants with lifetimes in their type are not yet supported" ,
2144+ ) ;
2145+ tcx. feed_anon_const_type ( anon. def_id , ty:: EarlyBinder :: bind ( Ty :: new_error ( tcx, e) ) ) ;
2146+ return ty:: Const :: new_error ( tcx, e) ;
2147+ }
2148+ if anon_const_type. has_non_region_infer ( ) {
2149+ let e = tcx. dcx ( ) . span_err (
2150+ const_arg. span ( ) ,
2151+ "anonymous constants with inferred types are not yet supported" ,
2152+ ) ;
2153+ tcx. feed_anon_const_type ( anon. def_id , ty:: EarlyBinder :: bind ( Ty :: new_error ( tcx, e) ) ) ;
2154+ return ty:: Const :: new_error ( tcx, e) ;
2155+ }
2156+
2157+ tcx. feed_anon_const_type (
2158+ anon. def_id ,
2159+ ty:: EarlyBinder :: bind ( tcx. type_of ( param_def_id) . instantiate ( tcx, args) ) ,
2160+ ) ;
21182161 }
21192162
21202163 let hir_id = const_arg. hir_id ;
@@ -2230,10 +2273,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22302273 let expr = & tcx. hir_body ( anon. body ) . value ;
22312274 debug ! ( ?expr) ;
22322275
2233- let ty = tcx
2234- . type_of ( anon . def_id )
2235- . no_bound_vars ( )
2236- . expect ( "const parameter types cannot be generic" ) ;
2276+ // FIXME(generic_const_parameter_types): We should use the proper generic args
2277+ // here. It's only used as a hint for literals so doesn't matter too much to use the right
2278+ // generic arguments, just weaker type inference.
2279+ let ty = tcx . type_of ( anon . def_id ) . instantiate_identity ( ) ;
22372280
22382281 match self . try_lower_anon_const_lit ( ty, expr) {
22392282 Some ( v) => v,
0 commit comments