Skip to content

Commit 6eb233a

Browse files
committed
rustc: unify and simplify managing associated items.
1 parent a5b6a9f commit 6eb233a

File tree

45 files changed

+990
-1667
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+990
-1667
lines changed

src/librustc/dep_graph/dep_node.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ pub enum DepNode<D: Clone + Debug> {
103103
// nodes. Often we map multiple tables to the same node if there
104104
// is no point in distinguishing them (e.g., both the type and
105105
// predicates for an item wind up in `ItemSignature`).
106-
ImplOrTraitItems(D),
106+
AssociatedItems(D),
107107
ItemSignature(D),
108108
FieldTy(D),
109109
SizedConstraint(D),
110-
ImplOrTraitItemDefIds(D),
110+
AssociatedItemDefIds(D),
111111
InherentImpls(D),
112112

113113
// The set of impls for a given trait. Ultimately, it would be
@@ -153,10 +153,10 @@ impl<D: Clone + Debug> DepNode<D> {
153153
TransCrateItem,
154154
TypeckItemType,
155155
TypeckItemBody,
156-
ImplOrTraitItems,
156+
AssociatedItems,
157157
ItemSignature,
158158
FieldTy,
159-
ImplOrTraitItemDefIds,
159+
AssociatedItemDefIds,
160160
InherentImpls,
161161
TraitImpls,
162162
ReprHints,
@@ -219,11 +219,11 @@ impl<D: Clone + Debug> DepNode<D> {
219219
RvalueCheck(ref d) => op(d).map(RvalueCheck),
220220
TransCrateItem(ref d) => op(d).map(TransCrateItem),
221221
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
222-
ImplOrTraitItems(ref d) => op(d).map(ImplOrTraitItems),
222+
AssociatedItems(ref d) => op(d).map(AssociatedItems),
223223
ItemSignature(ref d) => op(d).map(ItemSignature),
224224
FieldTy(ref d) => op(d).map(FieldTy),
225225
SizedConstraint(ref d) => op(d).map(SizedConstraint),
226-
ImplOrTraitItemDefIds(ref d) => op(d).map(ImplOrTraitItemDefIds),
226+
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
227227
InherentImpls(ref d) => op(d).map(InherentImpls),
228228
TraitImpls(ref d) => op(d).map(TraitImpls),
229229
TraitItems(ref d) => op(d).map(TraitItems),

src/librustc/middle/cstore.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ pub trait CrateStore<'tcx> {
148148
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
149149

150150
// impl info
151-
fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId>;
151+
fn associated_item_def_ids(&self, def_id: DefId) -> Vec<DefId>;
152152
fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
153153
-> Option<ty::TraitRef<'tcx>>;
154154
fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity;
@@ -158,8 +158,8 @@ pub trait CrateStore<'tcx> {
158158

159159
// trait/impl-item info
160160
fn trait_of_item(&self, def_id: DefId) -> Option<DefId>;
161-
fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
162-
-> Option<ty::ImplOrTraitItem<'tcx>>;
161+
fn associated_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
162+
-> Option<ty::AssociatedItem>;
163163

164164
// flags
165165
fn is_const_fn(&self, did: DefId) -> bool;
@@ -315,8 +315,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
315315
}
316316

317317
// impl info
318-
fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId>
319-
{ bug!("impl_or_trait_items") }
318+
fn associated_item_def_ids(&self, def_id: DefId) -> Vec<DefId>
319+
{ bug!("associated_items") }
320320
fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
321321
-> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
322322
fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity { bug!("impl_polarity") }
@@ -327,8 +327,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
327327

328328
// trait/impl-item info
329329
fn trait_of_item(&self, def_id: DefId) -> Option<DefId> { bug!("trait_of_item") }
330-
fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
331-
-> Option<ty::ImplOrTraitItem<'tcx>> { bug!("impl_or_trait_item") }
330+
fn associated_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
331+
-> Option<ty::AssociatedItem> { bug!("associated_item") }
332332

333333
// flags
334334
fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }

src/librustc/middle/dead.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,10 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
471471
// This is done to handle the case where, for example, the static
472472
// method of a private type is used, but the type itself is never
473473
// called directly.
474-
let impl_items = self.tcx.impl_or_trait_item_def_ids.borrow();
475474
if let Some(impl_list) =
476475
self.tcx.inherent_impls.borrow().get(&self.tcx.map.local_def_id(id)) {
477-
for impl_did in impl_list.iter() {
478-
for &item_did in &impl_items[impl_did][..] {
476+
for &impl_did in impl_list.iter() {
477+
for &item_did in &self.tcx.associated_item_def_ids(impl_did)[..] {
479478
if let Some(item_node_id) = self.tcx.map.as_local_node_id(item_did) {
480479
if self.live_symbols.contains(&item_node_id) {
481480
return true;

src/librustc/middle/expr_use_visitor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ impl OverloadedCallType {
227227
}
228228

229229
fn from_method_id(tcx: TyCtxt, method_id: DefId) -> OverloadedCallType {
230-
let method = tcx.impl_or_trait_item(method_id);
231-
OverloadedCallType::from_trait_id(tcx, method.container().id())
230+
let method = tcx.associated_item(method_id);
231+
OverloadedCallType::from_trait_id(tcx, method.container.id())
232232
}
233233
}
234234

src/librustc/middle/stability.rs

+5-15
Original file line numberDiff line numberDiff line change
@@ -529,14 +529,11 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
529529
// items.
530530
hir::ItemImpl(.., Some(ref t), _, ref impl_items) => {
531531
let trait_did = tcx.expect_def(t.ref_id).def_id();
532-
let trait_items = tcx.trait_items(trait_did);
533-
534532
for impl_item in impl_items {
535-
let item = trait_items.iter().find(|item| {
536-
item.name() == impl_item.name
537-
}).unwrap();
533+
let item = tcx.associated_items(trait_did)
534+
.find(|item| item.name == impl_item.name).unwrap();
538535
if warn_about_defns {
539-
maybe_do_stability_check(tcx, item.def_id(), impl_item.span, cb);
536+
maybe_do_stability_check(tcx, item.def_id, impl_item.span, cb);
540537
}
541538
}
542539
}
@@ -685,15 +682,8 @@ fn is_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span) -> bool {
685682
}
686683

687684
fn is_staged_api<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> bool {
688-
match tcx.trait_item_of_item(id) {
689-
Some(trait_method_id) if trait_method_id != id => {
690-
is_staged_api(tcx, trait_method_id)
691-
}
692-
_ => {
693-
*tcx.stability.borrow_mut().staged_api.entry(id.krate).or_insert_with(
694-
|| tcx.sess.cstore.is_staged_api(id.krate))
695-
}
696-
}
685+
*tcx.stability.borrow_mut().staged_api.entry(id.krate).or_insert_with(
686+
|| tcx.sess.cstore.is_staged_api(id.krate))
697687
}
698688

699689
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {

src/librustc/traits/error_reporting.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -617,25 +617,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
617617
in the supertrait listing"
618618
}
619619

620-
ObjectSafetyViolation::Method(method,
620+
ObjectSafetyViolation::Method(name,
621621
MethodViolationCode::StaticMethod) => {
622-
buf = format!("method `{}` has no receiver",
623-
method.name);
622+
buf = format!("method `{}` has no receiver", name);
624623
&buf
625624
}
626625

627-
ObjectSafetyViolation::Method(method,
626+
ObjectSafetyViolation::Method(name,
628627
MethodViolationCode::ReferencesSelf) => {
629628
buf = format!("method `{}` references the `Self` type \
630629
in its arguments or return type",
631-
method.name);
630+
name);
632631
&buf
633632
}
634633

635-
ObjectSafetyViolation::Method(method,
634+
ObjectSafetyViolation::Method(name,
636635
MethodViolationCode::Generic) => {
637-
buf = format!("method `{}` has generic type parameters",
638-
method.name);
636+
buf = format!("method `{}` has generic type parameters", name);
639637
&buf
640638
}
641639
};

src/librustc/traits/mod.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -569,18 +569,14 @@ pub fn get_vtable_methods<'a, 'tcx>(
569569
supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
570570
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
571571

572-
let trait_item_def_ids = tcx.impl_or_trait_items(trait_ref.def_id());
573-
let trait_methods = (0..trait_item_def_ids.len()).filter_map(move |i| {
574-
match tcx.impl_or_trait_item(trait_item_def_ids[i]) {
575-
ty::MethodTraitItem(m) => Some(m),
576-
_ => None
577-
}
578-
});
572+
let trait_methods = tcx.associated_items(trait_ref.def_id())
573+
.filter(|item| item.kind == ty::AssociatedKind::Method);
579574

580575
// Now list each method's DefId and Substs (for within its trait).
581576
// If the method can never be called from this object, produce None.
582577
trait_methods.map(move |trait_method| {
583578
debug!("get_vtable_methods: trait_method={:?}", trait_method);
579+
let def_id = trait_method.def_id;
584580

585581
// Some methods cannot be called on an object; skip those.
586582
if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
@@ -590,21 +586,21 @@ pub fn get_vtable_methods<'a, 'tcx>(
590586

591587
// the method may have some early-bound lifetimes, add
592588
// regions for those
593-
let substs = Substs::for_item(tcx, trait_method.def_id,
594-
|_, _| tcx.mk_region(ty::ReErased),
595-
|def, _| trait_ref.substs().type_for_def(def));
589+
let substs = Substs::for_item(tcx, def_id,
590+
|_, _| tcx.mk_region(ty::ReErased),
591+
|def, _| trait_ref.substs().type_for_def(def));
596592

597593
// It's possible that the method relies on where clauses that
598594
// do not hold for this particular set of type parameters.
599595
// Note that this method could then never be called, so we
600596
// do not want to try and trans it, in that case (see #23435).
601-
let predicates = trait_method.predicates.instantiate_own(tcx, substs);
597+
let predicates = tcx.lookup_predicates(def_id).instantiate_own(tcx, substs);
602598
if !normalize_and_test_predicates(tcx, predicates.predicates) {
603599
debug!("get_vtable_methods: predicates do not hold");
604600
return None;
605601
}
606602

607-
Some((trait_method.def_id, substs))
603+
Some((def_id, substs))
608604
})
609605
})
610606
}

src/librustc/traits/object_safety.rs

+17-31
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@ use super::elaborate_predicates;
2222
use hir::def_id::DefId;
2323
use traits;
2424
use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
25-
use std::rc::Rc;
2625
use syntax::ast;
2726

2827
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
29-
pub enum ObjectSafetyViolation<'tcx> {
28+
pub enum ObjectSafetyViolation {
3029
/// Self : Sized declared on the trait
3130
SizedSelf,
3231

@@ -35,7 +34,7 @@ pub enum ObjectSafetyViolation<'tcx> {
3534
SupertraitSelf,
3635

3736
/// Method has something illegal
38-
Method(Rc<ty::Method<'tcx>>, MethodViolationCode),
37+
Method(ast::Name, MethodViolationCode),
3938
}
4039

4140
/// Reasons a method might not be object-safe.
@@ -77,7 +76,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
7776
/// because `object_safety_violations` can't be used during
7877
/// type collection.
7978
pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
80-
-> Vec<ObjectSafetyViolation<'tcx>>
79+
-> Vec<ObjectSafetyViolation>
8180
{
8281
let mut violations = vec![];
8382

@@ -93,29 +92,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
9392
}
9493

9594
pub fn object_safety_violations(self, trait_def_id: DefId)
96-
-> Vec<ObjectSafetyViolation<'tcx>>
95+
-> Vec<ObjectSafetyViolation>
9796
{
9897
traits::supertrait_def_ids(self, trait_def_id)
9998
.flat_map(|def_id| self.object_safety_violations_for_trait(def_id))
10099
.collect()
101100
}
102101

103102
fn object_safety_violations_for_trait(self, trait_def_id: DefId)
104-
-> Vec<ObjectSafetyViolation<'tcx>>
103+
-> Vec<ObjectSafetyViolation>
105104
{
106105
// Check methods for violations.
107-
let mut violations: Vec<_> =
108-
self.trait_items(trait_def_id).iter()
106+
let mut violations: Vec<_> = self.associated_items(trait_def_id)
107+
.filter(|item| item.kind == ty::AssociatedKind::Method)
109108
.filter_map(|item| {
110-
match *item {
111-
ty::MethodTraitItem(ref m) => {
112-
self.object_safety_violation_for_method(trait_def_id, &m)
113-
.map(|code| ObjectSafetyViolation::Method(m.clone(), code))
114-
}
115-
_ => None,
116-
}
117-
})
118-
.collect();
109+
self.object_safety_violation_for_method(trait_def_id, &item)
110+
.map(|code| ObjectSafetyViolation::Method(item.name, code))
111+
}).collect();
119112

120113
// Check the trait itself.
121114
if self.trait_has_sized_self(trait_def_id) {
@@ -198,7 +191,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
198191
/// Returns `Some(_)` if this method makes the containing trait not object safe.
199192
fn object_safety_violation_for_method(self,
200193
trait_def_id: DefId,
201-
method: &ty::Method<'gcx>)
194+
method: &ty::AssociatedItem)
202195
-> Option<MethodViolationCode>
203196
{
204197
// Any method that has a `Self : Sized` requisite is otherwise
@@ -216,7 +209,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
216209
/// otherwise ensure that they cannot be used when `Self=Trait`.
217210
pub fn is_vtable_safe_method(self,
218211
trait_def_id: DefId,
219-
method: &ty::Method<'gcx>)
212+
method: &ty::AssociatedItem)
220213
-> bool
221214
{
222215
// Any method that has a `Self : Sized` requisite can't be called.
@@ -233,26 +226,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
233226
/// `Self:Sized`.
234227
fn virtual_call_violation_for_method(self,
235228
trait_def_id: DefId,
236-
method: &ty::Method<'tcx>)
229+
method: &ty::AssociatedItem)
237230
-> Option<MethodViolationCode>
238231
{
239232
// The method's first parameter must be something that derefs (or
240233
// autorefs) to `&self`. For now, we only accept `self`, `&self`
241234
// and `Box<Self>`.
242-
match method.explicit_self {
243-
ty::ExplicitSelfCategory::Static => {
244-
return Some(MethodViolationCode::StaticMethod);
245-
}
246-
247-
ty::ExplicitSelfCategory::ByValue |
248-
ty::ExplicitSelfCategory::ByReference(..) |
249-
ty::ExplicitSelfCategory::ByBox => {
250-
}
235+
if !method.method_has_self_argument {
236+
return Some(MethodViolationCode::StaticMethod);
251237
}
252238

253239
// The `Self` type is erased, so it should not appear in list of
254240
// arguments or return type apart from the receiver.
255-
let ref sig = method.fty.sig;
241+
let ref sig = self.lookup_item_type(method.def_id).ty.fn_sig();
256242
for &input_ty in &sig.0.inputs[1..] {
257243
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
258244
return Some(MethodViolationCode::ReferencesSelf);
@@ -263,7 +249,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
263249
}
264250

265251
// We can't monomorphize things like `fn foo<A>(...)`.
266-
if !method.generics.types.is_empty() {
252+
if !self.lookup_generics(method.def_id).types.is_empty() {
267253
return Some(MethodViolationCode::Generic);
268254
}
269255

0 commit comments

Comments
 (0)