Skip to content

Commit b29a4f9

Browse files
authored
Rollup merge of rust-lang#105004 - TaKO8Ki:fix-104897, r=wesleywiser
Fix `emit_unused_delims_expr` ICE Fixes rust-lang#104897 This is also related to rust-lang#104433.
2 parents db416ea + 5c7278a commit b29a4f9

File tree

3 files changed

+75
-5
lines changed

3 files changed

+75
-5
lines changed

compiler/rustc_lint/src/unused.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -633,13 +633,34 @@ trait UnusedDelimLint {
633633
left_pos: Option<BytePos>,
634634
right_pos: Option<BytePos>,
635635
) {
636+
// If `value` has `ExprKind::Err`, unused delim lint can be broken.
637+
// For example, the following code caused ICE.
638+
// This is because the `ExprKind::Call` in `value` has `ExprKind::Err` as its argument
639+
// and this leads to wrong spans. #104897
640+
//
641+
// ```
642+
// fn f(){(print!(á
643+
// ```
644+
use rustc_ast::visit::{walk_expr, Visitor};
645+
struct ErrExprVisitor {
646+
has_error: bool,
647+
}
648+
impl<'ast> Visitor<'ast> for ErrExprVisitor {
649+
fn visit_expr(&mut self, expr: &'ast ast::Expr) {
650+
if let ExprKind::Err = expr.kind {
651+
self.has_error = true;
652+
return;
653+
}
654+
walk_expr(self, expr)
655+
}
656+
}
657+
let mut visitor = ErrExprVisitor { has_error: false };
658+
visitor.visit_expr(value);
659+
if visitor.has_error {
660+
return;
661+
}
636662
let spans = match value.kind {
637663
ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => {
638-
if let StmtKind::Expr(expr) = &block.stmts[0].kind
639-
&& let ExprKind::Err = expr.kind
640-
{
641-
return
642-
}
643664
if let Some(span) = block.stmts[0].span.find_ancestor_inside(value.span) {
644665
Some((value.span.with_hi(span.lo()), value.span.with_lo(span.hi())))
645666
} else {

src/test/ui/lint/issue-104897.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// error-pattern: this file contains an unclosed delimiter
2+
// error-pattern: this file contains an unclosed delimiter
3+
// error-pattern: this file contains an unclosed delimiter
4+
// error-pattern: format argument must be a string literal
5+
6+
fn f(){(print!(á

src/test/ui/lint/issue-104897.stderr

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error: this file contains an unclosed delimiter
2+
--> $DIR/issue-104897.rs:6:18
3+
|
4+
LL | fn f(){(print!(á
5+
| -- - ^
6+
| || |
7+
| || unclosed delimiter
8+
| |unclosed delimiter
9+
| unclosed delimiter
10+
11+
error: this file contains an unclosed delimiter
12+
--> $DIR/issue-104897.rs:6:18
13+
|
14+
LL | fn f(){(print!(á
15+
| -- - ^
16+
| || |
17+
| || unclosed delimiter
18+
| |unclosed delimiter
19+
| unclosed delimiter
20+
21+
error: this file contains an unclosed delimiter
22+
--> $DIR/issue-104897.rs:6:18
23+
|
24+
LL | fn f(){(print!(á
25+
| -- - ^
26+
| || |
27+
| || unclosed delimiter
28+
| |unclosed delimiter
29+
| unclosed delimiter
30+
31+
error: format argument must be a string literal
32+
--> $DIR/issue-104897.rs:6:16
33+
|
34+
LL | fn f(){(print!(á
35+
| ^
36+
|
37+
help: you might be missing a string literal to format with
38+
|
39+
LL | fn f(){(print!("{}", á
40+
| +++++
41+
42+
error: aborting due to 4 previous errors
43+

0 commit comments

Comments
 (0)