Auto merge of #10453 - Jarcho:test_utils, r=dswij

Add utility macros to help with writing tests.

Adds two utility macros to help with testing:
* `external` expands to it's argument tokens, but makes them appear to come from an external macro. Helps make tests for `in_external_macro` much more readable.
* `inline_macros` is an attribute macro which allows the use of a pseudo `inline!` macro which expands to it's argument tokens, but makes them appear to be from a crate-local macro expansion. This removes the need to write `macro_rules` boilerplate when testing how lints interact with macros.

---

`external`'s usage is simple. `external!(struct Foo { x: u32});` will make the struct appear as though it came from an external macro. Individual tokens can be escaped if needed. `external!($x + 0 / 10)` will make everything except `x` appear as though it came from an external macro. Can also use `$literal` and `$(tokens...)` as well.

---

`inline_macros` is more complicated due to compiler constraints. Given:
```rust
#[inline_macros]
fn foo() {
    inline!(5 + 5 / 10);
}
```
`inline!(5 + 5 / 10)` will be replace with a call to a generated macro which expands to the contained tokens.

Tokens can be escaped by prefixing them with `$`:
```rust
#[inline_macros]
fn foo() {
    let x = 5;
    inline!($x + 5 / $10);
}
```
This will pass `x` as an `ident` argument and `10` as a `literal` argument.

Token sequences can also be passed with `$(...)`:
```rust
#[inline_macros]
fn foo() {
    let mut x = 5;
    inline!(if $(x >= 5) {
        $x = 5;
    });
}
```
This will pass `x >= 5` as `tt` arguments, and `x` as an `ident` argument.

---

Not 100% sure `inline_macros` is actually worth having. It does make the tests a little easier to read once you're used to it and it becomes more useful once there are multiple macro tests. The verbosity of declaring single use macros starts to hurt at that point.

changelog: None
This commit is contained in:
bors 2023-03-12 21:36:47 +00:00
commit e65ad6f5d0
86 changed files with 1179 additions and 1098 deletions

View File

