Skip to content

Commit 2aa01e2

Browse files
authored
Unrolled build for rust-lang#140801
Rollup merge of rust-lang#140801 - xizheyin:issue-140747, r=SparrowLii Use span before macro expansion in lint for-loops-over-falibles Fixes rust-lang#140747 I think there are going to be a lot of cases where macros are expanded in the compiler resulting in span offsets, and I'd like to know how that's typically handled. Does it have to be handled specially every time?
2 parents a7b1b24 + 88c1796 commit 2aa01e2

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

compiler/rustc_lint/src/for_loops_over_fallibles.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
4949
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
5050
let Some((pat, arg)) = extract_for_loop(expr) else { return };
5151

52+
let arg_span = arg.span.source_callsite();
53+
5254
let ty = cx.typeck_results().expr_ty(arg);
5355

5456
let (adt, args, ref_mutability) = match ty.kind() {
@@ -78,27 +80,27 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
7880
&& let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
7981
{
8082
ForLoopsOverFalliblesLoopSub::RemoveNext {
81-
suggestion: recv.span.between(arg.span.shrink_to_hi()),
83+
suggestion: recv.span.between(arg_span.shrink_to_hi()),
8284
recv_snip,
8385
}
8486
} else {
8587
ForLoopsOverFalliblesLoopSub::UseWhileLet {
8688
start_span: expr.span.with_hi(pat.span.lo()),
87-
end_span: pat.span.between(arg.span),
89+
end_span: pat.span.between(arg_span),
8890
var,
8991
}
9092
};
9193
let question_mark = suggest_question_mark(cx, adt, args, expr.span)
92-
.then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
94+
.then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg_span.shrink_to_hi() });
9395
let suggestion = ForLoopsOverFalliblesSuggestion {
9496
var,
9597
start_span: expr.span.with_hi(pat.span.lo()),
96-
end_span: pat.span.between(arg.span),
98+
end_span: pat.span.between(arg_span),
9799
};
98100

99101
cx.emit_span_lint(
100102
FOR_LOOPS_OVER_FALLIBLES,
101-
arg.span,
103+
arg_span,
102104
ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
103105
);
104106
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![forbid(for_loops_over_fallibles)]
2+
3+
fn main() {
4+
macro_rules! x {
5+
() => {
6+
None::<i32>
7+
};
8+
}
9+
for _ in x! {} {} //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles]
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error: for loop over an `Option`. This is more readably written as an `if let` statement
2+
--> $DIR/macro-issue-140747.rs:9:14
3+
|
4+
LL | for _ in x! {} {}
5+
| ^^^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/macro-issue-140747.rs:1:11
9+
|
10+
LL | #![forbid(for_loops_over_fallibles)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^
12+
help: to check pattern in a loop use `while let`
13+
|
14+
LL - for _ in x! {} {}
15+
LL + while let Some(_) = x! {} {}
16+
|
17+
help: consider using `if let` to clear intent
18+
|
19+
LL - for _ in x! {} {}
20+
LL + if let Some(_) = x! {} {}
21+
|
22+
23+
error: aborting due to 1 previous error
24+

0 commit comments

Comments
 (0)