@@ -1570,36 +1570,121 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
15701570 format ! ( "does not implement `{}`" , trait_ref. print_only_trait_path( ) )
15711571 } ;
15721572
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+ }
15881686 }
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+ } ;
16031688 match interior_or_upvar_span {
16041689 GeneratorInteriorOrUpvar :: Interior ( interior_span) => {
16051690 if let Some ( ( scope_span, yield_span, expr, from_awaited_ty) ) = interior_extra_info {
0 commit comments