Skip to content

Commit 3c782b7

Browse files
committed
Rework the get_type_parameter_bounds impl to use a trait object
and act more generically.
1 parent 0d9e473 commit 3c782b7

File tree

1 file changed

+79
-31
lines changed

1 file changed

+79
-31
lines changed

src/librustc_typeck/collect.rs

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,16 @@ struct CrateCtxt<'a,'tcx:'a> {
150150
stack: RefCell<Vec<AstConvRequest>>,
151151
}
152152

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.
153160
struct ItemCtxt<'a,'tcx:'a> {
154161
ccx: &'a CrateCtxt<'a,'tcx>,
155-
generics: &'a ty::Generics<'tcx>,
162+
param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
156163
}
157164

158165
#[derive(Copy, PartialEq, Eq)]
@@ -216,8 +223,8 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
216223
// Utility types and common code for the above passes.
217224

218225
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 }
221228
}
222229

223230
fn method_ty(&self, method_id: ast::NodeId) -> Rc<ty::Method<'tcx>> {
@@ -319,11 +326,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
319326
}
320327
}
321328

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> {
327330
fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &ast::Ty) -> Ty<'tcx> {
328331
ast_ty_to_ty(self, rs, ast_ty)
329332
}
@@ -354,14 +357,7 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
354357
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
355358
{
356359
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)
365361
})
366362
}
367363

@@ -381,6 +377,32 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
381377
}
382378
}
383379

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+
384406
fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
385407
enum_scheme: ty::TypeScheme<'tcx>,
386408
enum_predicates: ty::GenericPredicates<'tcx>,
@@ -1646,13 +1668,10 @@ fn ty_generic_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
16461668
&ast::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
16471669
let mut projections = Vec::new();
16481670

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);
16561675

16571676
result.predicates.push(space, trait_ref.as_predicate());
16581677

@@ -1934,6 +1953,38 @@ fn check_bounds_compatible<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
19341953
}
19351954
}
19361955

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+
19371988
fn conv_param_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
19381989
generics: &ty::Generics<'tcx>,
19391990
span: Span,
@@ -1952,14 +2003,11 @@ fn conv_param_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
19522003

19532004
let trait_bounds: Vec<ty::PolyTraitRef> =
19542005
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();
19632011

19642012
let region_bounds: Vec<ty::Region> =
19652013
region_bounds.into_iter()

0 commit comments

Comments
 (0)