1 // aux-build:proc_macro_derive.rs 2 3 #![feature(rustc_private)] 4 #![warn(clippy::all)] 5 #![allow(clippy::blacklisted_name, clippy::eq_op)] 6 #![warn(clippy::used_underscore_binding)] 7 8 #[macro_use] 9 extern crate proc_macro_derive; 10 11 // This should not trigger the lint. There's underscore binding inside the external derive that 12 // would trigger the `used_underscore_binding` lint. 13 #[derive(DeriveSomething)] 14 struct Baz; 15 16 macro_rules! test_macro { 17 () => {{ 18 let _foo = 42; 19 _foo + 1 20 }}; 21 } 22 23 /// Tests that we lint if we use a binding with a single leading underscore prefix_underscore(_foo: u32) -> u3224fn prefix_underscore(_foo: u32) -> u32 { 25 _foo + 1 26 } 27 28 /// Tests that we lint if we use a `_`-variable defined outside within a macro expansion in_macro_or_desugar(_foo: u32)29fn in_macro_or_desugar(_foo: u32) { 30 println!("{}", _foo); 31 assert_eq!(_foo, _foo); 32 33 test_macro!() + 1; 34 } 35 36 // Struct for testing use of fields prefixed with an underscore 37 struct StructFieldTest { 38 _underscore_field: u32, 39 } 40 41 /// Tests that we lint the use of a struct field which is prefixed with an underscore in_struct_field()42fn in_struct_field() { 43 let mut s = StructFieldTest { _underscore_field: 0 }; 44 s._underscore_field += 1; 45 } 46 47 /// Tests that we do not lint if the underscore is not a prefix non_prefix_underscore(some_foo: u32) -> u3248fn non_prefix_underscore(some_foo: u32) -> u32 { 49 some_foo + 1 50 } 51 52 /// Tests that we do not lint if we do not use the binding (simple case) unused_underscore_simple(_foo: u32) -> u3253fn unused_underscore_simple(_foo: u32) -> u32 { 54 1 55 } 56 57 /// Tests that we do not lint if we do not use the binding (complex case). This checks for 58 /// compatibility with the built-in `unused_variables` lint. unused_underscore_complex(mut _foo: u32) -> u3259fn unused_underscore_complex(mut _foo: u32) -> u32 { 60 _foo += 1; 61 _foo = 2; 62 1 63 } 64 65 /// Test that we do not lint for multiple underscores multiple_underscores(__foo: u32) -> u3266fn multiple_underscores(__foo: u32) -> u32 { 67 __foo + 1 68 } 69 70 // Non-variable bindings with preceding underscore _fn_test()71fn _fn_test() {} 72 struct _StructTest; 73 enum _EnumTest { 74 _Empty, 75 _Value(_StructTest), 76 } 77 78 /// Tests that we do not lint for non-variable bindings non_variables()79fn non_variables() { 80 _fn_test(); 81 let _s = _StructTest; 82 let _e = match _EnumTest::_Value(_StructTest) { 83 _EnumTest::_Empty => 0, 84 _EnumTest::_Value(_st) => 1, 85 }; 86 let f = _fn_test; 87 f(); 88 } 89 90 // Tests that we do not lint if the binding comes from await desugaring, 91 // but we do lint the awaited expression. See issue 5360. await_desugaring()92async fn await_desugaring() { 93 async fn foo() {} 94 fn uses_i(_i: i32) {} 95 96 foo().await; 97 ({ 98 let _i = 5; 99 uses_i(_i); 100 foo() 101 }) 102 .await 103 } 104 main()105fn main() { 106 let foo = 0u32; 107 // tests of unused_underscore lint 108 let _ = prefix_underscore(foo); 109 in_macro_or_desugar(foo); 110 in_struct_field(); 111 // possible false positives 112 let _ = non_prefix_underscore(foo); 113 let _ = unused_underscore_simple(foo); 114 let _ = unused_underscore_complex(foo); 115 let _ = multiple_underscores(foo); 116 non_variables(); 117 await_desugaring(); 118 } 119