Skip to content

Commit 3b45f8f

Browse files
authored
Rollup merge of rust-lang#130764 - compiler-errors:inherent, r=estebank
Separate collection of crate-local inherent impls from error tracking rust-lang#119895 changed the return type of the `crate_inherent_impls` query from `CrateInherentImpls` to `Result<CrateInherentImpls, ErrorGuaranteed>` to avoid needing to use the non-parallel-friendly `track_errors()` to track if an error was reporting from within the query... This was mostly fine until rust-lang#121113, which stopped halting compilation when we hit an `Err(ErrorGuaranteed)` in the `crate_inherent_impls` query. Thus we proceed onwards to typeck, and since a return type of `Result<CrateInherentImpls, ErrorGuaranteed>` means that the query can *either* return one of "the list inherent impls" or "error has been reported", later on when we want to assemble method or associated item candidates for inherent impls, we were just treating any `Err(ErrorGuaranteed)` return value as if Rust had no inherent impls defined anywhere at all! This leads to basically every inherent method call failing with an error, lol, which was reported in rust-lang#127798. This PR changes the `crate_inherent_impls` query to return `(CrateInherentImpls, Result<(), ErrorGuaranteed>)`, i.e. returning the inherent impls collected *and* whether an error was reported in the query itself. It firewalls the latter part of that query into a new `crate_inherent_impls_validity_check` just for the `ensure()` call. This fixes rust-lang#127798.
2 parents 1f52c07 + 28f6980 commit 3b45f8f

File tree

31 files changed

+136
-144
lines changed

31 files changed

+136
-144
lines changed

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

+18-16
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,38 @@ use crate::errors;
2222
pub(crate) fn crate_inherent_impls(
2323
tcx: TyCtxt<'_>,
2424
(): (),
25-
) -> Result<&'_ CrateInherentImpls, ErrorGuaranteed> {
25+
) -> (&'_ CrateInherentImpls, Result<(), ErrorGuaranteed>) {
2626
let mut collect = InherentCollect { tcx, impls_map: Default::default() };
27+
2728
let mut res = Ok(());
2829
for id in tcx.hir().items() {
2930
res = res.and(collect.check_item(id));
3031
}
31-
res?;
32-
Ok(tcx.arena.alloc(collect.impls_map))
32+
33+
(tcx.arena.alloc(collect.impls_map), res)
3334
}
3435

35-
pub(crate) fn crate_incoherent_impls(
36+
pub(crate) fn crate_inherent_impls_validity_check(
3637
tcx: TyCtxt<'_>,
37-
simp: SimplifiedType,
38-
) -> Result<&[DefId], ErrorGuaranteed> {
39-
let crate_map = tcx.crate_inherent_impls(())?;
40-
Ok(tcx.arena.alloc_from_iter(
38+
(): (),
39+
) -> Result<(), ErrorGuaranteed> {
40+
tcx.crate_inherent_impls(()).1
41+
}
42+
43+
pub(crate) fn crate_incoherent_impls(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] {
44+
let (crate_map, _) = tcx.crate_inherent_impls(());
45+
tcx.arena.alloc_from_iter(
4146
crate_map.incoherent_impls.get(&simp).unwrap_or(&Vec::new()).iter().map(|d| d.to_def_id()),
42-
))
47+
)
4348
}
4449

4550
/// On-demand query: yields a vector of the inherent impls for a specific type.
46-
pub(crate) fn inherent_impls(
47-
tcx: TyCtxt<'_>,
48-
ty_def_id: LocalDefId,
49-
) -> Result<&[DefId], ErrorGuaranteed> {
50-
let crate_map = tcx.crate_inherent_impls(())?;
51-
Ok(match crate_map.inherent_impls.get(&ty_def_id) {
51+
pub(crate) fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: LocalDefId) -> &[DefId] {
52+
let (crate_map, _) = tcx.crate_inherent_impls(());
53+
match crate_map.inherent_impls.get(&ty_def_id) {
5254
Some(v) => &v[..],
5355
None => &[],
54-
})
56+
}
5557
}
5658

5759
struct InherentCollect<'tcx> {

compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
177177
return Ok(());
178178
}
179179

180-
let impls = self.tcx.inherent_impls(id.owner_id)?;
181-
180+
let impls = self.tcx.inherent_impls(id.owner_id);
182181
let overlap_mode = OverlapMode::get(self.tcx, id.owner_id.to_def_id());
183182

184183
let impls_items = impls

