Skip to content

Commit c9cab06

Browse files
Add necessary supplement to VarBindingForm
1 parent 9925082 commit c9cab06

File tree

6 files changed

+69
-32
lines changed

6 files changed

+69
-32
lines changed

src/librustc_middle/lint.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
1212
use rustc_span::{Span, Symbol};
1313

1414
/// How a lint level was set.
15-
#[derive(Clone, Copy, PartialEq, Eq, HashStable)]
15+
#[derive(Clone, Copy, Debug, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
1616
pub enum LintSource {
1717
/// Lint is at the default level as declared
1818
/// in rustc or a plugin.

src/librustc_middle/mir/mod.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//!
33
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
44
5+
use crate::lint;
56
use crate::mir::interpret::{GlobalAlloc, Scalar};
67
use crate::mir::visit::MirVisitable;
78
use crate::ty::adjustment::PointerCast;
@@ -14,7 +15,7 @@ use crate::ty::{
1415
use rustc_hir as hir;
1516
use rustc_hir::def::{CtorKind, Namespace};
1617
use rustc_hir::def_id::DefId;
17-
use rustc_hir::{self, GeneratorKind};
18+
use rustc_hir::GeneratorKind;
1819
use rustc_target::abi::VariantIdx;
1920

2021
use polonius_engine::Atom;
@@ -596,6 +597,22 @@ pub enum LocalKind {
596597

597598
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
598599
pub struct VarBindingForm<'tcx> {
600+
/// Bindings in match arms with guards are lowered to two distinct locals, one for inside the
601+
/// guard and one for inside the match arm. If this local is the one used in the match arm,
602+
/// `counterpart_in_guard` will be the local representing the same binding in the guard.
603+
pub counterpart_in_guard: Option<Local>,
604+
605+
/// `true` if this variable was declared as a binding to a struct field with the same name
606+
/// (e.g., `x` in `Foo { x }`).
607+
pub is_shorthand_field_binding: bool,
608+
609+
/// The name of this variable.
610+
pub name: Symbol,
611+
612+
pub unused_variables_lint_level: lint::LevelSource,
613+
614+
pub unused_assignments_lint_level: lint::LevelSource,
615+
599616
/// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
600617
pub binding_mode: ty::BindingMode,
601618
/// If an explicit type was provided for this variable binding,
@@ -845,9 +862,7 @@ impl<'tcx> LocalDecl<'tcx> {
845862
match self.local_info {
846863
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
847864
binding_mode: ty::BindingMode::BindByValue(_),
848-
opt_ty_info: _,
849-
opt_match_place: _,
850-
pat_span: _,
865+
..
851866
})))) => true,
852867

853868
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(
@@ -865,9 +880,7 @@ impl<'tcx> LocalDecl<'tcx> {
865880
match self.local_info {
866881
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
867882
binding_mode: ty::BindingMode::BindByValue(_),
868-
opt_ty_info: _,
869-
opt_match_place: _,
870-
pat_span: _,
883+
..
871884
})))) => true,
872885

873886
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_)))) => true,

