@@ -21,7 +21,7 @@ use rustc_infer::traits::{
2121} ;
2222use rustc_middle:: ty:: print:: { PrintTraitRefExt as _, with_no_trimmed_paths} ;
2323use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
24- use rustc_span:: { ErrorGuaranteed , ExpnKind , Span } ;
24+ use rustc_span:: { DesugaringKind , ErrorGuaranteed , ExpnKind , Span } ;
2525use tracing:: { info, instrument} ;
2626
2727pub use self :: overflow:: * ;
@@ -154,9 +154,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
154154 } )
155155 . collect ( ) ;
156156
157- // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last.
157+ // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last,
158+ // and `Subtype` obligations from `FormatLiteral` desugarings come first.
158159 // This lets us display diagnostics with more relevant type information and hide redundant
159160 // E0282 errors.
161+ #[ derive( Debug , PartialEq , Eq , PartialOrd , Ord ) ]
162+ enum ErrorSortKey {
163+ SubtypeFormat ( usize , usize ) ,
164+ OtherKind ,
165+ SizedTrait ,
166+ MetaSizedTrait ,
167+ PointeeSizedTrait ,
168+ Coerce ,
169+ WellFormed ,
170+ }
160171 errors. sort_by_key ( |e| {
161172 let maybe_sizedness_did = match e. obligation . predicate . kind ( ) . skip_binder ( ) {
162173 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => Some ( pred. def_id ( ) ) ,
@@ -165,12 +176,30 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
165176 } ;
166177
167178 match e. obligation . predicate . kind ( ) . skip_binder ( ) {
168- _ if maybe_sizedness_did == self . tcx . lang_items ( ) . sized_trait ( ) => 1 ,
169- _ if maybe_sizedness_did == self . tcx . lang_items ( ) . meta_sized_trait ( ) => 2 ,
170- _ if maybe_sizedness_did == self . tcx . lang_items ( ) . pointee_sized_trait ( ) => 3 ,
171- ty:: PredicateKind :: Coerce ( _) => 4 ,
172- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed ( _) ) => 5 ,
173- _ => 0 ,
179+ ty:: PredicateKind :: Subtype ( _)
180+ if matches ! (
181+ e. obligation. cause. span. desugaring_kind( ) ,
182+ Some ( DesugaringKind :: FormatLiteral { .. } )
183+ ) =>
184+ {
185+ let ( _, row, col, ..) =
186+ self . tcx . sess . source_map ( ) . span_to_location_info ( e. obligation . cause . span ) ;
187+ ErrorSortKey :: SubtypeFormat ( row, col)
188+ }
189+ _ if maybe_sizedness_did == self . tcx . lang_items ( ) . sized_trait ( ) => {
190+ ErrorSortKey :: SizedTrait
191+ }
192+ _ if maybe_sizedness_did == self . tcx . lang_items ( ) . meta_sized_trait ( ) => {
193+ ErrorSortKey :: MetaSizedTrait
194+ }
195+ _ if maybe_sizedness_did == self . tcx . lang_items ( ) . pointee_sized_trait ( ) => {
196+ ErrorSortKey :: PointeeSizedTrait
197+ }
198+ ty:: PredicateKind :: Coerce ( _) => ErrorSortKey :: Coerce ,
199+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed ( _) ) => {
200+ ErrorSortKey :: WellFormed
201+ }
202+ _ => ErrorSortKey :: OtherKind ,
174203 }
175204 } ) ;
176205
0 commit comments