compiler/rustc_hir_analysis/src/coherence/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ fn enforce_empty_impls_for_marker_traits(
124124

125125
pub(crate) fn provide(providers: &mut Providers) {
126126
use self::builtin::coerce_unsized_info;
127-
use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls};
127+
use self::inherent_impls::{
128+
crate_incoherent_impls, crate_inherent_impls, crate_inherent_impls_validity_check,
129+
inherent_impls,
130+
};
128131
use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
129132
use self::orphan::orphan_check_impl;
130133

@@ -133,6 +136,7 @@ pub(crate) fn provide(providers: &mut Providers) {
133136
crate_inherent_impls,
134137
crate_incoherent_impls,
135138
inherent_impls,
139+
crate_inherent_impls_validity_check,
136140
crate_inherent_impls_overlap_check,
137141
coerce_unsized_info,
138142
orphan_check_impl,

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10281028
..
10291029
}) = node
10301030
&& let Some(ty_def_id) = qself_ty.ty_def_id()
1031-
&& let Ok([inherent_impl]) = tcx.inherent_impls(ty_def_id)
1031+
&& let [inherent_impl] = tcx.inherent_impls(ty_def_id)
10321032
&& let name = format!("{ident2}_{ident3}")
10331033
&& let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx
10341034
.associated_items(inherent_impl)

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12721272
}
12731273

12741274
let candidates: Vec<_> = tcx
1275-
.inherent_impls(adt_did)?
1275+
.inherent_impls(adt_did)
12761276
.iter()
12771277
.filter_map(|&impl_| {
12781278
let (item, scope) =

compiler/rustc_hir_analysis/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
170170
let _ = tcx.ensure().coherent_trait(trait_def_id);
171171
}
172172
// these queries are executed for side-effects (error reporting):
173-
let _ = tcx.ensure().crate_inherent_impls(());
173+
let _ = tcx.ensure().crate_inherent_impls_validity_check(());
174174
let _ = tcx.ensure().crate_inherent_impls_overlap_check(());
175175
});
176176