@ -1,6 +1,6 @@
// run-rustfix // run-rustfix
// edition:2018 // edition:2018
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![feature(exclusive_range_pattern)] #![feature(exclusive_range_pattern)]
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
@ -9,33 +9,10 @@
#![allow(clippy::needless_parens_on_range_literals)] #![allow(clippy::needless_parens_on_range_literals)]
#![allow(clippy::double_parens)] #![allow(clippy::double_parens)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
macro_rules! a {
() => {
'a'
};
}
macro_rules! A {
() => {
'A'
};
}
macro_rules! zero {
() => {
'0'
};
}
macro_rules! b {
() => {
let _ = 'a'..='z';
let _ = 'A'..='Z';
let _ = '0'..='9';
};
}
#[inline_macros]
fn main() { fn main() {
#[rustfmt::skip] #[rustfmt::skip]
{ {
@ -56,9 +33,9 @@ fn main() {
let _ = b'B'..b'Z'; let _ = b'B'..b'Z';
let _ = b'1'..b'9'; let _ = b'1'..b'9';
let _ = a!()..='z'; let _ = inline!('a')..='z';
let _ = A!()..='Z'; let _ = inline!('A')..='Z';
let _ = zero!()..='9'; let _ = inline!('0')..='9';
let _ = match 0u8 { let _ = match 0u8 {
b'a'..=b'z' if true => 1, b'a'..=b'z' if true => 1,
@ -80,8 +57,16 @@ fn main() {
_ => 7, _ => 7,
}; };
almost_complete_range!(); external!(
b!(); let _ = 'a'..'z';
let _ = 'A'..'Z';
let _ = '0'..'9';
);
inline!(
let _ = 'a'..='z';
let _ = 'A'..='Z';
let _ = '0'..='9';
);
} }
#[clippy::msrv = "1.25"] #[clippy::msrv = "1.25"]

View File

@ -1,6 +1,6 @@
// run-rustfix // run-rustfix
// edition:2018 // edition:2018
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![feature(exclusive_range_pattern)] #![feature(exclusive_range_pattern)]
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
@ -9,33 +9,10 @@
#![allow(clippy::needless_parens_on_range_literals)] #![allow(clippy::needless_parens_on_range_literals)]
#![allow(clippy::double_parens)] #![allow(clippy::double_parens)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
macro_rules! a {
() => {
'a'
};
}
macro_rules! A {
() => {
'A'
};
}
macro_rules! zero {
() => {
'0'
};
}
macro_rules! b {
() => {
let _ = 'a'..'z';
let _ = 'A'..'Z';
let _ = '0'..'9';
};
}
#[inline_macros]
fn main() { fn main() {
#[rustfmt::skip] #[rustfmt::skip]
{ {
@ -56,9 +33,9 @@ fn main() {
let _ = b'B'..b'Z'; let _ = b'B'..b'Z';
let _ = b'1'..b'9'; let _ = b'1'..b'9';
let _ = a!()..'z'; let _ = inline!('a')..'z';
let _ = A!()..'Z'; let _ = inline!('A')..'Z';
let _ = zero!()..'9'; let _ = inline!('0')..'9';
let _ = match 0u8 { let _ = match 0u8 {
b'a'..b'z' if true => 1, b'a'..b'z' if true => 1,
@ -80,8 +57,16 @@ fn main() {
_ => 7, _ => 7,
}; };
almost_complete_range!(); external!(
b!(); let _ = 'a'..'z';
let _ = 'A'..'Z';
let _ = '0'..'9';
);
inline!(
let _ = 'a'..'z';
let _ = 'A'..'Z';
let _ = '0'..'9';
);
} }
#[clippy::msrv = "1.25"] #[clippy::msrv = "1.25"]

View File

@ -1,5 +1,5 @@
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:42:17 --> $DIR/almost_complete_range.rs:19:17
| |
LL | let _ = ('a') ..'z'; LL | let _ = ('a') ..'z';
| ^^^^^^--^^^ | ^^^^^^--^^^
@ -9,7 +9,7 @@ LL | let _ = ('a') ..'z';
= note: `-D clippy::almost-complete-range` implied by `-D warnings` = note: `-D clippy::almost-complete-range` implied by `-D warnings`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:43:17 --> $DIR/almost_complete_range.rs:20:17
| |
LL | let _ = 'A' .. ('Z'); LL | let _ = 'A' .. ('Z');
| ^^^^--^^^^^^ | ^^^^--^^^^^^
@ -17,7 +17,7 @@ LL | let _ = 'A' .. ('Z');
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:44:17 --> $DIR/almost_complete_range.rs:21:17
| |
LL | let _ = ((('0'))) .. ('9'); LL | let _ = ((('0'))) .. ('9');
| ^^^^^^^^^^--^^^^^^ | ^^^^^^^^^^--^^^^^^
@ -25,7 +25,7 @@ LL | let _ = ((('0'))) .. ('9');
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:51:13 --> $DIR/almost_complete_range.rs:28:13
| |
LL | let _ = (b'a')..(b'z'); LL | let _ = (b'a')..(b'z');
| ^^^^^^--^^^^^^ | ^^^^^^--^^^^^^
@ -33,7 +33,7 @@ LL | let _ = (b'a')..(b'z');
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:52:13 --> $DIR/almost_complete_range.rs:29:13
| |
LL | let _ = b'A'..b'Z'; LL | let _ = b'A'..b'Z';
| ^^^^--^^^^ | ^^^^--^^^^
@ -41,7 +41,7 @@ LL | let _ = b'A'..b'Z';
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:53:13 --> $DIR/almost_complete_range.rs:30:13
| |
LL | let _ = b'0'..b'9'; LL | let _ = b'0'..b'9';
| ^^^^--^^^^ | ^^^^--^^^^
@ -49,31 +49,31 @@ LL | let _ = b'0'..b'9';
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:59:13 --> $DIR/almost_complete_range.rs:36:13
| |
LL | let _ = a!()..'z'; LL | let _ = inline!('a')..'z';
| ^^^^--^^^ | ^^^^^^^^^^^^--^^^
| | | |
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:60:13 --> $DIR/almost_complete_range.rs:37:13
| |
LL | let _ = A!()..'Z'; LL | let _ = inline!('A')..'Z';
| ^^^^--^^^ | ^^^^^^^^^^^^--^^^
| | | |
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:61:13 --> $DIR/almost_complete_range.rs:38:13
| |
LL | let _ = zero!()..'9'; LL | let _ = inline!('0')..'9';
| ^^^^^^^--^^^ | ^^^^^^^^^^^^--^^^
| | | |
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:64:9 --> $DIR/almost_complete_range.rs:41:9
| |
LL | b'a'..b'z' if true => 1, LL | b'a'..b'z' if true => 1,
| ^^^^--^^^^ | ^^^^--^^^^
@ -81,7 +81,7 @@ LL | b'a'..b'z' if true => 1,
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:65:9 --> $DIR/almost_complete_range.rs:42:9
| |
LL | b'A'..b'Z' if true => 2, LL | b'A'..b'Z' if true => 2,
| ^^^^--^^^^ | ^^^^--^^^^
@ -89,7 +89,7 @@ LL | b'A'..b'Z' if true => 2,
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:66:9 --> $DIR/almost_complete_range.rs:43:9
| |
LL | b'0'..b'9' if true => 3, LL | b'0'..b'9' if true => 3,
| ^^^^--^^^^ | ^^^^--^^^^
@ -97,7 +97,7 @@ LL | b'0'..b'9' if true => 3,
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:74:9 --> $DIR/almost_complete_range.rs:51:9
| |
LL | 'a'..'z' if true => 1, LL | 'a'..'z' if true => 1,
| ^^^--^^^ | ^^^--^^^
@ -105,7 +105,7 @@ LL | 'a'..'z' if true => 1,
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:75:9 --> $DIR/almost_complete_range.rs:52:9
| |
LL | 'A'..'Z' if true => 2, LL | 'A'..'Z' if true => 2,
| ^^^--^^^ | ^^^--^^^
@ -113,7 +113,7 @@ LL | 'A'..'Z' if true => 2,
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:76:9 --> $DIR/almost_complete_range.rs:53:9
| |
LL | '0'..'9' if true => 3, LL | '0'..'9' if true => 3,
| ^^^--^^^ | ^^^--^^^
@ -121,46 +121,37 @@ LL | '0'..'9' if true => 3,
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:33:17 --> $DIR/almost_complete_range.rs:66:17
| |
LL | let _ = 'a'..'z'; LL | let _ = 'a'..'z';
| ^^^--^^^ | ^^^--^^^
| | | |
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
...
LL | b!();
| ---- in this macro invocation
| |
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:34:17 --> $DIR/almost_complete_range.rs:67:17
| |
LL | let _ = 'A'..'Z'; LL | let _ = 'A'..'Z';
| ^^^--^^^ | ^^^--^^^
| | | |
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
...
LL | b!();
| ---- in this macro invocation
| |
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:35:17 --> $DIR/almost_complete_range.rs:68:17
| |
LL | let _ = '0'..'9'; LL | let _ = '0'..'9';
| ^^^--^^^ | ^^^--^^^
| | | |
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
...
LL | b!();
| ---- in this macro invocation
| |
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:90:9 --> $DIR/almost_complete_range.rs:75:9
| |
LL | 'a'..'z' => 1, LL | 'a'..'z' => 1,
| ^^^--^^^ | ^^^--^^^
@ -168,7 +159,7 @@ LL | 'a'..'z' => 1,
| help: use an inclusive range: `...` | help: use an inclusive range: `...`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:91:9 --> $DIR/almost_complete_range.rs:76:9
| |
LL | 'A'..'Z' => 2, LL | 'A'..'Z' => 2,
| ^^^--^^^ | ^^^--^^^
@ -176,7 +167,7 @@ LL | 'A'..'Z' => 2,
| help: use an inclusive range: `...` | help: use an inclusive range: `...`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:92:9 --> $DIR/almost_complete_range.rs:77:9
| |
LL | '0'..'9' => 3, LL | '0'..'9' => 3,
| ^^^--^^^ | ^^^--^^^
@ -184,7 +175,7 @@ LL | '0'..'9' => 3,
| help: use an inclusive range: `...` | help: use an inclusive range: `...`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:99:13 --> $DIR/almost_complete_range.rs:84:13
| |
LL | let _ = 'a'..'z'; LL | let _ = 'a'..'z';
| ^^^--^^^ | ^^^--^^^
@ -192,7 +183,7 @@ LL | let _ = 'a'..'z';
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:100:13 --> $DIR/almost_complete_range.rs:85:13
| |
LL | let _ = 'A'..'Z'; LL | let _ = 'A'..'Z';
| ^^^--^^^ | ^^^--^^^
@ -200,7 +191,7 @@ LL | let _ = 'A'..'Z';
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:101:13 --> $DIR/almost_complete_range.rs:86:13
| |
LL | let _ = '0'..'9'; LL | let _ = '0'..'9';
| ^^^--^^^ | ^^^--^^^
@ -208,7 +199,7 @@ LL | let _ = '0'..'9';
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:103:9 --> $DIR/almost_complete_range.rs:88:9
| |
LL | 'a'..'z' => 1, LL | 'a'..'z' => 1,
| ^^^--^^^ | ^^^--^^^
@ -216,7 +207,7 @@ LL | 'a'..'z' => 1,
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:104:9 --> $DIR/almost_complete_range.rs:89:9
| |
LL | 'A'..'Z' => 1, LL | 'A'..'Z' => 1,
| ^^^--^^^ | ^^^--^^^
@ -224,7 +215,7 @@ LL | 'A'..'Z' => 1,
| help: use an inclusive range: `..=` | help: use an inclusive range: `..=`
error: almost complete ascii range error: almost complete ascii range
--> $DIR/almost_complete_range.rs:105:9 --> $DIR/almost_complete_range.rs:90:9
| |
LL | '0'..'9' => 3, LL | '0'..'9' => 3,
| ^^^--^^^ | ^^^--^^^

View File

@ -1,20 +1,15 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::as_conversions)] #![warn(clippy::as_conversions)]
#![allow(clippy::borrow_as_ptr)] #![allow(clippy::borrow_as_ptr)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::external;
fn with_external_macro() {
as_conv_with_arg!(0u32 as u64);
as_conv!();
}
fn main() { fn main() {
let i = 0u32 as u64; let i = 0u32 as u64;
let j = &i as *const u64 as *mut u64; let j = &i as *const u64 as *mut u64;
with_external_macro(); external!(0u32 as u64);
} }

View File

@ -1,5 +1,5 @@
error: using a potentially dangerous silent `as` conversion error: using a potentially dangerous silent `as` conversion
--> $DIR/as_conversions.rs:15:13 --> $DIR/as_conversions.rs:10:13
| |
LL | let i = 0u32 as u64; LL | let i = 0u32 as u64;
| ^^^^^^^^^^^ | ^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | let i = 0u32 as u64;
= note: `-D clippy::as-conversions` implied by `-D warnings` = note: `-D clippy::as-conversions` implied by `-D warnings`
error: using a potentially dangerous silent `as` conversion error: using a potentially dangerous silent `as` conversion
--> $DIR/as_conversions.rs:17:13 --> $DIR/as_conversions.rs:12:13
| |
LL | let j = &i as *const u64 as *mut u64; LL | let j = &i as *const u64 as *mut u64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -16,7 +16,7 @@ LL | let j = &i as *const u64 as *mut u64;
= help: consider using a safe wrapper for this conversion = help: consider using a safe wrapper for this conversion
error: using a potentially dangerous silent `as` conversion error: using a potentially dangerous silent `as` conversion
--> $DIR/as_conversions.rs:17:13 --> $DIR/as_conversions.rs:12:13
| |
LL | let j = &i as *const u64 as *mut u64; LL | let j = &i as *const u64 as *mut u64;
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^

View File

@ -1,16 +0,0 @@
#[macro_export]
macro_rules! undocd_unsafe {
() => {
pub unsafe fn oy_vey() {
unimplemented!();
}
};
}
#[macro_export]
macro_rules! undocd_safe {
() => {
pub fn vey_oy() {
unimplemented!();
}
};
}

View File

@ -1,6 +0,0 @@
#[macro_export]
macro_rules! implicit_hasher_fn {
() => {
pub fn f(input: &HashMap<u32, u32>) {}
};
}

View File

@ -2,21 +2,6 @@
//! Used to test that certain lints don't trigger in imported external macros //! Used to test that certain lints don't trigger in imported external macros
#[macro_export]
macro_rules! foofoo {
() => {
loop {}
};
}
#[macro_export]
macro_rules! must_use_unit {
() => {
#[must_use]
fn foo() {}
};
}
#[macro_export] #[macro_export]
macro_rules! try_err { macro_rules! try_err {
() => { () => {
@ -36,135 +21,9 @@ macro_rules! string_add {
}; };
} }
#[macro_export]
macro_rules! take_external {
($s:expr) => {
std::mem::replace($s, Default::default())
};
}
#[macro_export]
macro_rules! option_env_unwrap_external {
($env: expr) => {
option_env!($env).unwrap()
};
($env: expr, $message: expr) => {
option_env!($env).expect($message)
};
}
#[macro_export]
macro_rules! ref_arg_binding {
() => {
let ref _y = 42;
};
}
#[macro_export]
macro_rules! ref_arg_function {
() => {
fn fun_example(ref _x: usize) {}
};
}
#[macro_export]
macro_rules! as_conv_with_arg {
(0u32 as u64) => {
()
};
}
#[macro_export]
macro_rules! as_conv {
() => {
0u32 as u64
};
}
#[macro_export]
macro_rules! large_enum_variant {
() => {
enum LargeEnumInMacro {
A(i32),
B([i32; 8000]),
}
};
}
#[macro_export]
macro_rules! field_reassign_with_default {
() => {
#[derive(Default)]
struct A {
pub i: i32,
pub j: i64,
}
fn lint() {
let mut a: A = Default::default();
a.i = 42;
a;
}
};
}
#[macro_export]
macro_rules! default_numeric_fallback {
() => {
let x = 22;
};
}
#[macro_export] #[macro_export]
macro_rules! mut_mut { macro_rules! mut_mut {
() => { () => {
let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32; let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32;
}; };
} }
#[macro_export]
macro_rules! ptr_as_ptr_cast {
($ptr: ident) => {
$ptr as *const i32
};
}
#[macro_export]
macro_rules! manual_rem_euclid {
() => {
let value: i32 = 5;
let _: i32 = ((value % 4) + 4) % 4;
};
}
#[macro_export]
macro_rules! equatable_if_let {
($a:ident) => {{ if let 2 = $a {} }};
}
#[macro_export]
macro_rules! almost_complete_range {
() => {
let _ = 'a'..'z';
let _ = 'A'..'Z';
let _ = '0'..'9';
};
}
#[macro_export]
macro_rules! unsafe_macro {
() => {
unsafe {
*core::ptr::null::<()>();
*core::ptr::null::<()>();
}
};
}
#[macro_export]
macro_rules! needless_lifetime {
() => {
fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 {
unimplemented!()
}
};
}

View File

@ -13,7 +13,7 @@ pub mod inner {
// RE-EXPORT // RE-EXPORT
// this will stick in `inner` module // this will stick in `inner` module
pub use macro_rules::foofoo; pub use macro_rules::mut_mut;
pub use macro_rules::try_err; pub use macro_rules::try_err;
pub mod nested { pub mod nested {

View File

@ -1,32 +0,0 @@
// compile-flags: --emit=link
// no-prefer-dynamic
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::{token_stream::IntoIter, Group, Span, TokenStream, TokenTree};
#[proc_macro]
pub fn with_span(input: TokenStream) -> TokenStream {
let mut iter = input.into_iter();
let span = iter.next().unwrap().span();
let mut res = TokenStream::new();
write_with_span(span, iter, &mut res);
res
}
fn write_with_span(s: Span, input: IntoIter, out: &mut TokenStream) {
for mut tt in input {
if let TokenTree::Group(g) = tt {
let mut stream = TokenStream::new();
write_with_span(s, g.stream().into_iter(), &mut stream);
let mut group = Group::new(g.delimiter(), stream);
group.set_span(s);
out.extend([TokenTree::Group(group)]);
} else {
tt.set_span(s);
out.extend([tt]);
}
}
}

View File

@ -0,0 +1,474 @@
// compile-flags: --emit=link
// no-prefer-dynamic
#![crate_type = "proc-macro"]
#![feature(let_chains)]
#![feature(proc_macro_span)]
#![allow(dead_code)]
extern crate proc_macro;
use core::mem;
use proc_macro::{
token_stream::IntoIter,
Delimiter::{self, Brace, Parenthesis},
Group, Ident, Literal, Punct,
Spacing::{self, Alone, Joint},
Span, TokenStream, TokenTree as TT,
};
type Result<T> = core::result::Result<T, TokenStream>;
/// Make a `compile_error!` pointing to the given span.
fn make_error(msg: &str, span: Span) -> TokenStream {
TokenStream::from_iter([
TT::Ident(Ident::new("compile_error", span)),
TT::Punct(punct_with_span('!', Alone, span)),
TT::Group({
let mut msg = Literal::string(msg);
msg.set_span(span);
group_with_span(Parenthesis, TokenStream::from_iter([TT::Literal(msg)]), span)
}),
])
}
fn expect_tt<T>(tt: Option<TT>, f: impl FnOnce(TT) -> Option<T>, expected: &str, span: Span) -> Result<T> {
match tt {
None => Err(make_error(
&format!("unexpected end of input, expected {expected}"),
span,
)),
Some(tt) => {
let span = tt.span();
match f(tt) {
Some(x) => Ok(x),
None => Err(make_error(&format!("unexpected token, expected {expected}"), span)),
}
},
}
}
fn punct_with_span(c: char, spacing: Spacing, span: Span) -> Punct {
let mut p = Punct::new(c, spacing);
p.set_span(span);
p
}
fn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Group {
let mut g = Group::new(delimiter, stream);
g.set_span(span);
g
}
/// Token used to escape the following token from the macro's span rules.
const ESCAPE_CHAR: char = '$';
/// Takes a single token followed by a sequence tokens. Returns the sequence of tokens with their
/// span set to that of the first token. Tokens may be escaped with either `#ident` or `#(tokens)`.
#[proc_macro]
pub fn with_span(input: TokenStream) -> TokenStream {
let mut iter = input.into_iter();
let span = iter.next().unwrap().span();
let mut res = TokenStream::new();
if let Err(e) = write_with_span(span, iter, &mut res) {
e
} else {
res
}
}
/// Takes a sequence of tokens and return the tokens with the span set such that they appear to be
/// from an external macro. Tokens may be escaped with either `#ident` or `#(tokens)`.
#[proc_macro]
pub fn external(input: TokenStream) -> TokenStream {
let mut res = TokenStream::new();
if let Err(e) = write_with_span(Span::mixed_site(), input.into_iter(), &mut res) {
e
} else {
res
}
}
/// Copies all the tokens, replacing all their spans with the given span. Tokens can be escaped
/// either by `#ident` or `#(tokens)`.
fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Result<()> {
while let Some(tt) = input.next() {
match tt {
TT::Punct(p) if p.as_char() == ESCAPE_CHAR => {
expect_tt(
input.next(),
|tt| match tt {
tt @ (TT::Ident(_) | TT::Literal(_)) => {
out.extend([tt]);
Some(())
},
TT::Punct(mut p) if p.as_char() == ESCAPE_CHAR => {
p.set_span(s);
out.extend([TT::Punct(p)]);
Some(())
},
TT::Group(g) if g.delimiter() == Parenthesis => {
out.extend([TT::Group(group_with_span(Delimiter::None, g.stream(), g.span()))]);
Some(())
},
_ => None,
},
"an ident, a literal, or parenthesized tokens",
p.span(),
)?;
},
TT::Group(g) => {
let mut stream = TokenStream::new();
write_with_span(s, g.stream().into_iter(), &mut stream)?;
out.extend([TT::Group(group_with_span(g.delimiter(), stream, s))]);
},
mut tt => {
tt.set_span(s);
out.extend([tt]);
},
}
}
Ok(())
}
/// Within the item this attribute is attached to, an `inline!` macro is available which expands the
/// contained tokens as though they came from a macro expansion.
///
/// Within the `inline!` macro, any token preceded by `$` is passed as though it were an argument
/// with an automatically chosen fragment specifier. `$ident` will be passed as `ident`, `$1` or
/// `$"literal"` will be passed as `literal`, `$'lt` will be passed as `lifetime`, and `$(...)` will
/// pass the contained tokens as a `tt` sequence (the wrapping parenthesis are removed). If another
/// specifier is required it can be specified within parenthesis like `$(@expr ...)`. This will
/// expand the remaining tokens as a single argument.
///
/// Multiple `inline!` macros may be nested within each other. This will expand as nested macro
/// calls. However, any arguments will be passed as though they came from the outermost context.
#[proc_macro_attribute]
pub fn inline_macros(args: TokenStream, input: TokenStream) -> TokenStream {
let mut args = args.into_iter();
let mac_name = match args.next() {
Some(TT::Ident(name)) => Some(name),
Some(tt) => {
return make_error(
"unexpected argument, expected either an ident or no arguments",
tt.span(),
);
},
None => None,
};
if let Some(tt) = args.next() {
return make_error(
"unexpected argument, expected either an ident or no arguments",
tt.span(),
);
};
let mac_name = if let Some(mac_name) = mac_name {
Ident::new(&format!("__inline_mac_{mac_name}"), Span::call_site())
} else {
let mut input = match LookaheadIter::new(input.clone().into_iter()) {
Some(x) => x,
None => return input,
};
loop {
match input.next() {
None => break Ident::new("__inline_mac", Span::call_site()),
Some(TT::Ident(kind)) => match &*kind.to_string() {
"impl" => break Ident::new("__inline_mac_impl", Span::call_site()),
kind @ ("struct" | "enum" | "union" | "fn" | "mod" | "trait" | "type" | "const" | "static") => {
if let TT::Ident(name) = &input.tt {
break Ident::new(&format!("__inline_mac_{kind}_{name}"), Span::call_site());
} else {
break Ident::new(&format!("__inline_mac_{kind}"), Span::call_site());
}
},
_ => {},
},
_ => {},
}
}
};
let mut expander = Expander::default();
let mut mac = MacWriter::new(mac_name);
if let Err(e) = expander.expand(input.into_iter(), &mut mac) {
return e;
}
let mut out = TokenStream::new();
mac.finish(&mut out);
out.extend(expander.expn);
out
}
/// Wraps a `TokenStream` iterator with a single token lookahead.
struct LookaheadIter {
tt: TT,
iter: IntoIter,
}
impl LookaheadIter {
fn new(mut iter: IntoIter) -> Option<Self> {
iter.next().map(|tt| Self { tt, iter })
}
/// Get's the lookahead token, replacing it with the next token in the stream.
/// Note: If there isn't a next token, this will not return the lookahead token.
fn next(&mut self) -> Option<TT> {
self.iter.next().map(|tt| mem::replace(&mut self.tt, tt))
}
}
/// Builds the macro used to implement all the `inline!` macro calls.
struct MacWriter {
name: Ident,
macros: TokenStream,
next_idx: usize,
}
impl MacWriter {
fn new(name: Ident) -> Self {
Self {
name,
macros: TokenStream::new(),
next_idx: 0,
}
}
/// Inserts a new `inline!` call.
fn insert(&mut self, name_span: Span, bang_span: Span, body: Group, expander: &mut Expander) -> Result<()> {
let idx = self.next_idx;
self.next_idx += 1;
let mut inner = Expander::for_arm(idx);
inner.expand(body.stream().into_iter(), self)?;
let new_arm = inner.arm.unwrap();
self.macros.extend([
TT::Group(Group::new(Parenthesis, new_arm.args_def)),
TT::Punct(Punct::new('=', Joint)),
TT::Punct(Punct::new('>', Alone)),
TT::Group(Group::new(Parenthesis, inner.expn)),
TT::Punct(Punct::new(';', Alone)),
]);
expander.expn.extend([
TT::Ident({
let mut name = self.name.clone();
name.set_span(name_span);
name
}),
TT::Punct(punct_with_span('!', Alone, bang_span)),
]);
let mut call_body = TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]);
if let Some(arm) = expander.arm.as_mut() {
if !new_arm.args.is_empty() {
arm.add_sub_args(new_arm.args, &mut call_body);
}
} else {
call_body.extend(new_arm.args);
}
let mut g = Group::new(body.delimiter(), call_body);
g.set_span(body.span());
expander.expn.extend([TT::Group(g)]);
Ok(())
}
/// Creates the macro definition.
fn finish(self, out: &mut TokenStream) {
if self.next_idx != 0 {
out.extend([
TT::Ident(Ident::new("macro_rules", Span::call_site())),
TT::Punct(Punct::new('!', Alone)),
TT::Ident(self.name),
TT::Group(Group::new(Brace, self.macros)),
])
}
}
}
struct MacroArm {
args_def: TokenStream,
args: Vec<TT>,
}
impl MacroArm {
fn add_single_arg_def(&mut self, kind: &str, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {
let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site());
self.args_def.extend([
TT::Punct(Punct::new('$', Alone)),
TT::Ident(name.clone()),
TT::Punct(Punct::new(':', Alone)),
TT::Ident(Ident::new(kind, Span::call_site())),
]);
name.set_span(arg_span);
out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]);
}
fn add_parenthesized_arg_def(&mut self, kind: Ident, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {
let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site());
self.args_def.extend([TT::Group(Group::new(
Parenthesis,
TokenStream::from_iter([
TT::Punct(Punct::new('$', Alone)),
TT::Ident(name.clone()),
TT::Punct(Punct::new(':', Alone)),
TT::Ident(kind),
]),
))]);
name.set_span(arg_span);
out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]);
}
fn add_multi_arg_def(&mut self, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {
let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site());
self.args_def.extend([TT::Group(Group::new(
Parenthesis,
TokenStream::from_iter([
TT::Punct(Punct::new('$', Alone)),
TT::Group(Group::new(
Parenthesis,
TokenStream::from_iter([
TT::Punct(Punct::new('$', Alone)),
TT::Ident(name.clone()),
TT::Punct(Punct::new(':', Alone)),
TT::Ident(Ident::new("tt", Span::call_site())),
]),
)),
TT::Punct(Punct::new('*', Alone)),
]),
))]);
name.set_span(arg_span);
out.extend([
TT::Punct(punct_with_span('$', Alone, dollar_span)),
TT::Group(group_with_span(
Parenthesis,
TokenStream::from_iter([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]),
dollar_span,
)),
TT::Punct(punct_with_span('*', Alone, dollar_span)),
]);
}
fn add_arg(&mut self, dollar_span: Span, tt: TT, input: &mut IntoIter, out: &mut TokenStream) -> Result<()> {
match tt {
TT::Punct(p) if p.as_char() == ESCAPE_CHAR => out.extend([TT::Punct(p)]),
TT::Punct(p) if p.as_char() == '\'' && p.spacing() == Joint => {
let lt_name = expect_tt(
input.next(),
|tt| match tt {
TT::Ident(x) => Some(x),
_ => None,
},
"lifetime name",
p.span(),
)?;
let arg_span = p.span().join(lt_name.span()).unwrap_or(p.span());
self.add_single_arg_def("lifetime", dollar_span, arg_span, out);
self.args.extend([TT::Punct(p), TT::Ident(lt_name)]);
},
TT::Ident(x) => {
self.add_single_arg_def("ident", dollar_span, x.span(), out);
self.args.push(TT::Ident(x));
},
TT::Literal(x) => {
self.add_single_arg_def("literal", dollar_span, x.span(), out);
self.args.push(TT::Literal(x));
},
TT::Group(g) if g.delimiter() == Parenthesis => {
let mut inner = g.stream().into_iter();
if let Some(TT::Punct(p)) = inner.next()
&& p.as_char() == '@'
{
let kind = expect_tt(
inner.next(),
|tt| match tt {
TT::Ident(kind) => Some(kind),
_ => None,
},
"a macro fragment specifier",
p.span(),
)?;
self.add_parenthesized_arg_def(kind, dollar_span, g.span(), out);
self.args.push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span())))
} else {
self.add_multi_arg_def(dollar_span, g.span(), out);
self.args.push(TT::Group(g));
}
},
tt => return Err(make_error("unsupported escape", tt.span())),
};
Ok(())
}
fn add_sub_args(&mut self, args: Vec<TT>, out: &mut TokenStream) {
self.add_multi_arg_def(Span::call_site(), Span::call_site(), out);
self.args
.extend([TT::Group(Group::new(Parenthesis, TokenStream::from_iter(args)))]);
}
}
#[derive(Default)]
struct Expander {
arm: Option<MacroArm>,
expn: TokenStream,
}
impl Expander {
fn for_arm(idx: usize) -> Self {
Self {
arm: Some(MacroArm {
args_def: TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]),
args: Vec::new(),
}),
expn: TokenStream::new(),
}
}
fn write_tt(&mut self, tt: TT, mac: &mut MacWriter) -> Result<()> {
match tt {
TT::Group(g) => {
let outer = mem::take(&mut self.expn);
self.expand(g.stream().into_iter(), mac)?;
let inner = mem::replace(&mut self.expn, outer);
self.expn
.extend([TT::Group(group_with_span(g.delimiter(), inner, g.span()))]);
},
tt => self.expn.extend([tt]),
}
Ok(())
}
fn expand(&mut self, input: IntoIter, mac: &mut MacWriter) -> Result<()> {
let Some(mut input) = LookaheadIter::new(input) else {
return Ok(());
};
while let Some(tt) = input.next() {
if let TT::Punct(p) = &tt
&& p.as_char() == ESCAPE_CHAR
&& let Some(arm) = self.arm.as_mut()
{
arm.add_arg(p.span(), mem::replace(&mut input.tt, tt), &mut input.iter, &mut self.expn)?;
if input.next().is_none() {
return Ok(());
}
} else if let TT::Punct(p) = &input.tt
&& p.as_char() == '!'
&& let TT::Ident(name) = &tt
&& name.to_string() == "inline"
{
let g = expect_tt(
input.iter.next(),
|tt| match tt {
TT::Group(g) => Some(g),
_ => None,
},
"macro arguments",
p.span(),
)?;
mac.insert(name.span(), p.span(), g, self)?;
if input.next().is_none() {
return Ok(());
}
} else {
self.write_tt(tt, mac)?;
}
}
self.write_tt(input.tt, mac)
}
}

