Skip to content

Commit 4ee002a

Browse files
committed
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.
1 parent ab8a769 commit 4ee002a

File tree

3 files changed

+52
-13
lines changed

3 files changed

+52
-13
lines changed

src/librustc_typeck/astconv.rs

+6-13
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ pub trait AstConv<'tcx> {
8282
fn get_type_parameter_bounds(&self, span: Span, def_id: ast::NodeId)
8383
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>;
8484

85+
fn trait_defines_associated_type_named(&self, trait_def_id: ast::DefId, name: ast::Name)
86+
-> bool;
87+
8588
/// Return an (optional) substitution to convert bound type parameters that
8689
/// are in scope into free ones. This function should only return Some
8790
/// within a fn body.
@@ -783,7 +786,7 @@ fn ast_type_binding_to_projection_predicate<'tcx>(
783786
// We want to produce `<B as SuperTrait<int>>::T == foo`.
784787

785788
// Simple case: X is defined in the current trait.
786-
if trait_defines_associated_type_named(this, trait_ref.def_id, binding.item_name) {
789+
if this.trait_defines_associated_type_named(trait_ref.def_id, binding.item_name) {
787790
return Ok(ty::ProjectionPredicate {
788791
projection_ty: ty::ProjectionTy {
789792
trait_ref: trait_ref,
@@ -812,7 +815,7 @@ fn ast_type_binding_to_projection_predicate<'tcx>(
812815

813816
let mut candidates: Vec<ty::PolyTraitRef> =
814817
traits::supertraits(tcx, trait_ref.to_poly_trait_ref())
815-
.filter(|r| trait_defines_associated_type_named(this, r.def_id(), binding.item_name))
818+
.filter(|r| this.trait_defines_associated_type_named(r.def_id(), binding.item_name))
816819
.collect();
817820

818821
// 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>,
10361039

10371040
let mut suitable_bounds: Vec<_> =
10381041
traits::transitive_bounds(tcx, &bounds)
1039-
.filter(|b| trait_defines_associated_type_named(this, b.def_id(), assoc_name))
1042+
.filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
10401043
.collect();
10411044

10421045
if suitable_bounds.len() == 0 {
@@ -1090,16 +1093,6 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
10901093
(ty, def::DefAssociatedTy(trait_did, item_did))
10911094
}
10921095

1093-
fn trait_defines_associated_type_named(this: &AstConv,
1094-
trait_def_id: ast::DefId,
1095-
assoc_name: ast::Name)
1096-
-> bool
1097-
{
1098-
let tcx = this.tcx();
1099-
let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
1100-
trait_def.associated_type_names.contains(&assoc_name)
1101-
}
1102-
11031096
fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
11041097
rscope: &RegionScope,
11051098
span: Span,

src/librustc_typeck/check/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,15 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
12481248
Ok(r)
12491249
}
12501250

1251+
fn trait_defines_associated_type_named(&self,
1252+
trait_def_id: ast::DefId,
1253+
assoc_name: ast::Name)
1254+
-> bool
1255+
{
1256+
let trait_def = ty::lookup_trait_def(self.ccx.tcx, trait_def_id);
1257+
trait_def.associated_type_names.contains(&assoc_name)
1258+
}
1259+
12511260
fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
12521261
self.infcx().next_ty_var()
12531262
}

src/librustc_typeck/collect.rs

+37
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,19 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
364364
})
365365
}
366366

367+
fn trait_defines_associated_type_named(&self,
368+
trait_def_id: ast::DefId,
369+
assoc_name: ast::Name)
370+
-> bool
371+
{
372+
if trait_def_id.krate == ast::LOCAL_CRATE {
373+
trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name)
374+
} else {
375+
let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
376+
trait_def.associated_type_names.contains(&assoc_name)
377+
}
378+
}
379+
367380
fn ty_infer(&self, span: Span) -> Ty<'tcx> {
368381
span_err!(self.tcx().sess, span, E0121,
369382
"the type placeholder `_` is not allowed within types on item signatures");
@@ -1296,6 +1309,30 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
12961309
}
12971310
}
12981311

1312+
fn trait_defines_associated_type_named(ccx: &CrateCtxt,
1313+
trait_node_id: ast::NodeId,
1314+
assoc_name: ast::Name)
1315+
-> bool
1316+
{
1317+
let item = match ccx.tcx.map.get(trait_node_id) {
1318+
ast_map::NodeItem(item) => item,
1319+
_ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
1320+
};
1321+
1322+
let trait_items = match item.node {
1323+
ast::ItemTrait(_, _, _, ref trait_items) => trait_items,
1324+
_ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
1325+
};
1326+
1327+
trait_items.iter()
1328+
.any(|trait_item| {
1329+
match *trait_item {
1330+
ast::TypeTraitItem(ref t) => t.ty_param.ident.name == assoc_name,
1331+
ast::RequiredMethod(..) | ast::ProvidedMethod(..) => false,
1332+
}
1333+
})
1334+
}
1335+
12991336
fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) {
13001337
let tcx = ccx.tcx;
13011338
let trait_def = trait_def_of_item(ccx, it);

0 commit comments

Comments
 (0)