@@ -88,6 +88,7 @@ pub trait AstConv<'tcx> {
88
88
fn projected_ty_from_poly_trait_ref ( & self ,
89
89
span : Span ,
90
90
item_def_id : DefId ,
91
+ item_segment : & hir:: PathSegment ,
91
92
poly_trait_ref : ty:: PolyTraitRef < ' tcx > )
92
93
-> Ty < ' tcx > ;
93
94
@@ -205,6 +206,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
205
206
let ( substs, assoc_bindings, _) = self . create_substs_for_ast_path (
206
207
span,
207
208
def_id,
209
+ & [ ] ,
208
210
item_segment. generic_args ( ) ,
209
211
item_segment. infer_args ,
210
212
None ,
@@ -615,9 +617,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
615
617
/// `Output = u32` are returned in the `Vec<ConvertedBinding...>` result.
616
618
///
617
619
/// 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]`.
618
631
fn create_substs_for_ast_path < ' a > ( & self ,
619
632
span : Span ,
620
633
def_id : DefId ,
634
+ parent_substs : & [ subst:: GenericArg < ' tcx > ] ,
621
635
generic_args : & ' a hir:: GenericArgs ,
622
636
infer_args : bool ,
623
637
self_ty : Option < Ty < ' tcx > > )
@@ -633,17 +647,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
633
647
let tcx = self . tcx ( ) ;
634
648
let generic_params = tcx. generics_of ( def_id) ;
635
649
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
+ }
638
662
639
- let has_self = generic_params. has_self ;
640
663
let ( _, potential_assoc_types) = Self :: check_generic_arg_count (
641
664
tcx,
642
665
span,
643
666
& generic_params,
644
667
& generic_args,
645
668
GenericArgPosition :: Type ,
646
- has_self ,
669
+ self_ty . is_some ( ) ,
647
670
infer_args,
648
671
) ;
649
672
@@ -652,7 +675,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
652
675
} ) ;
653
676
let default_needs_object_self = |param : & ty:: GenericParamDef | {
654
677
if let GenericParamDefKind :: Type { has_default, .. } = param. kind {
655
- if is_object && has_default && has_self {
678
+ if is_object && has_default {
656
679
let self_param = tcx. types . self_param ;
657
680
if tcx. at ( span) . type_of ( param. def_id ) . walk ( ) . any ( |ty| ty == self_param) {
658
681
// There is no suitable inference default for a type parameter
@@ -668,7 +691,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
668
691
let substs = Self :: create_substs_for_generic_args (
669
692
tcx,
670
693
def_id,
671
- & [ ] [ .. ] ,
694
+ parent_substs ,
672
695
self_ty. is_some ( ) ,
673
696
self_ty,
674
697
// Provide the generic args, and whether types should be inferred.
@@ -780,6 +803,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
780
803
( substs, assoc_bindings, potential_assoc_types)
781
804
}
782
805
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
+
783
830
/// Instantiates the path for the given trait reference, assuming that it's
784
831
/// bound to a valid trait type. Returns the `DefId` of the defining trait.
785
832
/// The type _cannot_ be a type other than a trait type.
@@ -919,6 +966,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
919
966
920
967
self . create_substs_for_ast_path ( span,
921
968
trait_def_id,
969
+ & [ ] ,
922
970
trait_segment. generic_args ( ) ,
923
971
trait_segment. infer_args ,
924
972
Some ( self_ty) )
@@ -1665,8 +1713,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1665
1713
1666
1714
debug ! ( "associated_path_to_ty: {:?}::{}" , qself_ty, assoc_ident) ;
1667
1715
1668
- self . prohibit_generics ( slice:: from_ref ( assoc_segment) ) ;
1669
-
1670
1716
// Check if we have an enum variant.
1671
1717
let mut variant_resolution = None ;
1672
1718
if let ty:: Adt ( adt_def, _) = qself_ty. kind {
@@ -1677,6 +1723,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1677
1723
if let Some ( variant_def) = variant_def {
1678
1724
if permit_variants {
1679
1725
tcx. check_stability ( variant_def. def_id , Some ( hir_ref_id) , span) ;
1726
+ self . prohibit_generics ( slice:: from_ref ( assoc_segment) ) ;
1680
1727
return Ok ( ( qself_ty, DefKind :: Variant , variant_def. def_id ) ) ;
1681
1728
} else {
1682
1729
variant_resolution = Some ( variant_def. def_id ) ;
@@ -1767,7 +1814,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1767
1814
i. ident . modern ( ) == assoc_ident
1768
1815
} ) . expect ( "missing associated type" ) ;
1769
1816
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) ;
1771
1818
let ty = self . normalize_ty ( span, ty) ;
1772
1819
1773
1820
let kind = DefKind :: AssocTy ;
@@ -1818,8 +1865,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1818
1865
1819
1866
debug ! ( "qpath_to_ty: trait_def_id={:?}" , trait_def_id) ;
1820
1867
1821
- self . prohibit_generics ( slice:: from_ref ( item_segment) ) ;
1822
-
1823
1868
let self_ty = if let Some ( ty) = opt_self_ty {
1824
1869
ty
1825
1870
} else {
@@ -1861,9 +1906,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1861
1906
self_ty,
1862
1907
trait_segment) ;
1863
1908
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
+
1864
1917
debug ! ( "qpath_to_ty: trait_ref={:?}" , trait_ref) ;
1865
1918
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 ) )
1867
1920
}
1868
1921
1869
1922
pub fn prohibit_generics < ' a , T : IntoIterator < Item = & ' a hir:: PathSegment > > (
@@ -2518,21 +2571,22 @@ impl<'tcx> Bounds<'tcx> {
2518
2571
// If it could be sized, and is, add the `Sized` predicate.
2519
2572
let sized_predicate = self . implicitly_sized . and_then ( |span| {
2520
2573
tcx. lang_items ( ) . sized_trait ( ) . map ( |sized| {
2521
- let trait_ref = ty:: TraitRef {
2574
+ let trait_ref = ty:: Binder :: bind ( ty :: TraitRef {
2522
2575
def_id : sized,
2523
2576
substs : tcx. mk_substs_trait ( param_ty, & [ ] )
2524
- } ;
2577
+ } ) ;
2525
2578
( trait_ref. to_predicate ( ) , span)
2526
2579
} )
2527
2580
} ) ;
2528
2581
2529
2582
sized_predicate. into_iter ( ) . chain (
2530
2583
self . region_bounds . iter ( ) . map ( |& ( region_bound, span) | {
2531
2584
// 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.
2533
2587
let region_bound = ty:: fold:: shift_region ( tcx, region_bound, 1 ) ;
2534
2588
let outlives = ty:: OutlivesPredicate ( param_ty, region_bound) ;
2535
- ( ty:: Binder :: dummy ( outlives) . to_predicate ( ) , span)
2589
+ ( ty:: Binder :: bind ( outlives) . to_predicate ( ) , span)
2536
2590
} ) . chain (
2537
2591
self . trait_bounds . iter ( ) . map ( |& ( bound_trait_ref, span) | {
2538
2592
( bound_trait_ref. to_predicate ( ) , span)
0 commit comments