View File

@ -1,5 +1,5 @@
// this file solely exists to test constants defined in foreign crates. // this file solely exists to test constants defined in foreign crates.
// As the most common case is the `http` crate, it replicates `http::HeadewrName`'s structure. // As the most common case is the `http` crate, it replicates `http::HeaderName`'s structure.
#![allow(clippy::declare_interior_mutable_const)] #![allow(clippy::declare_interior_mutable_const)]
#![allow(unused_tuple_struct_fields)] #![allow(unused_tuple_struct_fields)]

View File

@ -1,8 +1,8 @@
// aux-build:../../auxiliary/proc_macro_with_span.rs // aux-build:../../auxiliary/proc_macros.rs
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
fn main() { fn main() {
println!(with_span!(""something "")); println!(with_span!(""something ""));

View File

@ -1,5 +1,5 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::default_numeric_fallback)] #![warn(clippy::default_numeric_fallback)]
#![allow( #![allow(
@ -13,8 +13,8 @@
clippy::let_with_type_underscore clippy::let_with_type_underscore
)] )]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
mod basic_expr { mod basic_expr {
fn test() { fn test() {
@ -167,20 +167,17 @@ mod method_calls {
} }
mod in_macro { mod in_macro {
macro_rules! internal_macro { use super::*;
() => {
let x = 22.0_f64;
};
}
// Should lint in internal macro. // Should lint in internal macro.
#[inline_macros]
fn internal() { fn internal() {
internal_macro!(); inline!(let x = 22.0_f64;);
} }
// Should NOT lint in external macro. // Should NOT lint in external macro.
fn external() { fn external() {
default_numeric_fallback!(); external!(let x = 22.;);
} }
} }

View File

@ -1,5 +1,5 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::default_numeric_fallback)] #![warn(clippy::default_numeric_fallback)]
#![allow( #![allow(
@ -13,8 +13,8 @@
clippy::let_with_type_underscore clippy::let_with_type_underscore
)] )]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
mod basic_expr { mod basic_expr {
fn test() { fn test() {
@ -167,20 +167,17 @@ mod method_calls {
} }
mod in_macro { mod in_macro {
macro_rules! internal_macro { use super::*;
() => {
let x = 22.;
};
}
// Should lint in internal macro. // Should lint in internal macro.
#[inline_macros]
fn internal() { fn internal() {
internal_macro!(); inline!(let x = 22.;);
} }
// Should NOT lint in external macro. // Should NOT lint in external macro.
fn external() { fn external() {
default_numeric_fallback!(); external!(let x = 22.;);
} }
} }

View File

@ -139,15 +139,12 @@ LL | s.generic_arg(1.);
| ^^ help: consider adding suffix: `1.0_f64` | ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur error: default numeric fallback might occur
--> $DIR/default_numeric_fallback_f64.rs:172:21 --> $DIR/default_numeric_fallback_f64.rs:175:25
| |
LL | let x = 22.; LL | inline!(let x = 22.;);
| ^^^ help: consider adding suffix: `22.0_f64` | ^^^ help: consider adding suffix: `22.0_f64`
...
LL | internal_macro!();
| ----------------- in this macro invocation
| |
= note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 24 previous errors error: aborting due to 24 previous errors

View File

@ -1,5 +1,5 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![feature(lint_reasons)] #![feature(lint_reasons)]
#![warn(clippy::default_numeric_fallback)] #![warn(clippy::default_numeric_fallback)]
@ -13,8 +13,8 @@
clippy::let_with_type_underscore clippy::let_with_type_underscore
)] )]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
mod basic_expr { mod basic_expr {
fn test() { fn test() {
@ -168,20 +168,17 @@ mod method_calls {
} }
mod in_macro { mod in_macro {
macro_rules! internal_macro { use super::*;
() => {
let x = 22_i32;
};
}
// Should lint in internal macro. // Should lint in internal macro.
#[inline_macros]
fn internal() { fn internal() {
internal_macro!(); inline!(let x = 22_i32;);
} }
// Should NOT lint in external macro. // Should NOT lint in external macro.
fn external() { fn external() {
default_numeric_fallback!(); external!(let x = 22;);
} }
} }

View File

@ -1,5 +1,5 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![feature(lint_reasons)] #![feature(lint_reasons)]
#![warn(clippy::default_numeric_fallback)] #![warn(clippy::default_numeric_fallback)]
@ -13,8 +13,8 @@
clippy::let_with_type_underscore clippy::let_with_type_underscore
)] )]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
mod basic_expr { mod basic_expr {
fn test() { fn test() {
@ -168,20 +168,17 @@ mod method_calls {
} }
mod in_macro { mod in_macro {
macro_rules! internal_macro { use super::*;
() => {
let x = 22;
};
}
// Should lint in internal macro. // Should lint in internal macro.
#[inline_macros]
fn internal() { fn internal() {
internal_macro!(); inline!(let x = 22;);
} }
// Should NOT lint in external macro. // Should NOT lint in external macro.
fn external() { fn external() {
default_numeric_fallback!(); external!(let x = 22;);
} }
} }

View File

@ -151,15 +151,12 @@ LL | s.generic_arg(1);
| ^ help: consider adding suffix: `1_i32` | ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur error: default numeric fallback might occur
--> $DIR/default_numeric_fallback_i32.rs:173:21 --> $DIR/default_numeric_fallback_i32.rs:176:25
| |
LL | let x = 22; LL | inline!(let x = 22;);
| ^^ help: consider adding suffix: `22_i32` | ^^ help: consider adding suffix: `22_i32`
...
LL | internal_macro!();
| ----------------- in this macro invocation
| |
= note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 26 previous errors error: aborting due to 26 previous errors

View File

@ -1,12 +1,12 @@
// run-rustfix // run-rustfix
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![deny(clippy::default_trait_access)] #![deny(clippy::default_trait_access)]
#![allow(dead_code, unused_imports)] #![allow(dead_code, unused_imports)]
#![allow(clippy::uninlined_format_args)] #![allow(clippy::uninlined_format_args)]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
use std::default; use std::default;
use std::default::Default as D2; use std::default::Default as D2;
use std::string; use std::string;

View File

@ -1,12 +1,12 @@
// run-rustfix // run-rustfix
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![deny(clippy::default_trait_access)] #![deny(clippy::default_trait_access)]
#![allow(dead_code, unused_imports)] #![allow(dead_code, unused_imports)]
#![allow(clippy::uninlined_format_args)] #![allow(clippy::uninlined_format_args)]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
use std::default; use std::default;
use std::default::Default as D2; use std::default::Default as D2;
use std::string; use std::string;

View File

@ -1,7 +1,12 @@
// run-rustfix // run-rustfix
// aux-build:proc_macros.rs
#![allow(clippy::return_self_not_must_use)] #![allow(clippy::return_self_not_must_use)]
#![warn(clippy::deref_addrof)] #![warn(clippy::deref_addrof)]
extern crate proc_macros;
use proc_macros::inline_macros;
fn get_number() -> usize { fn get_number() -> usize {
10 10
} }
@ -41,28 +46,15 @@ fn main() {
let _ = unsafe { *core::ptr::addr_of!(a) }; let _ = unsafe { *core::ptr::addr_of!(a) };
} }
#[rustfmt::skip]
macro_rules! m {
($visitor: expr) => {
$visitor
};
}
#[rustfmt::skip]
macro_rules! m_mut {
($visitor: expr) => {
$visitor
};
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct S; pub struct S;
#[inline_macros]
impl S { impl S {
pub fn f(&self) -> &Self { pub fn f(&self) -> &Self {
m!(self) inline!($(@expr self))
} }
#[allow(unused_mut)] // mut will be unused, once the macro is fixed #[allow(unused_mut)] // mut will be unused, once the macro is fixed
pub fn f_mut(mut self) -> Self { pub fn f_mut(mut self) -> Self {
m_mut!(self) inline!($(@expr self))
} }
} }

View File

@ -1,7 +1,12 @@
// run-rustfix // run-rustfix
// aux-build:proc_macros.rs
#![allow(clippy::return_self_not_must_use)] #![allow(clippy::return_self_not_must_use)]
#![warn(clippy::deref_addrof)] #![warn(clippy::deref_addrof)]
extern crate proc_macros;
use proc_macros::inline_macros;
fn get_number() -> usize { fn get_number() -> usize {
10 10
} }
@ -41,28 +46,15 @@ fn main() {
let _ = unsafe { *core::ptr::addr_of!(a) }; let _ = unsafe { *core::ptr::addr_of!(a) };
} }
#[rustfmt::skip]
macro_rules! m {
($visitor: expr) => {
*& $visitor
};
}
#[rustfmt::skip]
macro_rules! m_mut {
($visitor: expr) => {
*& mut $visitor
};
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct S; pub struct S;
#[inline_macros]
impl S { impl S {
pub fn f(&self) -> &Self { pub fn f(&self) -> &Self {
m!(self) inline!(*& $(@expr self))
} }
#[allow(unused_mut)] // mut will be unused, once the macro is fixed #[allow(unused_mut)] // mut will be unused, once the macro is fixed
pub fn f_mut(mut self) -> Self { pub fn f_mut(mut self) -> Self {
m_mut!(self) inline!(*&mut $(@expr self))
} }
} }

View File

@ -1,5 +1,5 @@
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:19:13 --> $DIR/deref_addrof.rs:24:13
| |
LL | let b = *&a; LL | let b = *&a;
| ^^^ help: try this: `a` | ^^^ help: try this: `a`
@ -7,68 +7,62 @@ LL | let b = *&a;
= note: `-D clippy::deref-addrof` implied by `-D warnings` = note: `-D clippy::deref-addrof` implied by `-D warnings`
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:21:13 --> $DIR/deref_addrof.rs:26:13
| |
LL | let b = *&get_number(); LL | let b = *&get_number();
| ^^^^^^^^^^^^^^ help: try this: `get_number()` | ^^^^^^^^^^^^^^ help: try this: `get_number()`
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:26:13 --> $DIR/deref_addrof.rs:31:13
| |
LL | let b = *&bytes[1..2][0]; LL | let b = *&bytes[1..2][0];
| ^^^^^^^^^^^^^^^^ help: try this: `bytes[1..2][0]` | ^^^^^^^^^^^^^^^^ help: try this: `bytes[1..2][0]`
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:30:13 --> $DIR/deref_addrof.rs:35:13
| |
LL | let b = *&(a); LL | let b = *&(a);
| ^^^^^ help: try this: `(a)` | ^^^^^ help: try this: `(a)`
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:32:13 --> $DIR/deref_addrof.rs:37:13
| |
LL | let b = *(&a); LL | let b = *(&a);
| ^^^^^ help: try this: `a` | ^^^^^ help: try this: `a`
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:35:13 --> $DIR/deref_addrof.rs:40:13
| |
LL | let b = *((&a)); LL | let b = *((&a));
| ^^^^^^^ help: try this: `a` | ^^^^^^^ help: try this: `a`
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:37:13 --> $DIR/deref_addrof.rs:42:13
| |
LL | let b = *&&a; LL | let b = *&&a;
| ^^^^ help: try this: `&a` | ^^^^ help: try this: `&a`
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:39:14 --> $DIR/deref_addrof.rs:44:14
| |
LL | let b = **&aref; LL | let b = **&aref;
| ^^^^^^ help: try this: `aref` | ^^^^^^ help: try this: `aref`
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:47:9 --> $DIR/deref_addrof.rs:54:17
| |
LL | *& $visitor LL | inline!(*& $(@expr self))
| ^^^^^^^^^^^ help: try this: `$visitor` | ^^^^^^^^^^^^^^^^ help: try this: `$(@expr self)`
...
LL | m!(self)
| -------- in this macro invocation
| |
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
error: immediately dereferencing a reference error: immediately dereferencing a reference
--> $DIR/deref_addrof.rs:54:9 --> $DIR/deref_addrof.rs:58:17
| |
LL | *& mut $visitor LL | inline!(*&mut $(@expr self))
| ^^^^^^^^^^^^^^^ help: try this: `$visitor` | ^^^^^^^^^^^^^^^^^^^ help: try this: `$(@expr self)`
...
LL | m_mut!(self)
| ------------ in this macro invocation
| |
= note: this error originates in the macro `m_mut` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 10 previous errors error: aborting due to 10 previous errors

View File

@ -1,10 +1,13 @@
macro_rules! m { // aux-build:proc_macros.rs
($($x:tt),*) => { &[$(($x, stringify!(x)),)*] };
}
#[warn(clippy::deref_addrof)] #![warn(clippy::deref_addrof)]
fn f() -> [(i32, &'static str); 3] {
*m![1, 2, 3] // should be fine extern crate proc_macros;
#[proc_macros::inline_macros]
fn f() -> i32 {
// should be fine
*inline!(&$1)
} }
fn main() {} fn main() {}

View File

@ -1,9 +1,9 @@
// aux-build:doc_unsafe_macros.rs // aux-build:proc_macros.rs
#![allow(clippy::let_unit_value)] #![allow(clippy::let_unit_value)]
#[macro_use] extern crate proc_macros;
extern crate doc_unsafe_macros; use proc_macros::external;
/// This is not sufficiently documented /// This is not sufficiently documented
pub unsafe fn destroy_the_planet() { pub unsafe fn destroy_the_planet() {
@ -105,7 +105,11 @@ macro_rules! very_unsafe {
very_unsafe!(); very_unsafe!();
// we don't lint code from external macros // we don't lint code from external macros
undocd_unsafe!(); external! {
pub unsafe fn oy_vey() {
unimplemented!();
}
}
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,9 +1,9 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::empty_loop)] #![warn(clippy::empty_loop)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
fn should_trigger() { fn should_trigger() {
loop {} loop {}
@ -16,6 +16,7 @@ fn should_trigger() {
} }
} }
#[inline_macros]
fn should_not_trigger() { fn should_not_trigger() {
loop { loop {
panic!("This is fine") panic!("This is fine")
@ -38,14 +39,10 @@ fn should_not_trigger() {
loop {} loop {}
// We don't lint loops inside macros // We don't lint loops inside macros
macro_rules! foo { inline!(loop {});
() => {
loop {}
};
}
// We don't lint external macros // We don't lint external macros
foofoo!() external!(loop {});
} }
fn main() {} fn main() {}

View File

@ -1,11 +1,11 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)]
#![warn(clippy::equatable_if_let)] #![warn(clippy::equatable_if_let)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
use std::cmp::Ordering; use std::cmp::Ordering;
@ -44,6 +44,7 @@ impl PartialEq for NotStructuralEq {
} }
} }
#[inline_macros]
fn main() { fn main() {
let a = 2; let a = 2;
let b = 3; let b = 3;
@ -78,14 +79,9 @@ fn main() {
if Some(g) == Some(NotStructuralEq::A) {} if Some(g) == Some(NotStructuralEq::A) {}
if matches!(h, NoPartialEqStruct { a: 2, b: false }) {} if matches!(h, NoPartialEqStruct { a: 2, b: false }) {}
macro_rules! m1 { if "abc" == inline!("abc") {
(x) => {
"abc"
};
}
if "abc" == m1!(x) {
println!("OK"); println!("OK");
} }
equatable_if_let!(a); external!({ if let 2 = $a {} });
} }

View File

@ -1,11 +1,11 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)]
#![warn(clippy::equatable_if_let)] #![warn(clippy::equatable_if_let)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
use std::cmp::Ordering; use std::cmp::Ordering;
@ -44,6 +44,7 @@ impl PartialEq for NotStructuralEq {
} }
} }
#[inline_macros]
fn main() { fn main() {
let a = 2; let a = 2;
let b = 3; let b = 3;
@ -78,14 +79,9 @@ fn main() {
if let Some(NotStructuralEq::A) = Some(g) {} if let Some(NotStructuralEq::A) = Some(g) {}
if let NoPartialEqStruct { a: 2, b: false } = h {} if let NoPartialEqStruct { a: 2, b: false } = h {}
macro_rules! m1 { if let inline!("abc") = "abc" {
(x) => {
"abc"
};
}
if let m1!(x) = "abc" {
println!("OK"); println!("OK");
} }
equatable_if_let!(a); external!({ if let 2 = $a {} });
} }

View File

@ -1,5 +1,5 @@
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:59:8 --> $DIR/equatable_if_let.rs:60:8
| |
LL | if let 2 = a {} LL | if let 2 = a {}
| ^^^^^^^^^ help: try: `a == 2` | ^^^^^^^^^ help: try: `a == 2`
@ -7,82 +7,82 @@ LL | if let 2 = a {}
= note: `-D clippy::equatable-if-let` implied by `-D warnings` = note: `-D clippy::equatable-if-let` implied by `-D warnings`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:60:8 --> $DIR/equatable_if_let.rs:61:8
| |
LL | if let Ordering::Greater = a.cmp(&b) {} LL | if let Ordering::Greater = a.cmp(&b) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:61:8 --> $DIR/equatable_if_let.rs:62:8
| |
LL | if let Some(2) = c {} LL | if let Some(2) = c {}
| ^^^^^^^^^^^^^^^ help: try: `c == Some(2)` | ^^^^^^^^^^^^^^^ help: try: `c == Some(2)`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:62:8 --> $DIR/equatable_if_let.rs:63:8
| |
LL | if let Struct { a: 2, b: false } = d {} LL | if let Struct { a: 2, b: false } = d {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:63:8 --> $DIR/equatable_if_let.rs:64:8
| |
LL | if let Enum::TupleVariant(32, 64) = e {} LL | if let Enum::TupleVariant(32, 64) = e {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:64:8 --> $DIR/equatable_if_let.rs:65:8
| |
LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {} LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:65:8 --> $DIR/equatable_if_let.rs:66:8
| |
LL | if let Enum::UnitVariant = e {} LL | if let Enum::UnitVariant = e {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:66:8 --> $DIR/equatable_if_let.rs:67:8
| |
LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })`
error: this pattern matching can be expressed using `matches!` error: this pattern matching can be expressed using `matches!`
--> $DIR/equatable_if_let.rs:75:8 --> $DIR/equatable_if_let.rs:76:8
| |
LL | if let NotPartialEq::A = f {} LL | if let NotPartialEq::A = f {}
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)` | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:76:8 --> $DIR/equatable_if_let.rs:77:8
| |
LL | if let NotStructuralEq::A = g {} LL | if let NotStructuralEq::A = g {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A`
error: this pattern matching can be expressed using `matches!` error: this pattern matching can be expressed using `matches!`
--> $DIR/equatable_if_let.rs:77:8 --> $DIR/equatable_if_let.rs:78:8
| |
LL | if let Some(NotPartialEq::A) = Some(f) {} LL | if let Some(NotPartialEq::A) = Some(f) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:78:8 --> $DIR/equatable_if_let.rs:79:8
| |
LL | if let Some(NotStructuralEq::A) = Some(g) {} LL | if let Some(NotStructuralEq::A) = Some(g) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)`
error: this pattern matching can be expressed using `matches!` error: this pattern matching can be expressed using `matches!`
--> $DIR/equatable_if_let.rs:79:8 --> $DIR/equatable_if_let.rs:80:8
| |
LL | if let NoPartialEqStruct { a: 2, b: false } = h {} LL | if let NoPartialEqStruct { a: 2, b: false } = h {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })`
error: this pattern matching can be expressed using equality error: this pattern matching can be expressed using equality
--> $DIR/equatable_if_let.rs:86:8 --> $DIR/equatable_if_let.rs:82:8
| |
LL | if let m1!(x) = "abc" { LL | if let inline!("abc") = "abc" {
| ^^^^^^^^^^^^^^^^^^ help: try: `"abc" == m1!(x)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"abc" == inline!("abc")`
error: aborting due to 14 previous errors error: aborting due to 14 previous errors

View File

@ -1,12 +1,12 @@
// aux-build:proc_macro_derive.rs // aux-build:proc_macro_derive.rs
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::field_reassign_with_default)] #![warn(clippy::field_reassign_with_default)]
#[macro_use] #[macro_use]
extern crate proc_macro_derive; extern crate proc_macro_derive;
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
// Don't lint on derives that derive `Default` // Don't lint on derives that derive `Default`
// See https://github.com/rust-lang/rust-clippy/issues/6545 // See https://github.com/rust-lang/rust-clippy/issues/6545
@ -36,14 +36,6 @@ struct D {
b: Option<i32>, b: Option<i32>,
} }
macro_rules! m {
($key:ident: $value:tt) => {{
let mut data = $crate::D::default();
data.$key = Some($value);
data
}};
}
/// Implements .next() that returns a different number each time. /// Implements .next() that returns a different number each time.
struct SideEffect(i32); struct SideEffect(i32);
@ -57,6 +49,7 @@ impl SideEffect {
} }
} }
#[inline_macros]
fn main() { fn main() {
// wrong, produces first error in stderr // wrong, produces first error in stderr
let mut a: A = Default::default(); let mut a: A = Default::default();
@ -150,7 +143,18 @@ fn main() {
a.i = vec![1]; a.i = vec![1];
// Don't lint in external macros // Don't lint in external macros
field_reassign_with_default!(); external! {
#[derive(Default)]
struct A {
pub i: i32,
pub j: i64,
}
fn lint() {
let mut a: A = Default::default();
a.i = 42;
a;
}
}
// be sure suggestion is correct with generics // be sure suggestion is correct with generics
let mut a: Wrapper<bool> = Default::default(); let mut a: Wrapper<bool> = Default::default();
@ -160,9 +164,11 @@ fn main() {
a.i = 42; a.i = 42;
// Don't lint in macros // Don't lint in macros
m! { inline!(
a: 42 let mut data = $crate::D::default();
}; data.$a = Some($42);
data
);
} }
mod m { mod m {

View File

@ -1,132 +1,132 @@
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:63:5 --> $DIR/field_reassign_with_default.rs:56:5
| |
LL | a.i = 42; LL | a.i = 42;
| ^^^^^^^^^ | ^^^^^^^^^
| |
note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:62:5 --> $DIR/field_reassign_with_default.rs:55:5
| |
LL | let mut a: A = Default::default(); LL | let mut a: A = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::field-reassign-with-default` implied by `-D warnings` = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:103:5 --> $DIR/field_reassign_with_default.rs:96:5
| |
LL | a.j = 43; LL | a.j = 43;
| ^^^^^^^^^ | ^^^^^^^^^
| |
note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:102:5 --> $DIR/field_reassign_with_default.rs:95:5
| |
LL | let mut a: A = Default::default(); LL | let mut a: A = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:108:5 --> $DIR/field_reassign_with_default.rs:101:5
| |
LL | a.i = 42; LL | a.i = 42;
| ^^^^^^^^^ | ^^^^^^^^^
| |
note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:107:5 --> $DIR/field_reassign_with_default.rs:100:5
| |
LL | let mut a: A = Default::default(); LL | let mut a: A = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:114:5 --> $DIR/field_reassign_with_default.rs:107:5
| |
LL | a.i = 42; LL | a.i = 42;
| ^^^^^^^^^ | ^^^^^^^^^
| |
note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:113:5 --> $DIR/field_reassign_with_default.rs:106:5
| |
LL | let mut a = A::default(); LL | let mut a = A::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:124:5 --> $DIR/field_reassign_with_default.rs:117:5
| |
LL | a.i = Default::default(); LL | a.i = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:123:5 --> $DIR/field_reassign_with_default.rs:116:5
| |
LL | let mut a: A = Default::default(); LL | let mut a: A = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:128:5 --> $DIR/field_reassign_with_default.rs:121:5
| |
LL | a.i = Default::default(); LL | a.i = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:127:5 --> $DIR/field_reassign_with_default.rs:120:5
| |
LL | let mut a: A = Default::default(); LL | let mut a: A = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:150:5 --> $DIR/field_reassign_with_default.rs:143:5
| |
LL | a.i = vec![1]; LL | a.i = vec![1];
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:149:5 --> $DIR/field_reassign_with_default.rs:142:5
| |
LL | let mut a: C = C::default(); LL | let mut a: C = C::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:157:5 --> $DIR/field_reassign_with_default.rs:161:5
| |
LL | a.i = true; LL | a.i = true;
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
note: consider initializing the variable with `Wrapper::<bool> { i: true }` and removing relevant reassignments note: consider initializing the variable with `Wrapper::<bool> { i: true }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:156:5 --> $DIR/field_reassign_with_default.rs:160:5
| |
LL | let mut a: Wrapper<bool> = Default::default(); LL | let mut a: Wrapper<bool> = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:160:5 --> $DIR/field_reassign_with_default.rs:164:5
| |
LL | a.i = 42; LL | a.i = 42;
| ^^^^^^^^^ | ^^^^^^^^^
| |
note: consider initializing the variable with `WrapperMulti::<i32, i64> { i: 42, ..Default::default() }` and removing relevant reassignments note: consider initializing the variable with `WrapperMulti::<i32, i64> { i: 42, ..Default::default() }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:159:5 --> $DIR/field_reassign_with_default.rs:163:5
| |
LL | let mut a: WrapperMulti<i32, i64> = Default::default(); LL | let mut a: WrapperMulti<i32, i64> = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:229:13 --> $DIR/field_reassign_with_default.rs:235:13
| |
LL | f.name = name.len(); LL | f.name = name.len();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
note: consider initializing the variable with `issue6312::ImplDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments note: consider initializing the variable with `issue6312::ImplDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:228:13 --> $DIR/field_reassign_with_default.rs:234:13
| |
LL | let mut f = ImplDropAllCopy::default(); LL | let mut f = ImplDropAllCopy::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: field assignment outside of initializer for an instance created with Default::default() error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:245:13 --> $DIR/field_reassign_with_default.rs:251:13
| |
LL | f.name = name.len(); LL | f.name = name.len();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
note: consider initializing the variable with `issue6312::NoDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments note: consider initializing the variable with `issue6312::NoDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments
--> $DIR/field_reassign_with_default.rs:244:13 --> $DIR/field_reassign_with_default.rs:250:13
| |
LL | let mut f = NoDropAllCopy::default(); LL | let mut f = NoDropAllCopy::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,9 +1,11 @@
// aux-build:implicit_hasher_macros.rs // aux-build:proc_macros.rs
#![deny(clippy::implicit_hasher)] #![deny(clippy::implicit_hasher)]
#![allow(unused)] #![allow(unused)]
#[macro_use] #[macro_use]
extern crate implicit_hasher_macros; extern crate proc_macros;
use proc_macros::external;
use std::cmp::Eq; use std::cmp::Eq;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -68,22 +70,19 @@ impl<S: BuildHasher + Default> Foo<i64> for HashSet<String, S> {
pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {} pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
macro_rules! gen { #[proc_macros::inline_macros]
(impl) => { pub mod gen {
use super::*;
inline! {
impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> { impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {
fn make() -> (Self, Self) { fn make() -> (Self, Self) {
(HashMap::new(), HashMap::with_capacity(10)) (HashMap::new(), HashMap::with_capacity(10))
} }
} }
};
(fn $name:ident) => { pub fn bar(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
pub fn $name(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {} }
};
} }
#[rustfmt::skip]
gen!(impl);
gen!(fn bar);
// When the macro is in a different file, the suggestion spans can't be combined properly // When the macro is in a different file, the suggestion spans can't be combined properly
// and should not cause an ICE // and should not cause an ICE
@ -94,7 +93,9 @@ pub mod test_macro;
__implicit_hasher_test_macro!(impl<K, V> for HashMap<K, V> where V: test_macro::A); __implicit_hasher_test_macro!(impl<K, V> for HashMap<K, V> where V: test_macro::A);
// #4260 // #4260
implicit_hasher_fn!(); external! {
pub fn f(input: &HashMap<u32, u32>) {}
}
// #7712 // #7712
pub async fn election_vote(_data: HashMap<i32, i32>) {} pub async fn election_vote(_data: HashMap<i32, i32>) {}

View File

@ -1,11 +1,11 @@
error: impl for `HashMap` should be generalized over different hashers error: impl for `HashMap` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:16:35 --> $DIR/implicit_hasher.rs:18:35
| |
LL | impl<K: Hash + Eq, V> Foo<i8> for HashMap<K, V> { LL | impl<K: Hash + Eq, V> Foo<i8> for HashMap<K, V> {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/implicit_hasher.rs:2:9 --> $DIR/implicit_hasher.rs:3:9
| |
LL | #![deny(clippy::implicit_hasher)] LL | #![deny(clippy::implicit_hasher)]
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
@ -19,7 +19,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default:
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: impl for `HashMap` should be generalized over different hashers error: impl for `HashMap` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:25:36 --> $DIR/implicit_hasher.rs:27:36
| |
LL | impl<K: Hash + Eq, V> Foo<i8> for (HashMap<K, V>,) { LL | impl<K: Hash + Eq, V> Foo<i8> for (HashMap<K, V>,) {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -34,7 +34,7 @@ LL | ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Defa
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: impl for `HashMap` should be generalized over different hashers error: impl for `HashMap` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:30:19 --> $DIR/implicit_hasher.rs:32:19
| |
LL | impl Foo<i16> for HashMap<String, String> { LL | impl Foo<i16> for HashMap<String, String> {
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
@ -49,7 +49,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default:
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: impl for `HashSet` should be generalized over different hashers error: impl for `HashSet` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:47:32 --> $DIR/implicit_hasher.rs:49:32
| |
LL | impl<T: Hash + Eq> Foo<i8> for HashSet<T> { LL | impl<T: Hash + Eq> Foo<i8> for HashSet<T> {
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -64,7 +64,7 @@ LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default:
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: impl for `HashSet` should be generalized over different hashers error: impl for `HashSet` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:52:19 --> $DIR/implicit_hasher.rs:54:19
| |
LL | impl Foo<i16> for HashSet<String> { LL | impl Foo<i16> for HashSet<String> {
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
@ -79,7 +79,7 @@ LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default:
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: parameter of type `HashMap` should be generalized over different hashers error: parameter of type `HashMap` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:69:23 --> $DIR/implicit_hasher.rs:71:23
| |
LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {} LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
@ -90,7 +90,7 @@ LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32, S>, _s
| +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~
error: parameter of type `HashSet` should be generalized over different hashers error: parameter of type `HashSet` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:69:53 --> $DIR/implicit_hasher.rs:71:53
| |
LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {} LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
@ -101,15 +101,12 @@ LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set:
| +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~
error: impl for `HashMap` should be generalized over different hashers error: impl for `HashMap` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:73:43 --> $DIR/implicit_hasher.rs:77:43
| |
LL | impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> { LL | impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
...
LL | gen!(impl);
| ---------- in this macro invocation
| |
= note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider adding a type parameter help: consider adding a type parameter
| |
LL | impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> { LL | impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {
@ -120,37 +117,31 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10,
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: parameter of type `HashMap` should be generalized over different hashers error: parameter of type `HashMap` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:81:33 --> $DIR/implicit_hasher.rs:83:31
| |
LL | pub fn $name(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {} LL | pub fn bar(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
...
LL | gen!(fn bar);
| ------------ in this macro invocation
| |
= note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider adding a type parameter help: consider adding a type parameter
| |
LL | pub fn $name<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32, S>, _set: &mut HashSet<i32>) {} LL | pub fn bar<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32, S>, _set: &mut HashSet<i32>) {}
| +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~
error: parameter of type `HashSet` should be generalized over different hashers error: parameter of type `HashSet` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:81:63 --> $DIR/implicit_hasher.rs:83:61
| |
LL | pub fn $name(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {} LL | pub fn bar(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
...
LL | gen!(fn bar);
| ------------ in this macro invocation
| |
= note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider adding a type parameter help: consider adding a type parameter
| |
LL | pub fn $name<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32, S>) {} LL | pub fn bar<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32, S>) {}
| +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~
error: parameter of type `HashMap` should be generalized over different hashers error: parameter of type `HashMap` should be generalized over different hashers
--> $DIR/implicit_hasher.rs:100:35 --> $DIR/implicit_hasher.rs:101:35
| |
LL | pub async fn election_vote(_data: HashMap<i32, i32>) {} LL | pub async fn election_vote(_data: HashMap<i32, i32>) {}
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^

View File

@ -1,10 +1,14 @@
// run-rustfix // run-rustfix
// aux-build:proc_macros.rs
#![warn(clippy::inconsistent_struct_constructor)] #![warn(clippy::inconsistent_struct_constructor)]
#![allow(clippy::redundant_field_names)] #![allow(clippy::redundant_field_names)]
#![allow(clippy::unnecessary_operation)] #![allow(clippy::unnecessary_operation)]
#![allow(clippy::no_effect)] #![allow(clippy::no_effect)]
#![allow(dead_code)] #![allow(dead_code)]
extern crate proc_macros;
#[derive(Default)] #[derive(Default)]
struct Foo { struct Foo {
x: i32, x: i32,
@ -12,18 +16,10 @@ struct Foo {
z: i32, z: i32,
} }
macro_rules! new_foo {
() => {
let x = 1;
let y = 1;
let z = 1;
Foo { y, x, z }
};
}
mod without_base { mod without_base {
use super::Foo; use super::Foo;
#[proc_macros::inline_macros]
fn test() { fn test() {
let x = 1; let x = 1;
let y = 1; let y = 1;
@ -34,7 +30,12 @@ mod without_base {
// Should NOT lint. // Should NOT lint.
// issue #7069. // issue #7069.
new_foo!(); inline!({
let x = 1;
let y = 1;
let z = 1;
Foo { y, x, z }
});
// Should NOT lint because the order is the same as in the definition. // Should NOT lint because the order is the same as in the definition.
Foo { x, y, z }; Foo { x, y, z };

View File

@ -1,10 +1,14 @@
// run-rustfix // run-rustfix
// aux-build:proc_macros.rs
#![warn(clippy::inconsistent_struct_constructor)] #![warn(clippy::inconsistent_struct_constructor)]
#![allow(clippy::redundant_field_names)] #![allow(clippy::redundant_field_names)]
#![allow(clippy::unnecessary_operation)] #![allow(clippy::unnecessary_operation)]
#![allow(clippy::no_effect)] #![allow(clippy::no_effect)]
#![allow(dead_code)] #![allow(dead_code)]
extern crate proc_macros;
#[derive(Default)] #[derive(Default)]
struct Foo { struct Foo {
x: i32, x: i32,
@ -12,18 +16,10 @@ struct Foo {
z: i32, z: i32,
} }
macro_rules! new_foo {
() => {
let x = 1;
let y = 1;
let z = 1;
Foo { y, x, z }
};
}
mod without_base { mod without_base {
use super::Foo; use super::Foo;
#[proc_macros::inline_macros]
fn test() { fn test() {
let x = 1; let x = 1;
let y = 1; let y = 1;
@ -34,7 +30,12 @@ mod without_base {
// Should NOT lint. // Should NOT lint.
// issue #7069. // issue #7069.
new_foo!(); inline!({
let x = 1;
let y = 1;
let z = 1;
Foo { y, x, z }
});
// Should NOT lint because the order is the same as in the definition. // Should NOT lint because the order is the same as in the definition.
Foo { x, y, z }; Foo { x, y, z };

View File

@ -1,5 +1,5 @@
error: struct constructor field order is inconsistent with struct definition field order error: struct constructor field order is inconsistent with struct definition field order
--> $DIR/inconsistent_struct_constructor.rs:33:9 --> $DIR/inconsistent_struct_constructor.rs:29:9
| |
LL | Foo { y, x, z }; LL | Foo { y, x, z };
| ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }` | ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }`
@ -7,7 +7,7 @@ LL | Foo { y, x, z };
= note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings` = note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings`
error: struct constructor field order is inconsistent with struct definition field order error: struct constructor field order is inconsistent with struct definition field order
--> $DIR/inconsistent_struct_constructor.rs:55:9 --> $DIR/inconsistent_struct_constructor.rs:56:9
| |
LL | / Foo { LL | / Foo {
LL | | z, LL | | z,

View File

@ -1,11 +1,11 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![allow(dead_code)] #![allow(dead_code)]
#![allow(unused_variables)] #![allow(unused_variables)]
#![warn(clippy::large_enum_variant)] #![warn(clippy::large_enum_variant)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::external;
enum LargeEnum { enum LargeEnum {
A(i32), A(i32),
@ -155,5 +155,10 @@ enum LargeEnumOfConst {
} }
fn main() { fn main() {
large_enum_variant!(); external!(
enum LargeEnumInMacro {
A(i32),
B([i32; 8000]),
}
);
} }

View File

@ -20,7 +20,7 @@ mod a {
use mac; use mac;
use mini_mac::ClippyMiniMacroTest; use mini_mac::ClippyMiniMacroTest;
use mini_mac; use mini_mac;
use mac::{inner::foofoo, inner::try_err}; use mac::{inner::mut_mut, inner::try_err};
use mac::inner; use mac::inner;
use mac::inner::nested::string_add; use mac::inner::nested::string_add;
use mac::inner::nested; use mac::inner::nested;
@ -36,7 +36,7 @@ mod a {
let v: ty_macro!() = Vec::default(); let v: ty_macro!() = Vec::default();
inner::try_err!(); inner::try_err!();
inner::foofoo!(); inner::mut_mut!();
nested::string_add!(); nested::string_add!();
} }
} }

View File

@ -36,7 +36,7 @@ mod a {
let v: ty_macro!() = Vec::default(); let v: ty_macro!() = Vec::default();
inner::try_err!(); inner::try_err!();
inner::foofoo!(); inner::mut_mut!();
nested::string_add!(); nested::string_add!();
} }
} }

View File

@ -16,7 +16,7 @@ error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:23:5 --> $DIR/macro_use_imports.rs:23:5
| |
LL | #[macro_use] LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};` | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:19:5 --> $DIR/macro_use_imports.rs:19:5

View File

@ -39,7 +39,7 @@ mod a {
let v: ty_macro!() = Vec::default(); let v: ty_macro!() = Vec::default();
inner::try_err!(); inner::try_err!();
inner::foofoo!(); inner::mut_mut!();
nested::string_add!(); nested::string_add!();
} }
} }

View File

@ -1,19 +1,13 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::manual_rem_euclid)] #![warn(clippy::manual_rem_euclid)]
#![allow(clippy::let_with_type_underscore)] #![allow(clippy::let_with_type_underscore)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
macro_rules! internal_rem_euclid {
() => {
let value: i32 = 5;
let _: i32 = value.rem_euclid(4);
};
}
#[inline_macros]
fn main() { fn main() {
let value: i32 = 5; let value: i32 = 5;
@ -39,10 +33,16 @@ fn main() {
let _: i32 = ((4 % value) + 4) % 4; let _: i32 = ((4 % value) + 4) % 4;
// Lint in internal macros // Lint in internal macros
internal_rem_euclid!(); inline!(
let value: i32 = 5;
let _: i32 = value.rem_euclid(4);
);
// Do not lint in external macros // Do not lint in external macros
manual_rem_euclid!(); external!(
let value: i32 = 5;
let _: i32 = ((value % 4) + 4) % 4;
);
} }
// Should lint for params too // Should lint for params too

View File

@ -1,19 +1,13 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::manual_rem_euclid)] #![warn(clippy::manual_rem_euclid)]
#![allow(clippy::let_with_type_underscore)] #![allow(clippy::let_with_type_underscore)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
macro_rules! internal_rem_euclid {
() => {
let value: i32 = 5;
let _: i32 = ((value % 4) + 4) % 4;
};
}
#[inline_macros]
fn main() { fn main() {
let value: i32 = 5; let value: i32 = 5;
@ -39,10 +33,16 @@ fn main() {
let _: i32 = ((4 % value) + 4) % 4; let _: i32 = ((4 % value) + 4) % 4;
// Lint in internal macros // Lint in internal macros
internal_rem_euclid!(); inline!(
let value: i32 = 5;
let _: i32 = ((value % 4) + 4) % 4;
);
// Do not lint in external macros // Do not lint in external macros
manual_rem_euclid!(); external!(
let value: i32 = 5;
let _: i32 = ((value % 4) + 4) % 4;
);
} }
// Should lint for params too // Should lint for params too

View File

@ -1,5 +1,5 @@
error: manual `rem_euclid` implementation error: manual `rem_euclid` implementation
--> $DIR/manual_rem_euclid.rs:20:18 --> $DIR/manual_rem_euclid.rs:14:18
| |
LL | let _: i32 = ((value % 4) + 4) % 4; LL | let _: i32 = ((value % 4) + 4) % 4;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
@ -7,39 +7,36 @@ LL | let _: i32 = ((value % 4) + 4) % 4;
= note: `-D clippy::manual-rem-euclid` implied by `-D warnings` = note: `-D clippy::manual-rem-euclid` implied by `-D warnings`
error: manual `rem_euclid` implementation error: manual `rem_euclid` implementation
--> $DIR/manual_rem_euclid.rs:21:18 --> $DIR/manual_rem_euclid.rs:15:18
| |
LL | let _: i32 = (4 + (value % 4)) % 4; LL | let _: i32 = (4 + (value % 4)) % 4;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
error: manual `rem_euclid` implementation error: manual `rem_euclid` implementation
--> $DIR/manual_rem_euclid.rs:22:18 --> $DIR/manual_rem_euclid.rs:16:18
| |
LL | let _: i32 = (value % 4 + 4) % 4; LL | let _: i32 = (value % 4 + 4) % 4;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
error: manual `rem_euclid` implementation error: manual `rem_euclid` implementation
--> $DIR/manual_rem_euclid.rs:23:18 --> $DIR/manual_rem_euclid.rs:17:18
| |
LL | let _: i32 = (4 + value % 4) % 4; LL | let _: i32 = (4 + value % 4) % 4;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
error: manual `rem_euclid` implementation error: manual `rem_euclid` implementation
--> $DIR/manual_rem_euclid.rs:24:22 --> $DIR/manual_rem_euclid.rs:18:22
| |
LL | let _: i32 = 1 + (4 + value % 4) % 4; LL | let _: i32 = 1 + (4 + value % 4) % 4;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
error: manual `rem_euclid` implementation error: manual `rem_euclid` implementation
--> $DIR/manual_rem_euclid.rs:13:22 --> $DIR/manual_rem_euclid.rs:38:22
| |
LL | let _: i32 = ((value % 4) + 4) % 4; LL | let _: i32 = ((value % 4) + 4) % 4;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
...
LL | internal_rem_euclid!();
| ---------------------- in this macro invocation
| |
= note: this error originates in the macro `internal_rem_euclid` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: manual `rem_euclid` implementation error: manual `rem_euclid` implementation
--> $DIR/manual_rem_euclid.rs:50:5 --> $DIR/manual_rem_euclid.rs:50:5

View File

@ -1,21 +1,12 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::mem_replace_with_default)] #![warn(clippy::mem_replace_with_default)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
macro_rules! take {
($s:expr) => {
std::mem::replace($s, Default::default())
};
}
fn replace_with_default() {
let s = &mut String::from("foo");
take!(s);
take_external!(s);
}
#[inline_macros]
fn main() { fn main() {
replace_with_default(); let s = &mut String::from("foo");
inline!(std::mem::replace($s, Default::default()));
external!(std::mem::replace($s, Default::default()));
} }

View File

@ -1,14 +1,11 @@
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
--> $DIR/mem_replace_macro.rs:9:9 --> $DIR/mem_replace_macro.rs:10:13
| |
LL | std::mem::replace($s, Default::default()) LL | inline!(std::mem::replace($s, Default::default()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | take!(s);
| -------- in this macro invocation
| |
= note: `-D clippy::mem-replace-with-default` implied by `-D warnings` = note: `-D clippy::mem-replace-with-default` implied by `-D warnings`
= note: this error originates in the macro `take` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error error: aborting due to previous error

View File

@ -3,15 +3,15 @@
//! The .stderr output of this test should be empty. Otherwise it's a bug somewhere. //! The .stderr output of this test should be empty. Otherwise it's a bug somewhere.
// aux-build:helper.rs // aux-build:helper.rs
// aux-build:../../auxiliary/proc_macro_with_span.rs // aux-build:../../auxiliary/proc_macros.rs
#![warn(clippy::missing_const_for_fn)] #![warn(clippy::missing_const_for_fn)]
#![feature(start)] #![feature(start)]
extern crate helper; extern crate helper;
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
struct Game; struct Game;

View File

@ -1,5 +1,5 @@
// needs-asm-support // needs-asm-support
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![warn(clippy::missing_docs_in_private_items)] #![warn(clippy::missing_docs_in_private_items)]
// When denying at the crate level, be sure to not get random warnings from the // When denying at the crate level, be sure to not get random warnings from the
@ -8,9 +8,9 @@
//! Some garbage docs for the crate here //! Some garbage docs for the crate here
#![doc = "More garbage"] #![doc = "More garbage"]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
use std::arch::global_asm; use std::arch::global_asm;
type Typedef = String; type Typedef = String;

View File

@ -1,4 +1,4 @@
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![warn(clippy::missing_docs_in_private_items)] #![warn(clippy::missing_docs_in_private_items)]
#![allow(dead_code)] #![allow(dead_code)]
@ -7,8 +7,8 @@
//! Some garbage docs for the crate here //! Some garbage docs for the crate here
#![doc = "More garbage"] #![doc = "More garbage"]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
struct Foo { struct Foo {
a: isize, a: isize,

View File

@ -1,5 +1,5 @@
// run-rustfix // run-rustfix
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![allow( #![allow(
dead_code, dead_code,
@ -10,8 +10,8 @@
clippy::unusual_byte_groupings clippy::unusual_byte_groupings
)] )]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
fn main() { fn main() {
let fail14 = 2_i32; let fail14 = 2_i32;

View File

@ -1,5 +1,5 @@
// run-rustfix // run-rustfix
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![allow( #![allow(
dead_code, dead_code,
@ -10,8 +10,8 @@
clippy::unusual_byte_groupings clippy::unusual_byte_groupings
)] )]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
fn main() { fn main() {
let fail14 = 2_32; let fail14 = 2_32;

View File

@ -1,12 +1,12 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![allow(unused)] #![allow(unused)]
#![allow(deref_nullptr)] #![allow(deref_nullptr)]
#![allow(clippy::unnecessary_operation)] #![allow(clippy::unnecessary_operation)]
#![allow(clippy::drop_copy)] #![allow(clippy::drop_copy)]
#![warn(clippy::multiple_unsafe_ops_per_block)] #![warn(clippy::multiple_unsafe_ops_per_block)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::external;
use core::arch::asm; use core::arch::asm;
@ -113,7 +113,10 @@ unsafe fn read_char_good(ptr: *const u8) -> char {
// no lint // no lint
fn issue10259() { fn issue10259() {
unsafe_macro!(); external!(unsafe {
*core::ptr::null::<()>();
*core::ptr::null::<()>();
});
} }
fn _fn_ptr(x: unsafe fn()) { fn _fn_ptr(x: unsafe fn()) {

View File

@ -126,7 +126,7 @@ LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> $DIR/multiple_unsafe_ops_per_block.rs:120:5 --> $DIR/multiple_unsafe_ops_per_block.rs:123:5
| |
LL | / unsafe { LL | / unsafe {
LL | | x(); LL | | x();
@ -135,18 +135,18 @@ LL | | }
| |_____^ | |_____^
| |
note: unsafe function call occurs here note: unsafe function call occurs here
--> $DIR/multiple_unsafe_ops_per_block.rs:121:9 --> $DIR/multiple_unsafe_ops_per_block.rs:124:9
| |
LL | x(); LL | x();
| ^^^ | ^^^
note: unsafe function call occurs here note: unsafe function call occurs here
--> $DIR/multiple_unsafe_ops_per_block.rs:122:9 --> $DIR/multiple_unsafe_ops_per_block.rs:125:9
| |
LL | x(); LL | x();
| ^^^ | ^^^
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> $DIR/multiple_unsafe_ops_per_block.rs:131:9 --> $DIR/multiple_unsafe_ops_per_block.rs:134:9
| |
LL | / unsafe { LL | / unsafe {
LL | | T::X(); LL | | T::X();
@ -155,18 +155,18 @@ LL | | }
| |_________^ | |_________^
| |
note: unsafe function call occurs here note: unsafe function call occurs here
--> $DIR/multiple_unsafe_ops_per_block.rs:132:13 --> $DIR/multiple_unsafe_ops_per_block.rs:135:13
| |
LL | T::X(); LL | T::X();
| ^^^^^^ | ^^^^^^
note: unsafe function call occurs here note: unsafe function call occurs here
--> $DIR/multiple_unsafe_ops_per_block.rs:133:13 --> $DIR/multiple_unsafe_ops_per_block.rs:136:13
| |
LL | T::X(); LL | T::X();
| ^^^^^^ | ^^^^^^
error: this `unsafe` block contains 2 unsafe operations, expected only one error: this `unsafe` block contains 2 unsafe operations, expected only one
--> $DIR/multiple_unsafe_ops_per_block.rs:141:5 --> $DIR/multiple_unsafe_ops_per_block.rs:144:5
| |
LL | / unsafe { LL | / unsafe {
LL | | x.0(); LL | | x.0();
@ -175,12 +175,12 @@ LL | | }
| |_____^ | |_____^
| |
note: unsafe function call occurs here note: unsafe function call occurs here
--> $DIR/multiple_unsafe_ops_per_block.rs:142:9 --> $DIR/multiple_unsafe_ops_per_block.rs:145:9
| |
LL | x.0(); LL | x.0();
| ^^^^^ | ^^^^^
note: unsafe function call occurs here note: unsafe function call occurs here
--> $DIR/multiple_unsafe_ops_per_block.rs:143:9 --> $DIR/multiple_unsafe_ops_per_block.rs:146:9
| |
LL | x.0(); LL | x.0();
| ^^^^^ | ^^^^^

View File

@ -1,11 +1,11 @@
//run-rustfix //run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::must_use_unit)] #![warn(clippy::must_use_unit)]
#![allow(clippy::unused_unit)] #![allow(clippy::unused_unit)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::external;
pub fn must_use_default() {} pub fn must_use_default() {}
@ -22,5 +22,8 @@ fn main() {
must_use_with_note(); must_use_with_note();
// We should not lint in external macros // We should not lint in external macros
must_use_unit!(); external!(
#[must_use]
fn foo() {}
);
} }

View File

@ -1,11 +1,11 @@
//run-rustfix //run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::must_use_unit)] #![warn(clippy::must_use_unit)]
#![allow(clippy::unused_unit)] #![allow(clippy::unused_unit)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::external;
#[must_use] #[must_use]
pub fn must_use_default() {} pub fn must_use_default() {}
@ -22,5 +22,8 @@ fn main() {
must_use_with_note(); must_use_with_note();
// We should not lint in external macros // We should not lint in external macros
must_use_unit!(); external!(
#[must_use]
fn foo() {}
);
} }

View File

@ -1,10 +1,10 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::mut_mut)] #![warn(clippy::mut_mut)]
#![allow(unused)] #![allow(unused)]
#![allow(clippy::no_effect, clippy::uninlined_format_args, clippy::unnecessary_operation)] #![allow(clippy::no_effect, clippy::uninlined_format_args, clippy::unnecessary_operation)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
fn fun(x: &mut &mut u32) -> bool { fn fun(x: &mut &mut u32) -> bool {
**x > 0 **x > 0
@ -21,6 +21,7 @@ macro_rules! mut_ptr {
} }
#[allow(unused_mut, unused_variables)] #[allow(unused_mut, unused_variables)]
#[inline_macros]
fn main() { fn main() {
let mut x = &mut &mut 1u32; let mut x = &mut &mut 1u32;
{ {
@ -37,7 +38,7 @@ fn main() {
***y + **x; ***y + **x;
} }
let mut z = mut_ptr!(&mut 3u32); let mut z = inline!(&mut $(&mut 3u32));
} }
fn issue939() { fn issue939() {
@ -55,7 +56,7 @@ fn issue939() {
fn issue6922() { fn issue6922() {
// do not lint from an external macro // do not lint from an external macro
mut_mut!(); external!(let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32;);
} }
mod issue9035 { mod issue9035 {

View File

@ -7,54 +7,51 @@ LL | fn fun(x: &mut &mut u32) -> bool {
= note: `-D clippy::mut-mut` implied by `-D warnings` = note: `-D clippy::mut-mut` implied by `-D warnings`
error: generally you want to avoid `&mut &mut _` if possible error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:25:17 --> $DIR/mut_mut.rs:26:17
| |
LL | let mut x = &mut &mut 1u32; LL | let mut x = &mut &mut 1u32;
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:19:9 --> $DIR/mut_mut.rs:41:25
| |
LL | &mut $p LL | let mut z = inline!(&mut $(&mut 3u32));
| ^^^^^^^ | ^
...
LL | let mut z = mut_ptr!(&mut 3u32);
| ------------------- in this macro invocation
| |
= note: this error originates in the macro `mut_ptr` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this expression mutably borrows a mutable reference. Consider reborrowing error: this expression mutably borrows a mutable reference. Consider reborrowing
--> $DIR/mut_mut.rs:27:21 --> $DIR/mut_mut.rs:28:21
| |
LL | let mut y = &mut x; LL | let mut y = &mut x;
| ^^^^^^ | ^^^^^^
error: generally you want to avoid `&mut &mut _` if possible error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:31:32 --> $DIR/mut_mut.rs:32:32
| |
LL | let y: &mut &mut u32 = &mut &mut 2; LL | let y: &mut &mut u32 = &mut &mut 2;
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:31:16 --> $DIR/mut_mut.rs:32:16
| |
LL | let y: &mut &mut u32 = &mut &mut 2; LL | let y: &mut &mut u32 = &mut &mut 2;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:36:37 --> $DIR/mut_mut.rs:37:37
| |
LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2;
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:36:16 --> $DIR/mut_mut.rs:37:16
| |
LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2;
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:36:21 --> $DIR/mut_mut.rs:37:21
| |
LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^

View File

@ -1,4 +1,5 @@
// run-rustfix // run-rustfix
// aux-build:proc_macros.rs
#![feature(let_chains)] #![feature(let_chains)]
#![allow(unused)] #![allow(unused)]
#![allow( #![allow(
@ -10,6 +11,8 @@
clippy::uninlined_format_args clippy::uninlined_format_args
)] )]
extern crate proc_macros;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::rc::Rc; use std::rc::Rc;
@ -138,6 +141,7 @@ const fn in_const() -> &'static str {
a a
} }
#[proc_macros::inline_macros]
fn does_not_lint() { fn does_not_lint() {
let z; let z;
if false { if false {
@ -195,35 +199,27 @@ fn does_not_lint() {
} }
y = 3; y = 3;
macro_rules! assign {
($i:ident) => {
$i = 1;
};
}
let x; let x;
assign!(x); inline!($x = 1;);
let x; let x;
if true { if true {
assign!(x); inline!($x = 1;);
} else { } else {
x = 2; x = 2;
} }
macro_rules! in_macro { inline!({
() => { let x;
let x; x = 1;
x = 1;
let x; let x;
if true { if true {
x = 1; x = 1;
} else { } else {
x = 2; x = 2;
} }
}; });
}
in_macro!();
// ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613 // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613
let x; let x;

View File

@ -1,4 +1,5 @@
// run-rustfix // run-rustfix
// aux-build:proc_macros.rs
#![feature(let_chains)] #![feature(let_chains)]
#![allow(unused)] #![allow(unused)]
#![allow( #![allow(
@ -10,6 +11,8 @@
clippy::uninlined_format_args clippy::uninlined_format_args
)] )]
extern crate proc_macros;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::rc::Rc; use std::rc::Rc;
@ -138,6 +141,7 @@ const fn in_const() -> &'static str {
a a
} }
#[proc_macros::inline_macros]
fn does_not_lint() { fn does_not_lint() {
let z; let z;
if false { if false {
@ -195,35 +199,27 @@ fn does_not_lint() {
} }
y = 3; y = 3;
macro_rules! assign {
($i:ident) => {
$i = 1;
};
}
let x; let x;
assign!(x); inline!($x = 1;);
let x; let x;
if true { if true {
assign!(x); inline!($x = 1;);
} else { } else {
x = 2; x = 2;
} }
macro_rules! in_macro { inline!({
() => { let x;
let x; x = 1;
x = 1;
let x; let x;
if true { if true {
x = 1; x = 1;
} else { } else {
x = 2; x = 2;
} }
}; });
}
in_macro!();
// ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613 // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613
let x; let x;

View File

@ -1,5 +1,5 @@
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:24:5 --> $DIR/needless_late_init.rs:27:5
| |
LL | let a; LL | let a;
| ^^^^^^ created here | ^^^^^^ created here
@ -13,7 +13,7 @@ LL | let a = "zero";
| ~~~~~ | ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:27:5 --> $DIR/needless_late_init.rs:30:5
| |
LL | let b; LL | let b;
| ^^^^^^ created here | ^^^^^^ created here
@ -27,7 +27,7 @@ LL | let b = 1;
| ~~~~~ | ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:28:5 --> $DIR/needless_late_init.rs:31:5
| |
LL | let c; LL | let c;
| ^^^^^^ created here | ^^^^^^ created here
@ -41,7 +41,7 @@ LL | let c = 2;
| ~~~~~ | ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:32:5 --> $DIR/needless_late_init.rs:35:5
| |
LL | let d: usize; LL | let d: usize;
| ^^^^^^^^^^^^^ created here | ^^^^^^^^^^^^^ created here
@ -54,7 +54,7 @@ LL | let d: usize = 1;
| ~~~~~~~~~~~~ | ~~~~~~~~~~~~
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:35:5 --> $DIR/needless_late_init.rs:38:5
| |
LL | let e; LL | let e;
| ^^^^^^ created here | ^^^^^^ created here
@ -67,7 +67,7 @@ LL | let e = format!("{}", d);
| ~~~~~ | ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:40:5 --> $DIR/needless_late_init.rs:43:5
| |
LL | let a; LL | let a;
| ^^^^^^ | ^^^^^^
@ -88,7 +88,7 @@ LL | };
| + | +
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:49:5 --> $DIR/needless_late_init.rs:52:5
| |
LL | let b; LL | let b;
| ^^^^^^ | ^^^^^^
@ -109,7 +109,7 @@ LL | };
| + | +
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:56:5 --> $DIR/needless_late_init.rs:59:5
| |
LL | let d; LL | let d;
| ^^^^^^ | ^^^^^^
@ -130,7 +130,7 @@ LL | };
| + | +
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:64:5 --> $DIR/needless_late_init.rs:67:5
| |
LL | let e; LL | let e;
| ^^^^^^ | ^^^^^^
@ -151,7 +151,7 @@ LL | };
| + | +
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:71:5 --> $DIR/needless_late_init.rs:74:5
| |
LL | let f; LL | let f;
| ^^^^^^ | ^^^^^^
@ -167,7 +167,7 @@ LL + 1 => "three",
| |
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:77:5 --> $DIR/needless_late_init.rs:80:5
| |
LL | let g: usize; LL | let g: usize;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -187,7 +187,7 @@ LL | };
| + | +
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:85:5 --> $DIR/needless_late_init.rs:88:5
| |
LL | let x; LL | let x;
| ^^^^^^ created here | ^^^^^^ created here
@ -201,7 +201,7 @@ LL | let x = 1;
| ~~~~~ | ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:89:5 --> $DIR/needless_late_init.rs:92:5
| |
LL | let x; LL | let x;
| ^^^^^^ created here | ^^^^^^ created here
@ -215,7 +215,7 @@ LL | let x = SignificantDrop;
| ~~~~~ | ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:93:5 --> $DIR/needless_late_init.rs:96:5
| |
LL | let x; LL | let x;
| ^^^^^^ created here | ^^^^^^ created here
@ -229,7 +229,7 @@ LL | let x = SignificantDrop;
| ~~~~~ | ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:112:5 --> $DIR/needless_late_init.rs:115:5
| |
LL | let a; LL | let a;
| ^^^^^^ | ^^^^^^
@ -250,7 +250,7 @@ LL | };
| + | +
error: unneeded late initialization error: unneeded late initialization
--> $DIR/needless_late_init.rs:129:5 --> $DIR/needless_late_init.rs:132:5
| |
LL | let a; LL | let a;
| ^^^^^^ | ^^^^^^

View File

@ -1,5 +1,5 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::needless_lifetimes)] #![warn(clippy::needless_lifetimes)]
#![allow( #![allow(
@ -12,8 +12,8 @@
clippy::get_first clippy::get_first
)] )]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::inline_macros;
fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {} fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {}
@ -502,30 +502,29 @@ mod pr_9743_output_lifetime_checks {
} }
} }
#[inline_macros]
mod in_macro { mod in_macro {
macro_rules! local_one_input_macro { use proc_macros::external;
() => {
fn one_input(x: &u8) -> &u8 {
unimplemented!()
}
};
}
// lint local macro expands to function with needless lifetimes // lint local macro expands to function with needless lifetimes
local_one_input_macro!(); inline! {
fn one_input(x: &u8) -> &u8 {
// no lint on external macro unimplemented!()
macro_rules::needless_lifetime!();
macro_rules! expanded_lifetime {
($l:lifetime) => {
fn f<$l>(arg: &$l str) -> &$l str {
arg
}
} }
} }
expanded_lifetime!('a); // no lint on external macro
external! {
fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 {
unimplemented!()
}
}
inline! {
fn f<$'a>(arg: &$'a str) -> &$'a str {
arg
}
}
} }
mod issue5787 { mod issue5787 {

View File

@ -1,5 +1,5 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::needless_lifetimes)] #![warn(clippy::needless_lifetimes)]
#![allow( #![allow(
@ -12,8 +12,8 @@
clippy::get_first clippy::get_first
)] )]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::inline_macros;
fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}
@ -502,30 +502,29 @@ mod pr_9743_output_lifetime_checks {
} }
} }
#[inline_macros]
mod in_macro { mod in_macro {
macro_rules! local_one_input_macro { use proc_macros::external;
() => {
fn one_input<'a>(x: &'a u8) -> &'a u8 {
unimplemented!()
}
};
}
// lint local macro expands to function with needless lifetimes // lint local macro expands to function with needless lifetimes
local_one_input_macro!(); inline! {
fn one_input<'a>(x: &'a u8) -> &'a u8 {
// no lint on external macro unimplemented!()
macro_rules::needless_lifetime!();
macro_rules! expanded_lifetime {
($l:lifetime) => {
fn f<$l>(arg: &$l str) -> &$l str {
arg
}
} }
} }
expanded_lifetime!('a); // no lint on external macro
external! {
fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 {
unimplemented!()
}
}
inline! {
fn f<$'a>(arg: &$'a str) -> &$'a str {
arg
}
}
} }
mod issue5787 { mod issue5787 {

View File

@ -540,19 +540,16 @@ LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8)
| |
error: the following explicit lifetimes could be elided: 'a error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:508:13 --> $DIR/needless_lifetimes.rs:511:9
| |
LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | local_one_input_macro!();
| ------------------------ in this macro invocation
| |
= note: this error originates in the macro `local_one_input_macro` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_mod_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
help: elide the lifetimes help: elide the lifetimes
| |
LL - fn one_input<'a>(x: &'a u8) -> &'a u8 { LL - fn one_input<'a>(x: &'a u8) -> &'a u8 {
LL + fn one_input(x: &u8) -> &u8 { LL + fn one_input(x: &u8) -> &u8 {
| |
error: aborting due to 46 previous errors error: aborting due to 46 previous errors

View File

@ -1,24 +1,16 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::option_env_unwrap)] #![warn(clippy::option_env_unwrap)]
#![allow(clippy::map_flatten)] #![allow(clippy::map_flatten)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
macro_rules! option_env_unwrap {
($env: expr) => {
option_env!($env).unwrap()
};
($env: expr, $message: expr) => {
option_env!($env).expect($message)
};
}
#[inline_macros]
fn main() { fn main() {
let _ = option_env!("PATH").unwrap(); let _ = option_env!("PATH").unwrap();
let _ = option_env!("PATH").expect("environment variable PATH isn't set"); let _ = option_env!("PATH").expect("environment variable PATH isn't set");
let _ = option_env_unwrap!("PATH"); let _ = inline!(option_env!($"PATH").unwrap());
let _ = option_env_unwrap!("PATH", "environment variable PATH isn't set"); let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set"));
let _ = option_env_unwrap_external!("PATH"); let _ = external!(option_env!($"PATH").unwrap());
let _ = option_env_unwrap_external!("PATH", "environment variable PATH isn't set"); let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set"));
} }

View File

@ -1,5 +1,5 @@
error: this will panic at run-time if the environment variable doesn't exist at compile-time error: this will panic at run-time if the environment variable doesn't exist at compile-time
--> $DIR/option_env_unwrap.rs:18:13 --> $DIR/option_env_unwrap.rs:10:13
| |
LL | let _ = option_env!("PATH").unwrap(); LL | let _ = option_env!("PATH").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | let _ = option_env!("PATH").unwrap();
= note: `-D clippy::option-env-unwrap` implied by `-D warnings` = note: `-D clippy::option-env-unwrap` implied by `-D warnings`
error: this will panic at run-time if the environment variable doesn't exist at compile-time error: this will panic at run-time if the environment variable doesn't exist at compile-time
--> $DIR/option_env_unwrap.rs:19:13 --> $DIR/option_env_unwrap.rs:11:13
| |
LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set"); LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -16,46 +16,40 @@ LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set
= help: consider using the `env!` macro instead = help: consider using the `env!` macro instead
error: this will panic at run-time if the environment variable doesn't exist at compile-time error: this will panic at run-time if the environment variable doesn't exist at compile-time
--> $DIR/option_env_unwrap.rs:10:9 --> $DIR/option_env_unwrap.rs:12:21
| |
LL | option_env!($env).unwrap() LL | let _ = inline!(option_env!($"PATH").unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | let _ = option_env_unwrap!("PATH");
| -------------------------- in this macro invocation
| |
= help: consider using the `env!` macro instead = help: consider using the `env!` macro instead
= note: this error originates in the macro `option_env_unwrap` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this will panic at run-time if the environment variable doesn't exist at compile-time error: this will panic at run-time if the environment variable doesn't exist at compile-time
--> $DIR/option_env_unwrap.rs:13:9 --> $DIR/option_env_unwrap.rs:13:21
| |
LL | option_env!($env).expect($message) LL | let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | let _ = option_env_unwrap!("PATH", "environment variable PATH isn't set");
| ----------------------------------------------------------------- in this macro invocation
| |
= help: consider using the `env!` macro instead = help: consider using the `env!` macro instead
= note: this error originates in the macro `option_env_unwrap` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this will panic at run-time if the environment variable doesn't exist at compile-time error: this will panic at run-time if the environment variable doesn't exist at compile-time
--> $DIR/option_env_unwrap.rs:22:13 --> $DIR/option_env_unwrap.rs:14:13
| |
LL | let _ = option_env_unwrap_external!("PATH"); LL | let _ = external!(option_env!($"PATH").unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: consider using the `env!` macro instead = help: consider using the `env!` macro instead
= note: this error originates in the macro `option_env_unwrap_external` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this will panic at run-time if the environment variable doesn't exist at compile-time error: this will panic at run-time if the environment variable doesn't exist at compile-time
--> $DIR/option_env_unwrap.rs:23:13 --> $DIR/option_env_unwrap.rs:15:13
| |
LL | let _ = option_env_unwrap_external!("PATH", "environment variable PATH isn't set"); LL | let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: consider using the `env!` macro instead = help: consider using the `env!` macro instead
= note: this error originates in the macro `option_env_unwrap_external` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -1,16 +1,12 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::ptr_as_ptr)] #![warn(clippy::ptr_as_ptr)]
extern crate macro_rules; extern crate proc_macros;
use proc_macros::{external, inline_macros};
macro_rules! cast_it {
($ptr: ident) => {
$ptr.cast::<i32>()
};
}
#[inline_macros]
fn main() { fn main() {
let ptr: *const u32 = &42_u32; let ptr: *const u32 = &42_u32;
let mut_ptr: *mut u32 = &mut 42_u32; let mut_ptr: *mut u32 = &mut 42_u32;
@ -38,10 +34,10 @@ fn main() {
let _: *mut i32 = mut_ptr.cast(); let _: *mut i32 = mut_ptr.cast();
// Make sure the lint is triggered inside a macro // Make sure the lint is triggered inside a macro
let _ = cast_it!(ptr); let _ = inline!($ptr.cast::<i32>());
// Do not lint inside macros from external crates // Do not lint inside macros from external crates
let _ = macro_rules::ptr_as_ptr_cast!(ptr); let _ = external!($ptr as *const i32);
} }
#[clippy::msrv = "1.37"] #[clippy::msrv = "1.37"]

View File

@ -1,16 +1,12 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::ptr_as_ptr)] #![warn(clippy::ptr_as_ptr)]
extern crate macro_rules; extern crate proc_macros;
use proc_macros::{external, inline_macros};
macro_rules! cast_it {
($ptr: ident) => {
$ptr as *const i32
};
}
#[inline_macros]
fn main() { fn main() {
let ptr: *const u32 = &42_u32; let ptr: *const u32 = &42_u32;
let mut_ptr: *mut u32 = &mut 42_u32; let mut_ptr: *mut u32 = &mut 42_u32;
@ -38,10 +34,10 @@ fn main() {
let _: *mut i32 = mut_ptr as _; let _: *mut i32 = mut_ptr as _;
// Make sure the lint is triggered inside a macro // Make sure the lint is triggered inside a macro
let _ = cast_it!(ptr); let _ = inline!($ptr as *const i32);
// Do not lint inside macros from external crates // Do not lint inside macros from external crates
let _ = macro_rules::ptr_as_ptr_cast!(ptr); let _ = external!($ptr as *const i32);
} }
#[clippy::msrv = "1.37"] #[clippy::msrv = "1.37"]

View File

@ -1,5 +1,5 @@
error: `as` casting between raw pointers without changing its mutability error: `as` casting between raw pointers without changing its mutability
--> $DIR/ptr_as_ptr.rs:18:13 --> $DIR/ptr_as_ptr.rs:14:13
| |
LL | let _ = ptr as *const i32; LL | let _ = ptr as *const i32;
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()` | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
@ -7,48 +7,45 @@ LL | let _ = ptr as *const i32;
= note: `-D clippy::ptr-as-ptr` implied by `-D warnings` = note: `-D clippy::ptr-as-ptr` implied by `-D warnings`
error: `as` casting between raw pointers without changing its mutability error: `as` casting between raw pointers without changing its mutability
--> $DIR/ptr_as_ptr.rs:19:13 --> $DIR/ptr_as_ptr.rs:15:13
| |
LL | let _ = mut_ptr as *mut i32; LL | let _ = mut_ptr as *mut i32;
| ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()` | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
error: `as` casting between raw pointers without changing its mutability error: `as` casting between raw pointers without changing its mutability
--> $DIR/ptr_as_ptr.rs:24:17 --> $DIR/ptr_as_ptr.rs:20:17
| |
LL | let _ = *ptr_ptr as *const i32; LL | let _ = *ptr_ptr as *const i32;
| ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::<i32>()` | ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::<i32>()`
error: `as` casting between raw pointers without changing its mutability error: `as` casting between raw pointers without changing its mutability
--> $DIR/ptr_as_ptr.rs:37:25 --> $DIR/ptr_as_ptr.rs:33:25
| |
LL | let _: *const i32 = ptr as *const _; LL | let _: *const i32 = ptr as *const _;
| ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()` | ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()`
error: `as` casting between raw pointers without changing its mutability error: `as` casting between raw pointers without changing its mutability
--> $DIR/ptr_as_ptr.rs:38:23 --> $DIR/ptr_as_ptr.rs:34:23
| |
LL | let _: *mut i32 = mut_ptr as _; LL | let _: *mut i32 = mut_ptr as _;
| ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()` | ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()`
error: `as` casting between raw pointers without changing its mutability error: `as` casting between raw pointers without changing its mutability
--> $DIR/ptr_as_ptr.rs:10:9 --> $DIR/ptr_as_ptr.rs:37:21
| |
LL | $ptr as *const i32 LL | let _ = inline!($ptr as *const i32);
| ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()` | ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()`
...
LL | let _ = cast_it!(ptr);
| ------------- in this macro invocation
| |
= note: this error originates in the macro `cast_it` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `as` casting between raw pointers without changing its mutability error: `as` casting between raw pointers without changing its mutability
--> $DIR/ptr_as_ptr.rs:62:13 --> $DIR/ptr_as_ptr.rs:58:13
| |
LL | let _ = ptr as *const i32; LL | let _ = ptr as *const i32;
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()` | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
error: `as` casting between raw pointers without changing its mutability error: `as` casting between raw pointers without changing its mutability
--> $DIR/ptr_as_ptr.rs:63:13 --> $DIR/ptr_as_ptr.rs:59:13
| |
LL | let _ = mut_ptr as *mut i32; LL | let _ = mut_ptr as *mut i32;
| ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()` | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`

View File

@ -1,9 +1,9 @@
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![warn(clippy::single_match_else)] #![warn(clippy::single_match_else)]
#![allow(clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] #![allow(clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
enum ExprNode { enum ExprNode {
ExprAddrOf, ExprAddrOf,

View File

@ -1,7 +1,7 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::external;
#[warn(clippy::string_add)] #[warn(clippy::string_add)]
#[allow(clippy::string_add_assign, unused)] #[allow(clippy::string_add_assign, unused)]
@ -22,5 +22,8 @@ fn main() {
x = x + 1; x = x + 1;
assert_eq!(2, x); assert_eq!(2, x);
string_add!(); external!({
let y = "".to_owned();
let z = y + "...";
});
} }

View File

@ -1,17 +1,12 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::toplevel_ref_arg)] #![warn(clippy::toplevel_ref_arg)]
#![allow(clippy::uninlined_format_args)] #![allow(clippy::uninlined_format_args, unused)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
macro_rules! gen_binding {
() => {
let _y = &42;
};
}
#[inline_macros]
fn main() { fn main() {
// Closures should not warn // Closures should not warn
let y = |ref x| println!("{:?}", x); let y = |ref x| println!("{:?}", x);
@ -38,13 +33,8 @@ fn main() {
for ref _x in 0..10 {} for ref _x in 0..10 {}
// lint in macro // lint in macro
#[allow(unused)] inline!(let _y = &42;);
{
gen_binding!();
}
// do not lint in external macro // do not lint in external macro
{ external!(let ref _y = 42;);
ref_arg_binding!();
}
} }

View File

@ -1,17 +1,12 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::toplevel_ref_arg)] #![warn(clippy::toplevel_ref_arg)]
#![allow(clippy::uninlined_format_args)] #![allow(clippy::uninlined_format_args, unused)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
macro_rules! gen_binding {
() => {
let ref _y = 42;
};
}
#[inline_macros]
fn main() { fn main() {
// Closures should not warn // Closures should not warn
let y = |ref x| println!("{:?}", x); let y = |ref x| println!("{:?}", x);
@ -38,13 +33,8 @@ fn main() {
for ref _x in 0..10 {} for ref _x in 0..10 {}
// lint in macro // lint in macro
#[allow(unused)] inline!(let ref _y = 42;);
{
gen_binding!();
}
// do not lint in external macro // do not lint in external macro
{ external!(let ref _y = 42;);
ref_arg_binding!();
}
} }

View File

@ -1,5 +1,5 @@
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
--> $DIR/toplevel_ref_arg.rs:20:9 --> $DIR/toplevel_ref_arg.rs:15:9
| |
LL | let ref _x = 1; LL | let ref _x = 1;
| ----^^^^^^----- help: try: `let _x = &1;` | ----^^^^^^----- help: try: `let _x = &1;`
@ -7,39 +7,36 @@ LL | let ref _x = 1;
= note: `-D clippy::toplevel-ref-arg` implied by `-D warnings` = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
--> $DIR/toplevel_ref_arg.rs:22:9 --> $DIR/toplevel_ref_arg.rs:17:9
| |
LL | let ref _y: (&_, u8) = (&1, 2); LL | let ref _y: (&_, u8) = (&1, 2);
| ----^^^^^^--------------------- help: try: `let _y: &(&_, u8) = &(&1, 2);` | ----^^^^^^--------------------- help: try: `let _y: &(&_, u8) = &(&1, 2);`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
--> $DIR/toplevel_ref_arg.rs:24:9 --> $DIR/toplevel_ref_arg.rs:19:9
| |
LL | let ref _z = 1 + 2; LL | let ref _z = 1 + 2;
| ----^^^^^^--------- help: try: `let _z = &(1 + 2);` | ----^^^^^^--------- help: try: `let _z = &(1 + 2);`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
--> $DIR/toplevel_ref_arg.rs:26:9 --> $DIR/toplevel_ref_arg.rs:21:9
| |
LL | let ref mut _z = 1 + 2; LL | let ref mut _z = 1 + 2;
| ----^^^^^^^^^^--------- help: try: `let _z = &mut (1 + 2);` | ----^^^^^^^^^^--------- help: try: `let _z = &mut (1 + 2);`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
--> $DIR/toplevel_ref_arg.rs:31:9 --> $DIR/toplevel_ref_arg.rs:26:9
| |
LL | let ref _x = vec![1, 2, 3]; LL | let ref _x = vec![1, 2, 3];
| ----^^^^^^----------------- help: try: `let _x = &vec![1, 2, 3];` | ----^^^^^^----------------- help: try: `let _x = &vec![1, 2, 3];`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
--> $DIR/toplevel_ref_arg.rs:11:13 --> $DIR/toplevel_ref_arg.rs:36:17
| |
LL | let ref _y = 42; LL | inline!(let ref _y = 42;);
| ----^^^^^^------ help: try: `let _y = &42;` | ----^^^^^^------ help: try: `let _y = &42;`
...
LL | gen_binding!();
| -------------- in this macro invocation
| |
= note: this error originates in the macro `gen_binding` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -1,33 +1,27 @@
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![warn(clippy::toplevel_ref_arg)] #![warn(clippy::toplevel_ref_arg)]
#![allow(unused)] #![allow(unused)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
fn the_answer(ref mut x: u8) { fn the_answer(ref mut x: u8) {
*x = 42; *x = 42;
} }
macro_rules! gen_function { #[inline_macros]
() => {
fn fun_example(ref _x: usize) {}
};
}
fn main() { fn main() {
let mut x = 0; let mut x = 0;
the_answer(x); the_answer(x);
// lint in macro // lint in macro
#[allow(unused)] inline! {
{ fn fun_example(ref _x: usize) {}
gen_function!();
} }
// do not lint in external macro // do not lint in external macro
{ external! {
ref_arg_function!(); fn fun_example2(ref _x: usize) {}
} }
} }

View File

@ -7,15 +7,12 @@ LL | fn the_answer(ref mut x: u8) {
= note: `-D clippy::toplevel-ref-arg` implied by `-D warnings` = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings`
error: `ref` directly on a function argument is ignored. Consider using a reference type instead error: `ref` directly on a function argument is ignored. Consider using a reference type instead
--> $DIR/toplevel_ref_arg_non_rustfix.rs:15:24 --> $DIR/toplevel_ref_arg_non_rustfix.rs:20:24
| |
LL | fn fun_example(ref _x: usize) {} LL | fn fun_example(ref _x: usize) {}
| ^^^^^^ | ^^^^^^
...
LL | gen_function!();
| --------------- in this macro invocation
| |
= note: this error originates in the macro `gen_function` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -1,11 +1,11 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![deny(clippy::try_err)] #![deny(clippy::try_err)]
#![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
use std::io; use std::io;
use std::task::Poll; use std::task::Poll;
@ -79,36 +79,22 @@ fn nested_error() -> Result<i32, i32> {
Ok(1) Ok(1)
} }
// Bad suggestion when in macro (see #6242) #[inline_macros]
macro_rules! try_validation { fn calling_macro() -> Result<i32, i32> {
($e: expr) => {{ // macro
match $e { inline!(
match $(Ok::<_, i32>(5)) {
Ok(_) => 0, Ok(_) => 0,
Err(_) => return Err(1), Err(_) => return Err(1),
} }
}}; );
}
macro_rules! ret_one {
() => {
1
};
}
macro_rules! try_validation_in_macro {
($e: expr) => {{
match $e {
Ok(_) => 0,
Err(_) => return Err(ret_one!()),
}
}};
}
fn calling_macro() -> Result<i32, i32> {
// macro
try_validation!(Ok::<_, i32>(5));
// `Err` arg is another macro // `Err` arg is another macro
try_validation_in_macro!(Ok::<_, i32>(5)); inline!(
match $(Ok::<_, i32>(5)) {
Ok(_) => 0,
Err(_) => return Err(inline!(1)),
}
);
Ok(5) Ok(5)
} }
@ -121,24 +107,19 @@ fn main() {
calling_macro().unwrap(); calling_macro().unwrap();
// We don't want to lint in external macros // We don't want to lint in external macros
try_err!(); external! {
} pub fn try_err_fn() -> Result<i32, i32> {
let err: i32 = 1;
macro_rules! bar { // To avoid warnings during rustfix
() => { if true { Err(err)? } else { Ok(2) }
String::from("aasdfasdfasdfa") }
}; }
}
macro_rules! foo {
() => {
bar!()
};
} }
#[inline_macros]
pub fn macro_inside(fail: bool) -> Result<i32, String> { pub fn macro_inside(fail: bool) -> Result<i32, String> {
if fail { if fail {
return Err(foo!()); return Err(inline!(inline!(String::from("aasdfasdfasdfa"))));
} }
Ok(0) Ok(0)
} }

