@@ -80,61 +80,81 @@ 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 ) ]  
92-         struct  ErrorDescriptor < ' tcx >  { 
106+         struct  ErrorDescriptor < ' tcx ,   ' err >  { 
93107            predicate :  ty:: Predicate < ' tcx > , 
94-             index :  Option < usize > ,  // None if this is an old error 
108+             source :  Option < ( usize ,   & ' err   FulfillmentError < ' tcx > ) > ,  // None if this is an old error 
95109        } 
96110
97111        let  mut  error_map:  FxIndexMap < _ ,  Vec < _ > >  = self 
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,  source :  None  } ) 
121+                     . collect ( ) ; 
122+                 ( span,  reported_errors) 
110123            } ) 
111124            . collect ( ) ; 
112125
126+         #[ derive( Debug ,  Clone ,  Copy ,  PartialEq ,  Eq ,  PartialOrd ,  Ord ) ]  
127+         enum  ErrorOrd  { 
128+             Default , 
129+             Sized , 
130+             Metadata , 
131+             Coerce , 
132+             WellFormed , 
133+         } 
134+ 
113135        // 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. 
136+         // with more relevant type information and hide redundant E0282 ("type annotations needed")  errors. 
115137        errors. sort_by_key ( |e| match  e. obligation . predicate . kind ( ) . skip_binder ( )  { 
116138            ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) 
117139                if  Some ( pred. def_id ( ) )  == self . tcx . lang_items ( ) . sized_trait ( )  =>
118140            { 
119-                 1 
141+                 ErrorOrd :: Sized 
142+             } 
143+             ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( pred) ) 
144+                 if  Some ( pred. def_id ( ) )  == self . tcx . lang_items ( ) . metadata_type ( )  =>
145+             { 
146+                 ErrorOrd :: Metadata 
120147            } 
121-             ty:: PredicateKind :: Clause ( ty :: ClauseKind :: WellFormed ( _ ) )  => 3 , 
122-             ty:: PredicateKind :: Coerce ( _ )  => 2 , 
123-             _ => 0 , 
148+             ty:: PredicateKind :: Coerce ( _ )  => ErrorOrd :: Coerce , 
149+             ty:: PredicateKind :: Clause ( ty :: ClauseKind :: WellFormed ( _ ) )  => ErrorOrd :: WellFormed , 
150+             _ => ErrorOrd :: Default , 
124151        } ) ; 
125152
126153        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- 
154+             let  span = strip_desugaring ( error. obligation . cause . span ) ; 
135155            error_map. entry ( span) . or_default ( ) . push ( ErrorDescriptor  { 
136156                predicate :  error. obligation . predicate , 
137-                 index :  Some ( index) , 
157+                 source :  Some ( ( index,  error ) ) , 
138158            } ) ; 
139159        } 
140160
@@ -144,59 +164,63 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
144164        for  ( _,  error_set)  in  error_map. iter ( )  { 
145165            // We want to suppress "duplicate" errors with the same span. 
146166            for  error in  error_set { 
147-                 if  let  Some ( index)  = error. index  { 
167+                 let  Some ( ( index,  error_source) )  = error. source  else  { 
168+                     continue ; 
169+                 } ; 
170+ 
171+                 for  error2 in  error_set { 
148172                    // Suppress errors that are either: 
149173                    // 1) strictly implied by another error. 
150174                    // 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-                         } 
175+                     if  self . error_implied_by ( error. predicate ,  error2. predicate ) 
176+                         && ( !error2. source . is_some_and ( |( index2,  _) | index2 >= index) 
177+                             || !self . error_implied_by ( error2. predicate ,  error. predicate ) ) 
178+                     { 
179+                         info ! ( "skipping `{}` (implied by `{}`)" ,  error. predicate,  error2. predicate) ; 
180+                         is_suppressed[ index]  = true ; 
181+                         break ; 
182+                     } 
158183
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-                         } 
184+                     // Also suppress the error if we are absolutely certain that a different 
185+                     // error is the one that the user should fix. This will suppress errors 
186+                     // about `<T as Pointee>::Metadata == ()` that can be fixed by `T: Sized`. 
187+                     if  error. predicate . to_opt_poly_projection_pred ( ) . is_some ( ) 
188+                         && error2. predicate . to_opt_poly_trait_pred ( ) . is_some ( ) 
189+                         && self . error_fixed_by ( 
190+                             error_source. obligation . clone ( ) , 
191+                             error2. predicate . expect_clause ( ) , 
192+                         ) 
193+                     { 
194+                         info ! ( "skipping `{}` (fixed by `{}`)" ,  error. predicate,  error2. predicate) ; 
195+                         is_suppressed[ index]  = true ; 
196+                         break ; 
167197                    } 
168198                } 
169199            } 
170200        } 
171201
172-         let  mut  reported = None ; 
173- 
174202        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 ) ; 
203+             for  ( error,  & suppressed)  in  iter:: zip ( & errors,  & is_suppressed)  { 
204+                 let  span = error. obligation . cause . span ; 
205+                 if  suppressed || span. from_expansion ( )  != from_expansion { 
206+                     continue ; 
192207                } 
208+ 
209+                 let  guar = self . report_fulfillment_error ( error) ; 
210+                 reported = Some ( guar) ; 
211+ 
212+                 self . reported_trait_errors 
213+                     . borrow_mut ( ) 
214+                     . entry ( span) 
215+                     . or_insert_with ( || ( vec ! [ ] ,  guar) ) 
216+                     . 0 
217+                     . push ( error. obligation . predicate ) ; 
193218            } 
194219        } 
195220
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" ) ) 
221+         // If all errors are suppressed, then we must have reported at least one error 
222+         // from a previous call to this function. 
223+         reported. unwrap_or_else ( || bug ! ( "failed to report fulfillment errors" ) ) 
200224    } 
201225
202226    /// Reports that an overflow has occurred and halts compilation. We 
@@ -1465,10 +1489,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
14651489            && self . can_eq ( param_env,  goal. term ,  assumption. term ) 
14661490    } 
14671491
1468-     // returns if  `cond` not occurring implies that `error` does not occur - i.e., that 
1469-     // `error` occurring implies that `cond` occurs. 
1492+     /// Returns whether  `cond` not occurring implies that `error` does not occur - i.e., that 
1493+      ///  `error` occurring implies that `cond` occurs. 
14701494     #[ instrument( level = "debug" ,  skip( self ) ,  ret) ]  
1471-     fn  error_implies ( & self ,  cond :  ty:: Predicate < ' tcx > ,  error :  ty:: Predicate < ' tcx > )  -> bool  { 
1495+     fn  error_implied_by ( & self ,  error :  ty:: Predicate < ' tcx > ,  cond :  ty:: Predicate < ' tcx > )  -> bool  { 
14721496        if  cond == error { 
14731497            return  true ; 
14741498        } 
@@ -1490,6 +1514,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
14901514        } 
14911515    } 
14921516
1517+     /// Returns whether fixing `cond` will also fix `error`. 
1518+      #[ instrument( level = "debug" ,  skip( self ) ,  ret) ]  
1519+     fn  error_fixed_by ( & self ,  mut  error :  PredicateObligation < ' tcx > ,  cond :  ty:: Clause < ' tcx > )  -> bool  { 
1520+         self . probe ( |_| { 
1521+             let  ocx = ObligationCtxt :: new ( self ) ; 
1522+ 
1523+             let  clauses = elaborate ( self . tcx ,  std:: iter:: once ( cond) ) . collect :: < Vec < _ > > ( ) ; 
1524+             let  clauses = ocx. normalize ( & error. cause ,  error. param_env ,  clauses) ; 
1525+             let  mut  clauses = self . resolve_vars_if_possible ( clauses) ; 
1526+ 
1527+             if  clauses. has_infer ( )  { 
1528+                 return  false ; 
1529+             } 
1530+ 
1531+             clauses. extend ( error. param_env . caller_bounds ( ) ) ; 
1532+             let  clauses = self . tcx . mk_clauses ( & clauses) ; 
1533+             error. param_env  = ty:: ParamEnv :: new ( clauses,  error. param_env . reveal ( ) ) ; 
1534+ 
1535+             ocx. register_obligation ( error) ; 
1536+             ocx. select_all_or_error ( ) . is_empty ( ) 
1537+         } ) 
1538+     } 
1539+ 
14931540    #[ instrument( skip( self ) ,  level = "debug" ) ]  
14941541    fn  report_fulfillment_error ( & self ,  error :  & FulfillmentError < ' tcx > )  -> ErrorGuaranteed  { 
14951542        if  self . tcx . sess . opts . unstable_opts . next_solver . map ( |c| c. dump_tree ) . unwrap_or_default ( ) 
0 commit comments