Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a5b4dc5

Browse files
committedFeb 7, 2020
Auto merge of #68911 - jonas-schievink:inherent-overlap, r=<try>
Speed up the inherent impl overlap check This gives a ~7% improvement in compile times for the stm32f0(x2) crate. Also addresses @eddyb's comment in #68837 (comment).
2 parents 442ae7f + 000243c commit a5b4dc5

File tree

26 files changed

+118
-80
lines changed

26 files changed

+118
-80
lines changed
 

‎src/librustc/query/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ rustc_queries! {
311311
query associated_item(_: DefId) -> ty::AssocItem {}
312312

313313
/// Collects the associated items defined on a trait or impl.
314-
query associated_items(key: DefId) -> ty::AssocItemsIterator<'tcx> {
314+
query associated_items(key: DefId) -> &'tcx [ty::AssocItem] {
315315
desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) }
316316
}
317317

‎src/librustc/traits/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ fn vtable_methods<'tcx>(
517517
tcx.arena.alloc_from_iter(supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
518518
let trait_methods = tcx
519519
.associated_items(trait_ref.def_id())
520+
.iter()
520521
.filter(|item| item.kind == ty::AssocKind::Method);
521522

522523
// Now list each method's DefId and InternalSubsts (for within its trait).

‎src/librustc/traits/object_safety.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ fn object_safety_violations_for_trait(
212212
// Check methods for violations.
213213
let mut violations: Vec<_> = tcx
214214
.associated_items(trait_def_id)
215+
.iter()
215216
.filter(|item| item.kind == ty::AssocKind::Method)
216217
.filter_map(|item| {
217218
object_safety_violation_for_method(tcx, trait_def_id, &item)
@@ -277,6 +278,7 @@ fn object_safety_violations_for_trait(
277278

278279
violations.extend(
279280
tcx.associated_items(trait_def_id)
281+
.iter()
280282
.filter(|item| item.kind == ty::AssocKind::Const)
281283
.map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)),
282284
);
@@ -632,7 +634,9 @@ fn object_ty_for_trait<'tcx>(
632634

633635
let mut associated_types = traits::supertraits(tcx, ty::Binder::dummy(trait_ref))
634636
.flat_map(|super_trait_ref| {
635-
tcx.associated_items(super_trait_ref.def_id()).map(move |item| (super_trait_ref, item))
637+
tcx.associated_items(super_trait_ref.def_id())
638+
.iter()
639+
.map(move |item| (super_trait_ref, item))
636640
})
637641
.filter(|(_, item)| item.kind == ty::AssocKind::Type)
638642
.collect::<Vec<_>>();

‎src/librustc/traits/project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,7 @@ fn assoc_ty_def(
14361436
{
14371437
return specialization_graph::NodeItem {
14381438
node: specialization_graph::Node::Impl(impl_def_id),
1439-
item,
1439+
item: *item,
14401440
};
14411441
}
14421442
}

‎src/librustc/traits/types/specialization_graph.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<'tcx> Node {
8181
}
8282

8383
/// Iterate over the items defined directly by the given (impl or trait) node.
84-
pub fn items(&self, tcx: TyCtxt<'tcx>) -> ty::AssocItemsIterator<'tcx> {
84+
pub fn items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ty::AssocItem] {
8585
tcx.associated_items(self.def_id())
8686
}
8787

@@ -98,8 +98,10 @@ impl<'tcx> Node {
9898
) -> Option<ty::AssocItem> {
9999
use crate::ty::AssocKind::*;
100100

101-
tcx.associated_items(self.def_id()).find(move |impl_item| {
102-
match (trait_item_kind, impl_item.kind) {
101+
tcx.associated_items(self.def_id())
102+
.iter()
103+
.find(move |impl_item| {
104+
match (trait_item_kind, impl_item.kind) {
103105
| (Const, Const)
104106
| (Method, Method)
105107
| (Type, Type)
@@ -112,7 +114,8 @@ impl<'tcx> Node {
112114
| (OpaqueTy, _)
113115
=> false,
114116
}
115-
})
117+
})
118+
.copied()
116119
}
117120

118121
pub fn def_id(&self) -> DefId {

‎src/librustc/traits/wf.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
166166
let extend_cause_with_original_assoc_item_obligation =
167167
|cause: &mut traits::ObligationCause<'_>,
168168
pred: &ty::Predicate<'_>,
169-
trait_assoc_items: ty::AssocItemsIterator<'_>| {
169+
trait_assoc_items: &[ty::AssocItem]| {
170170
let trait_item = tcx
171171
.hir()
172172
.as_local_hir_id(trait_ref.def_id)
@@ -283,6 +283,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
283283
) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind))
284284
{
285285
if let Some((impl_item, trait_assoc_item)) = trait_assoc_items
286+
.iter()
286287
.filter(|i| i.def_id == *item_def_id)
287288
.next()
288289
.and_then(|trait_assoc_item| {
@@ -325,7 +326,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
325326
extend_cause_with_original_assoc_item_obligation(
326327
&mut cause,
327328
&pred,
328-
trait_assoc_items.clone(),
329+
trait_assoc_items,
329330
);
330331
traits::Obligation::new(cause, param_env, pred)
331332
});

‎src/librustc/ty/adjustment.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ impl<'tcx> OverloadedDeref<'tcx> {
122122
};
123123
let method_def_id = tcx
124124
.associated_items(trait_def_id.unwrap())
125+
.iter()
125126
.find(|m| m.kind == ty::AssocKind::Method)
126127
.unwrap()
127128
.def_id;

‎src/librustc/ty/instance.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ impl<'tcx> Instance<'tcx> {
376376
let fn_once = tcx.lang_items().fn_once_trait().unwrap();
377377
let call_once = tcx
378378
.associated_items(fn_once)
379+
.iter()
379380
.find(|it| it.kind == ty::AssocKind::Method)
380381
.unwrap()
381382
.def_id;

‎src/librustc/ty/mod.rs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,14 +2705,15 @@ impl<'tcx> TyCtxt<'tcx> {
27052705
.for_each(|&body_id| f(self.hir().body_owner_def_id(body_id)));
27062706
}
27072707

2708-
pub fn provided_trait_methods(self, id: DefId) -> Vec<AssocItem> {
2708+
pub fn provided_trait_methods(self, id: DefId) -> Vec<&'tcx AssocItem> {
27092709
self.associated_items(id)
2710+
.iter()
27102711
.filter(|item| item.kind == AssocKind::Method && item.defaultness.has_value())
27112712
.collect()
27122713
}
27132714

27142715
pub fn trait_relevant_for_never(self, did: DefId) -> bool {
2715-
self.associated_items(did).any(|item| item.relevant_for_never())
2716+
self.associated_items(did).iter().any(|item| item.relevant_for_never())
27162717
}
27172718

27182719
pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
@@ -2974,25 +2975,6 @@ impl<'tcx> TyCtxt<'tcx> {
29742975
}
29752976
}
29762977

2977-
#[derive(Copy, Clone, HashStable)]
2978-
pub struct AssocItemsIterator<'tcx> {
2979-
pub items: &'tcx [AssocItem],
2980-
}
2981-
2982-
impl<'tcx> Iterator for AssocItemsIterator<'tcx> {
2983-
type Item = AssocItem;
2984-
2985-
#[inline]
2986-
fn next(&mut self) -> Option<AssocItem> {
2987-
if let Some((first, rest)) = self.items.split_first() {
2988-
self.items = rest;
2989-
Some(*first)
2990-
} else {
2991-
None
2992-
}
2993-
}
2994-
}
2995-
29962978
#[derive(Clone, HashStable)]
29972979
pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]);
29982980

