@@ -1429,13 +1429,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1429
1429
}
1430
1430
}
1431
1431
1432
+ /// Extend a type error with extra labels pointing at "non-trivial" types, like closures and
1433
+ /// the return type of `async fn`s.
1434
+ ///
1435
+ /// `secondary_span` gives the caller the opportunity to expand `diag` with a `span_label`.
1436
+ ///
1437
+ /// `swap_secondary_and_primary` is used to make projection errors in particular nicer by using
1438
+ /// the message in `secondary_span` as the primary label, and apply the message that would
1439
+ /// otherwise be used for the primary label on the `secondary_span` `Span`. This applies on
1440
+ /// E0271, like `src/test/ui/issues/issue-39970.stderr`.
1432
1441
pub fn note_type_err (
1433
1442
& self ,
1434
1443
diag : & mut DiagnosticBuilder < ' tcx > ,
1435
1444
cause : & ObligationCause < ' tcx > ,
1436
1445
secondary_span : Option < ( Span , String ) > ,
1437
1446
mut values : Option < ValuePairs < ' tcx > > ,
1438
1447
terr : & TypeError < ' tcx > ,
1448
+ swap_secondary_and_primary : bool ,
1439
1449
) {
1440
1450
let span = cause. span ( self . tcx ) ;
1441
1451
debug ! ( "note_type_err cause={:?} values={:?}, terr={:?}" , cause, values, terr) ;
@@ -1612,9 +1622,32 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1612
1622
match terr {
1613
1623
TypeError :: ObjectUnsafeCoercion ( _) => { }
1614
1624
_ => {
1615
- diag. span_label ( span, terr. to_string ( ) ) ;
1625
+ let mut label_or_note = |span : Span , msg : & str | {
1626
+ if & [ span] == diag. span . primary_spans ( ) {
1627
+ diag. span_label ( span, msg) ;
1628
+ } else {
1629
+ diag. span_note ( span, msg) ;
1630
+ }
1631
+ } ;
1616
1632
if let Some ( ( sp, msg) ) = secondary_span {
1617
- diag. span_label ( sp, msg) ;
1633
+ if swap_secondary_and_primary {
1634
+ let terr = if let Some ( infer:: ValuePairs :: Types ( infer:: ExpectedFound {
1635
+ expected,
1636
+ ..
1637
+ } ) ) = values
1638
+ {
1639
+ format ! ( "expected this to be `{}`" , expected)
1640
+ } else {
1641
+ terr. to_string ( )
1642
+ } ;
1643
+ label_or_note ( sp, & terr) ;
1644
+ label_or_note ( span, & msg) ;
1645
+ } else {
1646
+ label_or_note ( span, & terr. to_string ( ) ) ;
1647
+ label_or_note ( sp, & msg) ;
1648
+ }
1649
+ } else {
1650
+ label_or_note ( span, & terr. to_string ( ) ) ;
1618
1651
}
1619
1652
}
1620
1653
} ;
@@ -2048,7 +2081,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2048
2081
struct_span_err ! ( self . tcx. sess, span, E0644 , "{}" , failure_str)
2049
2082
}
2050
2083
} ;
2051
- self . note_type_err ( & mut diag, & trace. cause , None , Some ( trace. values ) , terr) ;
2084
+ self . note_type_err ( & mut diag, & trace. cause , None , Some ( trace. values ) , terr, false ) ;
2052
2085
diag
2053
2086
}
2054
2087
0 commit comments