@@ -268,6 +268,9 @@ pub enum FeedConstTy<'a, 'tcx> {
268268 /// The list of generic args is used to instantiate the parameters
269269 /// used by the type of the const param specified by `DefId`.
270270 Param ( DefId , & ' a [ ty:: GenericArg < ' tcx > ] ) ,
271+ /// The type is of one field of the top const param that we are
272+ /// supplying this (anon) const arg to.
273+ Field ( Ty < ' tcx > ) ,
271274 /// Don't feed the type.
272275 No ,
273276}
@@ -2193,10 +2196,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21932196 ) -> Const < ' tcx > {
21942197 let tcx = self . tcx ( ) ;
21952198
2196- if let FeedConstTy :: Param ( param_def_id , args ) = feed
2197- && let hir :: ConstArgKind :: Anon ( anon ) = & const_arg . kind
2199+ if let hir :: ConstArgKind :: Anon ( anon ) = & const_arg . kind
2200+ && ! matches ! ( feed , FeedConstTy :: No )
21982201 {
2199- let anon_const_type = tcx. type_of ( param_def_id) . instantiate ( tcx, args) ;
2202+ let anon_const_type = if let FeedConstTy :: Param ( param_def_id, args) = feed {
2203+ tcx. type_of ( param_def_id) . instantiate ( tcx, args)
2204+ } else if let FeedConstTy :: Field ( ty) = feed {
2205+ ty
2206+ } else {
2207+ bug ! ( "unexpected feed const ty: {:?}" , feed)
2208+ } ;
22002209
22012210 // FIXME(generic_const_parameter_types): Ideally we remove these errors below when
22022211 // we have the ability to intermix typeck of anon const const args with the parent
@@ -2238,14 +2247,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22382247 return ty:: Const :: new_error ( tcx, e) ;
22392248 }
22402249
2241- tcx. feed_anon_const_type (
2242- anon. def_id ,
2243- ty:: EarlyBinder :: bind ( tcx. type_of ( param_def_id) . instantiate ( tcx, args) ) ,
2244- ) ;
2250+ tcx. feed_anon_const_type ( anon. def_id , ty:: EarlyBinder :: bind ( anon_const_type) ) ;
22452251 }
22462252
22472253 let hir_id = const_arg. hir_id ;
22482254 match const_arg. kind {
2255+ hir:: ConstArgKind :: Tup ( span, exprs) => self . lower_const_arg_tup ( exprs, feed, span) ,
22492256 hir:: ConstArgKind :: Path ( hir:: QPath :: Resolved ( maybe_qself, path) ) => {
22502257 debug ! ( ?maybe_qself, ?path) ;
22512258 let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| self . lower_ty ( qself) ) ;
@@ -2272,6 +2279,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22722279 }
22732280 }
22742281
2282+ fn lower_const_arg_tup (
2283+ & self ,
2284+ exprs : & ' tcx [ & ' tcx hir:: ConstArg < ' tcx > ] ,
2285+ feed : FeedConstTy < ' _ , ' tcx > ,
2286+ span : Span ,
2287+ ) -> Const < ' tcx > {
2288+ let tcx = self . tcx ( ) ;
2289+
2290+ // FIXME(mgca): support nested const tuples?
2291+ let ty = if let FeedConstTy :: Param ( did, args) = feed {
2292+ tcx. type_of ( did) . instantiate ( tcx, args)
2293+ } else if let FeedConstTy :: Field ( ty) = feed {
2294+ ty
2295+ } else {
2296+ return Const :: new_error_with_message ( tcx, span, "unsupported const tuple" ) ;
2297+ } ;
2298+
2299+ let ty:: Tuple ( tys) = ty. kind ( ) else {
2300+ return Const :: new_error_with_message ( tcx, span, "const tuple must have a tuple type" ) ;
2301+ } ;
2302+
2303+ let exprs = exprs
2304+ . iter ( )
2305+ . zip ( tys. iter ( ) )
2306+ . map ( |( expr, ty) | self . lower_const_arg ( expr, FeedConstTy :: Field ( ty) ) )
2307+ . collect :: < Vec < _ > > ( ) ;
2308+
2309+ let valtree = ty:: ValTree :: from_branches ( tcx, exprs) ;
2310+ ty:: Const :: new_value ( tcx, valtree, ty)
2311+ }
2312+
22752313 fn lower_const_arg_struct (
22762314 & self ,
22772315 hir_id : HirId ,
0 commit comments