‎src/librustc/ty/sty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,7 @@ impl<'tcx> ProjectionTy<'tcx> {
10471047
) -> ProjectionTy<'tcx> {
10481048
let item_def_id = tcx
10491049
.associated_items(trait_ref.def_id)
1050+
.iter()
10501051
.find(|item| {
10511052
item.kind == ty::AssocKind::Type
10521053
&& tcx.hygienic_eq(item_name, item.ident, trait_ref.def_id)

‎src/librustc/ty/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ impl<'tcx> TyCtxt<'tcx> {
355355
let mut dtor_did = None;
356356
let ty = self.type_of(adt_did);
357357
self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
358-
if let Some(item) = self.associated_items(impl_did).next() {
358+
if let Some(item) = self.associated_items(impl_did).first() {
359359
if validate(self, impl_did).is_ok() {
360360
dtor_did = Some(item.def_id);
361361
}

‎src/librustc_mir/shim.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
6868
let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
6969
let call_mut = tcx
7070
.associated_items(fn_mut)
71+
.iter()
7172
.find(|it| it.kind == ty::AssocKind::Method)
7273
.unwrap()
7374
.def_id;

‎src/librustc_mir/util/elaborate_drops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ where
539539
debug!("destructor_call_block({:?}, {:?})", self, succ);
540540
let tcx = self.tcx();
541541
let drop_trait = tcx.lang_items().drop_trait().unwrap();
542-
let drop_fn = tcx.associated_items(drop_trait).next().unwrap();
542+
let drop_fn = tcx.associated_items(drop_trait)[0];
543543
let ty = self.place_ty(self.place);
544544
let substs = tcx.mk_substs_trait(ty, &[]);
545545

‎src/librustc_passes/stability.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ impl Visitor<'tcx> for Checker<'tcx> {
468468
let trait_item_def_id = self
469469
.tcx
470470
.associated_items(trait_did)
471+
.iter()
471472
.find(|item| item.ident.name == impl_item.ident.name)
472473
.map(|item| item.def_id);
473474
if let Some(def_id) = trait_item_def_id {

‎src/librustc_save_analysis/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
423423
qualname.push_str(&self.tcx.def_path_str(def_id));
424424
self.tcx
425425
.associated_items(def_id)
426+
.iter()
426427
.find(|item| item.ident.name == ident.name)
427428
.map(|item| decl_id = Some(item.def_id));
428429
}
@@ -717,6 +718,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
717718
let ti = self.tcx.associated_item(decl_id);
718719
self.tcx
719720
.associated_items(ti.container.id())
721+
.iter()
720722
.find(|item| {
721723
item.ident.name == ti.ident.name && item.defaultness.has_value()
722724
})

‎src/librustc_ty/ty.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,10 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
206206
}
207207
}
208208

209-
fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AssocItemsIterator<'tcx> {
210-
ty::AssocItemsIterator {
211-
items: tcx.arena.alloc_from_iter(
212-
tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)),
213-
),
214-
}
209+
fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [ty::AssocItem] {
210+
tcx.arena.alloc_from_iter(
211+
tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)),
212+
)
215213
}
216214

