@@ -17,7 +17,7 @@ use rustc_hir as hir;
17
17
use rustc_hir:: def_id:: DefId ;
18
18
use rustc_index:: vec:: Idx ;
19
19
use rustc_macros:: HashStable ;
20
- use rustc_span:: symbol:: { kw, Ident , Symbol } ;
20
+ use rustc_span:: symbol:: { kw, Symbol } ;
21
21
use rustc_target:: abi:: VariantIdx ;
22
22
use rustc_target:: spec:: abi;
23
23
use std:: borrow:: Cow ;
@@ -1112,36 +1112,35 @@ pub struct ProjectionTy<'tcx> {
1112
1112
}
1113
1113
1114
1114
impl < ' tcx > ProjectionTy < ' tcx > {
1115
- /// Construct a `ProjectionTy` by searching the trait from `trait_ref` for the
1116
- /// associated item named `item_name`.
1117
- pub fn from_ref_and_name (
1118
- tcx : TyCtxt < ' _ > ,
1119
- trait_ref : ty:: TraitRef < ' tcx > ,
1120
- item_name : Ident ,
1121
- ) -> ProjectionTy < ' tcx > {
1122
- let item_def_id = tcx
1123
- . associated_items ( trait_ref. def_id )
1124
- . find_by_name_and_kind ( tcx, item_name, ty:: AssocKind :: Type , trait_ref. def_id )
1125
- . unwrap ( )
1126
- . def_id ;
1115
+ pub fn trait_def_id ( & self , tcx : TyCtxt < ' tcx > ) -> DefId {
1116
+ tcx. associated_item ( self . item_def_id ) . container . id ( )
1117
+ }
1127
1118
1128
- ProjectionTy { substs : trait_ref. substs , item_def_id }
1119
+ /// Extracts the underlying trait reference and own substs from this projection.
1120
+ /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
1121
+ /// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs
1122
+ pub fn trait_ref_and_own_substs (
1123
+ & self ,
1124
+ tcx : TyCtxt < ' tcx > ,
1125
+ ) -> ( ty:: TraitRef < ' tcx > , & ' tcx [ ty:: GenericArg < ' tcx > ] ) {
1126
+ let def_id = tcx. associated_item ( self . item_def_id ) . container . id ( ) ;
1127
+ let trait_generics = tcx. generics_of ( def_id) ;
1128
+ (
1129
+ ty:: TraitRef { def_id, substs : self . substs . truncate_to ( tcx, trait_generics) } ,
1130
+ & self . substs [ trait_generics. count ( ) ..] ,
1131
+ )
1129
1132
}
1130
1133
1131
1134
/// Extracts the underlying trait reference from this projection.
1132
1135
/// For example, if this is a projection of `<T as Iterator>::Item`,
1133
1136
/// then this function would return a `T: Iterator` trait reference.
1137
+ ///
1138
+ /// WARNING: This will drop the substs for generic associated types
1139
+ /// consider calling [Self::trait_ref_and_own_substs] to get those
1140
+ /// as well.
1134
1141
pub fn trait_ref ( & self , tcx : TyCtxt < ' tcx > ) -> ty:: TraitRef < ' tcx > {
1135
- // FIXME: This method probably shouldn't exist at all, since it's not
1136
- // clear what this method really intends to do. Be careful when
1137
- // using this method since the resulting TraitRef additionally
1138
- // contains the substs for the assoc_item, which strictly speaking
1139
- // is not correct
1140
- let def_id = tcx. associated_item ( self . item_def_id ) . container . id ( ) ;
1141
- // Include substitutions for generic arguments of associated types
1142
- let assoc_item = tcx. associated_item ( self . item_def_id ) ;
1143
- let substs_assoc_item = self . substs . truncate_to ( tcx, tcx. generics_of ( assoc_item. def_id ) ) ;
1144
- ty:: TraitRef { def_id, substs : substs_assoc_item }
1142
+ let def_id = self . trait_def_id ( tcx) ;
1143
+ ty:: TraitRef { def_id, substs : self . substs . truncate_to ( tcx, tcx. generics_of ( def_id) ) }
1145
1144
}
1146
1145
1147
1146
pub fn self_ty ( & self ) -> Ty < ' tcx > {
@@ -1493,12 +1492,11 @@ impl<'tcx> ExistentialProjection<'tcx> {
1493
1492
/// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
1494
1493
/// then this function would return a `exists T. T: Iterator` existential trait
1495
1494
/// reference.
1496
- pub fn trait_ref ( & self , tcx : TyCtxt < ' _ > ) -> ty:: ExistentialTraitRef < ' tcx > {
1497
- // FIXME(generic_associated_types): substs is the substs of the
1498
- // associated type, which should be truncated to get the correct substs
1499
- // for the trait.
1495
+ pub fn trait_ref ( & self , tcx : TyCtxt < ' tcx > ) -> ty:: ExistentialTraitRef < ' tcx > {
1500
1496
let def_id = tcx. associated_item ( self . item_def_id ) . container . id ( ) ;
1501
- ty:: ExistentialTraitRef { def_id, substs : self . substs }
1497
+ let subst_count = tcx. generics_of ( def_id) . count ( ) - 1 ;
1498
+ let substs = tcx. intern_substs ( & self . substs [ ..subst_count] ) ;
1499
+ ty:: ExistentialTraitRef { def_id, substs }
1502
1500
}
1503
1501
1504
1502
pub fn with_self_ty (
@@ -1517,6 +1515,20 @@ impl<'tcx> ExistentialProjection<'tcx> {
1517
1515
ty : self . ty ,
1518
1516
}
1519
1517
}
1518
+
1519
+ pub fn erase_self_ty (
1520
+ tcx : TyCtxt < ' tcx > ,
1521
+ projection_predicate : ty:: ProjectionPredicate < ' tcx > ,
1522
+ ) -> Self {
1523
+ // Assert there is a Self.
1524
+ projection_predicate. projection_ty . substs . type_at ( 0 ) ;
1525
+
1526
+ Self {
1527
+ item_def_id : projection_predicate. projection_ty . item_def_id ,
1528
+ substs : tcx. intern_substs ( & projection_predicate. projection_ty . substs [ 1 ..] ) ,
1529
+ ty : projection_predicate. ty ,
1530
+ }
1531
+ }
1520
1532
}
1521
1533
1522
1534
impl < ' tcx > PolyExistentialProjection < ' tcx > {
0 commit comments