@@ -88,6 +88,7 @@ pub trait AstConv<'tcx> {
8888 fn projected_ty_from_poly_trait_ref ( & self ,
8989 span : Span ,
9090 item_def_id : DefId ,
91+ item_segment : & hir:: PathSegment ,
9192 poly_trait_ref : ty:: PolyTraitRef < ' tcx > )
9293 -> Ty < ' tcx > ;
9394
@@ -205,6 +206,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
205206 let ( substs, assoc_bindings, _) = self . create_substs_for_ast_path (
206207 span,
207208 def_id,
209+ & [ ] ,
208210 item_segment. generic_args ( ) ,
209211 item_segment. infer_args ,
210212 None ,
@@ -615,9 +617,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
615617 /// `Output = u32` are returned in the `Vec<ConvertedBinding...>` result.
616618 ///
617619 /// Note that the type listing given here is *exactly* what the user provided.
620+ ///
621+ /// For (generic) associated types
622+ ///
623+ /// ```
624+ /// <Vec<u8> as Iterable<u8>>::Iter::<'a>
625+ /// ```
626+ ///
627+ /// We have the parent substs are the substs for the parent trait:
628+ /// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated
629+ /// type itself: `['a]`. The returned `SubstsRef` concatenates these two
630+ /// lists: `[Vec<u8>, u8, 'a]`.
618631 fn create_substs_for_ast_path < ' a > ( & self ,
619632 span : Span ,
620633 def_id : DefId ,
634+ parent_substs : & [ subst:: GenericArg < ' tcx > ] ,
621635 generic_args : & ' a hir:: GenericArgs ,
622636 infer_args : bool ,
623637 self_ty : Option < Ty < ' tcx > > )
@@ -633,17 +647,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
633647 let tcx = self . tcx ( ) ;
634648 let generic_params = tcx. generics_of ( def_id) ;
635649
636- // If a self-type was declared, one should be provided.
637- assert_eq ! ( generic_params. has_self, self_ty. is_some( ) ) ;
650+ if generic_params. has_self {
651+ if generic_params. parent . is_some ( ) {
652+ // The parent is a trait so it should have at least one subst
653+ // for the `Self` type.
654+ assert ! ( !parent_substs. is_empty( ) )
655+ } else {
656+ // This item (presumably a trait) needs a self-type.
657+ assert ! ( self_ty. is_some( ) ) ;
658+ }
659+ } else {
660+ assert ! ( self_ty. is_none( ) && parent_substs. is_empty( ) ) ;
661+ }
638662
639- let has_self = generic_params. has_self ;
640663 let ( _, potential_assoc_types) = Self :: check_generic_arg_count (
641664 tcx,
642665 span,
643666 & generic_params,
644667 & generic_args,
645668 GenericArgPosition :: Type ,
646- has_self ,
669+ self_ty . is_some ( ) ,
647670 infer_args,
648671 ) ;
649672
@@ -652,7 +675,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
652675 } ) ;
653676 let default_needs_object_self = |param : & ty:: GenericParamDef | {
654677 if let GenericParamDefKind :: Type { has_default, .. } = param. kind {
655- if is_object && has_default && has_self {
678+ if is_object && has_default {
656679 let self_param = tcx. types . self_param ;
657680 if tcx. at ( span) . type_of ( param. def_id ) . walk ( ) . any ( |ty| ty == self_param) {
658681 // There is no suitable inference default for a type parameter
@@ -668,7 +691,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
668691 let substs = Self :: create_substs_for_generic_args (
669692 tcx,
670693 def_id,
671- & [ ] [ .. ] ,
694+ parent_substs ,
672695 self_ty. is_some ( ) ,
673696 self_ty,
674697 // Provide the generic args, and whether types should be inferred.
@@ -780,6 +803,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
780803 ( substs, assoc_bindings, potential_assoc_types)
781804 }
782805
806+ crate fn create_substs_for_associated_item (
807+ & self ,
808+ tcx : TyCtxt < ' tcx > ,
809+ span : Span ,
810+ item_def_id : DefId ,
811+ item_segment : & hir:: PathSegment ,
812+ parent_substs : SubstsRef < ' tcx > ,
813+ ) -> SubstsRef < ' tcx > {
814+ if tcx. generics_of ( item_def_id) . params . is_empty ( ) {
815+ self . prohibit_generics ( slice:: from_ref ( item_segment) ) ;
816+
817+ parent_substs
818+ } else {
819+ self . create_substs_for_ast_path (
820+ span,
821+ item_def_id,
822+ parent_substs,
823+ item_segment. generic_args ( ) ,
824+ item_segment. infer_args ,
825+ None ,
826+ ) . 0
827+ }
828+ }
829+
783830 /// Instantiates the path for the given trait reference, assuming that it's
784831 /// bound to a valid trait type. Returns the `DefId` of the defining trait.
785832 /// The type _cannot_ be a type other than a trait type.
@@ -919,6 +966,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
919966
920967 self . create_substs_for_ast_path ( span,
921968 trait_def_id,
969+ & [ ] ,
922970 trait_segment. generic_args ( ) ,
923971 trait_segment. infer_args ,
924972 Some ( self_ty) )
@@ -1665,8 +1713,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16651713
16661714 debug ! ( "associated_path_to_ty: {:?}::{}" , qself_ty, assoc_ident) ;
16671715
1668- self . prohibit_generics ( slice:: from_ref ( assoc_segment) ) ;
1669-
16701716 // Check if we have an enum variant.
16711717 let mut variant_resolution = None ;
16721718 if let ty:: Adt ( adt_def, _) = qself_ty. kind {
@@ -1677,6 +1723,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16771723 if let Some ( variant_def) = variant_def {
16781724 if permit_variants {
16791725 tcx. check_stability ( variant_def. def_id , Some ( hir_ref_id) , span) ;
1726+ self . prohibit_generics ( slice:: from_ref ( assoc_segment) ) ;
16801727 return Ok ( ( qself_ty, DefKind :: Variant , variant_def. def_id ) ) ;
16811728 } else {
16821729 variant_resolution = Some ( variant_def. def_id ) ;
@@ -1767,7 +1814,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
17671814 i. ident . modern ( ) == assoc_ident
17681815 } ) . expect ( "missing associated type" ) ;
17691816
1770- let ty = self . projected_ty_from_poly_trait_ref ( span, item. def_id , bound) ;
1817+ let ty = self . projected_ty_from_poly_trait_ref ( span, item. def_id , assoc_segment , bound) ;
17711818 let ty = self . normalize_ty ( span, ty) ;
17721819
17731820 let kind = DefKind :: AssocTy ;
@@ -1818,8 +1865,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
18181865
18191866 debug ! ( "qpath_to_ty: trait_def_id={:?}" , trait_def_id) ;
18201867
1821- self . prohibit_generics ( slice:: from_ref ( item_segment) ) ;
1822-
18231868 let self_ty = if let Some ( ty) = opt_self_ty {
18241869 ty
18251870 } else {
@@ -1861,9 +1906,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
18611906 self_ty,
18621907 trait_segment) ;
18631908
1909+ let item_substs = self . create_substs_for_associated_item (
1910+ tcx,
1911+ span,
1912+ item_def_id,
1913+ item_segment,
1914+ trait_ref. substs ,
1915+ ) ;
1916+
18641917 debug ! ( "qpath_to_ty: trait_ref={:?}" , trait_ref) ;
18651918
1866- self . normalize_ty ( span, tcx. mk_projection ( item_def_id, trait_ref . substs ) )
1919+ self . normalize_ty ( span, tcx. mk_projection ( item_def_id, item_substs ) )
18671920 }
18681921
18691922 pub fn prohibit_generics < ' a , T : IntoIterator < Item = & ' a hir:: PathSegment > > (
@@ -2518,21 +2571,22 @@ impl<'tcx> Bounds<'tcx> {
25182571 // If it could be sized, and is, add the `Sized` predicate.
25192572 let sized_predicate = self . implicitly_sized . and_then ( |span| {
25202573 tcx. lang_items ( ) . sized_trait ( ) . map ( |sized| {
2521- let trait_ref = ty:: TraitRef {
2574+ let trait_ref = ty:: Binder :: bind ( ty :: TraitRef {
25222575 def_id : sized,
25232576 substs : tcx. mk_substs_trait ( param_ty, & [ ] )
2524- } ;
2577+ } ) ;
25252578 ( trait_ref. to_predicate ( ) , span)
25262579 } )
25272580 } ) ;
25282581
25292582 sized_predicate. into_iter ( ) . chain (
25302583 self . region_bounds . iter ( ) . map ( |& ( region_bound, span) | {
25312584 // Account for the binder being introduced below; no need to shift `param_ty`
2532- // because, at present at least, it can only refer to early-bound regions.
2585+ // because, at present at least, it either only refers to early-bound regions,
2586+ // or it's a generic associated type that deliberately has escaping bound vars.
25332587 let region_bound = ty:: fold:: shift_region ( tcx, region_bound, 1 ) ;
25342588 let outlives = ty:: OutlivesPredicate ( param_ty, region_bound) ;
2535- ( ty:: Binder :: dummy ( outlives) . to_predicate ( ) , span)
2589+ ( ty:: Binder :: bind ( outlives) . to_predicate ( ) , span)
25362590 } ) . chain (
25372591 self . trait_bounds . iter ( ) . map ( |& ( bound_trait_ref, span) | {
25382592 ( bound_trait_ref. to_predicate ( ) , span)
0 commit comments