@@ -314,6 +314,7 @@ pub enum PermitVariants {
314314enum TypeRelativePath < ' tcx > {
315315 AssocItem ( DefId , GenericArgsRef < ' tcx > ) ,
316316 Variant { adt : Ty < ' tcx > , variant_did : DefId } ,
317+ Ctor { ctor_def_id : DefId , args : GenericArgsRef < ' tcx > } ,
317318}
318319
319320/// New-typed boolean indicating whether explicit late-bound lifetimes
@@ -1375,6 +1376,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13751376 let adt = self . check_param_uses_if_mcg ( adt, span, false ) ;
13761377 Ok ( ( adt, DefKind :: Variant , variant_did) )
13771378 }
1379+ TypeRelativePath :: Ctor { .. } => {
1380+ let e = tcx. dcx ( ) . span_err ( span, "expected type, found tuple constructor" ) ;
1381+ Err ( e)
1382+ }
13781383 }
13791384 }
13801385
@@ -1410,6 +1415,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14101415 let ct = self . check_param_uses_if_mcg ( ct, span, false ) ;
14111416 Ok ( ct)
14121417 }
1418+ TypeRelativePath :: Ctor { ctor_def_id, args } => {
1419+ return Ok ( ty:: Const :: zero_sized ( tcx, Ty :: new_fn_def ( tcx, ctor_def_id, args) ) ) ;
1420+ }
14131421 // FIXME(mgca): implement support for this once ready to support all adt ctor expressions,
14141422 // not just const ctors
14151423 TypeRelativePath :: Variant { .. } => {
@@ -1441,6 +1449,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14411449 . iter ( )
14421450 . find ( |vd| tcx. hygienic_eq ( segment. ident , vd. ident ( tcx) , adt_def. did ( ) ) ) ;
14431451 if let Some ( variant_def) = variant_def {
1452+ // FIXME(mgca): do we want constructor resolutions to take priority over
1453+ // other possible resolutions?
1454+ if matches ! ( mode, LowerTypeRelativePathMode :: Const )
1455+ && let Some ( ( CtorKind :: Fn , ctor_def_id) ) = variant_def. ctor
1456+ {
1457+ tcx. check_stability ( variant_def. def_id , Some ( qpath_hir_id) , span, None ) ;
1458+ let _ = self . prohibit_generic_args (
1459+ slice:: from_ref ( segment) . iter ( ) ,
1460+ GenericsArgsErrExtend :: EnumVariant {
1461+ qself : hir_self_ty,
1462+ assoc_segment : segment,
1463+ adt_def,
1464+ } ,
1465+ ) ;
1466+ let ty:: Adt ( _, enum_args) = self_ty. kind ( ) else { unreachable ! ( ) } ;
1467+ return Ok ( TypeRelativePath :: Ctor { ctor_def_id, args : enum_args } ) ;
1468+ }
14441469 if let PermitVariants :: Yes = mode. permit_variants ( ) {
14451470 tcx. check_stability ( variant_def. def_id , Some ( qpath_hir_id) , span, None ) ;
14461471 let _ = self . prohibit_generic_args (
@@ -2349,12 +2374,106 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23492374 hir:: ConstArgKind :: Struct ( qpath, inits) => {
23502375 self . lower_const_arg_struct ( hir_id, qpath, inits, const_arg. span ( ) )
23512376 }
2377+ hir:: ConstArgKind :: TupleCall ( qpath, args) => {
2378+ self . lower_const_arg_tuple_call ( hir_id, qpath, args, const_arg. span ( ) )
2379+ }
23522380 hir:: ConstArgKind :: Anon ( anon) => self . lower_const_arg_anon ( anon) ,
23532381 hir:: ConstArgKind :: Infer ( span, ( ) ) => self . ct_infer ( None , span) ,
23542382 hir:: ConstArgKind :: Error ( _, e) => ty:: Const :: new_error ( tcx, e) ,
23552383 }
23562384 }
23572385
2386+ fn lower_const_arg_tuple_call (
2387+ & self ,
2388+ hir_id : HirId ,
2389+ qpath : hir:: QPath < ' tcx > ,
2390+ args : & ' tcx [ & ' tcx hir:: ConstArg < ' tcx > ] ,
2391+ span : Span ,
2392+ ) -> Const < ' tcx > {
2393+ let tcx = self . tcx ( ) ;
2394+
2395+ let non_adt_or_variant_res = || {
2396+ let e = tcx. dcx ( ) . span_err ( span, "tuple constructor with invalid base path" ) ;
2397+ ty:: Const :: new_error ( tcx, e)
2398+ } ;
2399+
2400+ let ctor_const = match qpath {
2401+ hir:: QPath :: Resolved ( maybe_qself, path) => {
2402+ let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| self . lower_ty ( qself) ) ;
2403+ self . lower_resolved_const_path ( opt_self_ty, path, hir_id)
2404+ }
2405+ hir:: QPath :: TypeRelative ( hir_self_ty, segment) => {
2406+ let self_ty = self . lower_ty ( hir_self_ty) ;
2407+ match self . lower_type_relative_const_path (
2408+ self_ty,
2409+ hir_self_ty,
2410+ segment,
2411+ hir_id,
2412+ span,
2413+ ) {
2414+ Ok ( c) => c,
2415+ Err ( _) => return non_adt_or_variant_res ( ) ,
2416+ }
2417+ }
2418+ } ;
2419+
2420+ let Some ( value) = ctor_const. try_to_value ( ) else {
2421+ return non_adt_or_variant_res ( ) ;
2422+ } ;
2423+
2424+ let ( adt_def, adt_args, variant_did) = match value. ty . kind ( ) {
2425+ ty:: FnDef ( def_id, fn_args)
2426+ if let DefKind :: Ctor ( CtorOf :: Variant , _) = tcx. def_kind ( * def_id) =>
2427+ {
2428+ let parent_did = tcx. parent ( * def_id) ;
2429+ let enum_did = tcx. parent ( parent_did) ;
2430+ ( tcx. adt_def ( enum_did) , fn_args, parent_did)
2431+ }
2432+ ty:: FnDef ( def_id, fn_args)
2433+ if let DefKind :: Ctor ( CtorOf :: Struct , _) = tcx. def_kind ( * def_id) =>
2434+ {
2435+ let parent_did = tcx. parent ( * def_id) ;
2436+ ( tcx. adt_def ( parent_did) , fn_args, parent_did)
2437+ }
2438+ _ => return non_adt_or_variant_res ( ) ,
2439+ } ;
2440+
2441+ let variant_def = adt_def. variant_with_id ( variant_did) ;
2442+ let variant_idx = adt_def. variant_index_with_id ( variant_did) . as_u32 ( ) ;
2443+
2444+ if args. len ( ) != variant_def. fields . len ( ) {
2445+ let e = tcx. dcx ( ) . span_err (
2446+ span,
2447+ format ! (
2448+ "tuple constructor has {} arguments but {} were provided" ,
2449+ variant_def. fields. len( ) ,
2450+ args. len( )
2451+ ) ,
2452+ ) ;
2453+ return ty:: Const :: new_error ( tcx, e) ;
2454+ }
2455+
2456+ let fields = variant_def
2457+ . fields
2458+ . iter ( )
2459+ . zip ( args)
2460+ . map ( |( field_def, arg) | {
2461+ self . lower_const_arg ( arg, FeedConstTy :: Param ( field_def. did , adt_args) )
2462+ } )
2463+ . collect :: < Vec < _ > > ( ) ;
2464+
2465+ let opt_discr_const = if adt_def. is_enum ( ) {
2466+ let valtree = ty:: ValTree :: from_scalar_int ( tcx, variant_idx. into ( ) ) ;
2467+ Some ( ty:: Const :: new_value ( tcx, valtree, tcx. types . u32 ) )
2468+ } else {
2469+ None
2470+ } ;
2471+
2472+ let valtree = ty:: ValTree :: from_branches ( tcx, opt_discr_const. into_iter ( ) . chain ( fields) ) ;
2473+ let adt_ty = Ty :: new_adt ( tcx, adt_def, adt_args) ;
2474+ ty:: Const :: new_value ( tcx, valtree, adt_ty)
2475+ }
2476+
23582477 fn lower_const_arg_struct (
23592478 & self ,
23602479 hir_id : HirId ,
@@ -2486,6 +2605,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24862605 let args = self . lower_generic_args_of_path_segment ( span, did, segment) ;
24872606 ty:: Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( did, args) )
24882607 }
2608+ Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fn ) , did) => {
2609+ assert_eq ! ( opt_self_ty, None ) ;
2610+ let [ leading_segments @ .., segment] = path. segments else { bug ! ( ) } ;
2611+ let _ = self
2612+ . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
2613+ let parent_did = tcx. parent ( did) ;
2614+ let generics_did = if let DefKind :: Ctor ( CtorOf :: Variant , _) = tcx. def_kind ( did) {
2615+ tcx. parent ( parent_did)
2616+ } else {
2617+ parent_did
2618+ } ;
2619+ let args = self . lower_generic_args_of_path_segment ( span, generics_did, segment) ;
2620+ ty:: Const :: zero_sized ( tcx, Ty :: new_fn_def ( tcx, did, args) )
2621+ }
24892622 Res :: Def ( DefKind :: AssocConst , did) => {
24902623 let trait_segment = if let [ modules @ .., trait_, _item] = path. segments {
24912624 let _ = self . prohibit_generic_args ( modules. iter ( ) , GenericsArgsErrExtend :: None ) ;
@@ -2521,9 +2654,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25212654 DefKind :: Mod
25222655 | DefKind :: Enum
25232656 | DefKind :: Variant
2524- | DefKind :: Ctor ( CtorOf :: Variant , CtorKind :: Fn )
25252657 | DefKind :: Struct
2526- | DefKind :: Ctor ( CtorOf :: Struct , CtorKind :: Fn )
25272658 | DefKind :: OpaqueTy
25282659 | DefKind :: TyAlias
25292660 | DefKind :: TraitAlias
0 commit comments