about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-12-06 16:54:53 +0100
committerGitHub <noreply@github.com>2022-12-06 16:54:53 +0100
commitb29a4f9bac50d1b1e24b90cc6de28af366825763 (patch)
tree4fcb6dc8560492bc418523f8dd5441ee513cbcfa
parentdb416ea195e46fa8f7c8adabc9e9b3e0b71f5c90 (diff)
parent5c7278a36412c1a0a06bab4f1364cf5719ab8287 (diff)
downloadrust-b29a4f9bac50d1b1e24b90cc6de28af366825763.tar.gz
rust-b29a4f9bac50d1b1e24b90cc6de28af366825763.zip
Rollup merge of #105004 - TaKO8Ki:fix-104897, r=wesleywiser
Fix `emit_unused_delims_expr` ICE

Fixes #104897

This is also related to #104433.
-rw-r--r--compiler/rustc_lint/src/unused.rs31
-rw-r--r--src/test/ui/lint/issue-104897.rs6
-rw-r--r--src/test/ui/lint/issue-104897.stderr43
3 files changed, 75 insertions, 5 deletions
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index a7836ea8e7a..b5db94f8c06 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -633,13 +633,34 @@ trait UnusedDelimLint {
         left_pos: Option<BytePos>,
         right_pos: Option<BytePos>,
     ) {
+        // 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 00000000000..5fbc658f155
--- /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 00000000000..817a93c2f3b
--- /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
+