@@ -1596,8 +1596,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
15961596 {
15971597 let e = self . tcx . erase_regions ( e) ;
15981598 let f = self . tcx . erase_regions ( f) ;
1599- let expected = with_forced_trimmed_paths ! ( e. sort_string( self . tcx) ) ;
1600- let found = with_forced_trimmed_paths ! ( f. sort_string( self . tcx) ) ;
1599+ let mut expected = with_forced_trimmed_paths ! ( e. sort_string( self . tcx) ) ;
1600+ let mut found = with_forced_trimmed_paths ! ( f. sort_string( self . tcx) ) ;
1601+ if let Some ( def_id) = cause. span . ctxt ( ) . outer_expn_data ( ) . macro_def_id
1602+ && self . tcx . is_diagnostic_item ( sym:: assert_macro, def_id)
1603+ {
1604+ // When the type error comes from `assert!()`, the cause and effect are reversed
1605+ // because that macro expands to `match val { false => {panic!()}, _ => {} }`, which
1606+ // would say something like "expected `Type`, found `bool`", confusing the user.
1607+ ( found, expected) = ( expected, found) ;
1608+ }
16011609 if expected == found {
16021610 label_or_note ( span, terr. to_string ( self . tcx ) ) ;
16031611 } else {
@@ -2114,7 +2122,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21142122 ) -> Option < ( DiagStyledString , DiagStyledString , Option < PathBuf > ) > {
21152123 match values {
21162124 ValuePairs :: Regions ( exp_found) => self . expected_found_str ( exp_found) ,
2117- ValuePairs :: Terms ( exp_found) => self . expected_found_str_term ( exp_found) ,
2125+ ValuePairs :: Terms ( exp_found) => self . expected_found_str_term ( cause , exp_found) ,
21182126 ValuePairs :: Aliases ( exp_found) => self . expected_found_str ( exp_found) ,
21192127 ValuePairs :: ExistentialTraitRef ( exp_found) => self . expected_found_str ( exp_found) ,
21202128 ValuePairs :: ExistentialProjection ( exp_found) => self . expected_found_str ( exp_found) ,
@@ -2155,14 +2163,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21552163
21562164 fn expected_found_str_term (
21572165 & self ,
2166+ cause : & ObligationCause < ' tcx > ,
21582167 exp_found : ty:: error:: ExpectedFound < ty:: Term < ' tcx > > ,
21592168 ) -> Option < ( DiagStyledString , DiagStyledString , Option < PathBuf > ) > {
21602169 let exp_found = self . resolve_vars_if_possible ( exp_found) ;
21612170 if exp_found. references_error ( ) {
21622171 return None ;
21632172 }
2173+ let ( mut expected, mut found) = ( exp_found. expected , exp_found. found ) ;
2174+ if let Some ( def_id) = cause. span . ctxt ( ) . outer_expn_data ( ) . macro_def_id
2175+ && self . tcx . is_diagnostic_item ( sym:: assert_macro, def_id)
2176+ {
2177+ // When the type error comes from `assert!()`, the cause and effect are reversed
2178+ // because that macro expands to `match val { false => {panic!()}, _ => {} }`, which
2179+ // would say something like
2180+ // = note: expected `Type`
2181+ // found `bool`"
2182+ ( expected, found) = ( found, expected) ;
2183+ }
21642184
2165- Some ( match ( exp_found . expected . unpack ( ) , exp_found . found . unpack ( ) ) {
2185+ Some ( match ( expected. unpack ( ) , found. unpack ( ) ) {
21662186 ( ty:: TermKind :: Ty ( expected) , ty:: TermKind :: Ty ( found) ) => {
21672187 let ( mut exp, mut fnd) = self . cmp ( expected, found) ;
21682188 // Use the terminal width as the basis to determine when to compress the printed
0 commit comments