提交 15ef2c2e 编写于 作者: N Niko Matsakis

Convert `astconv` to request bounds through the `AstConv` interface

rather than poking through the `TypeParameterDef` directly.
上级 e033a231
......@@ -55,7 +55,7 @@
use middle::resolve_lifetime;
use middle::infer;
use middle::stability;
use middle::subst::{self, Subst, Substs, VecPerParamSpace};
use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
use middle::traits;
use middle::ty;
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
......@@ -2996,6 +2996,13 @@ pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
_ => None,
}
}
pub fn is_param(&self, space: ParamSpace, index: u32) -> bool {
match self.sty {
ty::ty_param(ref data) => data.space == space && data.idx == index,
_ => false,
}
}
}
pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
......
......@@ -53,7 +53,7 @@
use middle::def;
use middle::resolve_lifetime as rl;
use middle::privacy::{AllPublic, LastMod};
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
use middle::subst::{FnSpace, ParamSpace, TypeSpace, SelfSpace, Subst, Substs};
use middle::traits;
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
......@@ -77,6 +77,8 @@ pub trait AstConv<'tcx> {
fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef<'tcx>>;
fn get_type_parameter_bounds(&self, space: ParamSpace, index: u32) -> Vec<ty::PolyTraitRef<'tcx>>;
/// Return an (optional) substitution to convert bound type parameters that
/// are in scope into free ones. This function should only return Some
/// within a fn body.
......@@ -1011,7 +1013,9 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
// FIXME(#20300) -- search where clauses, not bounds
suitable_bounds =
traits::transitive_bounds(tcx, &ty_param_def.bounds.trait_bounds)
traits::transitive_bounds(tcx,
&this.get_type_parameter_bounds(ty_param_def.space,
ty_param_def.index))
.filter(|b| trait_defines_associated_type_named(this, b.def_id(), assoc_name))
.collect();
}
......
......@@ -97,7 +97,7 @@
use middle::traits;
use middle::ty::{FnSig, GenericPredicates, VariantInfo, TypeScheme};
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
use middle::ty::{self, HasProjectionTypes, RegionEscape, Ty};
use middle::ty::{self, HasProjectionTypes, RegionEscape, ToPolyTraitRef, Ty};
use middle::ty::liberate_late_bound_regions;
use middle::ty::{MethodCall, MethodCallee, MethodMap, ObjectCastMap};
use middle::ty_fold::{TypeFolder, TypeFoldable};
......@@ -1218,6 +1218,30 @@ fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
Some(&self.inh.param_env.free_substs)
}
fn get_type_parameter_bounds(&self,
space: ParamSpace,
index: u32)
-> Vec<ty::PolyTraitRef<'tcx>>
{
self.inh.param_env.caller_bounds
.iter()
.filter_map(|predicate| {
match *predicate {
ty::Predicate::Trait(ref data) => {
if data.0.self_ty().is_param(space, index) {
Some(data.to_poly_trait_ref())
} else {
None
}
}
_ => {
None
}
}
})
.collect()
}
fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
self.infcx().next_ty_var()
}
......
......@@ -145,7 +145,6 @@ struct CrateCtxt<'a,'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
}
#[allow(dead_code)] // just temporary, for generics
struct ItemCtxt<'a,'tcx:'a> {
ccx: &'a CrateCtxt<'a,'tcx>,
generics: &'a ty::Generics<'tcx>,
......@@ -241,6 +240,19 @@ fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef<'tcx>> {
get_trait_def(self.ccx, id)
}
fn get_type_parameter_bounds(&self,
param: subst::ParamSpace,
index: u32)
-> Vec<ty::PolyTraitRef<'tcx>>
{
// TODO out of range indices can occur when you have something
// like fn foo<T:U::X,U>() { }
match self.generics.types.opt_get(param, index as usize) {
Some(def) => def.bounds.trait_bounds.clone(),
None => Vec::new(),
}
}
fn ty_infer(&self, span: Span) -> Ty<'tcx> {
span_err!(self.tcx().sess, span, E0121,
"the type placeholder `_` is not allowed within types on item signatures");
......@@ -1596,7 +1608,7 @@ fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
// Now create the real type parameters.
for (i, param) in types.iter().enumerate() {
let def = get_or_create_type_parameter_def(ccx, space, param, i as u32, where_clause);
let def = get_or_create_type_parameter_def(ccx, &result, space, param, i as u32);
debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
result.types.push(space, def);
}
......@@ -1605,6 +1617,7 @@ fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
}
fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
generics_so_far: &ty::Generics<'tcx>,
space: subst::ParamSpace,
param: &ast::TyParam,
index: u32,
......@@ -1619,7 +1632,7 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
let param_ty = ty::ParamTy::new(space, index, param.ident.name);
let bounds = compute_bounds(ccx,
&ty::Generics::empty(),
generics_so_far,
param_ty.to_ty(ccx.tcx),
&param.bounds,
SizedByDefault::Yes,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册