mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
Use span before macro expansion in lint for-loops-over-falibles
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
This commit is contained in:
parent
c0f0b5157f
commit
88c1796384
@ -49,6 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
|
|||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
let Some((pat, arg)) = extract_for_loop(expr) else { return };
|
let Some((pat, arg)) = extract_for_loop(expr) else { return };
|
||||||
|
|
||||||
|
let arg_span = arg.span.source_callsite();
|
||||||
|
|
||||||
let ty = cx.typeck_results().expr_ty(arg);
|
let ty = cx.typeck_results().expr_ty(arg);
|
||||||
|
|
||||||
let (adt, args, ref_mutability) = match ty.kind() {
|
let (adt, args, ref_mutability) = match ty.kind() {
|
||||||
@ -78,27 +80,27 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
|
|||||||
&& let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
|
&& let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
|
||||||
{
|
{
|
||||||
ForLoopsOverFalliblesLoopSub::RemoveNext {
|
ForLoopsOverFalliblesLoopSub::RemoveNext {
|
||||||
suggestion: recv.span.between(arg.span.shrink_to_hi()),
|
suggestion: recv.span.between(arg_span.shrink_to_hi()),
|
||||||
recv_snip,
|
recv_snip,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ForLoopsOverFalliblesLoopSub::UseWhileLet {
|
ForLoopsOverFalliblesLoopSub::UseWhileLet {
|
||||||
start_span: expr.span.with_hi(pat.span.lo()),
|
start_span: expr.span.with_hi(pat.span.lo()),
|
||||||
end_span: pat.span.between(arg.span),
|
end_span: pat.span.between(arg_span),
|
||||||
var,
|
var,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let question_mark = suggest_question_mark(cx, adt, args, expr.span)
|
let question_mark = suggest_question_mark(cx, adt, args, expr.span)
|
||||||
.then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
|
.then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg_span.shrink_to_hi() });
|
||||||
let suggestion = ForLoopsOverFalliblesSuggestion {
|
let suggestion = ForLoopsOverFalliblesSuggestion {
|
||||||
var,
|
var,
|
||||||
start_span: expr.span.with_hi(pat.span.lo()),
|
start_span: expr.span.with_hi(pat.span.lo()),
|
||||||
end_span: pat.span.between(arg.span),
|
end_span: pat.span.between(arg_span),
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.emit_span_lint(
|
cx.emit_span_lint(
|
||||||
FOR_LOOPS_OVER_FALLIBLES,
|
FOR_LOOPS_OVER_FALLIBLES,
|
||||||
arg.span,
|
arg_span,
|
||||||
ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
|
ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
macro_rules! x {
|
macro_rules! x {
|
||||||
() => {
|
() => {
|
||||||
None::<i32> //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles]
|
None::<i32>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
for _ in x! {} {}
|
for _ in x! {} {} //~ ERROR for loop over an `Option`. This is more readably written as an `if let` statement [for_loops_over_fallibles]
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,23 @@
|
|||||||
error: for loop over an `Option`. This is more readably written as an `if let` statement
|
error: for loop over an `Option`. This is more readably written as an `if let` statement
|
||||||
--> $DIR/macro-issue-140747.rs:6:13
|
--> $DIR/macro-issue-140747.rs:9:14
|
||||||
|
|
|
|
||||||
LL | None::<i32>
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | for _ in x! {} {}
|
LL | for _ in x! {} {}
|
||||||
| ----- in this macro invocation
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/macro-issue-140747.rs:1:11
|
--> $DIR/macro-issue-140747.rs:1:11
|
||||||
|
|
|
|
||||||
LL | #![forbid(for_loops_over_fallibles)]
|
LL | #![forbid(for_loops_over_fallibles)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: this error originates in the macro `x` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
help: to check pattern in a loop use `while let`
|
help: to check pattern in a loop use `while let`
|
||||||
|
|
|
|
||||||
LL ~ ) =
|
LL - for _ in x! {} {}
|
||||||
LL | };
|
LL + while let Some(_) = x! {} {}
|
||||||
LL | }
|
|
||||||
LL ~ while let Some(_ in x! {} {}
|
|
||||||
|
|
|
|
||||||
help: consider using `if let` to clear intent
|
help: consider using `if let` to clear intent
|
||||||
|
|
|
|
||||||
LL ~ ) =
|
LL - for _ in x! {} {}
|
||||||
LL | };
|
LL + if let Some(_) = x! {} {}
|
||||||
LL | }
|
|
||||||
LL ~ if let Some(_ in x! {} {}
|
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
Loading…
Reference in New Issue
Block a user