rustc: remove the closure ID from hir::Upvar's parent field.
This commit is contained in:
parent
4b9670a245
commit
9fe0052e54
|
@ -2497,8 +2497,8 @@ pub struct Upvar<Id = HirId> {
|
||||||
/// The variable being captured.
|
/// The variable being captured.
|
||||||
pub var_id: Id,
|
pub var_id: Id,
|
||||||
|
|
||||||
/// The parent closure, if this is not a direct capture.
|
/// Whether this is not a direct capture (comes from parent closure).
|
||||||
pub parent: Option<ast::NodeId>,
|
pub has_parent: bool,
|
||||||
|
|
||||||
// First span where it is accessed (there can be multiple).
|
// First span where it is accessed (there can be multiple).
|
||||||
pub span: Span
|
pub span: Span
|
||||||
|
@ -2508,7 +2508,7 @@ impl<Id: fmt::Debug + Copy> Upvar<Id> {
|
||||||
pub fn map_id<R>(self, map: impl FnOnce(Id) -> R) -> Upvar<R> {
|
pub fn map_id<R>(self, map: impl FnOnce(Id) -> R) -> Upvar<R> {
|
||||||
Upvar {
|
Upvar {
|
||||||
var_id: map(self.var_id),
|
var_id: map(self.var_id),
|
||||||
parent: self.parent,
|
has_parent: self.has_parent,
|
||||||
span: self.span,
|
span: self.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -961,12 +961,16 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||||
-> mc::McResult<mc::cmt_<'tcx>> {
|
-> mc::McResult<mc::cmt_<'tcx>> {
|
||||||
// Create the cmt for the variable being borrowed, from the
|
// Create the cmt for the variable being borrowed, from the
|
||||||
// caller's perspective
|
// caller's perspective
|
||||||
let var_ty = self.mc.node_ty(upvar.var_id)?;
|
if upvar.has_parent {
|
||||||
let res = upvar.parent.map_or(
|
let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_hir_id);
|
||||||
Res::Local(upvar.var_id),
|
let parent_def_id = self.tcx().parent(closure_def_id).unwrap();
|
||||||
|closure_node_id| Res::Upvar(upvar.var_id, closure_node_id),
|
assert!(self.tcx().is_closure(parent_def_id));
|
||||||
);
|
let var_nid = self.tcx().hir().hir_to_node_id(upvar.var_id);
|
||||||
self.mc.cat_res(closure_hir_id, closure_span, var_ty, res)
|
self.mc.cat_upvar(closure_hir_id, closure_span, var_nid, parent_def_id)
|
||||||
|
} else {
|
||||||
|
let var_ty = self.mc.node_ty(upvar.var_id)?;
|
||||||
|
self.mc.cat_res(closure_hir_id, closure_span, var_ty, Res::Local(upvar.var_id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -486,7 +486,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
|
||||||
let closure_def_id = ir.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
|
let closure_def_id = ir.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
|
||||||
if let Some(upvars) = ir.tcx.upvars(closure_def_id) {
|
if let Some(upvars) = ir.tcx.upvars(closure_def_id) {
|
||||||
call_caps.extend(upvars.iter().filter_map(|upvar| {
|
call_caps.extend(upvars.iter().filter_map(|upvar| {
|
||||||
if upvar.parent.is_none() {
|
if !upvar.has_parent {
|
||||||
let upvar_ln = ir.add_live_node(UpvarNode(upvar.span));
|
let upvar_ln = ir.add_live_node(UpvarNode(upvar.span));
|
||||||
Some(CaptureInfo { ln: upvar_ln, var_hid: upvar.var_id })
|
Some(CaptureInfo { ln: upvar_ln, var_hid: upvar.var_id })
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -737,9 +737,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Res::Upvar(var_id, fn_node_id) => {
|
Res::Upvar(var_id, closure_node_id) => {
|
||||||
let var_nid = self.tcx.hir().hir_to_node_id(var_id);
|
let var_nid = self.tcx.hir().hir_to_node_id(var_id);
|
||||||
self.cat_upvar(hir_id, span, var_nid, fn_node_id)
|
let closure_expr_def_id = self.tcx.hir().local_def_id(closure_node_id);
|
||||||
|
self.cat_upvar(hir_id, span, var_nid, closure_expr_def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
Res::Local(vid) => {
|
Res::Local(vid) => {
|
||||||
|
@ -760,15 +761,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
// Categorize an upvar, complete with invisible derefs of closure
|
// Categorize an upvar, complete with invisible derefs of closure
|
||||||
// environment and upvar reference as appropriate.
|
// environment and upvar reference as appropriate.
|
||||||
fn cat_upvar(&self,
|
pub fn cat_upvar(
|
||||||
hir_id: hir::HirId,
|
&self,
|
||||||
span: Span,
|
hir_id: hir::HirId,
|
||||||
var_id: ast::NodeId,
|
span: Span,
|
||||||
fn_node_id: ast::NodeId)
|
var_id: ast::NodeId,
|
||||||
-> McResult<cmt_<'tcx>>
|
closure_expr_def_id: DefId,
|
||||||
{
|
) -> McResult<cmt_<'tcx>> {
|
||||||
let fn_hir_id = self.tcx.hir().node_to_hir_id(fn_node_id);
|
|
||||||
|
|
||||||
// An upvar can have up to 3 components. We translate first to a
|
// An upvar can have up to 3 components. We translate first to a
|
||||||
// `Categorization::Upvar`, which is itself a fiction -- it represents the reference to the
|
// `Categorization::Upvar`, which is itself a fiction -- it represents the reference to the
|
||||||
// field from the environment.
|
// field from the environment.
|
||||||
|
@ -792,6 +791,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
// FnMut | copied -> &'env mut | upvar -> &'env mut -> &'up bk
|
// FnMut | copied -> &'env mut | upvar -> &'env mut -> &'up bk
|
||||||
// FnOnce | copied | upvar -> &'up bk
|
// FnOnce | copied | upvar -> &'up bk
|
||||||
|
|
||||||
|
let fn_hir_id = self.tcx.hir().local_def_id_to_hir_id(
|
||||||
|
LocalDefId::from_def_id(closure_expr_def_id),
|
||||||
|
);
|
||||||
let ty = self.node_ty(fn_hir_id)?;
|
let ty = self.node_ty(fn_hir_id)?;
|
||||||
let kind = match ty.sty {
|
let kind = match ty.sty {
|
||||||
ty::Generator(..) => ty::ClosureKind::FnOnce,
|
ty::Generator(..) => ty::ClosureKind::FnOnce,
|
||||||
|
@ -813,7 +815,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
_ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty),
|
_ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
let closure_expr_def_id = self.tcx.hir().local_def_id(fn_node_id);
|
|
||||||
let var_hir_id = self.tcx.hir().node_to_hir_id(var_id);
|
let var_hir_id = self.tcx.hir().node_to_hir_id(var_id);
|
||||||
let upvar_id = ty::UpvarId {
|
let upvar_id = ty::UpvarId {
|
||||||
var_path: ty::UpvarPath { hir_id: var_hir_id },
|
var_path: ty::UpvarPath { hir_id: var_hir_id },
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::hair::util::UserAnnotatedTyHelpers;
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
|
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
|
||||||
use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue};
|
use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue};
|
||||||
use rustc::ty::{self, AdtKind, Ty};
|
use rustc::ty::{self, AdtKind, DefIdTree, Ty};
|
||||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast};
|
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast};
|
||||||
use rustc::ty::subst::{InternalSubsts, SubstsRef};
|
use rustc::ty::subst::{InternalSubsts, SubstsRef};
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
@ -960,38 +960,50 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
Res::Def(DefKind::Static, id) => ExprKind::StaticRef { id },
|
Res::Def(DefKind::Static, id) => ExprKind::StaticRef { id },
|
||||||
|
|
||||||
Res::Local(..) | Res::Upvar(..) => convert_var(cx, expr, res),
|
Res::Local(var_hir_id) => convert_var(cx, expr, var_hir_id),
|
||||||
|
Res::Upvar(var_hir_id, closure_node_id) => {
|
||||||
|
let closure_def_id = cx.tcx.hir().local_def_id(closure_node_id);
|
||||||
|
assert_eq!(cx.body_owner, closure_def_id);
|
||||||
|
assert!(cx.upvar_indices.contains_key(&var_hir_id));
|
||||||
|
|
||||||
|
convert_var(cx, expr, var_hir_id)
|
||||||
|
}
|
||||||
|
|
||||||
_ => span_bug!(expr.span, "res `{:?}` not yet implemented", res),
|
_ => span_bug!(expr.span, "res `{:?}` not yet implemented", res),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
fn convert_var(
|
||||||
expr: &'tcx hir::Expr,
|
cx: &mut Cx<'_, '_, 'tcx>,
|
||||||
res: Res)
|
expr: &'tcx hir::Expr,
|
||||||
-> ExprKind<'tcx> {
|
var_hir_id: hir::HirId,
|
||||||
|
) -> ExprKind<'tcx> {
|
||||||
|
let upvar_index = cx.upvar_indices.get(&var_hir_id).cloned();
|
||||||
|
|
||||||
|
debug!("convert_var({:?}): upvar_index={:?}, body_owner={:?}",
|
||||||
|
var_hir_id, upvar_index, cx.body_owner);
|
||||||
|
|
||||||
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
|
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
|
||||||
|
|
||||||
match res {
|
match upvar_index {
|
||||||
Res::Local(id) => ExprKind::VarRef { id },
|
None => ExprKind::VarRef { id: var_hir_id },
|
||||||
|
|
||||||
Res::Upvar(var_hir_id, closure_expr_id) => {
|
Some(upvar_index) => {
|
||||||
let index = cx.upvar_indices[&var_hir_id];
|
let closure_def_id = cx.body_owner;
|
||||||
|
let upvar_id = ty::UpvarId {
|
||||||
debug!("convert_var(upvar({:?}, {:?}, {:?}))",
|
var_path: ty::UpvarPath {hir_id: var_hir_id},
|
||||||
var_hir_id,
|
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
|
||||||
index,
|
};
|
||||||
closure_expr_id);
|
|
||||||
let var_ty = cx.tables().node_type(var_hir_id);
|
let var_ty = cx.tables().node_type(var_hir_id);
|
||||||
|
|
||||||
// FIXME free regions in closures are not right
|
// FIXME free regions in closures are not right
|
||||||
let closure_ty = cx.tables()
|
let closure_ty = cx.tables().node_type(
|
||||||
.node_type(cx.tcx.hir().node_to_hir_id(closure_expr_id));
|
cx.tcx.hir().local_def_id_to_hir_id(upvar_id.closure_expr_id),
|
||||||
|
);
|
||||||
|
|
||||||
// FIXME we're just hard-coding the idea that the
|
// FIXME we're just hard-coding the idea that the
|
||||||
// signature will be &self or &mut self and hence will
|
// signature will be &self or &mut self and hence will
|
||||||
// have a bound region with number 0
|
// have a bound region with number 0
|
||||||
let closure_def_id = cx.tcx.hir().local_def_id(closure_expr_id);
|
|
||||||
let region = ty::ReFree(ty::FreeRegion {
|
let region = ty::ReFree(ty::FreeRegion {
|
||||||
scope: closure_def_id,
|
scope: closure_def_id,
|
||||||
bound_region: ty::BoundRegion::BrAnon(0),
|
bound_region: ty::BoundRegion::BrAnon(0),
|
||||||
|
@ -1062,15 +1074,11 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
// at this point we have `self.n`, which loads up the upvar
|
// at this point we have `self.n`, which loads up the upvar
|
||||||
let field_kind = ExprKind::Field {
|
let field_kind = ExprKind::Field {
|
||||||
lhs: self_expr.to_ref(),
|
lhs: self_expr.to_ref(),
|
||||||
name: Field::new(index),
|
name: Field::new(upvar_index),
|
||||||
};
|
};
|
||||||
|
|
||||||
// ...but the upvar might be an `&T` or `&mut T` capture, at which
|
// ...but the upvar might be an `&T` or `&mut T` capture, at which
|
||||||
// point we need an implicit deref
|
// point we need an implicit deref
|
||||||
let upvar_id = ty::UpvarId {
|
|
||||||
var_path: ty::UpvarPath {hir_id: var_hir_id},
|
|
||||||
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
|
|
||||||
};
|
|
||||||
match cx.tables().upvar_capture(upvar_id) {
|
match cx.tables().upvar_capture(upvar_id) {
|
||||||
ty::UpvarCapture::ByValue => field_kind,
|
ty::UpvarCapture::ByValue => field_kind,
|
||||||
ty::UpvarCapture::ByRef(borrow) => {
|
ty::UpvarCapture::ByRef(borrow) => {
|
||||||
|
@ -1089,8 +1097,6 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => span_bug!(expr.span, "type of & not region"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1190,15 +1196,16 @@ fn capture_upvar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
let upvar_capture = cx.tables().upvar_capture(upvar_id);
|
let upvar_capture = cx.tables().upvar_capture(upvar_id);
|
||||||
let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
|
let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
|
||||||
let var_ty = cx.tables().node_type(upvar.var_id);
|
let var_ty = cx.tables().node_type(upvar.var_id);
|
||||||
let upvar_res = upvar.parent.map_or(
|
if upvar.has_parent {
|
||||||
Res::Local(upvar.var_id),
|
let closure_def_id = upvar_id.closure_expr_id.to_def_id();
|
||||||
|closure_node_id| Res::Upvar(upvar.var_id, closure_node_id),
|
assert_eq!(cx.body_owner, cx.tcx.parent(closure_def_id).unwrap());
|
||||||
);
|
}
|
||||||
|
assert_eq!(upvar.has_parent, cx.upvar_indices.contains_key(&upvar.var_id));
|
||||||
let captured_var = Expr {
|
let captured_var = Expr {
|
||||||
temp_lifetime,
|
temp_lifetime,
|
||||||
ty: var_ty,
|
ty: var_ty,
|
||||||
span: closure_expr.span,
|
span: closure_expr.span,
|
||||||
kind: convert_var(cx, closure_expr, upvar_res),
|
kind: convert_var(cx, closure_expr, upvar.var_id),
|
||||||
};
|
};
|
||||||
match upvar_capture {
|
match upvar_capture {
|
||||||
ty::UpvarCapture::ByValue => captured_var.to_ref(),
|
ty::UpvarCapture::ByValue => captured_var.to_ref(),
|
||||||
|
|
|
@ -39,6 +39,9 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||||
/// `const`, or the body of a `const fn`.
|
/// `const`, or the body of a `const fn`.
|
||||||
constness: hir::Constness,
|
constness: hir::Constness,
|
||||||
|
|
||||||
|
/// The `DefId` of the owner of this body.
|
||||||
|
body_owner: DefId,
|
||||||
|
|
||||||
/// What kind of body is being compiled.
|
/// What kind of body is being compiled.
|
||||||
pub body_owner_kind: hir::BodyOwnerKind,
|
pub body_owner_kind: hir::BodyOwnerKind,
|
||||||
|
|
||||||
|
@ -97,6 +100,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
region_scope_tree: tcx.region_scope_tree(src_def_id),
|
region_scope_tree: tcx.region_scope_tree(src_def_id),
|
||||||
tables,
|
tables,
|
||||||
constness,
|
constness,
|
||||||
|
body_owner: src_def_id,
|
||||||
body_owner_kind,
|
body_owner_kind,
|
||||||
check_overflow,
|
check_overflow,
|
||||||
control_flow_destroyed: Vec::new(),
|
control_flow_destroyed: Vec::new(),
|
||||||
|
|
|
@ -4051,9 +4051,9 @@ impl<'a> Resolver<'a> {
|
||||||
// Nothing to do. Continue.
|
// Nothing to do. Continue.
|
||||||
}
|
}
|
||||||
ClosureRibKind(function_id) => {
|
ClosureRibKind(function_id) => {
|
||||||
let parent = match res {
|
let has_parent = match res {
|
||||||
Res::Upvar(_, closure) => Some(closure),
|
Res::Upvar(..) => true,
|
||||||
_ => None,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let seen = self.upvars_seen
|
let seen = self.upvars_seen
|
||||||
|
@ -4071,7 +4071,7 @@ impl<'a> Resolver<'a> {
|
||||||
if record_used {
|
if record_used {
|
||||||
vec.push(Upvar {
|
vec.push(Upvar {
|
||||||
var_id,
|
var_id,
|
||||||
parent,
|
has_parent,
|
||||||
span,
|
span,
|
||||||
});
|
});
|
||||||
seen.insert(var_id);
|
seen.insert(var_id);
|
||||||
|
|
Loading…
Reference in New Issue