@@ -259,17 +259,26 @@ impl AssocItemQSelf {
259259/// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
260260/// desired behavior.
261261#[ derive( Debug , Clone , Copy ) ]
262- pub enum FeedConstTy < ' a , ' tcx > {
263- /// Feed the type.
264- ///
262+ pub enum FeedConstTy < ' tcx > {
263+ /// Feed the type to the (anno) const arg.
264+ WithTy ( Ty < ' tcx > ) ,
265+ /// Don't feed the type.
266+ No ,
267+ }
268+
269+ impl < ' tcx > FeedConstTy < ' tcx > {
265270 /// The `DefId` belongs to the const param that we are supplying
266271 /// this (anon) const arg to.
267272 ///
268273 /// The list of generic args is used to instantiate the parameters
269274 /// used by the type of the const param specified by `DefId`.
270- Param ( DefId , & ' a [ ty:: GenericArg < ' tcx > ] ) ,
271- /// Don't feed the type.
272- No ,
275+ pub fn with_type_of (
276+ tcx : TyCtxt < ' tcx > ,
277+ def_id : DefId ,
278+ generic_args : & [ ty:: GenericArg < ' tcx > ] ,
279+ ) -> Self {
280+ Self :: WithTy ( tcx. type_of ( def_id) . instantiate ( tcx, generic_args) )
281+ }
273282}
274283
275284#[ derive( Debug , Clone , Copy ) ]
@@ -723,7 +732,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
723732 // Ambig portions of `ConstArg` are handled in the match arm below
724733 . lower_const_arg (
725734 ct. as_unambig_ct ( ) ,
726- FeedConstTy :: Param ( param. def_id , preceding_args) ,
735+ FeedConstTy :: with_type_of ( tcx , param. def_id , preceding_args) ,
727736 )
728737 . into ( ) ,
729738 ( & GenericParamDefKind :: Const { .. } , GenericArg :: Infer ( inf) ) => {
@@ -2303,15 +2312,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23032312 pub fn lower_const_arg (
23042313 & self ,
23052314 const_arg : & hir:: ConstArg < ' tcx > ,
2306- feed : FeedConstTy < ' _ , ' tcx > ,
2315+ feed : FeedConstTy < ' tcx > ,
23072316 ) -> Const < ' tcx > {
23082317 let tcx = self . tcx ( ) ;
23092318
2310- if let FeedConstTy :: Param ( param_def_id , args ) = feed
2319+ if let FeedConstTy :: WithTy ( anon_const_type ) = feed
23112320 && let hir:: ConstArgKind :: Anon ( anon) = & const_arg. kind
23122321 {
2313- let anon_const_type = tcx. type_of ( param_def_id) . instantiate ( tcx, args) ;
2314-
23152322 // FIXME(generic_const_parameter_types): Ideally we remove these errors below when
23162323 // we have the ability to intermix typeck of anon const const args with the parent
23172324 // bodies typeck.
@@ -2352,14 +2359,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23522359 return ty:: Const :: new_error ( tcx, e) ;
23532360 }
23542361
2355- tcx. feed_anon_const_type (
2356- anon. def_id ,
2357- ty:: EarlyBinder :: bind ( tcx. type_of ( param_def_id) . instantiate ( tcx, args) ) ,
2358- ) ;
2362+ tcx. feed_anon_const_type ( anon. def_id , ty:: EarlyBinder :: bind ( anon_const_type) ) ;
23592363 }
23602364
23612365 let hir_id = const_arg. hir_id ;
23622366 match const_arg. kind {
2367+ hir:: ConstArgKind :: Tup ( span, exprs) => self . lower_const_arg_tup ( exprs, feed, span) ,
23632368 hir:: ConstArgKind :: Path ( hir:: QPath :: Resolved ( maybe_qself, path) ) => {
23642369 debug ! ( ?maybe_qself, ?path) ;
23652370 let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| self . lower_ty ( qself) ) ;
@@ -2464,7 +2469,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24642469 . iter ( )
24652470 . zip ( args)
24662471 . map ( |( field_def, arg) | {
2467- self . lower_const_arg ( arg, FeedConstTy :: Param ( field_def. did , adt_args) )
2472+ self . lower_const_arg ( arg, FeedConstTy :: with_type_of ( tcx , field_def. did , adt_args) )
24682473 } )
24692474 . collect :: < Vec < _ > > ( ) ;
24702475
@@ -2480,6 +2485,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24802485 ty:: Const :: new_value ( tcx, valtree, adt_ty)
24812486 }
24822487
2488+ fn lower_const_arg_tup (
2489+ & self ,
2490+ exprs : & ' tcx [ & ' tcx hir:: ConstArg < ' tcx > ] ,
2491+ feed : FeedConstTy < ' tcx > ,
2492+ span : Span ,
2493+ ) -> Const < ' tcx > {
2494+ let tcx = self . tcx ( ) ;
2495+
2496+ let FeedConstTy :: WithTy ( ty) = feed else {
2497+ return Const :: new_error_with_message ( tcx, span, "unsupported const tuple" ) ;
2498+ } ;
2499+
2500+ let ty:: Tuple ( tys) = ty. kind ( ) else {
2501+ return Const :: new_error_with_message ( tcx, span, "const tuple must have a tuple type" ) ;
2502+ } ;
2503+
2504+ let exprs = exprs
2505+ . iter ( )
2506+ . zip ( tys. iter ( ) )
2507+ . map ( |( expr, ty) | self . lower_const_arg ( expr, FeedConstTy :: WithTy ( ty) ) )
2508+ . collect :: < Vec < _ > > ( ) ;
2509+
2510+ let valtree = ty:: ValTree :: from_branches ( tcx, exprs) ;
2511+ ty:: Const :: new_value ( tcx, valtree, ty)
2512+ }
2513+
24832514 fn lower_const_arg_struct (
24842515 & self ,
24852516 hir_id : HirId ,
@@ -2558,7 +2589,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25582589 return ty:: Const :: new_error ( tcx, e) ;
25592590 }
25602591
2561- self . lower_const_arg ( expr. expr , FeedConstTy :: Param ( field_def. did , adt_args) )
2592+ self . lower_const_arg (
2593+ expr. expr ,
2594+ FeedConstTy :: with_type_of ( tcx, field_def. did , adt_args) ,
2595+ )
25622596 }
25632597 None => {
25642598 let e = tcx. dcx ( ) . span_err (
0 commit comments