diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 43864ed45fae2..372b6d7a2b8c3 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -636,13 +636,34 @@ trait UnusedDelimLint { left_pos: Option, right_pos: Option, ) { + // If `value` has `ExprKind::Err`, unused delim lint can be broken. + // For example, the following code caused ICE. + // This is because the `ExprKind::Call` in `value` has `ExprKind::Err` as its argument + // and this leads to wrong spans. #104897 + // + // ``` + // fn f(){(print!(á + // ``` + use rustc_ast::visit::{walk_expr, Visitor}; + struct ErrExprVisitor { + has_error: bool, + } + impl<'ast> Visitor<'ast> for ErrExprVisitor { + fn visit_expr(&mut self, expr: &'ast ast::Expr) { + if let ExprKind::Err = expr.kind { + self.has_error = true; + return; + } + walk_expr(self, expr) + } + } + let mut visitor = ErrExprVisitor { has_error: false }; + visitor.visit_expr(value); + if visitor.has_error { + return; + } let spans = match value.kind { ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => { - if let StmtKind::Expr(expr) = &block.stmts[0].kind - && let ExprKind::Err = expr.kind - { - return - } if let Some(span) = block.stmts[0].span.find_ancestor_inside(value.span) { Some((value.span.with_hi(span.lo()), value.span.with_lo(span.hi()))) } else { diff --git a/src/test/ui/lint/issue-104897.rs b/src/test/ui/lint/issue-104897.rs new file mode 100644 index 0000000000000..5fbc658f1557c --- /dev/null +++ b/src/test/ui/lint/issue-104897.rs @@ -0,0 +1,6 @@ +// 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 + +fn f(){(print!(á diff --git a/src/test/ui/lint/issue-104897.stderr b/src/test/ui/lint/issue-104897.stderr new file mode 100644 index 0000000000000..817a93c2f3bb2 --- /dev/null +++ b/src/test/ui/lint/issue-104897.stderr @@ -0,0 +1,43 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-104897.rs:6:18 + | +LL | fn f(){(print!(á + | -- - ^ + | || | + | || unclosed delimiter + | |unclosed delimiter + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-104897.rs:6:18 + | +LL | fn f(){(print!(á + | -- - ^ + | || | + | || unclosed delimiter + | |unclosed delimiter + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-104897.rs:6:18 + | +LL | fn f(){(print!(á + | -- - ^ + | || | + | || unclosed delimiter + | |unclosed delimiter + | unclosed delimiter + +error: format argument must be a string literal + --> $DIR/issue-104897.rs:6: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 +