Change:
Reported by here: (Note that but does not fix this bug.)
searched nightlies: from nightly-2021-01-07 to nightly-2021-12-24 regressed nightly: nightly-2021-09-12 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
This regression was introduced in . cc
Not a fix, but if I make this change then there is no longer an ICE and I get
Thanks for opening the issue If someone finds a fix but doesn't know how to add the test, this pull request which solves a similar ICE has an example of how to add a test when there is a missing newline:

Discussion:
use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; <del> use rustc_span::{BytePos, Span, DUMMY_SP}; </del> <ins> use rustc_span::{BytePos, Span}; </ins> declare_lint! { /// The `unused_must_use` lint detects unused result of a type flagged as

ast::ExprKind::Block(ref block, None) if block.stmts.len() > 0 => { let start = block.stmts[0].span; let end = block.stmts[block.stmts.len() - 1].span; <del> if value.span.from_expansion() || start.from_expansion() || end.from_expansion() { ( value.span.with_hi(value.span.lo() + BytePos(1)), value.span.with_lo(value.span.hi() - BytePos(1)), ) </del> <ins> if let Some(start) = start.find_ancestor_inside(value.span) && let Some(end) = end.find_ancestor_inside(value.span) { Some(( value.span.with_hi(start.lo()), value.span.with_lo(end.hi()), )) </ins> } else { <del> (value.span.with_hi(start.lo()), value.span.with_lo(end.hi())) </del> <ins> None </ins> } } ast::ExprKind::Paren(ref expr) => { <del> if value.span.from_expansion() || expr.span.from_expansion() { ( value.span.with_hi(value.span.lo() + BytePos(1)), value.span.with_lo(value.span.hi() - BytePos(1)), ) </del> <ins> let expr_span = expr.span.find_ancestor_inside(value.span); if let Some(expr_span) = expr_span { Some((value.span.with_hi(expr_span.lo()), value.span.with_lo(expr_span.hi()))) </ins> } else { <del> (value.span.with_hi(expr.span.lo()), value.span.with_lo(expr.span.hi())) </del> <ins> None </ins> } } _ => return,

left_pos.map_or(false, |s| s >= value.span.lo()), right_pos.map_or(false, |s| s <= value.span.hi()), ); <del> self.emit_unused_delims(cx, spans, ctx.into(), keep_space); </del> <ins> self.emit_unused_delims(cx, value.span, spans, ctx.into(), keep_space); </ins> } fn emit_unused_delims( &self, cx: &EarlyContext<'_>, <del> spans: (Span, Span), </del> <ins> value_span: Span, spans: Option<(Span, Span)>, </ins> msg: &str, keep_space: (bool, bool), ) { <del> // FIXME(flip1995): Quick and dirty fix for #70814. This should be fixed in rustdoc // properly. if spans.0 == DUMMY_SP || spans.1 == DUMMY_SP { return; } cx.struct_span_lint(self.lint(), MultiSpan::from(vec![spans.0, spans.1]), |lint| { let replacement = vec![ (spans.0, if keep_space.0 { " ".into() } else { "".into() }), (spans.1, if keep_space.1 { " ".into() } else { "".into() }), ]; lint.build(fluent::lint::unused_delim) .set_arg("delim", Self::DELIM_STR) .set_arg("item", msg) .multipart_suggestion( </del> <ins> let primary_span = if let Some((lo, hi)) = spans { MultiSpan::from(vec![lo, hi]) } else { MultiSpan::from(value_span) }; cx.struct_span_lint(self.lint(), primary_span, |lint| { let mut db = lint.build(fluent::lint::unused_delim); db.set_arg("delim", Self::DELIM_STR); db.set_arg("item", msg); if let Some((lo, hi)) = spans { let replacement = vec![ (lo, if keep_space.0 { " ".into() } else { "".into() }), (hi, if keep_space.1 { " ".into() } else { "".into() }), ]; db.multipart_suggestion( </ins> fluent::lint::suggestion, replacement, Applicability::MachineApplicable, <del> ) .emit(); </del> <ins> ); } db.emit(); </ins> }); }

// Otherwise proceed with linting. _ => {} } <del> let spans = if value.span.from_expansion() || inner.span.from_expansion() { ( value.span.with_hi(value.span.lo() + BytePos(1)), value.span.with_lo(value.span.hi() - BytePos(1)), ) </del> <ins> let spans = if let Some(inner) = inner.span.find_ancestor_inside(value.span) { Some((value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi()))) </ins> } else { <del> (value.span.with_hi(inner.span.lo()), value.span.with_lo(inner.span.hi())) </del> <ins> None </ins> }; <del> self.emit_unused_delims(cx, spans, "pattern", (false, false)); </del> <ins> self.emit_unused_delims(cx, value.span, spans, "pattern", (false, false)); </ins> } } }

); } _ => { <del> let spans = if ty.span.from_expansion() || r.span.from_expansion() { ( ty.span.with_hi(ty.span.lo() + BytePos(1)), ty.span.with_lo(ty.span.hi() - BytePos(1)), ) </del> <ins> let spans = if let Some(r) = r.span.find_ancestor_inside(ty.span) { Some((ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi()))) </ins> } else { <del> (ty.span.with_hi(r.span.lo()), ty.span.with_lo(r.span.hi())) </del> <ins> None </ins> }; <del> self.emit_unused_delims(cx, spans, "type", (false, false)); </del> <ins> self.emit_unused_delims(cx, ty.span, spans, "type", (false, false)); </ins> } } }

<ins> // ignore-tidy-trailing-newlines // // error-pattern: this file contains an unclosed delimiter // error-pattern: this file contains an unclosed delimiter // error-pattern: this file contains an unclosed delimiter // error-pattern: format argument must be a string literal // // Verify that unused parens lint does not try to create a span // which points in the middle of a multibyte character. fn f(){(print!(á </ins>  No newline at end of file

<ins> error: this file contains an unclosed delimiter --> $DIR/unused_parens_multibyte_recovery.rs:11:17 | LL | fn f(){(print!(á |       --      - ^ |       ||      | |       ||      unclosed delimiter |       |unclosed delimiter |       unclosed delimiter error: this file contains an unclosed delimiter --> $DIR/unused_parens_multibyte_recovery.rs:11:17 | LL | fn f(){(print!(á |       --      - ^ |       ||      | |       ||      unclosed delimiter |       |unclosed delimiter |       unclosed delimiter error: this file contains an unclosed delimiter --> $DIR/unused_parens_multibyte_recovery.rs:11:17 | LL | fn f(){(print!(á |       --      - ^ |       ||      | |       ||      unclosed delimiter |       |unclosed delimiter |       unclosed delimiter error: format argument must be a string literal --> $DIR/unused_parens_multibyte_recovery.rs:11:16 | LL | fn f(){(print!(á |                ^ | help: you might be missing a string literal to format with | LL | fn f(){(print!("{}", á |                +++++ error: aborting due to 4 previous errors </ins>