#![warn(clippy::unit_arg)] #![allow( clippy::no_effect, unused_must_use, unused_variables, clippy::unused_unit, clippy::unnecessary_wraps, clippy::or_fun_call, clippy::needless_question_mark, clippy::self_named_constructors )] use std::fmt::Debug; fn foo(t: T) { println!("{:?}", t); } fn foo3(t1: T1, t2: T2, t3: T3) { println!("{:?}, {:?}, {:?}", t1, t2, t3); } struct Bar; impl Bar { fn bar(&self, t: T) { println!("{:?}", t); } } fn baz(t: T) { foo(t); } trait Tr { type Args; fn do_it(args: Self::Args); } struct A; impl Tr for A { type Args = (); fn do_it(_: Self::Args) {} } struct B; impl Tr for B { type Args = ::Args; fn do_it(args: Self::Args) { A::do_it(args) } } fn bad() { foo({ 1; }); foo(foo(1)); foo({ foo(1); foo(2); }); let b = Bar; b.bar({ 1; }); taking_multiple_units(foo(0), foo(1)); taking_multiple_units(foo(0), { foo(1); foo(2); }); taking_multiple_units( { foo(0); foo(1); }, { foo(2); foo(3); }, ); // here Some(foo(2)) isn't the top level statement expression, wrap the suggestion in a block None.or(Some(foo(2))); // in this case, the suggestion can be inlined, no need for a surrounding block // foo(()); foo(()) instead of { foo(()); foo(()) } foo(foo(())); } fn ok() { foo(()); foo(1); foo({ 1 }); foo3("a", 3, vec![3]); let b = Bar; b.bar({ 1 }); b.bar(()); question_mark(); let named_unit_arg = (); foo(named_unit_arg); baz(()); B::do_it(()); } fn question_mark() -> Result<(), ()> { Ok(Ok(())?)?; Ok(Ok(()))??; Ok(()) } #[allow(dead_code)] mod issue_2945 { fn unit_fn() -> Result<(), i32> { Ok(()) } fn fallible() -> Result<(), i32> { Ok(unit_fn()?) } } #[allow(dead_code)] fn returning_expr() -> Option<()> { Some(foo(1)) } fn taking_multiple_units(a: (), b: ()) {} fn main() { bad(); ok(); }