@@ -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
@@ -1261,6 +1262,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12611262 TypeRelativePath :: Variant { adt, variant_did } => {
12621263 Ok ( ( adt, DefKind :: Variant , variant_did) )
12631264 }
1265+ TypeRelativePath :: Ctor { .. } => {
1266+ let e = tcx. dcx ( ) . span_err ( span, "expected type, found tuple constructor" ) ;
1267+ Err ( e)
1268+ }
12641269 }
12651270 }
12661271
@@ -1294,6 +1299,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12941299 }
12951300 ( def_id, args)
12961301 }
1302+ TypeRelativePath :: Ctor { ctor_def_id, args } => {
1303+ return Ok ( ty:: Const :: zero_sized ( tcx, Ty :: new_fn_def ( tcx, ctor_def_id, args) ) ) ;
1304+ }
12971305 // FIXME(mgca): implement support for this once ready to support all adt ctor expressions,
12981306 // not just const ctors
12991307 TypeRelativePath :: Variant { .. } => {
@@ -1326,6 +1334,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13261334 . iter ( )
13271335 . find ( |vd| tcx. hygienic_eq ( segment. ident , vd. ident ( tcx) , adt_def. did ( ) ) ) ;
13281336 if let Some ( variant_def) = variant_def {
1337+ // FIXME(mgca): do we want constructor resolutions to take priority over
1338+ // other possible resolutions?
1339+ if matches ! ( mode, LowerTypeRelativePathMode :: Const )
1340+ && let Some ( ( CtorKind :: Fn , ctor_def_id) ) = variant_def. ctor
1341+ {
1342+ tcx. check_stability ( variant_def. def_id , Some ( qpath_hir_id) , span, None ) ;
1343+ let _ = self . prohibit_generic_args (
1344+ slice:: from_ref ( segment) . iter ( ) ,
1345+ GenericsArgsErrExtend :: EnumVariant {
1346+ qself : hir_self_ty,
1347+ assoc_segment : segment,
1348+ adt_def,
1349+ } ,
1350+ ) ;
1351+ let ty:: Adt ( _, enum_args) = self_ty. kind ( ) else { unreachable ! ( ) } ;
1352+ return Ok ( TypeRelativePath :: Ctor { ctor_def_id, args : enum_args } ) ;
1353+ }
13291354 if let PermitVariants :: Yes = mode. permit_variants ( ) {
13301355 tcx. check_stability ( variant_def. def_id , Some ( qpath_hir_id) , span, None ) ;
13311356 let _ = self . prohibit_generic_args (
@@ -2266,12 +2291,106 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22662291 hir:: ConstArgKind :: Struct ( qpath, inits) => {
22672292 self . lower_const_arg_struct ( hir_id, qpath, inits, const_arg. span ( ) )
22682293 }
2294+ hir:: ConstArgKind :: TupleCall ( qpath, args) => {
2295+ self . lower_const_arg_tuple_call ( hir_id, qpath, args, const_arg. span ( ) )
2296+ }
22692297 hir:: ConstArgKind :: Anon ( anon) => self . lower_const_arg_anon ( anon) ,
22702298 hir:: ConstArgKind :: Infer ( span, ( ) ) => self . ct_infer ( None , span) ,
22712299 hir:: ConstArgKind :: Error ( _, e) => ty:: Const :: new_error ( tcx, e) ,
22722300 }
22732301 }
22742302
2303+ fn lower_const_arg_tuple_call (
2304+ & self ,
2305+ hir_id : HirId ,
2306+ qpath : hir:: QPath < ' tcx > ,
2307+ args : & ' tcx [ & ' tcx hir:: ConstArg < ' tcx > ] ,
2308+ span : Span ,
2309+ ) -> Const < ' tcx > {
2310+ let tcx = self . tcx ( ) ;
2311+
2312+ let non_adt_or_variant_res = || {
2313+ let e = tcx. dcx ( ) . span_err ( span, "tuple constructor with invalid base path" ) ;
2314+ ty:: Const :: new_error ( tcx, e)
2315+ } ;
2316+
2317+ let ctor_const = match qpath {
2318+ hir:: QPath :: Resolved ( maybe_qself, path) => {
2319+ let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| self . lower_ty ( qself) ) ;
2320+ self . lower_resolved_const_path ( opt_self_ty, path, hir_id)
2321+ }
2322+ hir:: QPath :: TypeRelative ( hir_self_ty, segment) => {
2323+ let self_ty = self . lower_ty ( hir_self_ty) ;
2324+ match self . lower_type_relative_const_path (
2325+ self_ty,
2326+ hir_self_ty,
2327+ segment,
2328+ hir_id,
2329+ span,
2330+ ) {
2331+ Ok ( c) => c,
2332+ Err ( _) => return non_adt_or_variant_res ( ) ,
2333+ }
2334+ }
2335+ } ;
2336+
2337+ let Some ( value) = ctor_const. try_to_value ( ) else {
2338+ return non_adt_or_variant_res ( ) ;
2339+ } ;
2340+
2341+ let ( adt_def, adt_args, variant_did) = match value. ty . kind ( ) {
2342+ ty:: FnDef ( def_id, fn_args)
2343+ if let DefKind :: Ctor ( CtorOf :: Variant , _) = tcx. def_kind ( * def_id) =>
2344+ {
2345+ let parent_did = tcx. parent ( * def_id) ;
2346+ let enum_did = tcx. parent ( parent_did) ;
2347+ ( tcx. adt_def ( enum_did) , fn_args, parent_did)
2348+ }
2349+ ty:: FnDef ( def_id, fn_args)
2350+ if let DefKind :: Ctor ( CtorOf :: Struct , _) = tcx. def_kind ( * def_id) =>
2351+ {
2352+ let parent_did = tcx. parent ( * def_id) ;
2353+ ( tcx. adt_def ( parent_did) , fn_args, parent_did)
2354+ }
2355+ _ => return non_adt_or_variant_res ( ) ,
2356+ } ;
2357+
2358+ let variant_def = adt_def. variant_with_id ( variant_did) ;
2359+ let variant_idx = adt_def. variant_index_with_id ( variant_did) . as_u32 ( ) ;
2360+
2361+ if args. len ( ) != variant_def. fields . len ( ) {
2362+ let e = tcx. dcx ( ) . span_err (
2363+ span,
2364+ format ! (
2365+ "tuple constructor has {} arguments but {} were provided" ,
2366+ variant_def. fields. len( ) ,
2367+ args. len( )
2368+ ) ,
2369+ ) ;
2370+ return ty:: Const :: new_error ( tcx, e) ;
2371+ }
2372+
2373+ let fields = variant_def
2374+ . fields
2375+ . iter ( )
2376+ . zip ( args)
2377+ . map ( |( field_def, arg) | {
2378+ self . lower_const_arg ( arg, FeedConstTy :: Param ( field_def. did , adt_args) )
2379+ } )
2380+ . collect :: < Vec < _ > > ( ) ;
2381+
2382+ let opt_discr_const = if adt_def. is_enum ( ) {
2383+ let valtree = ty:: ValTree :: from_scalar_int ( tcx, variant_idx. into ( ) ) ;
2384+ Some ( ty:: Const :: new_value ( tcx, valtree, tcx. types . u32 ) )
2385+ } else {
2386+ None
2387+ } ;
2388+
2389+ let valtree = ty:: ValTree :: from_branches ( tcx, opt_discr_const. into_iter ( ) . chain ( fields) ) ;
2390+ let adt_ty = Ty :: new_adt ( tcx, adt_def, adt_args) ;
2391+ ty:: Const :: new_value ( tcx, valtree, adt_ty)
2392+ }
2393+
22752394 fn lower_const_arg_struct (
22762395 & self ,
22772396 hir_id : HirId ,
@@ -2403,6 +2522,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24032522 let args = self . lower_generic_args_of_path_segment ( span, did, segment) ;
24042523 ty:: Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( did, args) )
24052524 }
2525+ Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fn ) , did) => {
2526+ assert_eq ! ( opt_self_ty, None ) ;
2527+ let [ leading_segments @ .., segment] = path. segments else { bug ! ( ) } ;
2528+ let _ = self
2529+ . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
2530+ let parent_did = tcx. parent ( did) ;
2531+ let generics_did = if let DefKind :: Ctor ( CtorOf :: Variant , _) = tcx. def_kind ( did) {
2532+ tcx. parent ( parent_did)
2533+ } else {
2534+ parent_did
2535+ } ;
2536+ let args = self . lower_generic_args_of_path_segment ( span, generics_did, segment) ;
2537+ ty:: Const :: zero_sized ( tcx, Ty :: new_fn_def ( tcx, did, args) )
2538+ }
24062539 Res :: Def ( DefKind :: AssocConst , did) => {
24072540 let trait_segment = if let [ modules @ .., trait_, _item] = path. segments {
24082541 let _ = self . prohibit_generic_args ( modules. iter ( ) , GenericsArgsErrExtend :: None ) ;
@@ -2438,9 +2571,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24382571 DefKind :: Mod
24392572 | DefKind :: Enum
24402573 | DefKind :: Variant
2441- | DefKind :: Ctor ( CtorOf :: Variant , CtorKind :: Fn )
24422574 | DefKind :: Struct
2443- | DefKind :: Ctor ( CtorOf :: Struct , CtorKind :: Fn )
24442575 | DefKind :: OpaqueTy
24452576 | DefKind :: TyAlias
24462577 | DefKind :: TraitAlias
0 commit comments