提交 faa0a104 编写于 作者: B bors

Auto merge of #88271 - sexxi-goose:liveness, r=nikomatsakis

2229: Consider varaiables mentioned in closure as used

Fixes: https://github.com/rust-lang/project-rfc-2229/issues/57

r? `@nikomatsakis`
...@@ -337,8 +337,8 @@ fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { ...@@ -337,8 +337,8 @@ fn visit_body(&mut self, body: &'tcx hir::Body<'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 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { ...@@ -405,21 +405,14 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
// breaks or continues) // breaks or continues)
self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span, expr.hir_id)); self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span, expr.hir_id));
// 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> { ...@@ -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> { ...@@ -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 @@ fn new(ir: &'a mut IrMaps<'tcx>, body_owner: LocalDefId) -> Liveness<'a, 'tcx> { ...@@ -530,7 +521,6 @@ fn new(ir: &'a mut IrMaps<'tcx>, body_owner: LocalDefId) -> 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),
...@@ -1215,21 +1205,7 @@ fn access_path( ...@@ -1215,21 +1205,7 @@ fn access_path(
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 { ...@@ -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,
}; };
......
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` ...@@ -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() { ...@@ -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() { ...@@ -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` ...@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册