about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorTakayuki Maeda <takoyaki0316@gmail.com>2022-11-28 16:14:20 +0900
committerTakayuki Maeda <takoyaki0316@gmail.com>2022-12-02 17:01:21 +0900
commit5c7278a36412c1a0a06bab4f1364cf5719ab8287 (patch)
tree49f8a7b97d3d1bcf94fde57d2e4ca90185a95777 /compiler
parentc0e9c86b3f3e96267ba2cd80f95f362ef0cce40b (diff)
downloadrust-5c7278a36412c1a0a06bab4f1364cf5719ab8287.tar.gz
rust-5c7278a36412c1a0a06bab4f1364cf5719ab8287.zip
return when expr has error
fmt

add a comment
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_lint/src/unused.rs31
1 files changed, 26 insertions, 5 deletions
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 43864ed45fa..372b6d7a2b8 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -636,13 +636,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 {