@@ -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) ) => {
@@ -2297,15 +2306,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22972306 pub fn lower_const_arg (
22982307 & self ,
22992308 const_arg : & hir:: ConstArg < ' tcx > ,
2300- feed : FeedConstTy < ' _ , ' tcx > ,
2309+ feed : FeedConstTy < ' tcx > ,
23012310 ) -> Const < ' tcx > {
23022311 let tcx = self . tcx ( ) ;
23032312
2304- if let FeedConstTy :: Param ( param_def_id , args ) = feed
2313+ if let FeedConstTy :: WithTy ( anon_const_type ) = feed
23052314 && let hir:: ConstArgKind :: Anon ( anon) = & const_arg. kind
23062315 {
2307- let anon_const_type = tcx. type_of ( param_def_id) . instantiate ( tcx, args) ;
2308-
23092316 // FIXME(generic_const_parameter_types): Ideally we remove these errors below when
23102317 // we have the ability to intermix typeck of anon const const args with the parent
23112318 // bodies typeck.
@@ -2346,14 +2353,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23462353 return ty:: Const :: new_error ( tcx, e) ;
23472354 }
23482355
2349- tcx. feed_anon_const_type (
2350- anon. def_id ,
2351- ty:: EarlyBinder :: bind ( tcx. type_of ( param_def_id) . instantiate ( tcx, args) ) ,
2352- ) ;
2356+ tcx. feed_anon_const_type ( anon. def_id , ty:: EarlyBinder :: bind ( anon_const_type) ) ;
23532357 }
23542358
23552359 let hir_id = const_arg. hir_id ;
23562360 match const_arg. kind {
2361+ hir:: ConstArgKind :: Tup ( span, exprs) => self . lower_const_arg_tup ( exprs, feed, span) ,
23572362 hir:: ConstArgKind :: Path ( hir:: QPath :: Resolved ( maybe_qself, path) ) => {
23582363 debug ! ( ?maybe_qself, ?path) ;
23592364 let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| self . lower_ty ( qself) ) ;
@@ -2458,7 +2463,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24582463 . iter ( )
24592464 . zip ( args)
24602465 . map ( |( field_def, arg) | {
2461- self . lower_const_arg ( arg, FeedConstTy :: Param ( field_def. did , adt_args) )
2466+ self . lower_const_arg ( arg, FeedConstTy :: with_type_of ( tcx , field_def. did , adt_args) )
24622467 } )
24632468 . collect :: < Vec < _ > > ( ) ;
24642469
@@ -2474,6 +2479,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24742479 ty:: Const :: new_value ( tcx, valtree, adt_ty)
24752480 }
24762481
2482+ fn lower_const_arg_tup (
2483+ & self ,
2484+ exprs : & ' tcx [ & ' tcx hir:: ConstArg < ' tcx > ] ,
2485+ feed : FeedConstTy < ' tcx > ,
2486+ span : Span ,
2487+ ) -> Const < ' tcx > {
2488+ let tcx = self . tcx ( ) ;
2489+
2490+ let FeedConstTy :: WithTy ( ty) = feed else {
2491+ return Const :: new_error_with_message ( tcx, span, "unsupported const tuple" ) ;
2492+ } ;
2493+
2494+ let ty:: Tuple ( tys) = ty. kind ( ) else {
2495+ return Const :: new_error_with_message ( tcx, span, "const tuple must have a tuple type" ) ;
2496+ } ;
2497+
2498+ let exprs = exprs
2499+ . iter ( )
2500+ . zip ( tys. iter ( ) )
2501+ . map ( |( expr, ty) | self . lower_const_arg ( expr, FeedConstTy :: WithTy ( ty) ) )
2502+ . collect :: < Vec < _ > > ( ) ;
2503+
2504+ let valtree = ty:: ValTree :: from_branches ( tcx, exprs) ;
2505+ ty:: Const :: new_value ( tcx, valtree, ty)
2506+ }
2507+
24772508 fn lower_const_arg_struct (
24782509 & self ,
24792510 hir_id : HirId ,
@@ -2552,7 +2583,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25522583 return ty:: Const :: new_error ( tcx, e) ;
25532584 }
25542585
2555- self . lower_const_arg ( expr. expr , FeedConstTy :: Param ( field_def. did , adt_args) )
2586+ self . lower_const_arg (
2587+ expr. expr ,
2588+ FeedConstTy :: with_type_of ( tcx, field_def. did , adt_args) ,
2589+ )
25562590 }
25572591 None => {
25582592 let e = tcx. dcx ( ) . span_err (
0 commit comments