@@ -232,12 +232,12 @@ impl AssocItemQSelf {
232
232
/// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
233
233
/// desired behavior.
234
234
#[ derive( Debug , Clone , Copy ) ]
235
- pub enum FeedConstTy {
235
+ pub enum FeedConstTy < ' a , ' tcx > {
236
236
/// Feed the type.
237
237
///
238
238
/// The `DefId` belongs to the const param that we are supplying
239
239
/// this (anon) const arg to.
240
- Param ( DefId ) ,
240
+ Param ( DefId , & ' a [ ty :: GenericArg < ' tcx > ] ) ,
241
241
/// Don't feed the type.
242
242
No ,
243
243
}
@@ -298,6 +298,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
298
298
299
299
fn provided_kind (
300
300
& mut self ,
301
+ preceding_args : & [ ty:: GenericArg < ' tcx > ] ,
301
302
param : & ty:: GenericParamDef ,
302
303
arg : & GenericArg < ' tcx > ,
303
304
) -> ty:: GenericArg < ' tcx > ;
@@ -481,6 +482,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
481
482
482
483
fn provided_kind (
483
484
& mut self ,
485
+ preceding_args : & [ ty:: GenericArg < ' tcx > ] ,
484
486
param : & ty:: GenericParamDef ,
485
487
arg : & GenericArg < ' tcx > ,
486
488
) -> ty:: GenericArg < ' tcx > {
@@ -526,7 +528,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
526
528
( GenericParamDefKind :: Const { .. } , GenericArg :: Const ( ct) ) => self
527
529
. lowerer
528
530
// 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
+ )
530
535
. into ( ) ,
531
536
( & GenericParamDefKind :: Const { .. } , GenericArg :: Infer ( inf) ) => {
532
537
self . lowerer . ct_infer ( Some ( param) , inf. span ) . into ( )
@@ -582,8 +587,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
582
587
let ty = tcx
583
588
. at ( self . span )
584
589
. type_of ( param. def_id )
585
- . no_bound_vars ( )
586
- . expect ( "const parameter types cannot be generic" ) ;
590
+ . instantiate ( tcx, preceding_args) ;
587
591
if let Err ( guar) = ty. error_reported ( ) {
588
592
return ty:: Const :: new_error ( tcx, guar) . into ( ) ;
589
593
}
@@ -2107,14 +2111,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2107
2111
pub fn lower_const_arg (
2108
2112
& self ,
2109
2113
const_arg : & hir:: ConstArg < ' tcx > ,
2110
- feed : FeedConstTy ,
2114
+ feed : FeedConstTy < ' _ , ' tcx > ,
2111
2115
) -> Const < ' tcx > {
2112
2116
let tcx = self . tcx ( ) ;
2113
2117
2114
- if let FeedConstTy :: Param ( param_def_id) = feed
2118
+ if let FeedConstTy :: Param ( param_def_id, args ) = feed
2115
2119
&& let hir:: ConstArgKind :: Anon ( anon) = & const_arg. kind
2116
2120
{
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
+ ) ;
2118
2141
}
2119
2142
2120
2143
let hir_id = const_arg. hir_id ;
@@ -2230,10 +2253,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2230
2253
let expr = & tcx. hir_body ( anon. body ) . value ;
2231
2254
debug ! ( ?expr) ;
2232
2255
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 ( ) ;
2237
2260
2238
2261
match self . try_lower_anon_const_lit ( ty, expr) {
2239
2262
Some ( v) => v,
0 commit comments