@@ -457,7 +457,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
457457 span,
458458 format ! ( "this is an iterator with items of type `{}`" , args. type_at( 0 ) ) ,
459459 ) ;
460- } else {
460+ } else if !span . overlaps ( cause . span ) {
461461 let expected_ty = self . tcx . short_string ( expected_ty, err. long_ty_path ( ) ) ;
462462 err. span_label ( span, format ! ( "this expression has type `{expected_ty}`" ) ) ;
463463 }
@@ -1618,8 +1618,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
16181618 {
16191619 let e = self . tcx . erase_regions ( e) ;
16201620 let f = self . tcx . erase_regions ( f) ;
1621- let expected = with_forced_trimmed_paths ! ( e. sort_string( self . tcx) ) ;
1622- let found = with_forced_trimmed_paths ! ( f. sort_string( self . tcx) ) ;
1621+ let mut expected = with_forced_trimmed_paths ! ( e. sort_string( self . tcx) ) ;
1622+ let mut found = with_forced_trimmed_paths ! ( f. sort_string( self . tcx) ) ;
1623+ if let Some ( def_id) = cause. span . ctxt ( ) . outer_expn_data ( ) . macro_def_id
1624+ && self . tcx . is_diagnostic_item ( sym:: assert_macro, def_id)
1625+ {
1626+ // When the type error comes from `assert!()`, the cause and effect are reversed
1627+ // because that macro expands to `match val { false => {panic!()}, _ => {} }`, which
1628+ // would say something like "expected `Type`, found `bool`", confusing the user.
1629+ ( found, expected) = ( expected, found) ;
1630+ }
16231631 if expected == found {
16241632 label_or_note ( span, terr. to_string ( self . tcx ) ) ;
16251633 } else {
@@ -2141,7 +2149,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21412149 ) -> Option < ( DiagStyledString , DiagStyledString ) > {
21422150 match values {
21432151 ValuePairs :: Regions ( exp_found) => self . expected_found_str ( exp_found) ,
2144- ValuePairs :: Terms ( exp_found) => self . expected_found_str_term ( exp_found, file) ,
2152+ ValuePairs :: Terms ( exp_found) => self . expected_found_str_term ( cause , exp_found, file) ,
21452153 ValuePairs :: Aliases ( exp_found) => self . expected_found_str ( exp_found) ,
21462154 ValuePairs :: ExistentialTraitRef ( exp_found) => self . expected_found_str ( exp_found) ,
21472155 ValuePairs :: ExistentialProjection ( exp_found) => self . expected_found_str ( exp_found) ,
@@ -2180,15 +2188,27 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21802188
21812189 fn expected_found_str_term (
21822190 & self ,
2191+ cause : & ObligationCause < ' tcx > ,
21832192 exp_found : ty:: error:: ExpectedFound < ty:: Term < ' tcx > > ,
21842193 path : & mut Option < PathBuf > ,
21852194 ) -> Option < ( DiagStyledString , DiagStyledString ) > {
21862195 let exp_found = self . resolve_vars_if_possible ( exp_found) ;
21872196 if exp_found. references_error ( ) {
21882197 return None ;
21892198 }
2199+ let ( mut expected, mut found) = ( exp_found. expected , exp_found. found ) ;
2200+ if let Some ( def_id) = cause. span . ctxt ( ) . outer_expn_data ( ) . macro_def_id
2201+ && self . tcx . is_diagnostic_item ( sym:: assert_macro, def_id)
2202+ {
2203+ // When the type error comes from `assert!()`, the cause and effect are reversed
2204+ // because that macro expands to `match val { false => {panic!()}, _ => {} }`, which
2205+ // would say something like
2206+ // = note: expected `Type`
2207+ // found `bool`"
2208+ ( expected, found) = ( found, expected) ;
2209+ }
21902210
2191- Some ( match ( exp_found . expected . kind ( ) , exp_found . found . kind ( ) ) {
2211+ Some ( match ( expected. kind ( ) , found. kind ( ) ) {
21922212 ( ty:: TermKind :: Ty ( expected) , ty:: TermKind :: Ty ( found) ) => {
21932213 let ( mut exp, mut fnd) = self . cmp ( expected, found) ;
21942214 // Use the terminal width as the basis to determine when to compress the printed
0 commit comments