View File

@ -1,11 +1,11 @@
// run-rustfix // run-rustfix
// aux-build:macro_rules.rs // aux-build:proc_macros.rs
#![deny(clippy::try_err)] #![deny(clippy::try_err)]
#![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)]
#[macro_use] extern crate proc_macros;
extern crate macro_rules; use proc_macros::{external, inline_macros};
use std::io; use std::io;
use std::task::Poll; use std::task::Poll;
@ -79,36 +79,22 @@ fn nested_error() -> Result<i32, i32> {
Ok(1) Ok(1)
} }
// Bad suggestion when in macro (see #6242) #[inline_macros]
macro_rules! try_validation { fn calling_macro() -> Result<i32, i32> {
($e: expr) => {{ // macro
match $e { inline!(
match $(Ok::<_, i32>(5)) {
Ok(_) => 0, Ok(_) => 0,
Err(_) => Err(1)?, Err(_) => Err(1)?,
} }
}}; );
}
macro_rules! ret_one {
() => {
1
};
}
macro_rules! try_validation_in_macro {
($e: expr) => {{
match $e {
Ok(_) => 0,
Err(_) => Err(ret_one!())?,
}
}};
}
fn calling_macro() -> Result<i32, i32> {
// macro
try_validation!(Ok::<_, i32>(5));
// `Err` arg is another macro // `Err` arg is another macro
try_validation_in_macro!(Ok::<_, i32>(5)); inline!(
match $(Ok::<_, i32>(5)) {
Ok(_) => 0,
Err(_) => Err(inline!(1))?,
}
);
Ok(5) Ok(5)
} }
@ -121,24 +107,19 @@ fn main() {
calling_macro().unwrap(); calling_macro().unwrap();
// We don't want to lint in external macros // We don't want to lint in external macros
try_err!(); external! {
} pub fn try_err_fn() -> Result<i32, i32> {
let err: i32 = 1;
macro_rules! bar { // To avoid warnings during rustfix
() => { if true { Err(err)? } else { Ok(2) }
String::from("aasdfasdfasdfa") }
}; }
}
macro_rules! foo {
() => {
bar!()
};
} }
#[inline_macros]
pub fn macro_inside(fail: bool) -> Result<i32, String> { pub fn macro_inside(fail: bool) -> Result<i32, String> {
if fail { if fail {
Err(foo!())?; Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?;
} }
Ok(0) Ok(0)
} }

