Various fixes for handling of macros (#16296)
Closes rust-lang/rust-clippy#16293 Also contains fixes of several other lints, on handling macros changelog: [`checked_conversions`] fix wrongly unmangled macros changelog: [`manual_ignore_case_cmp`] fix wrongly unmangled macros changelog: [`manual_ilog2`] fix wrongly unmangled macros changelog: [`needless_bool_assign`] fix wrongly unmangled macros changelog: [`manual_is_multiple_of`] fix wrongly unmangled macros
This commit is contained in:
commit
7481abcc88
20 changed files with 274 additions and 37 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal, sym};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind};
|
||||
|
|
@ -80,7 +80,8 @@ impl LateLintPass<'_> for CheckedConversions {
|
|||
&& self.msrv.meets(cx, msrvs::TRY_FROM)
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let snippet = snippet_with_applicability(cx, cv.expr_to_cast.span, "_", &mut applicability);
|
||||
let (snippet, _) =
|
||||
snippet_with_context(cx, cv.expr_to_cast.span, item.span.ctxt(), "_", &mut applicability);
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
CHECKED_CONVERSIONS,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::manual_ignore_case_cmp::MatchType::{Literal, ToAscii};
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::res::MaybeDef;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::sym;
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
|
|
@ -111,14 +111,12 @@ impl LateLintPass<'_> for ManualIgnoreCaseCmp {
|
|||
"manual case-insensitive ASCII comparison",
|
||||
|diag| {
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let (left_snip, _) = snippet_with_context(cx, left_span, expr.span.ctxt(), "..", &mut app);
|
||||
let (right_snip, _) = snippet_with_context(cx, right_span, expr.span.ctxt(), "..", &mut app);
|
||||
diag.span_suggestion_verbose(
|
||||
expr.span,
|
||||
"consider using `.eq_ignore_ascii_case()` instead",
|
||||
format!(
|
||||
"{neg}{}.eq_ignore_ascii_case({deref}{})",
|
||||
snippet_with_applicability(cx, left_span, "_", &mut app),
|
||||
snippet_with_applicability(cx, right_span, "_", &mut app)
|
||||
),
|
||||
format!("{neg}{left_snip}.eq_ignore_ascii_case({deref}{right_snip})"),
|
||||
app,
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::{is_from_proc_macro, sym};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_data_structures::packed::Pu128;
|
||||
|
|
@ -102,7 +102,7 @@ impl LateLintPass<'_> for ManualIlog2 {
|
|||
|
||||
fn emit(cx: &LateContext<'_>, recv: &Expr<'_>, full_expr: &Expr<'_>) {
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let recv = snippet_with_applicability(cx, recv.span, "_", &mut app);
|
||||
let (recv, _) = snippet_with_context(cx, recv.span, full_expr.span.ctxt(), "_", &mut app);
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
MANUAL_ILOG2,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{
|
||||
SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_parent_stmt, is_receiver_of_method_call,
|
||||
|
|
@ -171,8 +171,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
|
|||
&& SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b)
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let cond = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability);
|
||||
let lhs = snippet_with_applicability(cx, lhs_a.span, "..", &mut applicability);
|
||||
let cond = Sugg::hir_with_context(cx, cond, e.span.ctxt(), "..", &mut applicability);
|
||||
let (lhs, _) = snippet_with_context(cx, lhs_a.span, e.span.ctxt(), "..", &mut applicability);
|
||||
let mut sugg = if a == b {
|
||||
format!("{cond}; {lhs} = {a:?};")
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(
|
|||
{
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let divisor = deref_sugg(
|
||||
Sugg::hir_with_applicability(cx, operand_right, "_", &mut app),
|
||||
Sugg::hir_with_context(cx, operand_right, expr.span.ctxt(), "_", &mut app),
|
||||
cx.typeck_results().expr_ty_adjusted(operand_right),
|
||||
);
|
||||
span_lint_and_sugg(
|
||||
|
|
@ -47,7 +47,7 @@ pub(super) fn check<'tcx>(
|
|||
format!(
|
||||
"{}{}.is_multiple_of({divisor})",
|
||||
if op == BinOpKind::Eq { "" } else { "!" },
|
||||
Sugg::hir_with_applicability(cx, operand_left, "_", &mut app).maybe_paren()
|
||||
Sugg::hir_with_context(cx, operand_left, expr.span.ctxt(), "_", &mut app).maybe_paren()
|
||||
),
|
||||
app,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(
|
||||
clippy::cast_lossless,
|
||||
clippy::legacy_numeric_constants,
|
||||
clippy::no_effect,
|
||||
unused,
|
||||
// Int::max_value will be deprecated in the future
|
||||
deprecated,
|
||||
|
|
@ -105,4 +106,19 @@ fn msrv_1_34() {
|
|||
//~^ checked_conversions
|
||||
}
|
||||
|
||||
fn issue16293() {
|
||||
struct Outer {
|
||||
inner: u32,
|
||||
}
|
||||
let outer = Outer { inner: 42 };
|
||||
macro_rules! dot_inner {
|
||||
($obj:expr) => {
|
||||
$obj.inner
|
||||
};
|
||||
}
|
||||
|
||||
i32::try_from(dot_inner!(outer)).is_ok();
|
||||
//~^ checked_conversions
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(
|
||||
clippy::cast_lossless,
|
||||
clippy::legacy_numeric_constants,
|
||||
clippy::no_effect,
|
||||
unused,
|
||||
// Int::max_value will be deprecated in the future
|
||||
deprecated,
|
||||
|
|
@ -105,4 +106,19 @@ fn msrv_1_34() {
|
|||
//~^ checked_conversions
|
||||
}
|
||||
|
||||
fn issue16293() {
|
||||
struct Outer {
|
||||
inner: u32,
|
||||
}
|
||||
let outer = Outer { inner: 42 };
|
||||
macro_rules! dot_inner {
|
||||
($obj:expr) => {
|
||||
$obj.inner
|
||||
};
|
||||
}
|
||||
|
||||
dot_inner!(outer) <= i32::MAX as u32;
|
||||
//~^ checked_conversions
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:15:13
|
||||
--> tests/ui/checked_conversions.rs:16:13
|
||||
|
|
||||
LL | let _ = value <= (u32::max_value() as i64) && value >= 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
|
||||
|
|
@ -8,100 +8,106 @@ LL | let _ = value <= (u32::max_value() as i64) && value >= 0;
|
|||
= help: to override `-D warnings` add `#[allow(clippy::checked_conversions)]`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:17:13
|
||||
--> tests/ui/checked_conversions.rs:18:13
|
||||
|
|
||||
LL | let _ = value <= (u32::MAX as i64) && value >= 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:22:13
|
||||
--> tests/ui/checked_conversions.rs:23:13
|
||||
|
|
||||
LL | let _ = value <= i64::from(u16::max_value()) && value >= 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:24:13
|
||||
--> tests/ui/checked_conversions.rs:25:13
|
||||
|
|
||||
LL | let _ = value <= i64::from(u16::MAX) && value >= 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:29:13
|
||||
--> tests/ui/checked_conversions.rs:30:13
|
||||
|
|
||||
LL | let _ = value <= (u8::max_value() as isize) && value >= 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:31:13
|
||||
--> tests/ui/checked_conversions.rs:32:13
|
||||
|
|
||||
LL | let _ = value <= (u8::MAX as isize) && value >= 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:38:13
|
||||
--> tests/ui/checked_conversions.rs:39:13
|
||||
|
|
||||
LL | let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:40:13
|
||||
--> tests/ui/checked_conversions.rs:41:13
|
||||
|
|
||||
LL | let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:45:13
|
||||
--> tests/ui/checked_conversions.rs:46:13
|
||||
|
|
||||
LL | let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:47:13
|
||||
--> tests/ui/checked_conversions.rs:48:13
|
||||
|
|
||||
LL | let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:54:13
|
||||
--> tests/ui/checked_conversions.rs:55:13
|
||||
|
|
||||
LL | let _ = value <= i32::max_value() as u32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:56:13
|
||||
--> tests/ui/checked_conversions.rs:57:13
|
||||
|
|
||||
LL | let _ = value <= i32::MAX as u32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:61:13
|
||||
--> tests/ui/checked_conversions.rs:62:13
|
||||
|
|
||||
LL | let _ = value <= isize::max_value() as usize && value as i32 == 5;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:63:13
|
||||
--> tests/ui/checked_conversions.rs:64:13
|
||||
|
|
||||
LL | let _ = value <= isize::MAX as usize && value as i32 == 5;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:68:13
|
||||
--> tests/ui/checked_conversions.rs:69:13
|
||||
|
|
||||
LL | let _ = value <= u16::max_value() as u32 && value as i32 == 5;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:70:13
|
||||
--> tests/ui/checked_conversions.rs:71:13
|
||||
|
|
||||
LL | let _ = value <= u16::MAX as u32 && value as i32 == 5;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
|
||||
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:104:13
|
||||
--> tests/ui/checked_conversions.rs:105:13
|
||||
|
|
||||
LL | let _ = value <= (u32::max_value() as i64) && value >= 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
error: checked cast can be simplified
|
||||
--> tests/ui/checked_conversions.rs:120:5
|
||||
|
|
||||
LL | dot_inner!(outer) <= i32::MAX as u32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(dot_inner!(outer)).is_ok()`
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -160,3 +160,23 @@ fn ref_osstring(a: OsString, b: &OsString) {
|
|||
b.eq_ignore_ascii_case(a);
|
||||
//~^ manual_ignore_case_cmp
|
||||
}
|
||||
|
||||
fn wrongly_unmangled_macros(a: &str, b: &str) -> bool {
|
||||
struct S<'a> {
|
||||
inner: &'a str,
|
||||
}
|
||||
|
||||
let a = S { inner: a };
|
||||
let b = S { inner: b };
|
||||
|
||||
macro_rules! dot_inner {
|
||||
($s:expr) => {
|
||||
$s.inner
|
||||
};
|
||||
}
|
||||
|
||||
dot_inner!(a).eq_ignore_ascii_case(dot_inner!(b))
|
||||
//~^ manual_ignore_case_cmp
|
||||
|| dot_inner!(a).eq_ignore_ascii_case("abc")
|
||||
//~^ manual_ignore_case_cmp
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,3 +160,23 @@ fn ref_osstring(a: OsString, b: &OsString) {
|
|||
b.to_ascii_lowercase() == a.to_ascii_lowercase();
|
||||
//~^ manual_ignore_case_cmp
|
||||
}
|
||||
|
||||
fn wrongly_unmangled_macros(a: &str, b: &str) -> bool {
|
||||
struct S<'a> {
|
||||
inner: &'a str,
|
||||
}
|
||||
|
||||
let a = S { inner: a };
|
||||
let b = S { inner: b };
|
||||
|
||||
macro_rules! dot_inner {
|
||||
($s:expr) => {
|
||||
$s.inner
|
||||
};
|
||||
}
|
||||
|
||||
dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase()
|
||||
//~^ manual_ignore_case_cmp
|
||||
|| dot_inner!(a).to_ascii_lowercase() == "abc"
|
||||
//~^ manual_ignore_case_cmp
|
||||
}
|
||||
|
|
|
|||
|
|
@ -588,5 +588,29 @@ LL - b.to_ascii_lowercase() == a.to_ascii_lowercase();
|
|||
LL + b.eq_ignore_ascii_case(a);
|
||||
|
|
||||
|
||||
error: aborting due to 49 previous errors
|
||||
error: manual case-insensitive ASCII comparison
|
||||
--> tests/ui/manual_ignore_case_cmp.rs:178:5
|
||||
|
|
||||
LL | dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider using `.eq_ignore_ascii_case()` instead
|
||||
|
|
||||
LL - dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase()
|
||||
LL + dot_inner!(a).eq_ignore_ascii_case(dot_inner!(b))
|
||||
|
|
||||
|
||||
error: manual case-insensitive ASCII comparison
|
||||
--> tests/ui/manual_ignore_case_cmp.rs:180:12
|
||||
|
|
||||
LL | || dot_inner!(a).to_ascii_lowercase() == "abc"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider using `.eq_ignore_ascii_case()` instead
|
||||
|
|
||||
LL - || dot_inner!(a).to_ascii_lowercase() == "abc"
|
||||
LL + || dot_inner!(a).eq_ignore_ascii_case("abc")
|
||||
|
|
||||
|
||||
error: aborting due to 51 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -30,3 +30,20 @@ fn foo(a: u32, b: u64) {
|
|||
external!($a.ilog(2));
|
||||
with_span!(span; a.ilog(2));
|
||||
}
|
||||
|
||||
fn wrongly_unmangled_macros() {
|
||||
struct S {
|
||||
inner: u32,
|
||||
}
|
||||
|
||||
let x = S { inner: 42 };
|
||||
macro_rules! access {
|
||||
($s:expr) => {
|
||||
$s.inner
|
||||
};
|
||||
}
|
||||
let log = access!(x).ilog2();
|
||||
//~^ manual_ilog2
|
||||
let log = access!(x).ilog2();
|
||||
//~^ manual_ilog2
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,3 +30,20 @@ fn foo(a: u32, b: u64) {
|
|||
external!($a.ilog(2));
|
||||
with_span!(span; a.ilog(2));
|
||||
}
|
||||
|
||||
fn wrongly_unmangled_macros() {
|
||||
struct S {
|
||||
inner: u32,
|
||||
}
|
||||
|
||||
let x = S { inner: 42 };
|
||||
macro_rules! access {
|
||||
($s:expr) => {
|
||||
$s.inner
|
||||
};
|
||||
}
|
||||
let log = 31 - access!(x).leading_zeros();
|
||||
//~^ manual_ilog2
|
||||
let log = access!(x).ilog(2);
|
||||
//~^ manual_ilog2
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,5 +19,17 @@ error: manually reimplementing `ilog2`
|
|||
LL | 63 - b.leading_zeros();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `b.ilog2()`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: manually reimplementing `ilog2`
|
||||
--> tests/ui/manual_ilog2.rs:45:15
|
||||
|
|
||||
LL | let log = 31 - access!(x).leading_zeros();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `access!(x).ilog2()`
|
||||
|
||||
error: manually reimplementing `ilog2`
|
||||
--> tests/ui/manual_ilog2.rs:47:15
|
||||
|
|
||||
LL | let log = access!(x).ilog(2);
|
||||
| ^^^^^^^^^^^^^^^^^^ help: try: `access!(x).ilog2()`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -101,3 +101,19 @@ mod issue15103 {
|
|||
(1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum()
|
||||
}
|
||||
}
|
||||
|
||||
fn wrongly_unmangled_macros(a: u32, b: u32) {
|
||||
struct Wrapper(u32);
|
||||
let a = Wrapper(a);
|
||||
let b = Wrapper(b);
|
||||
macro_rules! dot_0 {
|
||||
($x:expr) => {
|
||||
$x.0
|
||||
};
|
||||
}
|
||||
|
||||
if dot_0!(a).is_multiple_of(dot_0!(b)) {
|
||||
//~^ manual_is_multiple_of
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,3 +101,19 @@ mod issue15103 {
|
|||
(1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum()
|
||||
}
|
||||
}
|
||||
|
||||
fn wrongly_unmangled_macros(a: u32, b: u32) {
|
||||
struct Wrapper(u32);
|
||||
let a = Wrapper(a);
|
||||
let b = Wrapper(b);
|
||||
macro_rules! dot_0 {
|
||||
($x:expr) => {
|
||||
$x.0
|
||||
};
|
||||
}
|
||||
|
||||
if dot_0!(a) % dot_0!(b) == 0 {
|
||||
//~^ manual_is_multiple_of
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,5 +67,11 @@ error: manual implementation of `.is_multiple_of()`
|
|||
LL | let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n % i == 0).sum() };
|
||||
| ^^^^^^^^^^ help: replace with: `n.is_multiple_of(*i)`
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
error: manual implementation of `.is_multiple_of()`
|
||||
--> tests/ui/manual_is_multiple_of.rs:115:8
|
||||
|
|
||||
LL | if dot_0!(a) % dot_0!(b) == 0 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `dot_0!(a).is_multiple_of(dot_0!(b))`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -42,3 +42,22 @@ fn issue15063(x: bool, y: bool) {
|
|||
} else { z = x || y; }
|
||||
//~^^^^^ needless_bool_assign
|
||||
}
|
||||
|
||||
fn wrongly_unmangled_macros(must_keep: fn(usize, usize) -> bool, x: usize, y: usize) {
|
||||
struct Wrapper<T>(T);
|
||||
let mut skip = Wrapper(false);
|
||||
|
||||
macro_rules! invoke {
|
||||
($func:expr, $a:expr, $b:expr) => {
|
||||
$func($a, $b)
|
||||
};
|
||||
}
|
||||
macro_rules! dot_0 {
|
||||
($w:expr) => {
|
||||
$w.0
|
||||
};
|
||||
}
|
||||
|
||||
dot_0!(skip) = !invoke!(must_keep, x, y);
|
||||
//~^^^^^ needless_bool_assign
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,3 +58,26 @@ fn issue15063(x: bool, y: bool) {
|
|||
}
|
||||
//~^^^^^ needless_bool_assign
|
||||
}
|
||||
|
||||
fn wrongly_unmangled_macros(must_keep: fn(usize, usize) -> bool, x: usize, y: usize) {
|
||||
struct Wrapper<T>(T);
|
||||
let mut skip = Wrapper(false);
|
||||
|
||||
macro_rules! invoke {
|
||||
($func:expr, $a:expr, $b:expr) => {
|
||||
$func($a, $b)
|
||||
};
|
||||
}
|
||||
macro_rules! dot_0 {
|
||||
($w:expr) => {
|
||||
$w.0
|
||||
};
|
||||
}
|
||||
|
||||
if invoke!(must_keep, x, y) {
|
||||
dot_0!(skip) = false;
|
||||
} else {
|
||||
dot_0!(skip) = true;
|
||||
}
|
||||
//~^^^^^ needless_bool_assign
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,5 +62,15 @@ LL | | z = false;
|
|||
LL | | }
|
||||
| |_____^ help: you can reduce it to: `{ z = x || y; }`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: this if-then-else expression assigns a bool literal
|
||||
--> tests/ui/needless_bool_assign.rs:77:5
|
||||
|
|
||||
LL | / if invoke!(must_keep, x, y) {
|
||||
LL | | dot_0!(skip) = false;
|
||||
LL | | } else {
|
||||
LL | | dot_0!(skip) = true;
|
||||
LL | | }
|
||||
| |_____^ help: you can reduce it to: `dot_0!(skip) = !invoke!(must_keep, x, y);`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue