@@ -69,7 +69,7 @@ use rustc_middle::ty::error::TypeError;
69
69
use rustc_middle:: ty:: {
70
70
self ,
71
71
subst:: { GenericArgKind , Subst , SubstsRef } ,
72
- Region , Ty , TyCtxt , TypeFoldable ,
72
+ DefIdTree , Region , Ty , TyCtxt , TypeFoldable ,
73
73
} ;
74
74
use rustc_span:: { sym, BytePos , DesugaringKind , MultiSpan , Pos , Span } ;
75
75
use rustc_target:: spec:: abi;
@@ -1439,9 +1439,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1439
1439
values = None ;
1440
1440
}
1441
1441
struct OpaqueTypesVisitor < ' tcx > {
1442
- types : FxHashMap < TyCategory , FxHashSet < Span > > ,
1443
- expected : FxHashMap < TyCategory , FxHashSet < Span > > ,
1444
- found : FxHashMap < TyCategory , FxHashSet < Span > > ,
1442
+ types : FxHashMap < TyCategory , FxHashSet < DefId > > ,
1443
+ expected : FxHashMap < TyCategory , FxHashSet < DefId > > ,
1444
+ found : FxHashMap < TyCategory , FxHashSet < DefId > > ,
1445
1445
ignore_span : Span ,
1446
1446
tcx : TyCtxt < ' tcx > ,
1447
1447
}
@@ -1479,42 +1479,68 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1479
1479
& self ,
1480
1480
err : & mut DiagnosticBuilder < ' _ > ,
1481
1481
target : & str ,
1482
- types : & FxHashMap < TyCategory , FxHashSet < Span > > ,
1482
+ types : & FxHashMap < TyCategory , FxHashSet < DefId > > ,
1483
1483
) {
1484
1484
for ( key, values) in types. iter ( ) {
1485
1485
let count = values. len ( ) ;
1486
1486
let kind = key. descr ( ) ;
1487
1487
let mut returned_async_output_error = false ;
1488
- for & sp in values {
1488
+ for & def_id in values {
1489
+ let sp = self . tcx . def_span ( def_id) ;
1490
+ let ( fn_name, fn_desc, fn_span) = match self . tcx . parent ( def_id) {
1491
+ Some ( def_id) => (
1492
+ format ! ( "`{}`" , self . tcx. def_path_str( def_id) ) ,
1493
+ format ! ( "the async function `{}`" , self . tcx. def_path_str( def_id) ) ,
1494
+ Some (
1495
+ self . tcx
1496
+ . hir ( )
1497
+ . get_if_local ( def_id)
1498
+ . and_then ( |node| node. ident ( ) )
1499
+ . map_or_else (
1500
+ || self . tcx . def_span ( def_id) ,
1501
+ |ident| ident. span ,
1502
+ ) ,
1503
+ ) ,
1504
+ ) ,
1505
+ None => (
1506
+ "the async function" . to_string ( ) ,
1507
+ "an async function" . to_string ( ) ,
1508
+ None ,
1509
+ ) ,
1510
+ } ;
1489
1511
if sp. is_desugaring ( DesugaringKind :: Async ) && !returned_async_output_error {
1490
1512
if & [ sp] != err. span . primary_spans ( ) {
1491
1513
let mut span: MultiSpan = sp. into ( ) ;
1492
- span. push_span_label (
1493
- sp,
1494
- format ! (
1495
- "checked the `Output` of this `async fn`, {}{} {}{}" ,
1496
- if count > 1 { "one of the " } else { "" } ,
1497
- target,
1498
- kind,
1499
- pluralize!( count) ,
1500
- ) ,
1501
- ) ;
1514
+ if let Some ( fn_span) = fn_span {
1515
+ span. push_span_label (
1516
+ fn_span,
1517
+ "async functions return futures" . to_string ( ) ,
1518
+ ) ;
1519
+ span. push_span_label (
1520
+ sp,
1521
+ format ! (
1522
+ "the desugared version of {} returns `impl Future<Output = {}>`" ,
1523
+ fn_name,
1524
+ if let Ok ( snippet) = self . tcx. sess. source_map( ) . span_to_snippet( sp) {
1525
+ snippet
1526
+ } else {
1527
+ "{async return type}" . to_string( )
1528
+ }
1529
+ ) ,
1530
+ ) ;
1531
+ } else {
1532
+ span. push_span_label (
1533
+ sp,
1534
+ format ! ( "{} returns a future" , fn_desc, ) ,
1535
+ ) ;
1536
+ }
1502
1537
err. span_note (
1503
1538
span,
1504
- "while checking the return type of the `async fn`" ,
1539
+ & format ! ( "while checking the return type of {}" , fn_desc ) ,
1505
1540
) ;
1506
1541
} else {
1507
- err. span_label (
1508
- sp,
1509
- format ! (
1510
- "checked the `Output` of this `async fn`, {}{} {}{}" ,
1511
- if count > 1 { "one of the " } else { "" } ,
1512
- target,
1513
- kind,
1514
- pluralize!( count) ,
1515
- ) ,
1516
- ) ;
1517
- err. note ( "while checking the return type of the `async fn`" ) ;
1542
+ err. span_label ( sp, format ! ( "{} returns a future" , fn_desc) ) ;
1543
+ err. note ( & format ! ( "while checking the return type of {}" , fn_name) ) ;
1518
1544
}
1519
1545
returned_async_output_error = true ;
1520
1546
} else {
@@ -1552,7 +1578,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1552
1578
// = note: expected unit type `()`
1553
1579
// found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14 x:_]`
1554
1580
if !self . ignore_span . overlaps ( span) {
1555
- self . types . entry ( kind) . or_default ( ) . insert ( span ) ;
1581
+ self . types . entry ( kind) . or_default ( ) . insert ( def_id ) ;
1556
1582
}
1557
1583
}
1558
1584
t. super_visit_with ( self )
@@ -2539,7 +2565,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
2539
2565
2540
2566
/// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks
2541
2567
/// extra information about each type, but we only care about the category.
2542
- #[ derive( Clone , Copy , PartialEq , Eq , Hash ) ]
2568
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
2543
2569
pub enum TyCategory {
2544
2570
Closure ,
2545
2571
Opaque ,
0 commit comments