View File

@ -29,53 +29,47 @@ LL | Err(err)?;
| ^^^^^^^^^ help: try this: `return Err(err.into())` | ^^^^^^^^^ help: try this: `return Err(err.into())`
error: returning an `Err(_)` with the `?` operator error: returning an `Err(_)` with the `?` operator
--> $DIR/try_err.rs:87:23 --> $DIR/try_err.rs:88:23
| |
LL | Err(_) => Err(1)?, LL | Err(_) => Err(1)?,
| ^^^^^^^ help: try this: `return Err(1)` | ^^^^^^^ help: try this: `return Err(1)`
...
LL | try_validation!(Ok::<_, i32>(5));
| -------------------------------- in this macro invocation
| |
= note: this error originates in the macro `try_validation` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: returning an `Err(_)` with the `?` operator error: returning an `Err(_)` with the `?` operator
--> $DIR/try_err.rs:102:23 --> $DIR/try_err.rs:95:23
| |
LL | Err(_) => Err(ret_one!())?, LL | Err(_) => Err(inline!(1))?,
| ^^^^^^^^^^^^^^^^ help: try this: `return Err(ret_one!())` | ^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(1))`
...
LL | try_validation_in_macro!(Ok::<_, i32>(5));
| ----------------------------------------- in this macro invocation
| |
= note: this error originates in the macro `try_validation_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: returning an `Err(_)` with the `?` operator error: returning an `Err(_)` with the `?` operator
--> $DIR/try_err.rs:141:9 --> $DIR/try_err.rs:122:9
| |
LL | Err(foo!())?; LL | Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?;
| ^^^^^^^^^^^^ help: try this: `return Err(foo!())` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(inline!(String::from("aasdfasdfasdfa"))))`
error: returning an `Err(_)` with the `?` operator error: returning an `Err(_)` with the `?` operator
--> $DIR/try_err.rs:148:9 --> $DIR/try_err.rs:129:9
| |
LL | Err(io::ErrorKind::WriteZero)? LL | Err(io::ErrorKind::WriteZero)?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))`
error: returning an `Err(_)` with the `?` operator error: returning an `Err(_)` with the `?` operator
--> $DIR/try_err.rs:150:9 --> $DIR/try_err.rs:131:9
| |
LL | Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))? LL | Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))`
error: returning an `Err(_)` with the `?` operator error: returning an `Err(_)` with the `?` operator
--> $DIR/try_err.rs:158:9 --> $DIR/try_err.rs:139:9
| |
LL | Err(io::ErrorKind::NotFound)? LL | Err(io::ErrorKind::NotFound)?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))`
error: returning an `Err(_)` with the `?` operator error: returning an `Err(_)` with the `?` operator
--> $DIR/try_err.rs:167:16 --> $DIR/try_err.rs:148:16
| |
LL | return Err(42)?; LL | return Err(42)?;
| ^^^^^^^^ help: try this: `Err(42)` | ^^^^^^^^ help: try this: `Err(42)`

