@@ -80,14 +80,28 @@ pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>(
8080
8181#[ extension( pub trait TypeErrCtxtExt <' tcx>) ]
8282impl < ' tcx > TypeErrCtxt < ' _ , ' tcx > {
83+ #[ instrument( skip( self ) , level = "debug" ) ]
8384 fn report_fulfillment_errors (
8485 & self ,
8586 mut errors : Vec < FulfillmentError < ' tcx > > ,
8687 ) -> ErrorGuaranteed {
88+ if errors. is_empty ( ) {
89+ bug ! ( "attempted to report fulfillment errors, but there we no errors" ) ;
90+ }
91+
8792 self . sub_relations
8893 . borrow_mut ( )
8994 . add_constraints ( self , errors. iter ( ) . map ( |e| e. obligation . predicate ) ) ;
9095
96+ let mut reported = None ;
97+
98+ // We want to ignore desugarings when filtering errors: spans are equivalent even
99+ // if one is the result of a desugaring and the other is not.
100+ let strip_desugaring = |span : Span | {
101+ let expn_data = span. ctxt ( ) . outer_expn_data ( ) ;
102+ if let ExpnKind :: Desugaring ( _) = expn_data. kind { expn_data. call_site } else { span }
103+ } ;
104+
91105 #[ derive( Debug ) ]
92106 struct ErrorDescriptor < ' tcx > {
93107 predicate : ty:: Predicate < ' tcx > ,
@@ -98,40 +112,32 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
98112 . reported_trait_errors
99113 . borrow ( )
100114 . iter ( )
101- . map ( |( & span, predicates) | {
102- (
103- span,
104- predicates
105- . 0
106- . iter ( )
107- . map ( |& predicate| ErrorDescriptor { predicate, index : None } )
108- . collect ( ) ,
109- )
115+ . map ( |( & span, & ( ref predicates, guar) ) | {
116+ reported = Some ( guar) ;
117+ let span = strip_desugaring ( span) ;
118+ let reported_errors = predicates
119+ . iter ( )
120+ . map ( |& predicate| ErrorDescriptor { predicate, index : None } )
121+ . collect ( ) ;
122+ ( span, reported_errors)
110123 } )
111124 . collect ( ) ;
112125
113126 // Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics
114- // with more relevant type information and hide redundant E0282 errors.
127+ // with more relevant type information and hide redundant E0282 ("type annotations needed") errors.
115128 errors. sort_by_key ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
116129 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) )
117130 if Some ( pred. def_id ( ) ) == self . tcx . lang_items ( ) . sized_trait ( ) =>
118131 {
119132 1
120133 }
121- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed ( _) ) => 3 ,
122134 ty:: PredicateKind :: Coerce ( _) => 2 ,
135+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed ( _) ) => 3 ,
123136 _ => 0 ,
124137 } ) ;
125138
126139 for ( index, error) in errors. iter ( ) . enumerate ( ) {
127- // We want to ignore desugarings here: spans are equivalent even
128- // if one is the result of a desugaring and the other is not.
129- let mut span = error. obligation . cause . span ;
130- let expn_data = span. ctxt ( ) . outer_expn_data ( ) ;
131- if let ExpnKind :: Desugaring ( _) = expn_data. kind {
132- span = expn_data. call_site ;
133- }
134-
140+ let span = strip_desugaring ( error. obligation . cause . span ) ;
135141 error_map. entry ( span) . or_default ( ) . push ( ErrorDescriptor {
136142 predicate : error. obligation . predicate ,
137143 index : Some ( index) ,
@@ -144,59 +150,48 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
144150 for ( _, error_set) in error_map. iter ( ) {
145151 // We want to suppress "duplicate" errors with the same span.
146152 for error in error_set {
147- if let Some ( index) = error. index {
148- // Suppress errors that are either:
149- // 1) strictly implied by another error.
150- // 2) implied by an error with a smaller index.
151- for error2 in error_set {
152- if error2. index . is_some_and ( |index2| is_suppressed[ index2] ) {
153- // Avoid errors being suppressed by already-suppressed
154- // errors, to prevent all errors from being suppressed
155- // at once.
156- continue ;
157- }
153+ let Some ( index) = error. index else {
154+ continue ;
155+ } ;
158156
159- if self . error_implies ( error2. predicate , error. predicate )
160- && !( error2. index >= error. index
161- && self . error_implies ( error. predicate , error2. predicate ) )
162- {
163- info ! ( "skipping {:?} (implied by {:?})" , error, error2) ;
164- is_suppressed[ index] = true ;
165- break ;
166- }
157+ // Suppress errors that are either:
158+ // 1) strictly implied by another error.
159+ // 2) implied by an error with a smaller index.
160+ for error2 in error_set {
161+ if self . error_implies ( error2. predicate , error. predicate )
162+ && ( !error2. index . is_some_and ( |index2| index2 >= index)
163+ || !self . error_implies ( error. predicate , error2. predicate ) )
164+ {
165+ info ! ( "skipping `{}` (implied by `{}`)" , error. predicate, error2. predicate) ;
166+ is_suppressed[ index] = true ;
167+ break ;
167168 }
168169 }
169170 }
170171 }
171172
172- let mut reported = None ;
173-
174173 for from_expansion in [ false , true ] {
175- for ( error, suppressed) in iter:: zip ( & errors, & is_suppressed) {
176- if !suppressed && error. obligation . cause . span . from_expansion ( ) == from_expansion {
177- let guar = self . report_fulfillment_error ( error) ;
178- reported = Some ( guar) ;
179- // We want to ignore desugarings here: spans are equivalent even
180- // if one is the result of a desugaring and the other is not.
181- let mut span = error. obligation . cause . span ;
182- let expn_data = span. ctxt ( ) . outer_expn_data ( ) ;
183- if let ExpnKind :: Desugaring ( _) = expn_data. kind {
184- span = expn_data. call_site ;
185- }
186- self . reported_trait_errors
187- . borrow_mut ( )
188- . entry ( span)
189- . or_insert_with ( || ( vec ! [ ] , guar) )
190- . 0
191- . push ( error. obligation . predicate ) ;
174+ for ( error, & suppressed) in iter:: zip ( & errors, & is_suppressed) {
175+ let span = error. obligation . cause . span ;
176+ if suppressed || span. from_expansion ( ) != from_expansion {
177+ continue ;
192178 }
179+
180+ let guar = self . report_fulfillment_error ( error) ;
181+ reported = Some ( guar) ;
182+
183+ self . reported_trait_errors
184+ . borrow_mut ( )
185+ . entry ( span)
186+ . or_insert_with ( || ( vec ! [ ] , guar) )
187+ . 0
188+ . push ( error. obligation . predicate ) ;
193189 }
194190 }
195191
196- // It could be that we don't report an error because we have seen an `ErrorReported` from
197- // another source. We should probably be able to fix most of these, but some are delayed
198- // bugs that get a proper error after this function.
199- reported. unwrap_or_else ( || self . dcx ( ) . delayed_bug ( "failed to report fulfillment errors" ) )
192+ // If all errors are suppressed, then we must have reported at least one error
193+ // from a previous call to this function.
194+ reported. unwrap_or_else ( || bug ! ( "failed to report fulfillment errors" ) )
200195 }
201196
202197 /// Reports that an overflow has occurred and halts compilation. We
0 commit comments