@@ -125,8 +125,8 @@ enum ConvertedBindingKind<'a, 'tcx> {
125125 Constraint ( & ' a [ hir:: GenericBound < ' a > ] ) ,
126126}
127127
128- #[ derive( PartialEq ) ]
129- enum GenericArgPosition {
128+ #[ derive( PartialEq , Debug ) ]
129+ pub enum GenericArgPosition {
130130 Type ,
131131 Value , // e.g., functions
132132 MethodCall ,
@@ -195,6 +195,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
195195 span : Span ,
196196 def_id : DefId ,
197197 item_segment : & hir:: PathSegment < ' _ > ,
198+ generic_arg_position : GenericArgPosition ,
198199 ) -> SubstsRef < ' tcx > {
199200 let ( substs, assoc_bindings, _) = self . create_substs_for_ast_path (
200201 span,
@@ -203,6 +204,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
203204 item_segment. generic_args ( ) ,
204205 item_segment. infer_args ,
205206 None ,
207+ generic_arg_position,
206208 ) ;
207209
208210 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 {
630632 generic_args : & ' a hir:: GenericArgs < ' _ > ,
631633 infer_args : bool ,
632634 self_ty : Option < Ty < ' tcx > > ,
635+ generic_arg_position : GenericArgPosition ,
633636 ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Option < Vec < Span > > ) {
634637 // If the type is parameterized by this region, then replace this
635638 // region with the current anon region binding (in other words,
@@ -661,7 +664,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
661664 span,
662665 & generic_params,
663666 & generic_args,
664- GenericArgPosition :: Type ,
667+ generic_arg_position ,
665668 self_ty. is_some ( ) ,
666669 infer_args,
667670 ) ;
@@ -804,6 +807,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
804807 item_def_id : DefId ,
805808 item_segment : & hir:: PathSegment < ' _ > ,
806809 parent_substs : SubstsRef < ' tcx > ,
810+ generic_arg_position : GenericArgPosition ,
807811 ) -> SubstsRef < ' tcx > {
808812 if tcx. generics_of ( item_def_id) . params . is_empty ( ) {
809813 self . prohibit_generics ( slice:: from_ref ( item_segment) ) ;
@@ -817,6 +821,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
817821 item_segment. generic_args ( ) ,
818822 item_segment. infer_args ,
819823 None ,
824+ generic_arg_position,
820825 )
821826 . 0
822827 }
@@ -1100,6 +1105,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11001105 trait_segment. generic_args ( ) ,
11011106 trait_segment. infer_args ,
11021107 Some ( self_ty) ,
1108+ GenericArgPosition :: Type ,
11031109 )
11041110 }
11051111
@@ -1416,8 +1422,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14161422 span : Span ,
14171423 did : DefId ,
14181424 item_segment : & hir:: PathSegment < ' _ > ,
1425+ generic_arg_position : GenericArgPosition ,
14191426 ) -> 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 ) ;
14211428 self . normalize_ty ( span, self . tcx ( ) . at ( span) . type_of ( did) . subst ( self . tcx ( ) , substs) )
14221429 }
14231430
@@ -2253,6 +2260,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22532260 item_def_id : DefId ,
22542261 trait_segment : & hir:: PathSegment < ' _ > ,
22552262 item_segment : & hir:: PathSegment < ' _ > ,
2263+ generic_arg_position : GenericArgPosition ,
22562264 ) -> Ty < ' tcx > {
22572265 let tcx = self . tcx ( ) ;
22582266
@@ -2305,13 +2313,36 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
23052313 item_def_id,
23062314 item_segment,
23072315 trait_ref. substs ,
2316+ generic_arg_position,
23082317 ) ;
23092318
23102319 debug ! ( "qpath_to_ty: trait_ref={:?}" , trait_ref) ;
23112320
23122321 self . normalize_ty ( span, tcx. mk_projection ( item_def_id, item_substs) )
23132322 }
23142323
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+
23152346 pub fn prohibit_generics < ' a , T : IntoIterator < Item = & ' a hir:: PathSegment < ' a > > > (
23162347 & self ,
23172348 segments : T ,
@@ -2509,13 +2540,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25092540 & self ,
25102541 opt_self_ty : Option < Ty < ' tcx > > ,
25112542 path : & hir:: Path < ' _ > ,
2512- permit_variants : bool ,
2543+ generic_arg_position : GenericArgPosition ,
25132544 ) -> Ty < ' tcx > {
25142545 let tcx = self . tcx ( ) ;
25152546
25162547 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
25192550 ) ;
25202551
25212552 let span = path. span ;
@@ -2525,7 +2556,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25252556 assert ! ( ty:: is_impl_trait_defn( tcx, did) . is_none( ) ) ;
25262557 let item_segment = path. segments . split_last ( ) . unwrap ( ) ;
25272558 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) ;
25292561 self . normalize_ty ( span, tcx. mk_opaque ( did, substs) )
25302562 }
25312563 Res :: Def ( DefKind :: Enum , did)
@@ -2535,9 +2567,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25352567 | Res :: Def ( DefKind :: ForeignTy , did) => {
25362568 assert_eq ! ( opt_self_ty, None ) ;
25372569 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 )
25392571 }
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+ {
25412575 // Convert "variant type" as if it were a real type.
25422576 // The resulting `Ty` is type of the variant's enum for now.
25432577 assert_eq ! ( opt_self_ty, None ) ;
@@ -2546,14 +2580,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25462580 self . def_ids_for_value_path_segments ( & path. segments , None , kind, def_id) ;
25472581 let generic_segs: FxHashSet < _ > =
25482582 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+ }
25542591
25552592 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 )
25572594 }
25582595 Res :: Def ( DefKind :: TyParam , def_id) => {
25592596 assert_eq ! ( opt_self_ty, None ) ;
@@ -2588,6 +2625,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25882625 def_id,
25892626 & path. segments [ path. segments . len ( ) - 2 ] ,
25902627 path. segments . last ( ) . unwrap ( ) ,
2628+ generic_arg_position,
25912629 )
25922630 }
25932631 Res :: PrimTy ( prim_ty) => {
@@ -2642,7 +2680,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
26422680 hir:: TyKind :: Path ( hir:: QPath :: Resolved ( ref maybe_qself, ref path) ) => {
26432681 debug ! ( "ast_ty_to_ty: maybe_qself={:?} path={:?}" , maybe_qself, path) ;
26442682 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 )
26462684 }
26472685 hir:: TyKind :: Def ( item_id, ref lifetimes) => {
26482686 let did = tcx. hir ( ) . local_def_id ( item_id. id ) ;
0 commit comments