@@ -2263,8 +2263,81 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22632263 )
22642264 . unwrap_or_else ( |guar| Const :: new_error ( tcx, guar) )
22652265 }
2266- hir:: ConstArgKind :: Struct ( ..) => {
2267- span_bug ! ( const_arg. span( ) , "lowering `{:?}` is not yet implemented" , const_arg)
2266+ hir:: ConstArgKind :: Struct ( qpath, inits) => {
2267+ let ( ty, variant_did) = match qpath {
2268+ hir:: QPath :: Resolved ( maybe_qself, path) => {
2269+ debug ! ( ?maybe_qself, ?path) ;
2270+ let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| self . lower_ty ( qself) ) ;
2271+ let ty = self . lower_resolved_ty_path (
2272+ opt_self_ty,
2273+ path,
2274+ hir_id,
2275+ PermitVariants :: Yes ,
2276+ ) ;
2277+ let variant_did = match path. res {
2278+ Res :: Def ( DefKind :: Variant | DefKind :: Struct , did) => did,
2279+ _ => todo ! ( ) ,
2280+ } ;
2281+
2282+ ( ty, variant_did)
2283+ }
2284+ hir:: QPath :: TypeRelative ( hir_self_ty, segment) => {
2285+ debug ! ( ?hir_self_ty, ?segment) ;
2286+ let self_ty = self . lower_ty ( hir_self_ty) ;
2287+ let opt_res = self . lower_type_relative_ty_path (
2288+ self_ty,
2289+ hir_self_ty,
2290+ segment,
2291+ hir_id,
2292+ const_arg. span ( ) ,
2293+ PermitVariants :: Yes ,
2294+ ) ;
2295+
2296+ let ( ty, res, res_def_id) = match opt_res {
2297+ Ok ( r @ ( _, DefKind :: Variant | DefKind :: Struct , _) ) => r,
2298+ Ok ( _) => todo ! ( ) ,
2299+ Err ( e) => return ty:: Const :: new_error ( tcx, e) ,
2300+ } ;
2301+
2302+ ( ty, res_def_id)
2303+ }
2304+ } ;
2305+
2306+ let ( adt_def, adt_args) = match ty. kind ( ) {
2307+ ty:: Adt ( adt_def, args) => ( adt_def, args) ,
2308+ _ => todo ! ( ) ,
2309+ } ;
2310+
2311+ let variant_def = adt_def. variant_with_id ( variant_did) ;
2312+ let variant_idx = adt_def. variant_index_with_id ( variant_did) . as_u32 ( ) ;
2313+
2314+ let fields = variant_def
2315+ . fields
2316+ . iter ( )
2317+ . map ( |field_def| {
2318+ let init_expr = inits
2319+ . iter ( )
2320+ . find ( |init_expr| init_expr. field . name == field_def. name )
2321+ . unwrap ( ) ;
2322+ self . lower_const_arg (
2323+ init_expr. expr ,
2324+ FeedConstTy :: Param ( field_def. did , adt_args) ,
2325+ )
2326+ } )
2327+ . collect :: < Vec < _ > > ( ) ;
2328+
2329+ let opt_discr_const = if adt_def. is_enum ( ) {
2330+ let valtree = ty:: ValTree :: from_scalar_int ( tcx, variant_idx. into ( ) ) ;
2331+ Some ( ty:: Const :: new_value ( tcx, valtree, tcx. types . u32 ) )
2332+ } else {
2333+ None
2334+ } ;
2335+
2336+ let valtree = ty:: ValTree :: from_ty_const_branches (
2337+ tcx,
2338+ opt_discr_const. into_iter ( ) . chain ( fields) ,
2339+ ) ;
2340+ ty:: Const :: new_value ( tcx, valtree, ty)
22682341 }
22692342 hir:: ConstArgKind :: Anon ( anon) => self . lower_anon_const ( anon) ,
22702343 hir:: ConstArgKind :: Infer ( span, ( ) ) => self . ct_infer ( None , span) ,
0 commit comments