View File

@ -1,11 +1,11 @@
// aux-build:proc_macro_with_span.rs // aux-build:proc_macros.rs
// run-rustfix // run-rustfix
#![warn(clippy::uninlined_format_args)] #![warn(clippy::uninlined_format_args)]
#![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)] #![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)]
#![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] #![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
macro_rules! no_param_str { macro_rules! no_param_str {
() => { () => {

View File

@ -1,11 +1,11 @@
// aux-build:proc_macro_with_span.rs // aux-build:proc_macros.rs
// run-rustfix // run-rustfix
#![warn(clippy::uninlined_format_args)] #![warn(clippy::uninlined_format_args)]
#![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)] #![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)]
#![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] #![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
macro_rules! no_param_str { macro_rules! no_param_str {
() => { () => {

View File

@ -1,4 +1,4 @@
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![warn(clippy::unit_arg)] #![warn(clippy::unit_arg)]
#![allow(unused_must_use, unused_variables)] #![allow(unused_must_use, unused_variables)]
#![allow( #![allow(
@ -13,9 +13,9 @@
clippy::unused_unit clippy::unused_unit
)] )]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
use std::fmt::Debug; use std::fmt::Debug;
fn foo<T: Debug>(t: T) { fn foo<T: Debug>(t: T) {

View File

@ -1,12 +1,12 @@
// run-rustfix // run-rustfix
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![warn(clippy::unnecessary_lazy_evaluations)] #![warn(clippy::unnecessary_lazy_evaluations)]
#![allow(clippy::redundant_closure)] #![allow(clippy::redundant_closure)]
#![allow(clippy::bind_instead_of_map)] #![allow(clippy::bind_instead_of_map)]
#![allow(clippy::map_identity)] #![allow(clippy::map_identity)]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
struct Deep(Option<usize>); struct Deep(Option<usize>);

View File

@ -1,12 +1,12 @@
// run-rustfix // run-rustfix
// aux-build: proc_macro_with_span.rs // aux-build: proc_macros.rs
#![warn(clippy::unnecessary_lazy_evaluations)] #![warn(clippy::unnecessary_lazy_evaluations)]
#![allow(clippy::redundant_closure)] #![allow(clippy::redundant_closure)]
#![allow(clippy::bind_instead_of_map)] #![allow(clippy::bind_instead_of_map)]
#![allow(clippy::map_identity)] #![allow(clippy::map_identity)]
extern crate proc_macro_with_span; extern crate proc_macros;
use proc_macro_with_span::with_span; use proc_macros::with_span;
struct Deep(Option<usize>); struct Deep(Option<usize>);

View File

@ -1,10 +1,10 @@
// aux-build:doc_unsafe_macros.rs // aux-build:proc_macros.rs
#![allow(clippy::let_unit_value)] #![allow(clippy::let_unit_value)]
#![warn(clippy::unnecessary_safety_doc)] #![warn(clippy::unnecessary_safety_doc)]
#[macro_use] extern crate proc_macros;
extern crate doc_unsafe_macros; use proc_macros::external;
/// This is has no safety section, and does not need one either /// This is has no safety section, and does not need one either
pub fn destroy_the_planet() { pub fn destroy_the_planet() {
@ -129,7 +129,11 @@ macro_rules! very_safe {
very_safe!(); very_safe!();
// we don't lint code from external macros // we don't lint code from external macros
undocd_safe!(); external!(
pub fn vey_oy() {
unimplemented!();
}
);
fn main() {} fn main() {}

View File

@ -42,7 +42,7 @@ LL | very_safe!();
= note: this error originates in the macro `very_safe` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `very_safe` (in Nightly builds, run with -Z macro-backtrace for more info)
error: docs for safe trait have unnecessary `# Safety` section error: docs for safe trait have unnecessary `# Safety` section
--> $DIR/unnecessary_unsafety_doc.rs:147:1 --> $DIR/unnecessary_unsafety_doc.rs:151:1
| |
LL | pub trait DocumentedSafeTraitWithImplementationHeader { LL | pub trait DocumentedSafeTraitWithImplementationHeader {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^