Skip to content

Perform unused assignment and unused variables lints on MIR. #142390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// whether or not the right-hand side is a place expression
if let LocalInfo::User(BindingForm::Var(VarBindingForm {
opt_match_place: Some((opt_match_place, match_span)),
binding_mode: _,
opt_ty_info: _,
pat_span: _,
..
})) = *local_decl.local_info()
{
let stmt_source_info = self.body.source_info(location);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
LocalInfo::User(BindingForm::Var(mir::VarBindingForm {
binding_mode: BindingMode(ByRef::No, Mutability::Not),
opt_ty_info: Some(sp),
opt_match_place: _,
pat_span: _,
..
})) => {
if suggest {
err.span_note(sp, "the binding is already a mutable borrow");
Expand Down Expand Up @@ -738,6 +737,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
opt_ty_info: _,
opt_match_place: _,
pat_span,
introductions: _,
})) => pat_span,
_ => local_decl.source_info.span,
};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
tcx.ensure_ok().mir_borrowck(def_id)
}
tcx.ensure_ok().has_ffi_unwind_calls(def_id);
tcx.ensure_ok().check_liveness(def_id);

// If we need to codegen, ensure that we emit all errors from
// `mir_drops_elaborated_and_const_checked` now, to avoid discovering
Expand Down
24 changes: 9 additions & 15 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,8 @@ pub struct VarBindingForm<'tcx> {
pub opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
/// The span of the pattern in which this variable was bound.
pub pat_span: Span,
/// For each introduction place, record here the span and whether this was a shorthand pattern.
pub introductions: Vec<(Span, /* is_shorthand */ bool)>,
}

#[derive(Clone, Debug, TyEncodable, TyDecodable)]
Expand All @@ -935,7 +937,7 @@ pub enum BindingForm<'tcx> {
/// Binding for a `self`/`&self`/`&mut self` binding where the type is implicit.
ImplicitSelf(ImplicitSelfKind),
/// Reference used in a guard expression to ensure immutability.
RefForGuard,
RefForGuard(Local),
}

mod binding_form_impl {
Expand All @@ -950,7 +952,7 @@ mod binding_form_impl {
match self {
Var(binding) => binding.hash_stable(hcx, hasher),
ImplicitSelf(kind) => kind.hash_stable(hcx, hasher),
RefForGuard => (),
RefForGuard(local) => local.hash_stable(hcx, hasher),
}
}
}
Expand Down Expand Up @@ -1131,12 +1133,8 @@ impl<'tcx> LocalDecl<'tcx> {
matches!(
self.local_info(),
LocalInfo::User(
BindingForm::Var(VarBindingForm {
binding_mode: BindingMode(ByRef::No, _),
opt_ty_info: _,
opt_match_place: _,
pat_span: _,
}) | BindingForm::ImplicitSelf(ImplicitSelfKind::Imm),
BindingForm::Var(VarBindingForm { binding_mode: BindingMode(ByRef::No, _), .. })
| BindingForm::ImplicitSelf(ImplicitSelfKind::Imm),
)
)
}
Expand All @@ -1148,12 +1146,8 @@ impl<'tcx> LocalDecl<'tcx> {
matches!(
self.local_info(),
LocalInfo::User(
BindingForm::Var(VarBindingForm {
binding_mode: BindingMode(ByRef::No, _),
opt_ty_info: _,
opt_match_place: _,
pat_span: _,
}) | BindingForm::ImplicitSelf(_),
BindingForm::Var(VarBindingForm { binding_mode: BindingMode(ByRef::No, _), .. })
| BindingForm::ImplicitSelf(_),
)
)
}
Expand All @@ -1169,7 +1163,7 @@ impl<'tcx> LocalDecl<'tcx> {
/// expression that is used to access said variable for the guard of the
/// match arm.
pub fn is_ref_for_guard(&self) -> bool {
matches!(self.local_info(), LocalInfo::User(BindingForm::RefForGuard))
matches!(self.local_info(), LocalInfo::User(BindingForm::RefForGuard(_)))
}

/// Returns `Some` if this is a reference to a static item that is used to
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ impl<'tcx> PlaceTy<'tcx> {
impl<V, T> ProjectionElem<V, T> {
/// Returns `true` if the target of this projection may refer to a different region of memory
/// than the base.
fn is_indirect(&self) -> bool {
pub fn is_indirect(&self) -> bool {
match self {
Self::Deref => true,

Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,8 +1119,10 @@ rustc_queries! {
desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
}

query check_liveness(key: LocalDefId) {
desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key) }
query check_liveness(key: LocalDefId) -> &'tcx rustc_index::bit_set::DenseBitSet<abi::FieldIdx> {
arena_cache
desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) }
cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }
}

/// Return the live symbols in the crate for dead code check.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,7 @@ pub enum PatKind<'tcx> {
/// (The same binding can occur multiple times in different branches of
/// an or-pattern, but only one of them will be primary.)
is_primary: bool,
is_shorthand: bool,
},

/// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/ty/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,11 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc
)
}
},
HirProjectionKind::UnwrapUnsafeBinder => {
curr_string = format!("unwrap_binder!({curr_string})");
}
// Just change the type to the hidden type, so we can actually project.
HirProjectionKind::OpaqueCast => {}
proj => bug!("{:?} unexpected because it isn't captured", proj),
}
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,11 @@ mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
mir_build_union_pattern = cannot use unions in constant patterns
.label = can't use a `union` here

mir_build_unreachable_due_to_uninhabited = unreachable {$descr}
.label = unreachable {$descr}
.label_orig = any code following this expression is unreachable
.note = this expression has type `{$ty}`, which is uninhabited

mir_build_unreachable_making_this_unreachable = collectively making this unreachable

mir_build_unreachable_making_this_unreachable_n_more = ...and {$covered_by_many_n_more_count} other patterns collectively make this unreachable
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir_build/src/builder/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
node,
span,
false,
OutsideGuard,
ScheduleDrops::Yes,
);
Expand Down Expand Up @@ -296,6 +297,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
node,
span,
false,
OutsideGuard,
ScheduleDrops::Yes,
);
Expand Down
13 changes: 1 addition & 12 deletions compiler/rustc_mir_build/src/builder/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,18 +269,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
args,
unwind: UnwindAction::Continue,
destination,
// The presence or absence of a return edge affects control-flow sensitive
// MIR checks and ultimately whether code is accepted or not. We can only
// omit the return edge if a return type is visibly uninhabited to a module
// that makes the call.
target: expr
.ty
.is_inhabited_from(
this.tcx,
this.parent_module,
this.infcx.typing_env(this.param_env),
)
.then_some(success),
target: Some(success),
call_source: if from_hir_call {
CallSource::Normal
} else {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_mir_build/src/builder/matches/match_pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl<'tcx> MatchPairTree<'tcx> {
None
}

PatKind::Binding { mode, var, ref subpattern, .. } => {
PatKind::Binding { mode, var, is_shorthand, ref subpattern, .. } => {
// In order to please the borrow checker, when lowering a pattern
// like `x @ subpat` we must establish any bindings in `subpat`
// before establishing the binding for `x`.
Expand Down Expand Up @@ -199,6 +199,7 @@ impl<'tcx> MatchPairTree<'tcx> {
source,
var_id: var,
binding_mode: mode,
is_shorthand,
});
}

Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_mir_build/src/builder/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
var,
irrefutable_pat.span,
false,
OutsideGuard,
ScheduleDrops::Yes,
);
Expand Down Expand Up @@ -629,6 +630,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
var,
irrefutable_pat.span,
false,
OutsideGuard,
ScheduleDrops::Yes,
);
Expand Down Expand Up @@ -761,6 +763,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pattern,
&ProjectedUserTypesNode::None,
&mut |this, name, mode, var, span, ty, user_tys| {
let saved_scope = this.source_scope;
this.set_correct_source_scope_for_arg(var.0, saved_scope, span);
let vis_scope = *visibility_scope
.get_or_insert_with(|| this.new_source_scope(scope_span, LintLevel::Inherited));
let source_info = SourceInfo { span, scope: this.source_scope };
Expand All @@ -778,6 +782,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
opt_match_place.map(|(x, y)| (x.cloned(), y)),
pattern.span,
);
this.source_scope = saved_scope;
},
);
if let Some(guard_expr) = guard {
Expand Down Expand Up @@ -821,6 +826,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block: BasicBlock,
var: LocalVarId,
span: Span,
is_shorthand: bool,
for_guard: ForGuard,
schedule_drop: ScheduleDrops,
) -> Place<'tcx> {
Expand All @@ -834,6 +840,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
{
self.schedule_drop(span, region_scope, local_id, DropKind::Storage);
}
let local_info = self.local_decls[local_id].local_info.as_mut().unwrap_crate_local();
if let LocalInfo::User(BindingForm::Var(var_info)) = &mut **local_info {
var_info.introductions.push((span, is_shorthand));
}
Place::from(local_id)
}

Expand Down Expand Up @@ -1230,6 +1240,7 @@ struct Binding<'tcx> {
source: Place<'tcx>,
var_id: LocalVarId,
binding_mode: BindingMode,
is_shorthand: bool,
}

/// Indicates that the type of `source` must be a subtype of the
Expand Down Expand Up @@ -2693,6 +2704,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
binding.var_id,
binding.span,
binding.is_shorthand,
RefWithinGuard,
schedule_drops,
);
Expand All @@ -2709,6 +2721,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
binding.var_id,
binding.span,
binding.is_shorthand,
OutsideGuard,
schedule_drops,
);
Expand Down Expand Up @@ -2748,6 +2761,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
binding.var_id,
binding.span,
binding.is_shorthand,
OutsideGuard,
schedule_drops,
),
Expand Down Expand Up @@ -2801,6 +2815,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
opt_ty_info: None,
opt_match_place,
pat_span,
introductions: Vec::new(),
},
)))),
};
Expand All @@ -2823,7 +2838,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
user_ty: None,
source_info,
local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(
BindingForm::RefForGuard,
BindingForm::RefForGuard(for_arm_body),
))),
});
if self.should_emit_debug_info_for_binding(name, var_id) {
Expand Down
Loading
Loading