@@ -6,16 +6,18 @@ use rustc_hir::def_id::DefId;
6
6
use rustc_index:: IndexVec ;
7
7
use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
8
8
use rustc_middle:: ty:: { self , TyCtxt } ;
9
- use rustc_span:: Symbol ;
9
+ use rustc_span:: { ErrorGuaranteed , Symbol } ;
10
10
use rustc_trait_selection:: traits:: { self , SkipLeakCheck } ;
11
11
use smallvec:: SmallVec ;
12
12
use std:: collections:: hash_map:: Entry ;
13
13
14
- pub fn crate_inherent_impls_overlap_check ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) {
14
+ pub fn crate_inherent_impls_overlap_check ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> Result < ( ) , ErrorGuaranteed > {
15
15
let mut inherent_overlap_checker = InherentOverlapChecker { tcx } ;
16
+ let mut res = Ok ( ( ) ) ;
16
17
for id in tcx. hir ( ) . items ( ) {
17
- inherent_overlap_checker. check_item ( id) ;
18
+ res = res . and ( inherent_overlap_checker. check_item ( id) ) ;
18
19
}
20
+ res
19
21
}
20
22
21
23
struct InherentOverlapChecker < ' tcx > {
@@ -58,10 +60,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
58
60
== item2. ident ( self . tcx ) . normalize_to_macros_2_0 ( )
59
61
}
60
62
61
- fn check_for_duplicate_items_in_impl ( & self , impl_ : DefId ) {
63
+ fn check_for_duplicate_items_in_impl ( & self , impl_ : DefId ) -> Result < ( ) , ErrorGuaranteed > {
62
64
let impl_items = self . tcx . associated_items ( impl_) ;
63
65
64
66
let mut seen_items = FxHashMap :: default ( ) ;
67
+ let mut res = Ok ( ( ) ) ;
65
68
for impl_item in impl_items. in_definition_order ( ) {
66
69
let span = self . tcx . def_span ( impl_item. def_id ) ;
67
70
let ident = impl_item. ident ( self . tcx ) ;
@@ -70,7 +73,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
70
73
match seen_items. entry ( norm_ident) {
71
74
Entry :: Occupied ( entry) => {
72
75
let former = entry. get ( ) ;
73
- struct_span_code_err ! (
76
+ res = Err ( struct_span_code_err ! (
74
77
self . tcx. dcx( ) ,
75
78
span,
76
79
E0592 ,
@@ -79,24 +82,26 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
79
82
)
80
83
. with_span_label ( span, format ! ( "duplicate definitions for `{ident}`" ) )
81
84
. with_span_label ( * former, format ! ( "other definition for `{ident}`" ) )
82
- . emit ( ) ;
85
+ . emit ( ) ) ;
83
86
}
84
87
Entry :: Vacant ( entry) => {
85
88
entry. insert ( span) ;
86
89
}
87
90
}
88
91
}
92
+ res
89
93
}
90
94
91
95
fn check_for_common_items_in_impls (
92
96
& self ,
93
97
impl1 : DefId ,
94
98
impl2 : DefId ,
95
99
overlap : traits:: OverlapResult < ' _ > ,
96
- ) {
100
+ ) -> Result < ( ) , ErrorGuaranteed > {
97
101
let impl_items1 = self . tcx . associated_items ( impl1) ;
98
102
let impl_items2 = self . tcx . associated_items ( impl2) ;
99
103
104
+ let mut res = Ok ( ( ) ) ;
100
105
for & item1 in impl_items1. in_definition_order ( ) {
101
106
let collision = impl_items2
102
107
. filter_by_name_unhygienic ( item1. name )
@@ -128,17 +133,18 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
128
133
traits:: add_placeholder_note ( & mut err) ;
129
134
}
130
135
131
- err. emit ( ) ;
136
+ res = Err ( err. emit ( ) ) ;
132
137
}
133
138
}
139
+ res
134
140
}
135
141
136
142
fn check_for_overlapping_inherent_impls (
137
143
& self ,
138
144
overlap_mode : OverlapMode ,
139
145
impl1_def_id : DefId ,
140
146
impl2_def_id : DefId ,
141
- ) {
147
+ ) -> Result < ( ) , ErrorGuaranteed > {
142
148
let maybe_overlap = traits:: overlapping_impls (
143
149
self . tcx ,
144
150
impl1_def_id,
@@ -150,14 +156,16 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
150
156
) ;
151
157
152
158
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 ( ( ) )
154
162
}
155
163
}
156
164
157
- fn check_item ( & mut self , id : hir:: ItemId ) {
165
+ fn check_item ( & mut self , id : hir:: ItemId ) -> Result < ( ) , ErrorGuaranteed > {
158
166
let def_kind = self . tcx . def_kind ( id. owner_id ) ;
159
167
if !matches ! ( def_kind, DefKind :: Enum | DefKind :: Struct | DefKind :: Trait | DefKind :: Union ) {
160
- return ;
168
+ return Ok ( ( ) ) ;
161
169
}
162
170
163
171
let impls = self . tcx . inherent_impls ( id. owner_id ) ;
@@ -173,17 +181,18 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
173
181
// otherwise switch to an allocating algorithm with
174
182
// faster asymptotic runtime.
175
183
const ALLOCATING_ALGO_THRESHOLD : usize = 500 ;
184
+ let mut res = Ok ( ( ) ) ;
176
185
if impls. len ( ) < ALLOCATING_ALGO_THRESHOLD {
177
186
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) ) ;
179
188
180
189
for & ( & impl2_def_id, impl_items2) in & impls_items[ ( i + 1 ) ..] {
181
190
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 (
183
192
overlap_mode,
184
193
impl1_def_id,
185
194
impl2_def_id,
186
- ) ;
195
+ ) ) ;
187
196
}
188
197
}
189
198
}
@@ -315,20 +324,21 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
315
324
impl_blocks. sort_unstable ( ) ;
316
325
for ( i, & impl1_items_idx) in impl_blocks. iter ( ) . enumerate ( ) {
317
326
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) ) ;
319
328
320
329
for & impl2_items_idx in impl_blocks[ ( i + 1 ) ..] . iter ( ) {
321
330
let & ( & impl2_def_id, impl_items2) = & impls_items[ impl2_items_idx] ;
322
331
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 (
324
333
overlap_mode,
325
334
impl1_def_id,
326
335
impl2_def_id,
327
- ) ;
336
+ ) ) ;
328
337
}
329
338
}
330
339
}
331
340
}
332
341
}
342
+ res
333
343
}
334
344
}
0 commit comments