@@ -150,9 +150,16 @@ struct CrateCtxt<'a,'tcx:'a> {
150
150
stack : RefCell < Vec < AstConvRequest > > ,
151
151
}
152
152
153
+ /// Context specific to some particular item. This is what implements
154
+ /// AstConv. It has information about the predicates that are defined
155
+ /// on the trait. Unfortunately, this predicate information is
156
+ /// available in various different forms at various points in the
157
+ /// process. So we can't just store a pointer to e.g. the AST or the
158
+ /// parsed ty form, we have to wind up keeping both (and making both
159
+ /// optional) and extracting what we need from what's available.
153
160
struct ItemCtxt < ' a , ' tcx : ' a > {
154
161
ccx : & ' a CrateCtxt < ' a , ' tcx > ,
155
- generics : & ' a ty :: Generics < ' tcx > ,
162
+ param_bounds : & ' a ( GetTypeParameterBounds < ' tcx > + ' a ) ,
156
163
}
157
164
158
165
#[ derive( Copy , PartialEq , Eq ) ]
@@ -216,8 +223,8 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
216
223
// Utility types and common code for the above passes.
217
224
218
225
impl < ' a , ' tcx > CrateCtxt < ' a , ' tcx > {
219
- fn icx ( & ' a self , generics : & ' a ty :: Generics < ' tcx > ) -> ItemCtxt < ' a , ' tcx > {
220
- ItemCtxt { ccx : self , generics : generics }
226
+ fn icx ( & ' a self , param_bounds : & ' a GetTypeParameterBounds < ' tcx > ) -> ItemCtxt < ' a , ' tcx > {
227
+ ItemCtxt { ccx : self , param_bounds : param_bounds }
221
228
}
222
229
223
230
fn method_ty ( & self , method_id : ast:: NodeId ) -> Rc < ty:: Method < ' tcx > > {
@@ -319,11 +326,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
319
326
}
320
327
}
321
328
322
- pub trait ToTy < ' tcx > {
323
- fn to_ty < RS : RegionScope > ( & self , rs : & RS , ast_ty : & ast:: Ty ) -> Ty < ' tcx > ;
324
- }
325
-
326
- impl < ' a , ' tcx > ToTy < ' tcx > for ItemCtxt < ' a , ' tcx > {
329
+ impl < ' a , ' tcx > ItemCtxt < ' a , ' tcx > {
327
330
fn to_ty < RS : RegionScope > ( & self , rs : & RS , ast_ty : & ast:: Ty ) -> Ty < ' tcx > {
328
331
ast_ty_to_ty ( self , rs, ast_ty)
329
332
}
@@ -354,14 +357,7 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
354
357
-> Result < Vec < ty:: PolyTraitRef < ' tcx > > , ErrorReported >
355
358
{
356
359
self . ccx . cycle_check ( span, AstConvRequest :: GetTypeParameterBounds ( node_id) , || {
357
- let def = self . tcx ( ) . type_parameter_def ( node_id) ;
358
-
359
- // TODO out of range indices can occur when you have something
360
- // like fn foo<T:U::X,U>() { }
361
- match self . generics . types . opt_get ( def. space , def. index as usize ) {
362
- Some ( def) => def. bounds . trait_bounds . clone ( ) ,
363
- None => Vec :: new ( ) ,
364
- }
360
+ self . param_bounds . get_type_parameter_bounds ( self , span, node_id)
365
361
} )
366
362
}
367
363
@@ -381,6 +377,32 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
381
377
}
382
378
}
383
379
380
+
381
+ trait GetTypeParameterBounds < ' tcx > {
382
+ fn get_type_parameter_bounds ( & self ,
383
+ astconv : & AstConv < ' tcx > ,
384
+ span : Span ,
385
+ node_id : ast:: NodeId )
386
+ -> Vec < ty:: PolyTraitRef < ' tcx > > ;
387
+ }
388
+ impl < ' tcx > GetTypeParameterBounds < ' tcx > for ty:: Generics < ' tcx > {
389
+ fn get_type_parameter_bounds ( & self ,
390
+ astconv : & AstConv < ' tcx > ,
391
+ _span : Span ,
392
+ node_id : ast:: NodeId )
393
+ -> Vec < ty:: PolyTraitRef < ' tcx > >
394
+ {
395
+ let def = astconv. tcx ( ) . type_parameter_def ( node_id) ;
396
+
397
+ // TODO out of range indices can occur when you have something
398
+ // like fn foo<T:U::X,U>() { }
399
+ match self . types . opt_get ( def. space , def. index as usize ) {
400
+ Some ( def) => def. bounds . trait_bounds . clone ( ) ,
401
+ None => Vec :: new ( ) ,
402
+ }
403
+ }
404
+ }
405
+
384
406
fn get_enum_variant_types < ' a , ' tcx > ( ccx : & CrateCtxt < ' a , ' tcx > ,
385
407
enum_scheme : ty:: TypeScheme < ' tcx > ,
386
408
enum_predicates : ty:: GenericPredicates < ' tcx > ,
@@ -1646,13 +1668,10 @@ fn ty_generic_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1646
1668
& ast:: TyParamBound :: TraitTyParamBound ( ref poly_trait_ref, _) => {
1647
1669
let mut projections = Vec :: new ( ) ;
1648
1670
1649
- let trait_ref = astconv:: instantiate_poly_trait_ref (
1650
- & ccx. icx ( generics) ,
1651
- & ExplicitRscope ,
1652
- poly_trait_ref,
1653
- Some ( ty) ,
1654
- & mut projections,
1655
- ) ;
1671
+ let trait_ref = conv_poly_trait_ref ( & ccx. icx ( generics) ,
1672
+ ty,
1673
+ poly_trait_ref,
1674
+ & mut projections) ;
1656
1675
1657
1676
result. predicates . push ( space, trait_ref. as_predicate ( ) ) ;
1658
1677
@@ -1934,6 +1953,38 @@ fn check_bounds_compatible<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1934
1953
}
1935
1954
}
1936
1955
1956
+ /// Converts a specific TyParamBound from the AST into the
1957
+ /// appropriate poly-trait-reference.
1958
+ fn poly_trait_ref_from_bound < ' tcx > ( astconv : & AstConv < ' tcx > ,
1959
+ param_ty : Ty < ' tcx > ,
1960
+ bound : & ast:: TyParamBound ,
1961
+ projections : & mut Vec < ty:: PolyProjectionPredicate < ' tcx > > )
1962
+ -> Option < ty:: PolyTraitRef < ' tcx > >
1963
+ {
1964
+ match * bound {
1965
+ ast:: TraitTyParamBound ( ref tr, ast:: TraitBoundModifier :: None ) => {
1966
+ Some ( conv_poly_trait_ref ( astconv, param_ty, tr, projections) )
1967
+ }
1968
+ ast:: TraitTyParamBound ( _, ast:: TraitBoundModifier :: Maybe ) |
1969
+ ast:: RegionTyParamBound ( _) => {
1970
+ None
1971
+ }
1972
+ }
1973
+ }
1974
+
1975
+ fn conv_poly_trait_ref < ' tcx > ( astconv : & AstConv < ' tcx > ,
1976
+ param_ty : Ty < ' tcx > ,
1977
+ trait_ref : & ast:: PolyTraitRef ,
1978
+ projections : & mut Vec < ty:: PolyProjectionPredicate < ' tcx > > )
1979
+ -> ty:: PolyTraitRef < ' tcx >
1980
+ {
1981
+ astconv:: instantiate_poly_trait_ref ( astconv,
1982
+ & ExplicitRscope ,
1983
+ trait_ref,
1984
+ Some ( param_ty) ,
1985
+ projections)
1986
+ }
1987
+
1937
1988
fn conv_param_bounds < ' a , ' tcx > ( ccx : & CrateCtxt < ' a , ' tcx > ,
1938
1989
generics : & ty:: Generics < ' tcx > ,
1939
1990
span : Span ,
@@ -1952,14 +2003,11 @@ fn conv_param_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1952
2003
1953
2004
let trait_bounds: Vec < ty:: PolyTraitRef > =
1954
2005
trait_bounds. into_iter ( )
1955
- . map ( |bound| {
1956
- astconv:: instantiate_poly_trait_ref ( & ccx. icx ( generics) ,
1957
- & ExplicitRscope ,
1958
- bound,
1959
- Some ( param_ty) ,
1960
- & mut projection_bounds)
1961
- } )
1962
- . collect ( ) ;
2006
+ . map ( |bound| conv_poly_trait_ref ( & ccx. icx ( generics) ,
2007
+ param_ty,
2008
+ bound,
2009
+ & mut projection_bounds) )
2010
+ . collect ( ) ;
1963
2011
1964
2012
let region_bounds: Vec < ty:: Region > =
1965
2013
region_bounds. into_iter ( )
0 commit comments