compiler/rustc_hir_typeck/src/expr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2126,7 +2126,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21262126
.tcx
21272127
.inherent_impls(def_id)
21282128
.into_iter()
2129-
.flatten()
21302129
.flat_map(|i| self.tcx.associated_items(i).in_definition_order())
21312130
// Only assoc fn with no receivers.
21322131
.filter(|item| {

compiler/rustc_hir_typeck/src/method/probe.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -728,13 +728,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
728728
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else {
729729
bug!("unexpected incoherent type: {:?}", self_ty)
730730
};
731-
for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter().flatten() {
731+
for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter() {
732732
self.assemble_inherent_impl_probe(impl_def_id);
733733
}
734734
}
735735

736736
fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
737-
let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter().flatten();
737+
let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter();
738738
for &impl_def_id in impl_def_ids {
739739
self.assemble_inherent_impl_probe(impl_def_id);
740740
}

compiler/rustc_hir_typeck/src/method/suggest.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
680680
self.tcx
681681
.inherent_impls(adt_def.did())
682682
.into_iter()
683-
.flatten()
684683
.any(|def_id| self.associated_value(*def_id, item_name).is_some())
685684
} else {
686685
false
@@ -1438,7 +1437,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14381437
.tcx
14391438
.inherent_impls(adt.did())
14401439
.into_iter()
1441-
.flatten()
14421440
.copied()
14431441
.filter(|def_id| {
14441442
if let Some(assoc) = self.associated_value(*def_id, item_name) {
@@ -1900,7 +1898,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19001898
call_args: Option<Vec<Ty<'tcx>>>,
19011899
) -> Option<Symbol> {
19021900
if let ty::Adt(adt, adt_args) = rcvr_ty.kind() {
1903-
for inherent_impl_did in self.tcx.inherent_impls(adt.did()).into_iter().flatten() {
1901+
for inherent_impl_did in self.tcx.inherent_impls(adt.did()).into_iter() {
19041902
for inherent_method in
19051903
self.tcx.associated_items(inherent_impl_did).in_definition_order()
19061904
{
@@ -2114,9 +2112,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21142112
let ty::Adt(adt_def, _) = rcvr_ty.kind() else {
21152113
return;
21162114
};
2117-
// FIXME(oli-obk): try out bubbling this error up one level and cancelling the other error in that case.
2118-
let Ok(impls) = self.tcx.inherent_impls(adt_def.did()) else { return };
2119-
let mut items = impls
2115+
let mut items = self
2116+
.tcx
2117+
.inherent_impls(adt_def.did())
21202118
.iter()
21212119
.flat_map(|i| self.tcx.associated_items(i).in_definition_order())
21222120
// Only assoc fn with no receivers and only if
@@ -2495,7 +2493,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24952493
.and_then(|simp| {
24962494
tcx.incoherent_impls(simp)
24972495
.into_iter()
2498-
.flatten()
24992496
.find_map(|&id| self.associated_value(id, item_name))
25002497
})
25012498
.is_some()

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ provide! { tcx, def_id, other, cdata,
347347
tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index))
348348
}
349349
associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) }
350-
inherent_impls => { Ok(cdata.get_inherent_implementations_for_type(tcx, def_id.index)) }
350+
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
351351
item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
352352
is_mir_available => { cdata.is_item_mir_available(def_id.index) }
353353
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
@@ -393,7 +393,7 @@ provide! { tcx, def_id, other, cdata,
393393
traits => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
394394
trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) }
395395
implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
396-
crate_incoherent_impls => { Ok(cdata.get_incoherent_impls(tcx, other)) }
396+
crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) }
397397

398398
dep_kind => { cdata.dep_kind }
399399
module_children => {

compiler/rustc_metadata/src/rmeta/encoder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15401540
}
15411541
}
15421542

1543-
for (def_id, impls) in &tcx.crate_inherent_impls(()).unwrap().inherent_impls {
1543+
for (def_id, impls) in &tcx.crate_inherent_impls(()).0.inherent_impls {
15441544
record_defaulted_array!(self.tables.inherent_impls[def_id.to_def_id()] <- impls.iter().map(|def_id| {
15451545
assert!(def_id.is_local());
15461546
def_id.index
@@ -2089,7 +2089,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
20892089

20902090
let all_impls: Vec<_> = tcx
20912091
.crate_inherent_impls(())
2092-
.unwrap()
2092+
.0
20932093
.incoherent_impls
20942094
.iter()
20952095
.map(|(&simp, impls)| IncoherentImpls {

compiler/rustc_middle/src/query/erase.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::intrinsics::transmute_unchecked;
22
use std::mem::MaybeUninit;
33

4+
use rustc_span::ErrorGuaranteed;
5+
46
use crate::query::CyclePlaceholder;
57
use crate::ty::adjustment::CoerceUnsizedInfo;
68
use crate::ty::{self, Ty};
@@ -216,6 +218,10 @@ impl<T0, T1> EraseType for (&'_ T0, &'_ [T1]) {
216218
type Result = [u8; size_of::<(&'static (), &'static [()])>()];
217219
}
218220

221+
impl<T0> EraseType for (&'_ T0, Result<(), ErrorGuaranteed>) {
222+
type Result = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()];
223+
}
224+
219225
macro_rules! trivial {
220226
($($ty:ty),+ $(,)?) => {
221227
$(

compiler/rustc_middle/src/query/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -881,13 +881,13 @@ rustc_queries! {
881881
/// Maps a `DefId` of a type to a list of its inherent impls.
882882
/// Contains implementations of methods that are inherent to a type.
883883
/// Methods in these implementations don't need to be exported.
884-
query inherent_impls(key: DefId) -> Result<&'tcx [DefId], ErrorGuaranteed> {
884+
query inherent_impls(key: DefId) -> &'tcx [DefId] {
885885
desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) }
886886
cache_on_disk_if { key.is_local() }
887887
separate_provide_extern
888888
}
889889

890-
query incoherent_impls(key: SimplifiedType) -> Result<&'tcx [DefId], ErrorGuaranteed> {
890+
query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] {
891891
desc { |tcx| "collecting all inherent impls for `{:?}`", key }
892892
}
893893

@@ -1017,8 +1017,14 @@ rustc_queries! {
10171017

10181018
/// Gets a complete map from all types to their inherent impls.
10191019
/// Not meant to be used directly outside of coherence.
1020-
query crate_inherent_impls(k: ()) -> Result<&'tcx CrateInherentImpls, ErrorGuaranteed> {
1020+
query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) {
10211021
desc { "finding all inherent impls defined in crate" }
1022+
}
1023+
1024+
/// Checks all types in the crate for overlap in their inherent impls. Reports errors.
1025+
/// Not meant to be used directly outside of coherence.
1026+
query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> {
1027+
desc { "check for inherent impls that should not be defined in crate" }
10221028
ensure_forwards_result_if_red
10231029
}
10241030

@@ -1715,7 +1721,7 @@ rustc_queries! {
17151721
///
17161722
/// Do not call this directly, but instead use the `incoherent_impls` query.
17171723
/// This query is only used to get the data necessary for that query.
1718-
query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> Result<&'tcx [DefId], ErrorGuaranteed> {
1724+
query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> &'tcx [DefId] {
17191725
desc { |tcx| "collecting all impls for a type in a crate" }
17201726
separate_provide_extern
17211727
}

compiler/rustc_middle/src/ty/trait_def.rs

+3-17
Original file line numberDiff line numberDiff line change
@@ -253,30 +253,16 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
253253
}
254254

255255
/// Query provider for `incoherent_impls`.
256-
pub(super) fn incoherent_impls_provider(
257-
tcx: TyCtxt<'_>,
258-
simp: SimplifiedType,
259-
) -> Result<&[DefId], ErrorGuaranteed> {
256+
pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] {
260257
let mut impls = Vec::new();
261-
262-
let mut res = Ok(());
263258
for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) {
264-
let incoherent_impls = match tcx.crate_incoherent_impls((cnum, simp)) {
265-
Ok(impls) => impls,
266-
Err(e) => {
267-
res = Err(e);
268-
continue;
269-
}
270-
};
271-
for &impl_def_id in incoherent_impls {
259+
for &impl_def_id in tcx.crate_incoherent_impls((cnum, simp)) {
272260
impls.push(impl_def_id)
273261
}
274262
}
275-
276263
debug!(?impls);
277-
res?;
278264

279-
Ok(tcx.arena.alloc_slice(&impls))
265+
tcx.arena.alloc_slice(&impls)
280266
}
281267

282268
pub(super) fn traits_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] {

compiler/rustc_monomorphize/src/collector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
11831183
}
11841184

11851185
fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option<DefId> {
1186-
for impl_def_id in tcx.inherent_impls(def_id).ok()? {
1186+
for impl_def_id in tcx.inherent_impls(def_id) {
11871187
if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind(
11881188
tcx,
11891189
fn_ident,

compiler/rustc_resolve/src/late/diagnostics.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1825,10 +1825,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
18251825
// Doing analysis on local `DefId`s would cause infinite recursion.
18261826
return;
18271827
}
1828-
let Ok(impls) = self.r.tcx.inherent_impls(def_id) else { return };
18291828
// Look at all the associated functions without receivers in the type's
18301829
// inherent impls to look for builders that return `Self`
1831-
let mut items = impls
1830+
let mut items = self
1831+
.r
1832+
.tcx
1833+
.inherent_impls(def_id)
18321834
.iter()
18331835
.flat_map(|i| self.r.tcx.associated_items(i).in_definition_order())
18341836
// Only assoc fn with no receivers.

src/librustdoc/clean/inline.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ pub(crate) fn build_impls(
373373
let tcx = cx.tcx;
374374

375375
// for each implementation of an item represented by `did`, build the clean::Item for that impl
376-
for &did in tcx.inherent_impls(did).into_iter().flatten() {
376+
for &did in tcx.inherent_impls(did).into_iter() {
377377
cx.with_param_env(did, |cx| {
378378
build_impl(cx, did, attrs, ret);
379379
});
@@ -388,7 +388,7 @@ pub(crate) fn build_impls(
388388
if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
389389
let type_ =
390390
if tcx.is_trait(did) { SimplifiedType::Trait(did) } else { SimplifiedType::Adt(did) };
391-
for &did in tcx.incoherent_impls(type_).into_iter().flatten() {
391+
for &did in tcx.incoherent_impls(type_).into_iter() {
392392
cx.with_param_env(did, |cx| {
393393
build_impl(cx, did, attrs, ret);
394394
});

src/librustdoc/clean/types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1863,15 +1863,15 @@ impl PrimitiveType {
18631863
.get(self)
18641864
.into_iter()
18651865
.flatten()
1866-
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter().flatten())
1866+
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter())
18671867
.copied()
18681868
}
18691869

18701870
pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> + '_ {
18711871
Self::simplified_types()
18721872
.values()
18731873
.flatten()
1874-
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter().flatten())
1874+
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter())
18751875
.copied()
18761876
}
18771877

src/librustdoc/passes/collect_intra_doc_links.rs

-1
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
608608
let mut assoc_items: Vec<_> = tcx
609609
.inherent_impls(did)
610610
.into_iter()
611-
.flatten()
612611
.flat_map(|&imp| {
613612
filter_assoc_items_by_name_and_namespace(
614613
tcx,

src/tools/clippy/clippy_lints/src/derive.rs

-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,6 @@ fn check_unsafe_derive_deserialize<'tcx>(
386386
.tcx
387387
.inherent_impls(def.did())
388388
.into_iter()
389-
.flatten()
390389
.map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
391390
.any(|imp| has_unsafe(cx, imp))
392391
{

src/tools/clippy/clippy_lints/src/inherent_impl.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
5151
// List of spans to lint. (lint_span, first_span)
5252
let mut lint_spans = Vec::new();
5353

54-
let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
55-
return;
56-
};
54+
let (impls, _) = cx.tcx.crate_inherent_impls(());
5755

5856
for (&id, impl_ids) in &impls.inherent_impls {
5957
if impl_ids.len() < 2

0 commit comments

Comments
 (0)