Convert astconv
to request bounds through the AstConv
interface
rather than poking through the `TypeParameterDef` directly.
This commit is contained in:
parent
e033a231ab
commit
15ef2c2e6b
@ -55,7 +55,7 @@ use middle::region;
|
||||
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 @@ impl<'tcx> TyS<'tcx> {
|
||||
_ => 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::const_eval;
|
||||
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::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace
|
||||
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 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, '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 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, '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),
|
||||
¶m.bounds,
|
||||
SizedByDefault::Yes,
|
||||
|
Loading…
x
Reference in New Issue
Block a user