@@ -6,16 +6,18 @@ use rustc_hir::def_id::DefId;
66use rustc_index:: IndexVec ;
77use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
88use rustc_middle:: ty:: { self , TyCtxt } ;
9- use rustc_span:: Symbol ;
9+ use rustc_span:: { ErrorGuaranteed , Symbol } ;
1010use rustc_trait_selection:: traits:: { self , SkipLeakCheck } ;
1111use smallvec:: SmallVec ;
1212use 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
2123struct 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}
0 commit comments