@@ -1570,36 +1570,130 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1570
1570
format ! ( "does not implement `{}`" , trait_ref. print_only_trait_path( ) )
1571
1571
} ;
1572
1572
1573
- let mut explain_yield = |interior_span : Span ,
1574
- yield_span : Span ,
1575
- scope_span : Option < Span > | {
1576
- let mut span = MultiSpan :: from_span ( yield_span) ;
1577
- if let Ok ( snippet) = source_map. span_to_snippet ( interior_span) {
1578
- span. push_span_label (
1579
- yield_span,
1580
- format ! ( "{} occurs here, with `{}` maybe used later" , await_or_yield, snippet) ,
1581
- ) ;
1582
- // If available, use the scope span to annotate the drop location.
1583
- if let Some ( scope_span) = scope_span {
1584
- span. push_span_label (
1585
- source_map. end_point ( scope_span) ,
1586
- format ! ( "`{}` is later dropped here" , snippet) ,
1587
- ) ;
1573
+ let mut explain_yield =
1574
+ |interior_span : Span , yield_span : Span , scope_span : Option < Span > | {
1575
+ let mut span = MultiSpan :: from_span ( yield_span) ;
1576
+ if let Ok ( snippet) = source_map. span_to_snippet ( interior_span) {
1577
+ // #70935: If snippet contains newlines, display "the value" instead
1578
+ // so that we do not emit complex diagnostics.
1579
+ let snippet = & format ! ( "`{}`" , snippet) ;
1580
+ let snippet = if snippet. contains ( '\n' ) { "the value" } else { snippet } ;
1581
+ // The multispan can be complex here, like:
1582
+ // note: future is not `Send` as this value is used across an await
1583
+ // --> $DIR/issue-70935-complex-spans.rs:13:9
1584
+ // |
1585
+ // LL | baz(|| async{
1586
+ // | __________^___-
1587
+ // | | _________|
1588
+ // | ||
1589
+ // LL | || foo(tx.clone());
1590
+ // LL | || }).await;
1591
+ // | || - ^- value is later dropped here
1592
+ // | ||_________|______|
1593
+ // | |__________| await occurs here, with value maybe used later
1594
+ // | has type `closure` which is not `Send`
1595
+ //
1596
+ // So, detect it and separate into some notes, like:
1597
+ //
1598
+ // note: future is not `Send` as this value is used across an await
1599
+ // --> $DIR/issue-70935-complex-spans.rs:13:9
1600
+ // |
1601
+ // LL | / baz(|| async{
1602
+ // LL | | foo(tx.clone());
1603
+ // LL | | }).await;
1604
+ // | |________________^ first, await occurs here, with the value maybe used later...
1605
+ // note: the value is later dropped here
1606
+ // --> $DIR/issue-70935-complex-spans.rs:15:17
1607
+ // |
1608
+ // LL | }).await;
1609
+ // | ^
1610
+ //
1611
+ // If available, use the scope span to annotate the drop location.
1612
+ if let Some ( scope_span) = scope_span {
1613
+ let scope_span = source_map. end_point ( scope_span) ;
1614
+ let is_overlapped =
1615
+ yield_span. overlaps ( scope_span) || yield_span. overlaps ( interior_span) ;
1616
+ if is_overlapped {
1617
+ span. push_span_label (
1618
+ yield_span,
1619
+ format ! (
1620
+ "first, {} occurs here, with {} maybe used later..." ,
1621
+ await_or_yield, snippet
1622
+ ) ,
1623
+ ) ;
1624
+ err. span_note (
1625
+ span,
1626
+ & format ! (
1627
+ "{} {} as this value is used across {}" ,
1628
+ future_or_generator, trait_explanation, an_await_or_yield
1629
+ ) ,
1630
+ ) ;
1631
+ if source_map. is_multiline ( interior_span) {
1632
+ err. span_note (
1633
+ scope_span,
1634
+ & format ! ( "{} is later dropped here" , snippet) ,
1635
+ ) ;
1636
+ err. span_note (
1637
+ interior_span,
1638
+ & format ! (
1639
+ "this has type `{}` which {}" ,
1640
+ target_ty, trait_explanation
1641
+ ) ,
1642
+ ) ;
1643
+ } else {
1644
+ let mut span = MultiSpan :: from_span ( scope_span) ;
1645
+ span. push_span_label (
1646
+ interior_span,
1647
+ format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1648
+ ) ;
1649
+ err. span_note ( span, & format ! ( "{} is later dropped here" , snippet) ) ;
1650
+ }
1651
+ } else {
1652
+ span. push_span_label (
1653
+ yield_span,
1654
+ format ! (
1655
+ "{} occurs here, with {} maybe used later" ,
1656
+ await_or_yield, snippet
1657
+ ) ,
1658
+ ) ;
1659
+ span. push_span_label (
1660
+ scope_span,
1661
+ format ! ( "{} is later dropped here" , snippet) ,
1662
+ ) ;
1663
+ span. push_span_label (
1664
+ interior_span,
1665
+ format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1666
+ ) ;
1667
+ err. span_note (
1668
+ span,
1669
+ & format ! (
1670
+ "{} {} as this value is used across {}" ,
1671
+ future_or_generator, trait_explanation, an_await_or_yield
1672
+ ) ,
1673
+ ) ;
1674
+ }
1675
+ } else {
1676
+ span. push_span_label (
1677
+ yield_span,
1678
+ format ! (
1679
+ "{} occurs here, with {} maybe used later" ,
1680
+ await_or_yield, snippet
1681
+ ) ,
1682
+ ) ;
1683
+ span. push_span_label (
1684
+ interior_span,
1685
+ format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1686
+ ) ;
1687
+ err. span_note (
1688
+ span,
1689
+ & format ! (
1690
+ "{} {} as this value is used across {}" ,
1691
+ future_or_generator, trait_explanation, an_await_or_yield
1692
+ ) ,
1693
+ ) ;
1694
+ }
1588
1695
}
1589
- }
1590
- span. push_span_label (
1591
- interior_span,
1592
- format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1593
- ) ;
1594
-
1595
- err. span_note (
1596
- span,
1597
- & format ! (
1598
- "{} {} as this value is used across {}" ,
1599
- future_or_generator, trait_explanation, an_await_or_yield
1600
- ) ,
1601
- ) ;
1602
- } ;
1696
+ } ;
1603
1697
match interior_or_upvar_span {
1604
1698
GeneratorInteriorOrUpvar :: Interior ( interior_span) => {
1605
1699
if let Some ( ( scope_span, yield_span, expr, from_awaited_ty) ) = interior_extra_info {
0 commit comments