Differentiate between closure and function bodies
This commit is contained in:
parent
b5f5a2715e
commit
64afc6b517
12 changed files with 38 additions and 17 deletions
|
@ -455,11 +455,20 @@ impl<'hir> Map<'hir> {
|
||||||
Node::AnonConst(_) => {
|
Node::AnonConst(_) => {
|
||||||
BodyOwnerKind::Const
|
BodyOwnerKind::Const
|
||||||
}
|
}
|
||||||
|
Node::Variant(&Spanned { node: VariantKind { data: VariantData::Tuple(..), .. }, .. }) |
|
||||||
|
Node::StructCtor(..) |
|
||||||
|
Node::Item(&Item { node: ItemKind::Fn(..), .. }) |
|
||||||
|
Node::TraitItem(&TraitItem { node: TraitItemKind::Method(..), .. }) |
|
||||||
|
Node::ImplItem(&ImplItem { node: ImplItemKind::Method(..), .. }) => {
|
||||||
|
BodyOwnerKind::Fn
|
||||||
|
}
|
||||||
Node::Item(&Item { node: ItemKind::Static(_, m, _), .. }) => {
|
Node::Item(&Item { node: ItemKind::Static(_, m, _), .. }) => {
|
||||||
BodyOwnerKind::Static(m)
|
BodyOwnerKind::Static(m)
|
||||||
}
|
}
|
||||||
// Default to function if it's not a constant or static.
|
Node::Expr(&Expr { node: ExprKind::Closure(..), .. }) => {
|
||||||
_ => BodyOwnerKind::Fn
|
BodyOwnerKind::Closure
|
||||||
|
}
|
||||||
|
node => bug!("{:#?} is not a body node", node),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1270,6 +1270,9 @@ pub enum BodyOwnerKind {
|
||||||
/// Functions and methods.
|
/// Functions and methods.
|
||||||
Fn,
|
Fn,
|
||||||
|
|
||||||
|
/// Closures
|
||||||
|
Closure,
|
||||||
|
|
||||||
/// Constants and associated constants.
|
/// Constants and associated constants.
|
||||||
Const,
|
Const,
|
||||||
|
|
||||||
|
@ -1277,6 +1280,15 @@ pub enum BodyOwnerKind {
|
||||||
Static(Mutability),
|
Static(Mutability),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BodyOwnerKind {
|
||||||
|
pub fn is_fn_or_closure(self) -> bool {
|
||||||
|
match self {
|
||||||
|
BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
|
||||||
|
BodyOwnerKind::Const | BodyOwnerKind::Static(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A constant (expression) that's not an item or associated item,
|
/// A constant (expression) that's not an item or associated item,
|
||||||
/// but needs its own `DefId` for type-checking, const-eval, etc.
|
/// but needs its own `DefId` for type-checking, const-eval, etc.
|
||||||
/// These are usually found nested inside types (e.g., array lengths)
|
/// These are usually found nested inside types (e.g., array lengths)
|
||||||
|
|
|
@ -1268,8 +1268,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
// The body of the every fn is a root scope.
|
// The body of the every fn is a root scope.
|
||||||
self.cx.parent = self.cx.var_parent;
|
self.cx.parent = self.cx.var_parent;
|
||||||
if let hir::BodyOwnerKind::Fn = self.tcx.hir().body_owner_kind(owner_id) {
|
if self.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() {
|
||||||
self.visit_expr(&body.value);
|
self.visit_expr(&body.value)
|
||||||
} else {
|
} else {
|
||||||
// Only functions have an outer terminating (drop) scope, while
|
// Only functions have an outer terminating (drop) scope, while
|
||||||
// temporaries in constant initializers may be 'static, but only
|
// temporaries in constant initializers may be 'static, but only
|
||||||
|
|
|
@ -163,10 +163,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
||||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
|
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
|
||||||
));
|
));
|
||||||
|
|
||||||
let locals_are_invalidated_at_exit = match tcx.hir().body_owner_kind(id) {
|
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure();
|
||||||
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => false,
|
|
||||||
hir::BodyOwnerKind::Fn => true,
|
|
||||||
};
|
|
||||||
let borrow_set = Rc::new(BorrowSet::build(
|
let borrow_set = Rc::new(BorrowSet::build(
|
||||||
tcx, mir, locals_are_invalidated_at_exit, &mdpe.move_data));
|
tcx, mir, locals_are_invalidated_at_exit, &mdpe.move_data));
|
||||||
|
|
||||||
|
|
|
@ -476,6 +476,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
|
||||||
let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id);
|
let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id);
|
||||||
|
|
||||||
match tcx.hir().body_owner_kind(self.mir_node_id) {
|
match tcx.hir().body_owner_kind(self.mir_node_id) {
|
||||||
|
BodyOwnerKind::Closure |
|
||||||
BodyOwnerKind::Fn => {
|
BodyOwnerKind::Fn => {
|
||||||
let defining_ty = if self.mir_def_id == closure_base_def_id {
|
let defining_ty = if self.mir_def_id == closure_base_def_id {
|
||||||
tcx.type_of(closure_base_def_id)
|
tcx.type_of(closure_base_def_id)
|
||||||
|
|
|
@ -75,7 +75,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
|
||||||
let cx = Cx::new(&infcx, id);
|
let cx = Cx::new(&infcx, id);
|
||||||
let mut mir = if cx.tables().tainted_by_errors {
|
let mut mir = if cx.tables().tainted_by_errors {
|
||||||
build::construct_error(cx, body_id)
|
build::construct_error(cx, body_id)
|
||||||
} else if let hir::BodyOwnerKind::Fn = cx.body_owner_kind {
|
} else if cx.body_owner_kind.is_fn_or_closure() {
|
||||||
// fetch the fully liberated fn signature (that is, all bound
|
// fetch the fully liberated fn signature (that is, all bound
|
||||||
// types/lifetimes replaced)
|
// types/lifetimes replaced)
|
||||||
let fn_hir_id = tcx.hir().node_to_hir_id(id);
|
let fn_hir_id = tcx.hir().node_to_hir_id(id);
|
||||||
|
|
|
@ -613,6 +613,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
hir::BodyOwnerKind::Static(_) =>
|
hir::BodyOwnerKind::Static(_) =>
|
||||||
// No need to free storage in this context.
|
// No need to free storage in this context.
|
||||||
None,
|
None,
|
||||||
|
hir::BodyOwnerKind::Closure |
|
||||||
hir::BodyOwnerKind::Fn =>
|
hir::BodyOwnerKind::Fn =>
|
||||||
Some(self.topmost_scope()),
|
Some(self.topmost_scope()),
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
let constness = match body_owner_kind {
|
let constness = match body_owner_kind {
|
||||||
hir::BodyOwnerKind::Const |
|
hir::BodyOwnerKind::Const |
|
||||||
hir::BodyOwnerKind::Static(_) => hir::Constness::Const,
|
hir::BodyOwnerKind::Static(_) => hir::Constness::Const,
|
||||||
|
hir::BodyOwnerKind::Closure |
|
||||||
hir::BodyOwnerKind::Fn => hir::Constness::NotConst,
|
hir::BodyOwnerKind::Fn => hir::Constness::NotConst,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//! Inlining pass for MIR functions
|
//! Inlining pass for MIR functions
|
||||||
|
|
||||||
use rustc::hir;
|
|
||||||
use rustc::hir::CodegenFnAttrFlags;
|
use rustc::hir::CodegenFnAttrFlags;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
|
|
||||||
|
@ -74,10 +73,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||||
|
|
||||||
// Only do inlining into fn bodies.
|
// Only do inlining into fn bodies.
|
||||||
let id = self.tcx.hir().as_local_node_id(self.source.def_id).unwrap();
|
let id = self.tcx.hir().as_local_node_id(self.source.def_id).unwrap();
|
||||||
let body_owner_kind = self.tcx.hir().body_owner_kind(id);
|
if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() {
|
||||||
|
|
||||||
if let (hir::BodyOwnerKind::Fn, None) = (body_owner_kind, self.source.promoted) {
|
|
||||||
|
|
||||||
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
|
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
|
||||||
if let Some(callsite) = self.get_valid_function_call(bb,
|
if let Some(callsite) = self.get_valid_function_call(bb,
|
||||||
bb_data,
|
bb_data,
|
||||||
|
|
|
@ -1152,6 +1152,7 @@ impl MirPass for QualifyAndPromoteConstants {
|
||||||
let id = tcx.hir().as_local_node_id(def_id).unwrap();
|
let id = tcx.hir().as_local_node_id(def_id).unwrap();
|
||||||
let mut const_promoted_temps = None;
|
let mut const_promoted_temps = None;
|
||||||
let mode = match tcx.hir().body_owner_kind(id) {
|
let mode = match tcx.hir().body_owner_kind(id) {
|
||||||
|
hir::BodyOwnerKind::Closure => Mode::Fn,
|
||||||
hir::BodyOwnerKind::Fn => {
|
hir::BodyOwnerKind::Fn => {
|
||||||
if tcx.is_const_fn(def_id) {
|
if tcx.is_const_fn(def_id) {
|
||||||
Mode::ConstFn
|
Mode::ConstFn
|
||||||
|
|
|
@ -573,6 +573,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> i
|
||||||
let body_owner_kind = tcx.hir().body_owner_kind(id);
|
let body_owner_kind = tcx.hir().body_owner_kind(id);
|
||||||
match (body_owner_kind, src.promoted) {
|
match (body_owner_kind, src.promoted) {
|
||||||
(_, Some(i)) => write!(w, "{:?} in", i)?,
|
(_, Some(i)) => write!(w, "{:?} in", i)?,
|
||||||
|
(hir::BodyOwnerKind::Closure, _) |
|
||||||
(hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?,
|
(hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?,
|
||||||
(hir::BodyOwnerKind::Const, _) => write!(w, "const")?,
|
(hir::BodyOwnerKind::Const, _) => write!(w, "const")?,
|
||||||
(hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?,
|
(hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?,
|
||||||
|
@ -585,6 +586,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> i
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
match (body_owner_kind, src.promoted) {
|
match (body_owner_kind, src.promoted) {
|
||||||
|
(hir::BodyOwnerKind::Closure, None) |
|
||||||
(hir::BodyOwnerKind::Fn, None) => {
|
(hir::BodyOwnerKind::Fn, None) => {
|
||||||
write!(w, "(")?;
|
write!(w, "(")?;
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||||
self.in_static = false;
|
self.in_static = false;
|
||||||
|
|
||||||
match self.tcx.hir().body_owner_kind(item_id) {
|
match self.tcx.hir().body_owner_kind(item_id) {
|
||||||
|
hir::BodyOwnerKind::Closure |
|
||||||
hir::BodyOwnerKind::Fn => self.in_fn = true,
|
hir::BodyOwnerKind::Fn => self.in_fn = true,
|
||||||
hir::BodyOwnerKind::Static(_) => self.in_static = true,
|
hir::BodyOwnerKind::Static(_) => self.in_static = true,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue