1- use super :: ambiguity:: TypeErrCtxtAmbiguityExt as _;
21use super :: on_unimplemented:: { AppendConstMessage , OnUnimplementedNote , TypeErrCtxtExt as _} ;
32use super :: suggestions:: { get_explanation_based_on_obligation, TypeErrCtxtExt as _} ;
43use crate :: error_reporting:: traits:: infer_ctxt_ext:: InferCtxtExt ;
5- use crate :: error_reporting:: traits:: overflow:: TypeErrCtxtOverflowExt ;
64use crate :: errors:: {
75 AsyncClosureNotFn , ClosureFnMutLabel , ClosureFnOnceLabel , ClosureKindMismatch ,
86} ;
@@ -12,12 +10,12 @@ use crate::infer::{self, InferCtxt};
1210use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
1311use crate :: traits:: NormalizeExt ;
1412use crate :: traits:: {
15- elaborate, FulfillmentError , FulfillmentErrorCode , MismatchedProjectionTypes , Obligation ,
16- ObligationCause , ObligationCauseCode , ObligationCtxt , Overflow , PredicateObligation ,
17- SelectionError , SignatureMismatch , TraitNotObjectSafe ,
13+ elaborate, MismatchedProjectionTypes , Obligation , ObligationCause , ObligationCauseCode ,
14+ ObligationCtxt , Overflow , PredicateObligation , SelectionError , SignatureMismatch ,
15+ TraitNotObjectSafe ,
1816} ;
1917use core:: ops:: ControlFlow ;
20- use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap } ;
18+ use rustc_data_structures:: fx:: FxHashMap ;
2119use rustc_data_structures:: unord:: UnordSet ;
2220use rustc_errors:: codes:: * ;
2321use rustc_errors:: { pluralize, struct_span_code_err, Applicability , StringPart } ;
@@ -44,138 +42,17 @@ use rustc_middle::ty::{
4442} ;
4543use rustc_middle:: { bug, span_bug} ;
4644use rustc_span:: symbol:: sym;
47- use rustc_span:: { BytePos , ExpnKind , Span , Symbol , DUMMY_SP } ;
45+ use rustc_span:: { BytePos , Span , Symbol , DUMMY_SP } ;
4846use std:: borrow:: Cow ;
49- use std:: iter;
5047
5148use super :: {
5249 ArgKind , CandidateSimilarity , GetSafeTransmuteErrorAndReason , ImplCandidate , UnsatisfiedConst ,
5350} ;
5451
5552pub use rustc_infer:: traits:: error_reporting:: * ;
5653
57- #[ extension( pub trait TypeErrCtxtExt <' a, ' tcx>) ]
54+ #[ extension( pub trait TypeErrCtxtSelectionErrExt <' a, ' tcx>) ]
5855impl < ' a , ' tcx > TypeErrCtxt < ' a , ' tcx > {
59- fn report_fulfillment_errors (
60- & self ,
61- mut errors : Vec < FulfillmentError < ' tcx > > ,
62- ) -> ErrorGuaranteed {
63- self . sub_relations
64- . borrow_mut ( )
65- . add_constraints ( self , errors. iter ( ) . map ( |e| e. obligation . predicate ) ) ;
66-
67- #[ derive( Debug ) ]
68- struct ErrorDescriptor < ' tcx > {
69- predicate : ty:: Predicate < ' tcx > ,
70- index : Option < usize > , // None if this is an old error
71- }
72-
73- let mut error_map: FxIndexMap < _ , Vec < _ > > = self
74- . reported_trait_errors
75- . borrow ( )
76- . iter ( )
77- . map ( |( & span, predicates) | {
78- (
79- span,
80- predicates
81- . 0
82- . iter ( )
83- . map ( |& predicate| ErrorDescriptor { predicate, index : None } )
84- . collect ( ) ,
85- )
86- } )
87- . collect ( ) ;
88-
89- // Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics
90- // with more relevant type information and hide redundant E0282 errors.
91- errors. sort_by_key ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
92- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) )
93- if self . tcx . is_lang_item ( pred. def_id ( ) , LangItem :: Sized ) =>
94- {
95- 1
96- }
97- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed ( _) ) => 3 ,
98- ty:: PredicateKind :: Coerce ( _) => 2 ,
99- _ => 0 ,
100- } ) ;
101-
102- for ( index, error) in errors. iter ( ) . enumerate ( ) {
103- // We want to ignore desugarings here: spans are equivalent even
104- // if one is the result of a desugaring and the other is not.
105- let mut span = error. obligation . cause . span ;
106- let expn_data = span. ctxt ( ) . outer_expn_data ( ) ;
107- if let ExpnKind :: Desugaring ( _) = expn_data. kind {
108- span = expn_data. call_site ;
109- }
110-
111- error_map. entry ( span) . or_default ( ) . push ( ErrorDescriptor {
112- predicate : error. obligation . predicate ,
113- index : Some ( index) ,
114- } ) ;
115- }
116-
117- // We do this in 2 passes because we want to display errors in order, though
118- // maybe it *is* better to sort errors by span or something.
119- let mut is_suppressed = vec ! [ false ; errors. len( ) ] ;
120- for ( _, error_set) in error_map. iter ( ) {
121- // We want to suppress "duplicate" errors with the same span.
122- for error in error_set {
123- if let Some ( index) = error. index {
124- // Suppress errors that are either:
125- // 1) strictly implied by another error.
126- // 2) implied by an error with a smaller index.
127- for error2 in error_set {
128- if error2. index . is_some_and ( |index2| is_suppressed[ index2] ) {
129- // Avoid errors being suppressed by already-suppressed
130- // errors, to prevent all errors from being suppressed
131- // at once.
132- continue ;
133- }
134-
135- if self . error_implies ( error2. predicate , error. predicate )
136- && !( error2. index >= error. index
137- && self . error_implies ( error. predicate , error2. predicate ) )
138- {
139- info ! ( "skipping {:?} (implied by {:?})" , error, error2) ;
140- is_suppressed[ index] = true ;
141- break ;
142- }
143- }
144- }
145- }
146- }
147-
148- let mut reported = None ;
149-
150- for from_expansion in [ false , true ] {
151- for ( error, suppressed) in iter:: zip ( & errors, & is_suppressed) {
152- if !suppressed && error. obligation . cause . span . from_expansion ( ) == from_expansion {
153- let guar = self . report_fulfillment_error ( error) ;
154- self . infcx . set_tainted_by_errors ( guar) ;
155- reported = Some ( guar) ;
156- // We want to ignore desugarings here: spans are equivalent even
157- // if one is the result of a desugaring and the other is not.
158- let mut span = error. obligation . cause . span ;
159- let expn_data = span. ctxt ( ) . outer_expn_data ( ) ;
160- if let ExpnKind :: Desugaring ( _) = expn_data. kind {
161- span = expn_data. call_site ;
162- }
163- self . reported_trait_errors
164- . borrow_mut ( )
165- . entry ( span)
166- . or_insert_with ( || ( vec ! [ ] , guar) )
167- . 0
168- . push ( error. obligation . predicate ) ;
169- }
170- }
171- }
172-
173- // It could be that we don't report an error because we have seen an `ErrorReported` from
174- // another source. We should probably be able to fix most of these, but some are delayed
175- // bugs that get a proper error after this function.
176- reported. unwrap_or_else ( || self . dcx ( ) . delayed_bug ( "failed to report fulfillment errors" ) )
177- }
178-
17956 /// The `root_obligation` parameter should be the `root_obligation` field
18057 /// from a `FulfillmentError`. If no `FulfillmentError` is available,
18158 /// then it should be the same as `obligation`.
@@ -803,7 +680,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
803680 self . point_at_returns_when_relevant ( & mut err, & obligation) ;
804681 err. emit ( )
805682 }
683+ }
806684
685+ #[ extension( pub ( super ) trait TypeErrCtxtExt <' a, ' tcx>) ]
686+ impl < ' a , ' tcx > TypeErrCtxt < ' a , ' tcx > {
807687 fn apply_do_not_recommend ( & self , obligation : & mut PredicateObligation < ' tcx > ) -> bool {
808688 let mut base_cause = obligation. cause . code ( ) . clone ( ) ;
809689 let mut applied_do_not_recommend = false ;
@@ -1324,72 +1204,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
13241204 }
13251205 }
13261206
1327- #[ instrument( skip( self ) , level = "debug" ) ]
1328- fn report_fulfillment_error ( & self , error : & FulfillmentError < ' tcx > ) -> ErrorGuaranteed {
1329- let mut error = FulfillmentError {
1330- obligation : error. obligation . clone ( ) ,
1331- code : error. code . clone ( ) ,
1332- root_obligation : error. root_obligation . clone ( ) ,
1333- } ;
1334- if matches ! (
1335- error. code,
1336- FulfillmentErrorCode :: Select ( crate :: traits:: SelectionError :: Unimplemented )
1337- | FulfillmentErrorCode :: Project ( _)
1338- ) && self . apply_do_not_recommend ( & mut error. obligation )
1339- {
1340- error. code = FulfillmentErrorCode :: Select ( SelectionError :: Unimplemented ) ;
1341- }
1342-
1343- match error. code {
1344- FulfillmentErrorCode :: Select ( ref selection_error) => self . report_selection_error (
1345- error. obligation . clone ( ) ,
1346- & error. root_obligation ,
1347- selection_error,
1348- ) ,
1349- FulfillmentErrorCode :: Project ( ref e) => {
1350- self . report_projection_error ( & error. obligation , e)
1351- }
1352- FulfillmentErrorCode :: Ambiguity { overflow : None } => {
1353- self . maybe_report_ambiguity ( & error. obligation )
1354- }
1355- FulfillmentErrorCode :: Ambiguity { overflow : Some ( suggest_increasing_limit) } => {
1356- self . report_overflow_no_abort ( error. obligation . clone ( ) , suggest_increasing_limit)
1357- }
1358- FulfillmentErrorCode :: Subtype ( ref expected_found, ref err) => self
1359- . report_mismatched_types (
1360- & error. obligation . cause ,
1361- expected_found. expected ,
1362- expected_found. found ,
1363- * err,
1364- )
1365- . emit ( ) ,
1366- FulfillmentErrorCode :: ConstEquate ( ref expected_found, ref err) => {
1367- let mut diag = self . report_mismatched_consts (
1368- & error. obligation . cause ,
1369- expected_found. expected ,
1370- expected_found. found ,
1371- * err,
1372- ) ;
1373- let code = error. obligation . cause . code ( ) . peel_derives ( ) . peel_match_impls ( ) ;
1374- if let ObligationCauseCode :: WhereClause ( ..)
1375- | ObligationCauseCode :: WhereClauseInExpr ( ..) = code
1376- {
1377- self . note_obligation_cause_code (
1378- error. obligation . cause . body_id ,
1379- & mut diag,
1380- error. obligation . predicate ,
1381- error. obligation . param_env ,
1382- code,
1383- & mut vec ! [ ] ,
1384- & mut Default :: default ( ) ,
1385- ) ;
1386- }
1387- diag. emit ( )
1388- }
1389- FulfillmentErrorCode :: Cycle ( ref cycle) => self . report_overflow_obligation_cycle ( cycle) ,
1390- }
1391- }
1392-
13931207 #[ instrument( level = "debug" , skip_all) ]
13941208 fn report_projection_error (
13951209 & self ,
0 commit comments