@@ -1570,36 +1570,121 @@ 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
+ // = note: the return type of a function must have a statically known size
1596
+ // So, detect it and separate into some notes, like:
1597
+ // note: future is not `Send` as this value is used across an await
1598
+ // --> $DIR/issue-70935-complex-spans.rs:13:9
1599
+ // |
1600
+ // LL | / baz(|| async{
1601
+ // LL | | foo(tx.clone());
1602
+ // LL | | }).await;
1603
+ // | |________________^
1604
+ // note: first, await occurs here, with the value maybe used later
1605
+ // --> $DIR/issue-70935-complex-spans.rs:13:9
1606
+ // |
1607
+ // LL | / baz(|| async{
1608
+ // LL | | foo(tx.clone());
1609
+ // LL | | }).await;
1610
+ // | |________________^
1611
+ // note: ...but, the value is later dropped here
1612
+ // --> $DIR/issue-70935-complex-spans.rs:15:17
1613
+ // |
1614
+ // LL | }).await;
1615
+ // | ^
1616
+ // = note: the return type of a function must have a statically known size
1617
+
1618
+ // If available, use the scope span to annotate the drop location.
1619
+ if let Some ( scope_span) = scope_span {
1620
+ let scope_span = source_map. end_point ( scope_span) ;
1621
+ let is_overlapped =
1622
+ yield_span. overlaps ( scope_span) || yield_span. overlaps ( interior_span) ;
1623
+ if is_overlapped {
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
+ err. span_note (
1632
+ yield_span,
1633
+ & format ! (
1634
+ "first, {} occurs here, with {} maybe used later" ,
1635
+ await_or_yield, snippet
1636
+ ) ,
1637
+ ) ;
1638
+ err. span_note (
1639
+ scope_span,
1640
+ & format ! ( "...but, {} is later dropped here" , snippet) ,
1641
+ ) ;
1642
+ } else {
1643
+ span. push_span_label (
1644
+ yield_span,
1645
+ format ! (
1646
+ "{} occurs here, with {} maybe used later" ,
1647
+ await_or_yield, snippet
1648
+ ) ,
1649
+ ) ;
1650
+ span. push_span_label (
1651
+ scope_span,
1652
+ format ! ( "{} is later dropped here" , snippet) ,
1653
+ ) ;
1654
+ span. push_span_label (
1655
+ interior_span,
1656
+ format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1657
+ ) ;
1658
+ err. span_note (
1659
+ span,
1660
+ & format ! (
1661
+ "{} {} as this value is used across {}" ,
1662
+ future_or_generator, trait_explanation, an_await_or_yield
1663
+ ) ,
1664
+ ) ;
1665
+ }
1666
+ } else {
1667
+ span. push_span_label (
1668
+ yield_span,
1669
+ format ! (
1670
+ "{} occurs here, with {} maybe used later" ,
1671
+ await_or_yield, snippet
1672
+ ) ,
1673
+ ) ;
1674
+ span. push_span_label (
1675
+ interior_span,
1676
+ format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1677
+ ) ;
1678
+ err. span_note (
1679
+ span,
1680
+ & format ! (
1681
+ "{} {} as this value is used across {}" ,
1682
+ future_or_generator, trait_explanation, an_await_or_yield
1683
+ ) ,
1684
+ ) ;
1685
+ }
1588
1686
}
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
- } ;
1687
+ } ;
1603
1688
match interior_or_upvar_span {
1604
1689
GeneratorInteriorOrUpvar :: Interior ( interior_span) => {
1605
1690
if let Some ( ( scope_span, yield_span, expr, from_awaited_ty) ) = interior_extra_info {
0 commit comments