use rustc_hir::def::Res;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::hir_id::ItemLocalId;
-use rustc_hir::{
- Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, Let, Node, Pat, PatKind, QPath, UnOp,
-};
+use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, Let, Node, Pat, PatKind, QPath, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{Span, Symbol};
/// ### Example
/// ```rust
/// # let x = 1;
- /// // Bad
/// let x = &x;
+ /// ```
///
- /// // Good
+ /// Use instead:
+ /// ```rust
+ /// # let x = 1;
/// let y = &x; // use different variable name
/// ```
#[clippy::version = "pre 1.29.0"]
/// # let y = 1;
/// # let z = 2;
/// let x = y;
- ///
- /// // Bad
/// let x = z; // shadows the earlier binding
+ /// ```
///
- /// // Good
+ /// Use instead:
+ /// ```rust
+ /// # let y = 1;
+ /// # let z = 2;
+ /// let x = y;
/// let w = z; // use different variable name
/// ```
#[clippy::version = "pre 1.29.0"]
fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {
let hir = cx.tcx.hir();
- if !matches!(hir.body_owner_kind(hir.body_owner_def_id(body.id())), BodyOwnerKind::Closure)
- {
+ if !matches!(
+ hir.body_owner_kind(hir.body_owner_def_id(body.id())),
+ BodyOwnerKind::Closure
+ ) {
self.bindings.push(FxHashMap::default());
}
}
fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {
let hir = cx.tcx.hir();
- if !matches!(hir.body_owner_kind(hir.body_owner_def_id(body.id())), BodyOwnerKind::Closure)
- {
+ if !matches!(
+ hir.body_owner_kind(hir.body_owner_def_id(body.id())),
+ BodyOwnerKind::Closure
+ ) {
self.bindings.pop();
}
}
}
-fn is_shadow(
- cx: &LateContext<'_>,
- owner: LocalDefId,
- first: ItemLocalId,
- second: ItemLocalId,
-) -> bool {
- let scope_tree = &cx
- .tcx
- .typeck_body(cx.tcx.hir().body_owned_by(cx.tcx.hir().local_def_id_to_hir_id(owner)))
- .region_scope_tree;
- let first_scope = scope_tree.var_scope(first).unwrap();
- let second_scope = scope_tree.var_scope(second).unwrap();
- scope_tree.is_subscope_of(second_scope, first_scope)
+fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {
+ let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id());
+ if let Some(first_scope) = scope_tree.var_scope(first) {
+ if let Some(second_scope) = scope_tree.var_scope(second) {
+ return scope_tree.is_subscope_of(second_scope, first_scope);
+ }
+ }
+
+ false
}
fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span) {
snippet(cx, expr.span, "..")
);
(SHADOW_SAME, msg)
- }
+ },
Some(expr) if is_local_used(cx, expr, shadowed) => {
let msg = format!("`{}` is shadowed", snippet(cx, pat.span, "_"));
(SHADOW_REUSE, msg)
- }
+ },
_ => {
- let msg =
- format!("`{}` shadows a previous, unrelated binding", snippet(cx, pat.span, "_"));
+ let msg = format!("`{}` shadows a previous, unrelated binding", snippet(cx, pat.span, "_"));
(SHADOW_UNRELATED, msg)
- }
+ },
};
span_lint_and_note(
cx,
expr = match expr.kind {
ExprKind::Box(e)
| ExprKind::AddrOf(_, _, e)
- | ExprKind::Block(&Block { stmts: [], expr: Some(e), .. }, _)
+ | ExprKind::Block(
+ &Block {
+ stmts: [],
+ expr: Some(e),
+ ..
+ },
+ _,
+ )
| ExprKind::Unary(UnOp::Deref, e) => e,
ExprKind::Path(QPath::Resolved(None, path)) => break path.res == Res::Local(hir_id),
_ => break false,