use crate::lints::UnitBindingsDiag; use crate::{LateLintPass, LintContext}; use rustc_hir as hir; use rustc_middle::ty::Ty; declare_lint! { /// The `unit_bindings` lint detects cases where bindings are useless because they have /// the unit type `()` as their inferred type. The lint is suppressed if the user explicitly /// annotates the let binding with the unit type `()`, or if the let binding uses an underscore /// wildcard pattern, i.e. `let _ = expr`, or if the binding is produced from macro expansions. /// /// ### Example /// /// ```rust,compile_fail /// #![deny(unit_bindings)] /// /// fn foo() { /// println!("do work"); /// } /// /// pub fn main() { /// let x = foo(); // useless binding /// } /// ``` /// /// {{produces}} /// /// ### Explanation /// /// Creating a local binding with the unit type `()` does not do much and can be a sign of a /// user error, such as in this example: /// /// ```rust,no_run /// fn main() { /// let mut x = [1, 2, 3]; /// x[0] = 5; /// let y = x.sort(); // useless binding as `sort` returns `()` and not the sorted array. /// println!("{:?}", y); // prints "()" /// } /// ``` pub UNIT_BINDINGS, Allow, "binding is useless because it has the unit `()` type" } declare_lint_pass!(UnitBindings => [UNIT_BINDINGS]); impl<'tcx> LateLintPass<'tcx> for UnitBindings { fn check_local(&mut self, cx: &crate::LateContext<'tcx>, local: &'tcx hir::Local<'tcx>) { // Suppress warning if user: // - explicitly ascribes a type to the pattern // - explicitly wrote `let pat = ();` // - explicitly wrote `let () = init;`. if !local.span.from_expansion() && let Some(tyck_results) = cx.maybe_typeck_results() && let Some(init) = local.init && let init_ty = tyck_results.expr_ty(init) && let local_ty = tyck_results.node_type(local.hir_id) && init_ty == Ty::new_unit(cx.tcx) && local_ty == Ty::new_unit(cx.tcx) && local.ty.is_none() && !matches!(init.kind, hir::ExprKind::Tup([])) && !matches!(local.pat.kind, hir::PatKind::Tuple([], ..)) { cx.emit_spanned_lint( UNIT_BINDINGS, local.span, UnitBindingsDiag { label: local.pat.span }, ); } } }