217215
fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span {

‎src/librustc_typeck/astconv.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11091109
trait_def_id: DefId,
11101110
assoc_name: ast::Ident,
11111111
) -> bool {
1112-
self.tcx().associated_items(trait_def_id).any(|item| {
1112+
self.tcx().associated_items(trait_def_id).iter().any(|item| {
11131113
item.kind == ty::AssocKind::Type
11141114
&& self.tcx().hygienic_eq(assoc_name, item.ident, trait_def_id)
11151115
})
@@ -1347,6 +1347,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13471347
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
13481348
let assoc_ty = tcx
13491349
.associated_items(candidate.def_id())
1350+
.iter()
13501351
.find(|i| i.kind == ty::AssocKind::Type && i.ident.modern() == assoc_ident)
13511352
.expect("missing associated type");
13521353

@@ -1512,6 +1513,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
15121513
ty::Predicate::Trait(pred, _) => {
15131514
associated_types.entry(span).or_default().extend(
15141515
tcx.associated_items(pred.def_id())
1516+
.iter()
15151517
.filter(|item| item.kind == ty::AssocKind::Type)
15161518
.map(|item| item.def_id),
15171519
);
@@ -1969,6 +1971,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
19691971
let bound_span = self
19701972
.tcx()
19711973
.associated_items(bound.def_id())
1974+
.iter()
19721975
.find(|item| {
19731976
item.kind == ty::AssocKind::Type
19741977
&& self.tcx().hygienic_eq(assoc_name, item.ident, bound.def_id())
@@ -2198,6 +2201,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
21982201
tcx.adjust_ident_and_get_scope(assoc_ident, trait_did, hir_ref_id);
21992202
let item = tcx
22002203
.associated_items(trait_did)
2204+
.iter()
22012205
.find(|i| Namespace::from(i.kind) == Namespace::Type && i.ident.modern() == assoc_ident)
22022206
.expect("missing associated type");
22032207

‎src/librustc_typeck/check/closure.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
242242
if is_gen {
243243
// Check that we deduce the signature from the `<_ as std::ops::Generator>::Return`
244244
// associated item and not yield.
245-
let return_assoc_item = self.tcx.associated_items(gen_trait).nth(1).unwrap().def_id;
245+
let return_assoc_item = self.tcx.associated_items(gen_trait)[1].def_id;
246246
if return_assoc_item != projection.projection_def_id() {
247247
debug!("deduce_sig_from_projection: not return assoc item of generator");
248248
return None;
@@ -666,7 +666,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
666666

667667
// The `Future` trait has only one associted item, `Output`,
668668
// so check that this is what we see.
669-
let output_assoc_item = self.tcx.associated_items(future_trait).nth(0).unwrap().def_id;
669+
let output_assoc_item = self.tcx.associated_items(future_trait)[0].def_id;
670670
if output_assoc_item != predicate.projection_ty.item_def_id {
671671
span_bug!(
672672
cause_span,

‎src/librustc_typeck/check/demand.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
536536
let item_def_id = self
537537
.tcx
538538
.associated_items(deref_trait)
539+
.iter()
539540
.find(|item| item.kind == ty::AssocKind::Type)
540541
.unwrap()
541542
.def_id;

‎src/librustc_typeck/check/method/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
474474
item_name: ast::Ident,
475475
ns: Namespace,
476476
) -> Option<ty::AssocItem> {
477-
self.tcx.associated_items(def_id).find(|item| {
478-
Namespace::from(item.kind) == ns && self.tcx.hygienic_eq(item_name, item.ident, def_id)
479-
})
477+
self.tcx
478+
.associated_items(def_id)
479+
.iter()
480+
.find(|item| {
481+
Namespace::from(item.kind) == ns
482+
&& self.tcx.hygienic_eq(item_name, item.ident, def_id)
483+
})
484+
.copied()
480485
}
481486
}

‎src/librustc_typeck/check/method/probe.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1696,18 +1696,20 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16961696
let max_dist = max(name.as_str().len(), 3) / 3;
16971697
self.tcx
16981698
.associated_items(def_id)
1699+
.iter()
16991700
.filter(|x| {
17001701
let dist = lev_distance(&*name.as_str(), &x.ident.as_str());
17011702
Namespace::from(x.kind) == Namespace::Value && dist > 0 && dist <= max_dist
17021703
})
1704+
.copied()
17031705
.collect()
17041706
} else {
17051707
self.fcx
17061708
.associated_item(def_id, name, Namespace::Value)
17071709
.map_or(Vec::new(), |x| vec![x])
17081710
}
17091711
} else {
1710-
self.tcx.associated_items(def_id).collect()
1712+
self.tcx.associated_items(def_id).to_vec()
17111713
}
17121714
}
17131715
}

‎src/librustc_typeck/check/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,13 +1966,15 @@ fn check_impl_items_against_trait<'tcx>(
19661966
let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
19671967
let ty_trait_item = tcx
19681968
.associated_items(impl_trait_ref.def_id)
1969+
.iter()
19691970
.find(|ac| {
19701971
Namespace::from(&impl_item.kind) == Namespace::from(ac.kind)
19711972
&& tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id)
19721973
})
19731974
.or_else(|| {
19741975
// Not compatible, but needed for the error message
19751976
tcx.associated_items(impl_trait_ref.def_id)
1977+
.iter()
19761978
.find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
19771979
});
19781980

@@ -2086,7 +2088,7 @@ fn check_impl_items_against_trait<'tcx>(
20862088

20872089
if !is_implemented && !traits::impl_is_default(tcx, impl_id) {
20882090
if !trait_item.defaultness.has_value() {
2089-
missing_items.push(trait_item);
2091+
missing_items.push(*trait_item);
20902092
} else if associated_type_overridden {
20912093
invalidated_items.push(trait_item.ident);
20922094
}
@@ -5086,7 +5088,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
50865088
// Check for `Future` implementations by constructing a predicate to
50875089
// prove: `<T as Future>::Output == U`
50885090
let future_trait = self.tcx.lang_items().future_trait().unwrap();
5089-
let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id;
5091+
let item_def_id = self.tcx.associated_items(future_trait)[0].def_id;
50905092
let predicate =
50915093
ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
50925094
// `<T as Future>::Output`

‎src/librustc_typeck/coherence/inherent_impls_overlap.rs

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::namespace::Namespace;
22
use rustc::traits::{self, IntercrateMode};
3-
use rustc::ty::TyCtxt;
3+
use rustc::ty::{AssocItem, TyCtxt};
44
use rustc_errors::struct_span_err;
55
use rustc_hir as hir;
66
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -17,38 +17,60 @@ struct InherentOverlapChecker<'tcx> {
1717
}
1818

1919
impl InherentOverlapChecker<'tcx> {
20+
/// Checks whether any associated items in impls 1 and 2 share the same identifier and
21+
/// namespace.
22+
fn impls_have_common_items(&self, impl1: DefId, impl2: DefId) -> bool {
23+
let impl_items1 = self.tcx.associated_items(impl1);
24+
let impl_items2 = self.tcx.associated_items(impl2);
25+
26+
for item1 in &impl_items1[..] {
27+
for item2 in &impl_items2[..] {
28+
// Avoid costly `.modern()` calls as much as possible by doing them as late as we
29+
// can. Compare raw symbols first.
30+
if item1.ident.name == item2.ident.name
31+
&& Namespace::from(item1.kind) == Namespace::from(item2.kind)
32+
{
33+
// Symbols and namespace match, compare hygienically.
34+
if item1.ident.modern() == item2.ident.modern() {
35+
return true;
36+
}
37+
}
38+
}
39+
}
40+
41+
false
42+
}
43+
2044
fn check_for_common_items_in_impls(
2145
&self,
2246
impl1: DefId,
2347
impl2: DefId,
2448
overlap: traits::OverlapResult<'_>,
2549
) {
26-
let name_and_namespace = |def_id| {
27-
let item = self.tcx.associated_item(def_id);
28-
(item.ident.modern(), Namespace::from(item.kind))
29-
};
50+
let name_and_namespace =
51+
|assoc: &AssocItem| (assoc.ident.modern(), Namespace::from(assoc.kind));
3052

31-
let impl_items1 = self.tcx.associated_item_def_ids(impl1);
32-
let impl_items2 = self.tcx.associated_item_def_ids(impl2);
53+
let impl_items1 = self.tcx.associated_items(impl1);
54+
let impl_items2 = self.tcx.associated_items(impl2);
3355

34-
for &item1 in &impl_items1[..] {
56+
for item1 in &impl_items1[..] {
3557
let (name, namespace) = name_and_namespace(item1);
3658

37-
for &item2 in &impl_items2[..] {
59+
for item2 in &impl_items2[..] {
3860
if (name, namespace) == name_and_namespace(item2) {
3961
let mut err = struct_span_err!(
4062
self.tcx.sess,
41-
self.tcx.span_of_impl(item1).unwrap(),
63+
self.tcx.span_of_impl(item1.def_id).unwrap(),
4264
E0592,
4365
"duplicate definitions with name `{}`",
4466
name
4567
);
4668
err.span_label(
47-
self.tcx.span_of_impl(item1).unwrap(),
69+
self.tcx.span_of_impl(item1.def_id).unwrap(),
4870
format!("duplicate definitions for `{}`", name),
4971
);
5072
err.span_label(
51-
self.tcx.span_of_impl(item2).unwrap(),
73+
self.tcx.span_of_impl(item2.def_id).unwrap(),
5274
format!("other definition for `{}`", name),
5375
);
5476

@@ -66,24 +88,18 @@ impl InherentOverlapChecker<'tcx> {
6688
}
6789
}
6890

69-
fn check_for_overlapping_inherent_impls(&self, ty_def_id: DefId) {
70-
let impls = self.tcx.inherent_impls(ty_def_id);
71-
72-
for (i, &impl1_def_id) in impls.iter().enumerate() {
73-
for &impl2_def_id in &impls[(i + 1)..] {
74-
traits::overlapping_impls(
75-
self.tcx,
76-
impl1_def_id,
77-
impl2_def_id,
78-
IntercrateMode::Issue43355,
79-
|overlap| {
80-
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
81-
false
82-
},
83-
|| true,
84-
);
85-
}
86-
}
91+
fn check_for_overlapping_inherent_impls(&self, impl1_def_id: DefId, impl2_def_id: DefId) {
92+
traits::overlapping_impls(
93+
self.tcx,
94+
impl1_def_id,
95+
impl2_def_id,
96+
IntercrateMode::Issue43355,
97+
|overlap| {
98+
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
99+
false
100+
},
101+
|| true,
102+
);
87103
}
88104
}
89105

@@ -94,8 +110,16 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
94110
| hir::ItemKind::Struct(..)
95111
| hir::ItemKind::Trait(..)
96112
| hir::ItemKind::Union(..) => {
97-
let type_def_id = self.tcx.hir().local_def_id(item.hir_id);
98-
self.check_for_overlapping_inherent_impls(type_def_id);
113+
let ty_def_id = self.tcx.hir().local_def_id(item.hir_id);
114+
let impls = self.tcx.inherent_impls(ty_def_id);
115+
116+
for (i, &impl1_def_id) in impls.iter().enumerate() {
117+
for &impl2_def_id in &impls[(i + 1)..] {
118+
if self.impls_have_common_items(impl1_def_id, impl2_def_id) {
119+
self.check_for_overlapping_inherent_impls(impl1_def_id, impl2_def_id);
120+
}
121+
}
122+
}
99123
}
100124
_ => {}
101125
}

‎src/librustdoc/clean/blanket_impl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
115115
.cx
116116
.tcx
117117
.associated_items(impl_def_id)
118+
.iter()
119+
.copied()
118120
.collect::<Vec<_>>()
119121
.clean(self.cx),
120122
polarity: None,

‎src/librustdoc/clean/inline.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ pub fn record_extern_fqn(cx: &DocContext<'_>, did: DefId, kind: clean::TypeKind)
191191

192192
pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
193193
let auto_trait = cx.tcx.trait_def(did).has_auto_impl;
194-
let trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect();
194+
let trait_items = cx.tcx.associated_items(did).iter().map(|item| item.clean(cx)).collect();
195195
let predicates = cx.tcx.predicates_of(did);
196196
let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
197197
let generics = filter_non_trait_generics(did, generics);
@@ -376,6 +376,7 @@ pub fn build_impl(
376376
} else {
377377
(
378378
tcx.associated_items(did)
379+
.iter()
379380
.filter_map(|item| {
380381
if associated_trait.is_some() || item.vis == ty::Visibility::Public {
381382
Some(item.clean(cx))

‎src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
206206
return cx
207207
.tcx
208208
.associated_items(did)
209+
.iter()
209210
.find(|item| item.ident.name == item_name)
210211
.and_then(|item| match item.kind {
211212
ty::AssocKind::Method => Some("method"),

0 commit comments

Comments
 (0)
Please sign in to comment.