Skip to content

Commit d74b60d

Browse files
committed
Make crate_inherent_impls_overlap_check bubble up its errors
1 parent fb045e8 commit d74b60d

File tree

3 files changed

+31
-20
lines changed

3 files changed

+31
-20
lines changed

compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs

+28-18
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@ use rustc_hir::def_id::DefId;
66
use rustc_index::IndexVec;
77
use rustc_middle::traits::specialization_graph::OverlapMode;
88
use rustc_middle::ty::{self, TyCtxt};
9-
use rustc_span::Symbol;
9+
use rustc_span::{ErrorGuaranteed, Symbol};
1010
use rustc_trait_selection::traits::{self, SkipLeakCheck};
1111
use smallvec::SmallVec;
1212
use std::collections::hash_map::Entry;
1313

14-
pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) {
14+
pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
1515
let mut inherent_overlap_checker = InherentOverlapChecker { tcx };
16+
let mut res = Ok(());
1617
for id in tcx.hir().items() {
17-
inherent_overlap_checker.check_item(id);
18+
res = res.and(inherent_overlap_checker.check_item(id));
1819
}
20+
res
1921
}
2022

2123
struct InherentOverlapChecker<'tcx> {
@@ -58,10 +60,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
5860
== item2.ident(self.tcx).normalize_to_macros_2_0()
5961
}
6062

61-
fn check_for_duplicate_items_in_impl(&self, impl_: DefId) {
63+
fn check_for_duplicate_items_in_impl(&self, impl_: DefId) -> Result<(), ErrorGuaranteed> {
6264
let impl_items = self.tcx.associated_items(impl_);
6365

6466
let mut seen_items = FxHashMap::default();
67+
let mut res = Ok(());
6568
for impl_item in impl_items.in_definition_order() {
6669
let span = self.tcx.def_span(impl_item.def_id);
6770
let ident = impl_item.ident(self.tcx);
@@ -70,7 +73,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
7073
match seen_items.entry(norm_ident) {
7174
Entry::Occupied(entry) => {
7275
let former = entry.get();
73-
struct_span_code_err!(
76+
res = Err(struct_span_code_err!(
7477
self.tcx.dcx(),
7578
span,
7679
E0592,
@@ -79,24 +82,26 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
7982
)
8083
.with_span_label(span, format!("duplicate definitions for `{ident}`"))
8184
.with_span_label(*former, format!("other definition for `{ident}`"))
82-
.emit();
85+
.emit());
8386
}
8487
Entry::Vacant(entry) => {
8588
entry.insert(span);
8689
}
8790
}
8891
}
92+
res
8993
}
9094

9195
fn check_for_common_items_in_impls(
9296
&self,
9397
impl1: DefId,
9498
impl2: DefId,
9599
overlap: traits::OverlapResult<'_>,
96-
) {
100+
) -> Result<(), ErrorGuaranteed> {
97101
let impl_items1 = self.tcx.associated_items(impl1);
98102
let impl_items2 = self.tcx.associated_items(impl2);
99103

104+
let mut res = Ok(());
100105
for &item1 in impl_items1.in_definition_order() {
101106
let collision = impl_items2
102107
.filter_by_name_unhygienic(item1.name)
@@ -128,17 +133,18 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
128133
traits::add_placeholder_note(&mut err);
129134
}
130135

131-
err.emit();
136+
res = Err(err.emit());
132137
}
133138
}
139+
res
134140
}
135141

136142
fn check_for_overlapping_inherent_impls(
137143
&self,
138144
overlap_mode: OverlapMode,
139145
impl1_def_id: DefId,
140146
impl2_def_id: DefId,
141-
) {
147+
) -> Result<(), ErrorGuaranteed> {
142148
let maybe_overlap = traits::overlapping_impls(
143149
self.tcx,
144150
impl1_def_id,
@@ -150,14 +156,16 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
150156
);
151157

152158
if let Some(overlap) = maybe_overlap {
153-
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
159+
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap)
160+
} else {
161+
Ok(())
154162
}
155163
}
156164

157-
fn check_item(&mut self, id: hir::ItemId) {
165+
fn check_item(&mut self, id: hir::ItemId) -> Result<(), ErrorGuaranteed> {
158166
let def_kind = self.tcx.def_kind(id.owner_id);
159167
if !matches!(def_kind, DefKind::Enum | DefKind::Struct | DefKind::Trait | DefKind::Union) {
160-
return;
168+
return Ok(());
161169
}
162170

163171
let impls = self.tcx.inherent_impls(id.owner_id);
@@ -173,17 +181,18 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
173181
// otherwise switch to an allocating algorithm with
174182
// faster asymptotic runtime.
175183
const ALLOCATING_ALGO_THRESHOLD: usize = 500;
184+
let mut res = Ok(());
176185
if impls.len() < ALLOCATING_ALGO_THRESHOLD {
177186
for (i, &(&impl1_def_id, impl_items1)) in impls_items.iter().enumerate() {
178-
self.check_for_duplicate_items_in_impl(impl1_def_id);
187+
res = res.and(self.check_for_duplicate_items_in_impl(impl1_def_id));
179188

180189
for &(&impl2_def_id, impl_items2) in &impls_items[(i + 1)..] {
181190
if self.impls_have_common_items(impl_items1, impl_items2) {
182-
self.check_for_overlapping_inherent_impls(
191+
res = res.and(self.check_for_overlapping_inherent_impls(
183192
overlap_mode,
184193
impl1_def_id,
185194
impl2_def_id,
186-
);
195+
));
187196
}
188197
}
189198
}
@@ -315,20 +324,21 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
315324
impl_blocks.sort_unstable();
316325
for (i, &impl1_items_idx) in impl_blocks.iter().enumerate() {
317326
let &(&impl1_def_id, impl_items1) = &impls_items[impl1_items_idx];
318-
self.check_for_duplicate_items_in_impl(impl1_def_id);
327+
res = res.and(self.check_for_duplicate_items_in_impl(impl1_def_id));
319328

320329
for &impl2_items_idx in impl_blocks[(i + 1)..].iter() {
321330
let &(&impl2_def_id, impl_items2) = &impls_items[impl2_items_idx];
322331
if self.impls_have_common_items(impl_items1, impl_items2) {
323-
self.check_for_overlapping_inherent_impls(
332+
res = res.and(self.check_for_overlapping_inherent_impls(
324333
overlap_mode,
325334
impl1_def_id,
326335
impl2_def_id,
327-
);
336+
));
328337
}
329338
}
330339
}
331340
}
332341
}
342+
res
333343
}
334344
}

compiler/rustc_hir_analysis/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
188188

189189
// these queries are executed for side-effects (error reporting):
190190
tcx.ensure().crate_inherent_impls(());
191-
tcx.ensure().crate_inherent_impls_overlap_check(());
192191
}))
192+
.and(tcx.ensure().crate_inherent_impls_overlap_check(()))
193193
})?;
194194

195195
if tcx.features().rustc_attrs {

compiler/rustc_middle/src/query/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1019,8 +1019,9 @@ rustc_queries! {
10191019

10201020
/// Checks all types in the crate for overlap in their inherent impls. Reports errors.
10211021
/// Not meant to be used directly outside of coherence.
1022-
query crate_inherent_impls_overlap_check(_: ()) -> () {
1022+
query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> {
10231023
desc { "check for overlap between inherent impls defined in this crate" }
1024+
ensure_forwards_result_if_red
10241025
}
10251026

10261027
/// Checks whether all impls in the crate pass the overlap check, returning

0 commit comments

Comments
 (0)