@@ -232,12 +232,15 @@ 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
+ ///
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 > ] ) ,
241
244
/// Don't feed the type.
242
245
No ,
243
246
}
@@ -298,6 +301,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
298
301
299
302
fn provided_kind (
300
303
& mut self ,
304
+ preceding_args : & [ ty:: GenericArg < ' tcx > ] ,
301
305
param : & ty:: GenericParamDef ,
302
306
arg : & GenericArg < ' tcx > ,
303
307
) -> ty:: GenericArg < ' tcx > ;
@@ -481,6 +485,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
481
485
482
486
fn provided_kind (
483
487
& mut self ,
488
+ preceding_args : & [ ty:: GenericArg < ' tcx > ] ,
484
489
param : & ty:: GenericParamDef ,
485
490
arg : & GenericArg < ' tcx > ,
486
491
) -> ty:: GenericArg < ' tcx > {
@@ -526,7 +531,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
526
531
( GenericParamDefKind :: Const { .. } , GenericArg :: Const ( ct) ) => self
527
532
. lowerer
528
533
// 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
+ )
530
538
. into ( ) ,
531
539
( & GenericParamDefKind :: Const { .. } , GenericArg :: Infer ( inf) ) => {
532
540
self . lowerer . ct_infer ( Some ( param) , inf. span ) . into ( )
@@ -582,8 +590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
582
590
let ty = tcx
583
591
. at ( self . span )
584
592
. type_of ( param. def_id )
585
- . no_bound_vars ( )
586
- . expect ( "const parameter types cannot be generic" ) ;
593
+ . instantiate ( tcx, preceding_args) ;
587
594
if let Err ( guar) = ty. error_reported ( ) {
588
595
return ty:: Const :: new_error ( tcx, guar) . into ( ) ;
589
596
}
@@ -2107,14 +2114,50 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2107
2114
pub fn lower_const_arg (
2108
2115
& self ,
2109
2116
const_arg : & hir:: ConstArg < ' tcx > ,
2110
- feed : FeedConstTy ,
2117
+ feed : FeedConstTy < ' _ , ' tcx > ,
2111
2118
) -> Const < ' tcx > {
2112
2119
let tcx = self . tcx ( ) ;
2113
2120
2114
- if let FeedConstTy :: Param ( param_def_id) = feed
2121
+ if let FeedConstTy :: Param ( param_def_id, args ) = feed
2115
2122
&& let hir:: ConstArgKind :: Anon ( anon) = & const_arg. kind
2116
2123
{
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
+ ) ;
2118
2161
}
2119
2162
2120
2163
let hir_id = const_arg. hir_id ;
@@ -2230,10 +2273,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2230
2273
let expr = & tcx. hir_body ( anon. body ) . value ;
2231
2274
debug ! ( ?expr) ;
2232
2275
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 ( ) ;
2237
2280
2238
2281
match self . try_lower_anon_const_lit ( ty, expr) {
2239
2282
Some ( v) => v,
0 commit comments