提交 4ee002a1 编写于 作者: N Niko Matsakis

Extract out trait_defines_associated_type_named into the AstConv

interface, so that we can perform this query without requiring a full
trait def or set of supertraits.
上级 ab8a769c
......@@ -82,6 +82,9 @@ fn get_trait_def(&self, span: Span, id: ast::DefId)
fn get_type_parameter_bounds(&self, span: Span, def_id: ast::NodeId)
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>;
fn trait_defines_associated_type_named(&self, trait_def_id: ast::DefId, name: ast::Name)
-> bool;
/// 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.
......@@ -783,7 +786,7 @@ fn ast_type_binding_to_projection_predicate<'tcx>(
// We want to produce `<B as SuperTrait<int>>::T == foo`.
// Simple case: X is defined in the current trait.
if trait_defines_associated_type_named(this, trait_ref.def_id, binding.item_name) {
if this.trait_defines_associated_type_named(trait_ref.def_id, binding.item_name) {
return Ok(ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy {
trait_ref: trait_ref,
......@@ -812,7 +815,7 @@ fn ast_type_binding_to_projection_predicate<'tcx>(
let mut candidates: Vec<ty::PolyTraitRef> =
traits::supertraits(tcx, trait_ref.to_poly_trait_ref())
.filter(|r| trait_defines_associated_type_named(this, r.def_id(), binding.item_name))
.filter(|r| this.trait_defines_associated_type_named(r.def_id(), binding.item_name))
.collect();
// If converting for an object type, then remove the dummy-ty from `Self` now.
......@@ -1036,7 +1039,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
let mut suitable_bounds: Vec<_> =
traits::transitive_bounds(tcx, &bounds)
.filter(|b| trait_defines_associated_type_named(this, b.def_id(), assoc_name))
.filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
.collect();
if suitable_bounds.len() == 0 {
......@@ -1090,16 +1093,6 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
(ty, def::DefAssociatedTy(trait_did, item_did))
}
fn trait_defines_associated_type_named(this: &AstConv,
trait_def_id: ast::DefId,
assoc_name: ast::Name)
-> bool
{
let tcx = this.tcx();
let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
trait_def.associated_type_names.contains(&assoc_name)
}
fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
rscope: &RegionScope,
span: Span,
......
......@@ -1248,6 +1248,15 @@ fn get_type_parameter_bounds(&self,
Ok(r)
}
fn trait_defines_associated_type_named(&self,
trait_def_id: ast::DefId,
assoc_name: ast::Name)
-> bool
{
let trait_def = ty::lookup_trait_def(self.ccx.tcx, trait_def_id);
trait_def.associated_type_names.contains(&assoc_name)
}
fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
self.infcx().next_ty_var()
}
......
......@@ -364,6 +364,19 @@ fn get_type_parameter_bounds(&self,
})
}
fn trait_defines_associated_type_named(&self,
trait_def_id: ast::DefId,
assoc_name: ast::Name)
-> bool
{
if trait_def_id.krate == ast::LOCAL_CRATE {
trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name)
} else {
let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
trait_def.associated_type_names.contains(&assoc_name)
}
}
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");
......@@ -1296,6 +1309,30 @@ fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
}
fn trait_defines_associated_type_named(ccx: &CrateCtxt,
trait_node_id: ast::NodeId,
assoc_name: ast::Name)
-> bool
{
let item = match ccx.tcx.map.get(trait_node_id) {
ast_map::NodeItem(item) => item,
_ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
};
let trait_items = match item.node {
ast::ItemTrait(_, _, _, ref trait_items) => trait_items,
_ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
};
trait_items.iter()
.any(|trait_item| {
match *trait_item {
ast::TypeTraitItem(ref t) => t.ty_param.ident.name == assoc_name,
ast::RequiredMethod(..) | ast::ProvidedMethod(..) => false,
}
})
}
fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) {
let tcx = ccx.tcx;
let trait_def = trait_def_of_item(ccx, it);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册