diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 2486f21ce42..131a910bebb 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -139,7 +139,6 @@ pub enum Res { // Value namespace SelfCtor(DefId /* impl */), // `DefId` refers to the impl Local(Id), - Upvar(Id), // Macro namespace NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]` @@ -345,7 +344,6 @@ impl Res { Res::Def(_, id) => Some(id), Res::Local(..) | - Res::Upvar(..) | Res::PrimTy(..) | Res::SelfTy(..) | Res::SelfCtor(..) | @@ -372,7 +370,6 @@ impl Res { Res::SelfCtor(..) => "self constructor", Res::PrimTy(..) => "builtin type", Res::Local(..) => "local variable", - Res::Upvar(..) => "closure capture", Res::SelfTy(..) => "self type", Res::ToolMod => "tool module", Res::NonMacroAttr(attr_kind) => attr_kind.descr(), @@ -395,7 +392,6 @@ impl Res { Res::SelfCtor(id) => Res::SelfCtor(id), Res::PrimTy(id) => Res::PrimTy(id), Res::Local(id) => Res::Local(map(id)), - Res::Upvar(id) => Res::Upvar(map(id)), Res::SelfTy(a, b) => Res::SelfTy(a, b), Res::ToolMod => Res::ToolMod, Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 38ef4d3dbd6..fa62ab15a97 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1409,7 +1409,6 @@ impl Expr { ExprKind::Path(QPath::Resolved(_, ref path)) => { match path.res { Res::Local(..) - | Res::Upvar(..) | Res::Def(DefKind::Static, _) | Res::Err => true, _ => false, diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 14553a972b7..04f5b35a006 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -78,7 +78,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } _ if self.in_pat => {}, Res::PrimTy(..) | Res::SelfTy(..) | Res::SelfCtor(..) | - Res::Local(..) | Res::Upvar(..) => {} + Res::Local(..) => {} Res::Def(DefKind::Ctor(CtorOf::Variant, ..), ctor_def_id) => { let variant_id = self.tcx.parent(ctor_def_id).unwrap(); let enum_id = self.tcx.parent(variant_id).unwrap(); diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 477f5ceff61..34cea2d75ea 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -968,14 +968,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { var_id: hir::HirId) -> mc::McResult> { // Create the cmt for the variable being borrowed, from the - // caller's perspective - let res = if self.mc.upvars.map_or(false, |upvars| upvars.contains_key(&var_id)) { - Res::Upvar(var_id) - } else { - Res::Local(var_id) - }; + // perspective of the creator (parent) of the closure. let var_ty = self.mc.node_ty(var_id)?; - self.mc.cat_res(closure_hir_id, closure_span, var_ty, res) + self.mc.cat_res(closure_hir_id, closure_span, var_ty, Res::Local(var_id)) } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index be2f533ced0..45b4fb56056 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -474,8 +474,11 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) { // live nodes required for uses or definitions of variables: hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => { debug!("expr {}: path that leads to {:?}", expr.hir_id, path.res); - if let Res::Local(..) = path.res { - ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span)); + if let Res::Local(var_hir_id) = path.res { + let upvars = ir.tcx.upvars(ir.body_owner); + if !upvars.map_or(false, |upvars| upvars.contains_key(&var_hir_id)) { + ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span)); + } } intravisit::walk_expr(ir, expr); } @@ -1338,8 +1341,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { -> LiveNode { match path.res { Res::Local(hid) => { - let nid = self.ir.tcx.hir().hir_to_node_id(hid); - self.access_var(hir_id, nid, succ, acc, path.span) + let upvars = self.ir.tcx.upvars(self.ir.body_owner); + if !upvars.map_or(false, |upvars| upvars.contains_key(&hid)) { + let nid = self.ir.tcx.hir().hir_to_node_id(hid); + self.access_var(hir_id, nid, succ, acc, path.span) + } else { + succ + } } _ => succ } @@ -1531,13 +1539,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match expr.node { hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => { if let Res::Local(var_hid) = path.res { - // Assignment to an immutable variable or argument: only legal - // if there is no later assignment. If this local is actually - // mutable, then check for a reassignment to flag the mutability - // as being used. - let ln = self.live_node(expr.hir_id, expr.span); - let var = self.variable(var_hid, expr.span); - self.warn_about_dead_assign(expr.span, expr.hir_id, ln, var); + let upvars = self.ir.tcx.upvars(self.ir.body_owner); + if !upvars.map_or(false, |upvars| upvars.contains_key(&var_hid)) { + // Assignment to an immutable variable or argument: only legal + // if there is no later assignment. If this local is actually + // mutable, then check for a reassignment to flag the mutability + // as being used. + let ln = self.live_node(expr.hir_id, expr.span); + let var = self.variable(var_hid, expr.span); + self.warn_about_dead_assign(expr.span, expr.hir_id, ln, var); + } } } _ => { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 17ec2de2f3a..7011948148d 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -746,23 +746,20 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { }) } - Res::Upvar(var_id) => { - assert!(self.upvars.map_or(false, |upvars| upvars.contains_key(&var_id))); - let var_nid = self.tcx.hir().hir_to_node_id(var_id); - self.cat_upvar(hir_id, span, var_nid) - } - Res::Local(var_id) => { - assert!(!self.upvars.map_or(false, |upvars| upvars.contains_key(&var_id))); let var_nid = self.tcx.hir().hir_to_node_id(var_id); - Ok(cmt_ { - hir_id, - span, - cat: Categorization::Local(var_id), - mutbl: MutabilityCategory::from_local(self.tcx, self.tables, var_nid), - ty: expr_ty, - note: NoteNone - }) + if self.upvars.map_or(false, |upvars| upvars.contains_key(&var_id)) { + self.cat_upvar(hir_id, span, var_nid) + } else { + Ok(cmt_ { + hir_id, + span, + cat: Categorization::Local(var_id), + mutbl: MutabilityCategory::from_local(self.tcx, self.tables, var_nid), + ty: expr_ty, + note: NoteNone + }) + } } def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def) diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index c9835dbd5e7..45e1d983511 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -104,7 +104,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { }; match res { - Some(Res::Local(hir_id)) | Some(Res::Upvar(hir_id, ..)) => { + Some(Res::Local(hir_id)) => { self.reachable_symbols.insert(hir_id); } Some(res) => { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 181313f9436..5a6b6a74830 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -960,18 +960,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Res::Def(DefKind::Static, id) => ExprKind::StaticRef { id }, - Res::Local(var_hir_id) => { - assert!(!cx.tables().upvar_list.get(&cx.body_owner) - .map_or(false, |upvars| upvars.contains_key(&var_hir_id))); - - convert_var(cx, expr, var_hir_id) - } - Res::Upvar(var_hir_id) => { - assert!(cx.tables().upvar_list.get(&cx.body_owner) - .map_or(false, |upvars| upvars.contains_key(&var_hir_id))); - - convert_var(cx, expr, var_hir_id) - } + Res::Local(var_hir_id) => convert_var(cx, expr, var_hir_id), _ => span_bug!(expr.span, "res `{:?}` not yet implemented", res), } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c8ec7367edc..ff54643989b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -612,7 +612,6 @@ impl<'a> PathSource<'a> { | Res::Def(DefKind::Const, _) | Res::Def(DefKind::Static, _) | Res::Local(..) - | Res::Upvar(..) | Res::Def(DefKind::Fn, _) | Res::Def(DefKind::Method, _) | Res::Def(DefKind::AssocConst, _) @@ -2204,7 +2203,7 @@ impl<'a> Resolver<'a> { if let Some(res) = self.ribs[ns][i].bindings.get(&ident).cloned() { // The ident resolves to a type parameter or local variable. return Some(LexicalScopeBinding::Res( - self.adjust_local_res(ns, i, res, record_used, path_span) + self.validate_res_from_ribs(ns, i, res, record_used, path_span), )); } @@ -4006,14 +4005,16 @@ impl<'a> Resolver<'a> { diag); } - // Resolve a local definition, potentially adjusting for closures. - fn adjust_local_res(&mut self, - ns: Namespace, - rib_index: usize, - mut res: Res, - record_used: bool, - span: Span) -> Res { - debug!("adjust_local_res"); + // Validate a local resolution (from ribs), potentially recording closure upvars. + fn validate_res_from_ribs( + &mut self, + ns: Namespace, + rib_index: usize, + res: Res, + record_used: bool, + span: Span, + ) -> Res { + debug!("validate_res_from_ribs({:?})", res); let ribs = &self.ribs[ns][rib_index + 1..]; // An invalid forward use of a type parameter from a previous default. @@ -4035,9 +4036,6 @@ impl<'a> Resolver<'a> { } match res { - Res::Upvar(..) => { - span_bug!(span, "unexpected {:?} in bindings", res) - } Res::Local(var_id) => { use ResolutionError::*; let mut res_err = None; @@ -4049,14 +4047,9 @@ impl<'a> Resolver<'a> { // Nothing to do. Continue. } ClosureRibKind(function_id) => { - res = Res::Upvar(var_id); - match self.upvars.entry(function_id).or_default().entry(var_id) { - indexmap::map::Entry::Occupied(_) => continue, - indexmap::map::Entry::Vacant(entry) => { - if record_used { - entry.insert(Upvar { span }); - } - } + if record_used { + self.upvars.entry(function_id).or_default() + .entry(var_id).or_insert(Upvar { span }); } } ItemRibKind | FnItemRibKind | AssocItemRibKind => { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 8faa4c71807..cca5682d90a 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -702,7 +702,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let span = self.span_from_span(span); match res { - Res::Upvar(id, ..) | Res::Local(id) => { + Res::Local(id) => { Some(Ref { kind: RefKind::Variable, span, diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 61c281d3dd9..a6cd157dc03 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -350,7 +350,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let def_span = match def { Res::Err => None, - Res::Local(id) | Res::Upvar(id, ..) => { + Res::Local(id) => { Some(self.tcx.hir().span_by_hir_id(id)) }, _ => def diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7a6d02cc33b..82d198f0b78 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5264,7 +5264,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Err(ErrorReported) => return (tcx.types.err, res), }; let path_segs = match res { - Res::Local(_) | Res::Upvar(..) => Vec::new(), + Res::Local(_) => vec![], Res::Def(kind, def_id) => AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id), _ => bug!("instantiate_value_path on {:?}", res), @@ -5325,14 +5325,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } })); - match res { - Res::Local(hid) | Res::Upvar(hid, ..) => { - let ty = self.local_ty(span, hid).decl_ty; - let ty = self.normalize_associated_types_in(span, &ty); - self.write_ty(hir_id, ty); - return (ty, res); - } - _ => {} + if let Res::Local(hid) = res { + let ty = self.local_ty(span, hid).decl_ty; + let ty = self.normalize_associated_types_in(span, &ty); + self.write_ty(hir_id, ty); + return (ty, res); } if generics_has_err {