src/librustc_mir/borrow_check/diagnostics/move_errors.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
106106
if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
107107
VarBindingForm {
108108
opt_match_place: Some((opt_match_place, match_span)),
109-
binding_mode: _,
110-
opt_ty_info: _,
111-
pat_span: _,
109+
..
112110
},
113111
)))) = local_decl.local_info
114112
{

src/librustc_mir_build/build/matches/mod.rs

+36-20
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_index::bit_set::BitSet;
1616
use rustc_middle::middle::region;
1717
use rustc_middle::mir::*;
1818
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
19+
use rustc_session::lint;
1920
use rustc_span::Span;
2021
use rustc_span::symbol::Symbol;
2122
use rustc_target::abi::VariantIdx;
@@ -1980,6 +1981,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19801981
BindingMode::ByRef(_) => ty::BindingMode::BindByReference(mutability),
19811982
};
19821983
debug!("declare_binding: user_ty={:?}", user_ty);
1984+
1985+
let ref_for_guard = has_guard.0.then(|| {
1986+
let local = self.local_decls.push(LocalDecl::<'tcx> {
1987+
// This variable isn't mutated but has a name, so has to be
1988+
// immutable to avoid the unused mut lint.
1989+
mutability: Mutability::Not,
1990+
ty: tcx.mk_imm_ref(tcx.lifetimes.re_erased, var_ty),
1991+
user_ty: None,
1992+
source_info,
1993+
internal: false,
1994+
is_block_tail: None,
1995+
local_info: Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard))),
1996+
});
1997+
self.var_debug_info.push(VarDebugInfo {
1998+
name,
1999+
source_info: debug_source_info,
2000+
place: local.into(),
2001+
});
2002+
local
2003+
});
2004+
2005+
let name = tcx.hir().name(var_id);
2006+
let is_shorthand_field_binding = false;
2007+
let unused_variables_lint_level = tcx.lint_level_at_node(lint::builtin::UNUSED_VARIABLES, var_id);
2008+
let unused_assignments_lint_level = tcx.lint_level_at_node(lint::builtin::UNUSED_ASSIGNMENTS, var_id);
19832009
let local = LocalDecl::<'tcx> {
19842010
mutability,
19852011
ty: var_ty,
@@ -1988,6 +2014,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19882014
internal: false,
19892015
is_block_tail: None,
19902016
local_info: Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
2017+
unused_assignments_lint_level,
2018+
unused_variables_lint_level,
2019+
is_shorthand_field_binding,
2020+
counterpart_in_guard: ref_for_guard,
2021+
name,
19912022
binding_mode,
19922023
// hypothetically, `visit_primary_bindings` could try to unzip
19932024
// an outermost hir::Ty as we descend, matching up
@@ -2004,27 +2035,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20042035
source_info: debug_source_info,
20052036
place: for_arm_body.into(),
20062037
});
2007-
let locals = if has_guard.0 {
2008-
let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
2009-
// This variable isn't mutated but has a name, so has to be
2010-
// immutable to avoid the unused mut lint.
2011-
mutability: Mutability::Not,
2012-
ty: tcx.mk_imm_ref(tcx.lifetimes.re_erased, var_ty),
2013-
user_ty: None,
2014-
source_info,
2015-
internal: false,
2016-
is_block_tail: None,
2017-
local_info: Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard))),
2018-
});
2019-
self.var_debug_info.push(VarDebugInfo {
2020-
name,
2021-
source_info: debug_source_info,
2022-
place: ref_for_guard.into(),
2023-
});
2024-
LocalsForNode::ForGuard { ref_for_guard, for_arm_body }
2025-
} else {
2026-
LocalsForNode::One(for_arm_body)
2038+
2039+
let locals = match ref_for_guard {
2040+
Some(ref_for_guard) => LocalsForNode::ForGuard { ref_for_guard, for_arm_body },
2041+
None => LocalsForNode::One(for_arm_body),
20272042
};
2043+
20282044
debug!("declare_binding: vars={:?}", locals);
20292045
self.var_indices.insert(var_id, locals);
20302046
}

src/librustc_mir_build/build/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_middle::middle::region;
1414
use rustc_middle::mir::*;
1515
use rustc_middle::ty::subst::Subst;
1616
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
17+
use rustc_session::lint;
1718
use rustc_span::symbol::kw;
1819
use rustc_span::Span;
1920
use rustc_target::spec::abi::Abi;
@@ -888,8 +889,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
888889
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(*kind))))
889890
} else {
890891
let binding_mode = ty::BindingMode::BindByValue(mutability);
892+
let unused_variables_lint_level = tcx.lint_level_at_node(lint::builtin::UNUSED_VARIABLES, var);
893+
let unused_assignments_lint_level = tcx.lint_level_at_node(lint::builtin::UNUSED_ASSIGNMENTS, var);
894+
let is_shorthand_field_binding = false;
895+
let name = tcx_hir.name(var);
891896
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
892897
VarBindingForm {
898+
is_shorthand_field_binding,
899+
counterpart_in_guard: None,
900+
name,
901+
unused_variables_lint_level,
902+
unused_assignments_lint_level,
893903
binding_mode,
894904
opt_ty_info,
895905
opt_match_place: Some((Some(place), span)),

src/librustc_session/lint.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
88
pub mod builtin;
99

1010
/// Setting for how to handle a lint.
11-
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
11+
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash, RustcEncodable, RustcDecodable)]
1212
pub enum Level {
1313
Allow,
1414
Warn,

0 commit comments

Comments
 (0)