@@ -1619,8 +1619,18 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
16191619 {
16201620 let e = self . tcx . erase_regions ( e) ;
16211621 let f = self . tcx . erase_regions ( f) ;
1622- let expected = with_forced_trimmed_paths ! ( e. sort_string( self . tcx) ) ;
1623- let found = with_forced_trimmed_paths ! ( f. sort_string( self . tcx) ) ;
1622+ let mut expected = with_forced_trimmed_paths ! ( e. sort_string( self . tcx) ) ;
1623+ let mut found = with_forced_trimmed_paths ! ( f. sort_string( self . tcx) ) ;
1624+ if let ObligationCauseCode :: Pattern { span, .. } = cause. code ( )
1625+ && let Some ( span) = span
1626+ && !span. from_expansion ( )
1627+ && cause. span . from_expansion ( )
1628+ {
1629+ // When the type error comes from a macro like `assert!()`, and we are pointing at
1630+ // code the user wrote the cause and effect are reversed as the expected value is
1631+ // what the macro expanded to.
1632+ ( found, expected) = ( expected, found) ;
1633+ }
16241634 if expected == found {
16251635 label_or_note ( span, terr. to_string ( self . tcx ) ) ;
16261636 } else {
@@ -2143,7 +2153,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21432153 ) -> Option < ( DiagStyledString , DiagStyledString ) > {
21442154 match values {
21452155 ValuePairs :: Regions ( exp_found) => self . expected_found_str ( exp_found) ,
2146- ValuePairs :: Terms ( exp_found) => self . expected_found_str_term ( exp_found, long_ty_path) ,
2156+ ValuePairs :: Terms ( exp_found) => {
2157+ self . expected_found_str_term ( cause, exp_found, long_ty_path)
2158+ }
21472159 ValuePairs :: Aliases ( exp_found) => self . expected_found_str ( exp_found) ,
21482160 ValuePairs :: ExistentialTraitRef ( exp_found) => self . expected_found_str ( exp_found) ,
21492161 ValuePairs :: ExistentialProjection ( exp_found) => self . expected_found_str ( exp_found) ,
@@ -2182,15 +2194,35 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21822194
21832195 fn expected_found_str_term (
21842196 & self ,
2197+ cause : & ObligationCause < ' tcx > ,
21852198 exp_found : ty:: error:: ExpectedFound < ty:: Term < ' tcx > > ,
21862199 long_ty_path : & mut Option < PathBuf > ,
21872200 ) -> Option < ( DiagStyledString , DiagStyledString ) > {
21882201 let exp_found = self . resolve_vars_if_possible ( exp_found) ;
21892202 if exp_found. references_error ( ) {
21902203 return None ;
21912204 }
2205+ let ( mut expected, mut found) = ( exp_found. expected , exp_found. found ) ;
2206+
2207+ if let ObligationCauseCode :: Pattern { span, .. } = cause. code ( )
2208+ && let Some ( span) = span
2209+ && !span. from_expansion ( )
2210+ && cause. span . from_expansion ( )
2211+ {
2212+ // When the type error comes from a macro like `assert!()`, and we are pointing at
2213+ // code the user wrote, the cause and effect are reversed as the expected value is
2214+ // what the macro expanded to. So if the user provided a `Type` when the macro is
2215+ // written in such a way that a `bool` was expected, we want to print:
2216+ // = note: expected `bool`
2217+ // found `Type`"
2218+ // but as far as the compiler is concerned, after expansion what was expected was `Type`
2219+ // = note: expected `Type`
2220+ // found `bool`"
2221+ // so we reverse them here to match user expectation.
2222+ ( expected, found) = ( found, expected) ;
2223+ }
21922224
2193- Some ( match ( exp_found . expected . kind ( ) , exp_found . found . kind ( ) ) {
2225+ Some ( match ( expected. kind ( ) , found. kind ( ) ) {
21942226 ( ty:: TermKind :: Ty ( expected) , ty:: TermKind :: Ty ( found) ) => {
21952227 let ( mut exp, mut fnd) = self . cmp ( expected, found) ;
21962228 // Use the terminal width as the basis to determine when to compress the printed
0 commit comments