@@ -125,8 +125,8 @@ enum ConvertedBindingKind<'a, 'tcx> {
125
125
Constraint ( & ' a [ hir:: GenericBound < ' a > ] ) ,
126
126
}
127
127
128
- #[ derive( PartialEq ) ]
129
- enum GenericArgPosition {
128
+ #[ derive( PartialEq , Debug ) ]
129
+ pub enum GenericArgPosition {
130
130
Type ,
131
131
Value , // e.g., functions
132
132
MethodCall ,
@@ -195,6 +195,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
195
195
span : Span ,
196
196
def_id : DefId ,
197
197
item_segment : & hir:: PathSegment < ' _ > ,
198
+ generic_arg_position : GenericArgPosition ,
198
199
) -> SubstsRef < ' tcx > {
199
200
let ( substs, assoc_bindings, _) = self . create_substs_for_ast_path (
200
201
span,
@@ -203,6 +204,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
203
204
item_segment. generic_args ( ) ,
204
205
item_segment. infer_args ,
205
206
None ,
207
+ generic_arg_position,
206
208
) ;
207
209
208
210
assoc_bindings. first ( ) . map ( |b| Self :: prohibit_assoc_ty_binding ( self . tcx ( ) , b. span ) ) ;
@@ -630,6 +632,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
630
632
generic_args : & ' a hir:: GenericArgs < ' _ > ,
631
633
infer_args : bool ,
632
634
self_ty : Option < Ty < ' tcx > > ,
635
+ generic_arg_position : GenericArgPosition ,
633
636
) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Option < Vec < Span > > ) {
634
637
// If the type is parameterized by this region, then replace this
635
638
// region with the current anon region binding (in other words,
@@ -661,7 +664,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
661
664
span,
662
665
& generic_params,
663
666
& generic_args,
664
- GenericArgPosition :: Type ,
667
+ generic_arg_position ,
665
668
self_ty. is_some ( ) ,
666
669
infer_args,
667
670
) ;
@@ -804,6 +807,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
804
807
item_def_id : DefId ,
805
808
item_segment : & hir:: PathSegment < ' _ > ,
806
809
parent_substs : SubstsRef < ' tcx > ,
810
+ generic_arg_position : GenericArgPosition ,
807
811
) -> SubstsRef < ' tcx > {
808
812
if tcx. generics_of ( item_def_id) . params . is_empty ( ) {
809
813
self . prohibit_generics ( slice:: from_ref ( item_segment) ) ;
@@ -817,6 +821,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
817
821
item_segment. generic_args ( ) ,
818
822
item_segment. infer_args ,
819
823
None ,
824
+ generic_arg_position,
820
825
)
821
826
. 0
822
827
}
@@ -1100,6 +1105,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1100
1105
trait_segment. generic_args ( ) ,
1101
1106
trait_segment. infer_args ,
1102
1107
Some ( self_ty) ,
1108
+ GenericArgPosition :: Type ,
1103
1109
)
1104
1110
}
1105
1111
@@ -1416,8 +1422,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1416
1422
span : Span ,
1417
1423
did : DefId ,
1418
1424
item_segment : & hir:: PathSegment < ' _ > ,
1425
+ generic_arg_position : GenericArgPosition ,
1419
1426
) -> Ty < ' tcx > {
1420
- let substs = self . ast_path_substs_for_ty ( span, did, item_segment) ;
1427
+ let substs = self . ast_path_substs_for_ty ( span, did, item_segment, generic_arg_position ) ;
1421
1428
self . normalize_ty ( span, self . tcx ( ) . at ( span) . type_of ( did) . subst ( self . tcx ( ) , substs) )
1422
1429
}
1423
1430
@@ -2253,6 +2260,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2253
2260
item_def_id : DefId ,
2254
2261
trait_segment : & hir:: PathSegment < ' _ > ,
2255
2262
item_segment : & hir:: PathSegment < ' _ > ,
2263
+ generic_arg_position : GenericArgPosition ,
2256
2264
) -> Ty < ' tcx > {
2257
2265
let tcx = self . tcx ( ) ;
2258
2266
@@ -2305,13 +2313,36 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2305
2313
item_def_id,
2306
2314
item_segment,
2307
2315
trait_ref. substs ,
2316
+ generic_arg_position,
2308
2317
) ;
2309
2318
2310
2319
debug ! ( "qpath_to_ty: trait_ref={:?}" , trait_ref) ;
2311
2320
2312
2321
self . normalize_ty ( span, tcx. mk_projection ( item_def_id, item_substs) )
2313
2322
}
2314
2323
2324
+ pub fn prohibit_multiple_params < ' a , T : IntoIterator < Item = & ' a hir:: PathSegment < ' a > > > (
2325
+ & self ,
2326
+ segments : T ,
2327
+ ) -> bool {
2328
+ let segments_with_params = segments
2329
+ . into_iter ( )
2330
+ . filter_map ( |segment| segment. args . map ( |_| segment. ident . span ) )
2331
+ . collect :: < Vec < _ > > ( ) ;
2332
+ if segments_with_params. len ( ) <= 1 {
2333
+ return false ;
2334
+ }
2335
+ self . tcx ( )
2336
+ . sess
2337
+ . struct_span_err (
2338
+ segments_with_params,
2339
+ "multiple segments with type parameters are not allowed" ,
2340
+ )
2341
+ . note ( "only a single path segment can specify type parameters" )
2342
+ . emit ( ) ;
2343
+ true
2344
+ }
2345
+
2315
2346
pub fn prohibit_generics < ' a , T : IntoIterator < Item = & ' a hir:: PathSegment < ' a > > > (
2316
2347
& self ,
2317
2348
segments : T ,
@@ -2509,13 +2540,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2509
2540
& self ,
2510
2541
opt_self_ty : Option < Ty < ' tcx > > ,
2511
2542
path : & hir:: Path < ' _ > ,
2512
- permit_variants : bool ,
2543
+ generic_arg_position : GenericArgPosition ,
2513
2544
) -> Ty < ' tcx > {
2514
2545
let tcx = self . tcx ( ) ;
2515
2546
2516
2547
debug ! (
2517
- "res_to_ty(res={:?}, opt_self_ty={:?}, path_segments={:?})" ,
2518
- path. res, opt_self_ty, path. segments
2548
+ "res_to_ty(res={:?}, opt_self_ty={:?}, path_segments={:?} generic_arg_pos={:?} )" ,
2549
+ path. res, opt_self_ty, path. segments, generic_arg_position
2519
2550
) ;
2520
2551
2521
2552
let span = path. span ;
@@ -2525,7 +2556,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2525
2556
assert ! ( ty:: is_impl_trait_defn( tcx, did) . is_none( ) ) ;
2526
2557
let item_segment = path. segments . split_last ( ) . unwrap ( ) ;
2527
2558
self . prohibit_generics ( item_segment. 1 ) ;
2528
- let substs = self . ast_path_substs_for_ty ( span, did, item_segment. 0 ) ;
2559
+ let substs =
2560
+ self . ast_path_substs_for_ty ( span, did, item_segment. 0 , generic_arg_position) ;
2529
2561
self . normalize_ty ( span, tcx. mk_opaque ( did, substs) )
2530
2562
}
2531
2563
Res :: Def ( DefKind :: Enum , did)
@@ -2535,9 +2567,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2535
2567
| Res :: Def ( DefKind :: ForeignTy , did) => {
2536
2568
assert_eq ! ( opt_self_ty, None ) ;
2537
2569
self . prohibit_generics ( path. segments . split_last ( ) . unwrap ( ) . 1 ) ;
2538
- self . ast_path_to_ty ( span, did, path. segments . last ( ) . unwrap ( ) )
2570
+ self . ast_path_to_ty ( span, did, path. segments . last ( ) . unwrap ( ) , generic_arg_position )
2539
2571
}
2540
- Res :: Def ( kind @ DefKind :: Variant , def_id) if permit_variants => {
2572
+ Res :: Def ( kind @ DefKind :: Variant , def_id)
2573
+ if generic_arg_position == GenericArgPosition :: Value =>
2574
+ {
2541
2575
// Convert "variant type" as if it were a real type.
2542
2576
// The resulting `Ty` is type of the variant's enum for now.
2543
2577
assert_eq ! ( opt_self_ty, None ) ;
@@ -2546,14 +2580,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2546
2580
self . def_ids_for_value_path_segments ( & path. segments , None , kind, def_id) ;
2547
2581
let generic_segs: FxHashSet < _ > =
2548
2582
path_segs. iter ( ) . map ( |PathSeg ( _, index) | index) . collect ( ) ;
2549
- self . prohibit_generics ( path. segments . iter ( ) . enumerate ( ) . filter_map (
2550
- |( index, seg) | {
2551
- if !generic_segs. contains ( & index) { Some ( seg) } else { None }
2552
- } ,
2553
- ) ) ;
2583
+
2584
+ if !self . prohibit_multiple_params ( path. segments . iter ( ) ) {
2585
+ self . prohibit_generics ( path. segments . iter ( ) . enumerate ( ) . filter_map (
2586
+ |( index, seg) | {
2587
+ if !generic_segs. contains ( & index) { Some ( seg) } else { None }
2588
+ } ,
2589
+ ) ) ;
2590
+ }
2554
2591
2555
2592
let PathSeg ( def_id, index) = path_segs. last ( ) . unwrap ( ) ;
2556
- self . ast_path_to_ty ( span, * def_id, & path. segments [ * index] )
2593
+ self . ast_path_to_ty ( span, * def_id, & path. segments [ * index] , generic_arg_position )
2557
2594
}
2558
2595
Res :: Def ( DefKind :: TyParam , def_id) => {
2559
2596
assert_eq ! ( opt_self_ty, None ) ;
@@ -2588,6 +2625,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2588
2625
def_id,
2589
2626
& path. segments [ path. segments . len ( ) - 2 ] ,
2590
2627
path. segments . last ( ) . unwrap ( ) ,
2628
+ generic_arg_position,
2591
2629
)
2592
2630
}
2593
2631
Res :: PrimTy ( prim_ty) => {
@@ -2642,7 +2680,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2642
2680
hir:: TyKind :: Path ( hir:: QPath :: Resolved ( ref maybe_qself, ref path) ) => {
2643
2681
debug ! ( "ast_ty_to_ty: maybe_qself={:?} path={:?}" , maybe_qself, path) ;
2644
2682
let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| self . ast_ty_to_ty ( qself) ) ;
2645
- self . res_to_ty ( opt_self_ty, path, false )
2683
+ self . res_to_ty ( opt_self_ty, path, GenericArgPosition :: Type )
2646
2684
}
2647
2685
hir:: TyKind :: Def ( item_id, ref lifetimes) => {
2648
2686
let did = tcx. hir ( ) . local_def_id ( item_id. id ) ;
0 commit comments