2229: Consider varaiables mentioned in closure as used
This commit is contained in:
parent
9583fd1bdd
commit
d7b4ee8a32
5 changed files with 10 additions and 63 deletions
|
@ -337,8 +337,8 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(captures) = maps.tcx.typeck(local_def_id).closure_min_captures.get(&def_id) {
|
if let Some(upvars) = maps.tcx.upvars_mentioned(def_id) {
|
||||||
for &var_hir_id in captures.keys() {
|
for &var_hir_id in upvars.keys() {
|
||||||
let var_name = maps.tcx.hir().name(var_hir_id);
|
let var_name = maps.tcx.hir().name(var_hir_id);
|
||||||
maps.add_variable(Upvar(var_hir_id, var_name));
|
maps.add_variable(Upvar(var_hir_id, var_name));
|
||||||
}
|
}
|
||||||
|
@ -405,21 +405,14 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
|
||||||
// breaks or continues)
|
// breaks or continues)
|
||||||
self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
|
self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
|
||||||
|
|
||||||
// Make a live_node for each captured variable, with the span
|
// Make a live_node for each mentioned variable, with the span
|
||||||
// being the location that the variable is used. This results
|
// being the location that the variable is used. This results
|
||||||
// in better error messages than just pointing at the closure
|
// in better error messages than just pointing at the closure
|
||||||
// construction site.
|
// construction site.
|
||||||
let mut call_caps = Vec::new();
|
let mut call_caps = Vec::new();
|
||||||
let closure_def_id = self.tcx.hir().local_def_id(expr.hir_id);
|
let closure_def_id = self.tcx.hir().local_def_id(expr.hir_id);
|
||||||
if let Some(captures) = self
|
if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
|
||||||
.tcx
|
call_caps.extend(upvars.keys().map(|var_id| {
|
||||||
.typeck(closure_def_id)
|
|
||||||
.closure_min_captures
|
|
||||||
.get(&closure_def_id.to_def_id())
|
|
||||||
{
|
|
||||||
// If closure_min_captures is Some, upvars_mentioned must also be Some
|
|
||||||
let upvars = self.tcx.upvars_mentioned(closure_def_id).unwrap();
|
|
||||||
call_caps.extend(captures.keys().map(|var_id| {
|
|
||||||
let upvar = upvars[var_id];
|
let upvar = upvars[var_id];
|
||||||
let upvar_ln = self.add_live_node(UpvarNode(upvar.span));
|
let upvar_ln = self.add_live_node(UpvarNode(upvar.span));
|
||||||
CaptureInfo { ln: upvar_ln, var_hid: *var_id }
|
CaptureInfo { ln: upvar_ln, var_hid: *var_id }
|
||||||
|
@ -494,7 +487,6 @@ struct Liveness<'a, 'tcx> {
|
||||||
ir: &'a mut IrMaps<'tcx>,
|
ir: &'a mut IrMaps<'tcx>,
|
||||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
|
|
||||||
closure_min_captures: Option<&'tcx RootVariableMinCaptureList<'tcx>>,
|
closure_min_captures: Option<&'tcx RootVariableMinCaptureList<'tcx>>,
|
||||||
successors: IndexVec<LiveNode, Option<LiveNode>>,
|
successors: IndexVec<LiveNode, Option<LiveNode>>,
|
||||||
rwu_table: rwu_table::RWUTable,
|
rwu_table: rwu_table::RWUTable,
|
||||||
|
@ -518,7 +510,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
fn new(ir: &'a mut IrMaps<'tcx>, body_owner: LocalDefId) -> Liveness<'a, 'tcx> {
|
fn new(ir: &'a mut IrMaps<'tcx>, body_owner: LocalDefId) -> Liveness<'a, 'tcx> {
|
||||||
let typeck_results = ir.tcx.typeck(body_owner);
|
let typeck_results = ir.tcx.typeck(body_owner);
|
||||||
let param_env = ir.tcx.param_env(body_owner);
|
let param_env = ir.tcx.param_env(body_owner);
|
||||||
let upvars = ir.tcx.upvars_mentioned(body_owner);
|
|
||||||
let closure_min_captures = typeck_results.closure_min_captures.get(&body_owner.to_def_id());
|
let closure_min_captures = typeck_results.closure_min_captures.get(&body_owner.to_def_id());
|
||||||
let closure_ln = ir.add_live_node(ClosureNode);
|
let closure_ln = ir.add_live_node(ClosureNode);
|
||||||
let exit_ln = ir.add_live_node(ExitNode);
|
let exit_ln = ir.add_live_node(ExitNode);
|
||||||
|
@ -530,7 +521,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
ir,
|
ir,
|
||||||
typeck_results,
|
typeck_results,
|
||||||
param_env,
|
param_env,
|
||||||
upvars,
|
|
||||||
closure_min_captures,
|
closure_min_captures,
|
||||||
successors: IndexVec::from_elem_n(None, num_live_nodes),
|
successors: IndexVec::from_elem_n(None, num_live_nodes),
|
||||||
rwu_table: rwu_table::RWUTable::new(num_live_nodes, num_vars),
|
rwu_table: rwu_table::RWUTable::new(num_live_nodes, num_vars),
|
||||||
|
@ -1234,21 +1224,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
acc: u32,
|
acc: u32,
|
||||||
) -> LiveNode {
|
) -> LiveNode {
|
||||||
match path.res {
|
match path.res {
|
||||||
Res::Local(hid) => {
|
Res::Local(hid) => self.access_var(hir_id, hid, succ, acc, path.span),
|
||||||
let in_upvars = self.upvars.map_or(false, |u| u.contains_key(&hid));
|
|
||||||
let in_captures = self.closure_min_captures.map_or(false, |c| c.contains_key(&hid));
|
|
||||||
|
|
||||||
match (in_upvars, in_captures) {
|
|
||||||
(false, _) | (true, true) => self.access_var(hir_id, hid, succ, acc, path.span),
|
|
||||||
(true, false) => {
|
|
||||||
// This case is possible when with RFC-2229, a wild pattern
|
|
||||||
// is used within a closure.
|
|
||||||
// eg: `let _ = x`. The closure doesn't capture x here,
|
|
||||||
// even though it's mentioned in the closure.
|
|
||||||
succ
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => succ,
|
_ => succ,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct Props {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Test 1
|
// Test 1
|
||||||
let props_2 = Props { //~ WARNING: unused variable: `props_2`
|
let props_2 = Props {
|
||||||
field_1: 1,
|
field_1: 1,
|
||||||
field_2: 1,
|
field_2: 1,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
warning: unused variable: `props_2`
|
|
||||||
--> $DIR/issue-87987.rs:11:9
|
|
||||||
|
|
|
||||||
LL | let props_2 = Props {
|
|
||||||
| ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_props_2`
|
|
||||||
|
|
|
||||||
= note: `#[warn(unused_variables)]` on by default
|
|
||||||
|
|
||||||
warning: field is never read: `field_1`
|
warning: field is never read: `field_1`
|
||||||
--> $DIR/issue-87987.rs:5:5
|
--> $DIR/issue-87987.rs:5:5
|
||||||
|
|
|
|
||||||
|
@ -20,5 +12,5 @@ warning: field is never read: `field_2`
|
||||||
LL | field_2: u32,
|
LL | field_2: u32,
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: 3 warnings emitted
|
warning: 2 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ fn test3() {
|
||||||
|
|
||||||
fn test4() {
|
fn test4() {
|
||||||
let t = (String::from("Hello"), String::from("World"));
|
let t = (String::from("Hello"), String::from("World"));
|
||||||
//~^ WARN unused variable: `t`
|
|
||||||
|
|
||||||
let c = || {
|
let c = || {
|
||||||
let (_, _) = t;
|
let (_, _) = t;
|
||||||
|
@ -81,9 +80,7 @@ fn test7() {
|
||||||
|
|
||||||
fn test8() {
|
fn test8() {
|
||||||
let x = 0;
|
let x = 0;
|
||||||
//~^ WARN unused variable: `x`
|
|
||||||
let tup = (1, 2);
|
let tup = (1, 2);
|
||||||
//~^ WARN unused variable: `tup`
|
|
||||||
let p = Point { x: 10, y: 20 };
|
let p = Point { x: 10, y: 20 };
|
||||||
|
|
||||||
let c = || {
|
let c = || {
|
||||||
|
|
|
@ -29,29 +29,11 @@ warning: unused variable: `t2`
|
||||||
LL | let (_, t2) = t;
|
LL | let (_, t2) = t;
|
||||||
| ^^ help: if this is intentional, prefix it with an underscore: `_t2`
|
| ^^ help: if this is intentional, prefix it with an underscore: `_t2`
|
||||||
|
|
||||||
warning: unused variable: `t`
|
|
||||||
--> $DIR/destructure_patterns.rs:45:9
|
|
||||||
|
|
|
||||||
LL | let t = (String::from("Hello"), String::from("World"));
|
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_t`
|
|
||||||
|
|
||||||
warning: unused variable: `x`
|
warning: unused variable: `x`
|
||||||
--> $DIR/destructure_patterns.rs:91:21
|
--> $DIR/destructure_patterns.rs:88:21
|
||||||
|
|
|
|
||||||
LL | let Point { x, y } = p;
|
LL | let Point { x, y } = p;
|
||||||
| ^ help: try ignoring the field: `x: _`
|
| ^ help: try ignoring the field: `x: _`
|
||||||
|
|
||||||
warning: unused variable: `x`
|
warning: 5 warnings emitted
|
||||||
--> $DIR/destructure_patterns.rs:83:9
|
|
||||||
|
|
|
||||||
LL | let x = 0;
|
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
|
||||||
|
|
||||||
warning: unused variable: `tup`
|
|
||||||
--> $DIR/destructure_patterns.rs:85:9
|
|
||||||
|
|
|
||||||
LL | let tup = (1, 2);
|
|
||||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_tup`
|
|
||||||
|
|
||||||
warning: 8 warnings emitted
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue