about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs5
-rw-r--r--compiler/rustc_hir/src/hir.rs27
-rw-r--r--compiler/rustc_hir/src/intravisit.rs8
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs5
-rw-r--r--compiler/rustc_middle/src/hir/map/blocks.rs239
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/lints.rs5
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs5
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs3
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs5
11 files changed, 47 insertions, 260 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index df4cc295fac..80551518d3c 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -1,6 +1,5 @@
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_middle::hir::map::blocks::FnLikeNode;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::Symbol;
@@ -44,8 +43,8 @@ fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         } else {
             false
         }
-    } else if let Some(fn_like) = FnLikeNode::from_node(node) {
-        if fn_like.constness() == hir::Constness::Const {
+    } else if let Some(fn_kind) = node.fn_kind() {
+        if fn_kind.constness() == hir::Constness::Const {
             return true;
         }
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index b5c1e31c258..6f25715fbec 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1,6 +1,7 @@
 use crate::def::{CtorKind, DefKind, Res};
 use crate::def_id::DefId;
 crate use crate::hir_id::{HirId, ItemLocalId};
+use crate::intravisit::FnKind;
 use crate::LangItem;
 
 use rustc_ast::util::parser::ExprPrecedence;
@@ -3258,6 +3259,32 @@ impl<'hir> Node<'hir> {
             _ => None,
         }
     }
+
+    pub fn fn_kind(self) -> Option<FnKind<'hir>> {
+        match self {
+            Node::Item(i) => match i.kind {
+                ItemKind::Fn(ref sig, ref generics, _) => {
+                    Some(FnKind::ItemFn(i.ident, generics, sig.header, &i.vis))
+                }
+                _ => None,
+            },
+            Node::TraitItem(ti) => match ti.kind {
+                TraitItemKind::Fn(ref sig, TraitFn::Provided(_)) => {
+                    Some(FnKind::Method(ti.ident, sig, None))
+                }
+                _ => None,
+            },
+            Node::ImplItem(ii) => match ii.kind {
+                ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig, Some(&ii.vis))),
+                _ => None,
+            },
+            Node::Expr(e) => match e.kind {
+                ExprKind::Closure(..) => Some(FnKind::Closure),
+                _ => None,
+            },
+            _ => None,
+        }
+    }
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 3e58af1f167..cff543760f4 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -117,6 +117,14 @@ impl<'a> FnKind<'a> {
             FnKind::Closure => None,
         }
     }
+
+    pub fn constness(self) -> Constness {
+        self.header().map_or(Constness::NotConst, |header| header.constness)
+    }
+
+    pub fn asyncness(self) -> IsAsync {
+        self.header().map_or(IsAsync::NotAsync, |header| header.asyncness)
+    }
 }
 
 /// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
index 8dcdd4b149e..90bc5b3b2fe 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
@@ -143,9 +143,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         // similar to the asyncness fn in rustc_ty_utils::ty
         let hir_id = self.tcx().hir().local_def_id_to_hir_id(local_def_id);
         let node = self.tcx().hir().get(hir_id);
-        let fn_like = rustc_middle::hir::map::blocks::FnLikeNode::from_node(node)?;
-
-        Some(fn_like.asyncness())
+        let fn_kind = node.fn_kind()?;
+        Some(fn_kind.asyncness())
     }
 
     // Here, we check for the case where the anonymous region
diff --git a/compiler/rustc_middle/src/hir/map/blocks.rs b/compiler/rustc_middle/src/hir/map/blocks.rs
deleted file mode 100644
index 8efec8ef567..00000000000
--- a/compiler/rustc_middle/src/hir/map/blocks.rs
+++ /dev/null
@@ -1,239 +0,0 @@
-//! This module provides a simplified abstraction for working with
-//! code blocks identified by their integer `NodeId`. In particular,
-//! it captures a common set of attributes that all "function-like
-//! things" (represented by `FnLike` instances) share. For example,
-//! all `FnLike` instances have a type signature (be it explicit or
-//! inferred). And all `FnLike` instances have a body, i.e., the code
-//! that is run when the function-like thing it represents is invoked.
-//!
-//! With the above abstraction in place, one can treat the program
-//! text as a collection of blocks of code (and most such blocks are
-//! nested within a uniquely determined `FnLike`), and users can ask
-//! for the `Code` associated with a particular NodeId.
-
-use crate::hir::map::Map;
-use rustc_hir as hir;
-use rustc_hir::intravisit::FnKind;
-use rustc_hir::{Expr, FnDecl, Node};
-use rustc_span::symbol::Ident;
-use rustc_span::Span;
-
-/// An FnLikeNode is a Node that is like a fn, in that it has a decl
-/// and a body (as well as a NodeId, a span, etc).
-///
-/// More specifically, it is one of either:
-///
-///   - A function item,
-///   - A closure expr (i.e., an ExprKind::Closure), or
-///   - The default implementation for a trait method.
-///
-/// To construct one, use the `Code::from_node` function.
-#[derive(Copy, Clone, Debug)]
-pub struct FnLikeNode<'a> {
-    node: Node<'a>,
-}
-
-/// MaybeFnLike wraps a method that indicates if an object
-/// corresponds to some FnLikeNode.
-trait MaybeFnLike {
-    fn is_fn_like(&self) -> bool;
-}
-
-impl MaybeFnLike for hir::Item<'_> {
-    fn is_fn_like(&self) -> bool {
-        matches!(self.kind, hir::ItemKind::Fn(..))
-    }
-}
-
-impl MaybeFnLike for hir::ImplItem<'_> {
-    fn is_fn_like(&self) -> bool {
-        matches!(self.kind, hir::ImplItemKind::Fn(..))
-    }
-}
-
-impl MaybeFnLike for hir::TraitItem<'_> {
-    fn is_fn_like(&self) -> bool {
-        matches!(self.kind, hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)))
-    }
-}
-
-impl MaybeFnLike for hir::Expr<'_> {
-    fn is_fn_like(&self) -> bool {
-        matches!(self.kind, hir::ExprKind::Closure(..))
-    }
-}
-
-/// Carries either an FnLikeNode or an Expr, as these are the two
-/// constructs that correspond to "code" (as in, something from which
-/// we can construct a control-flow graph).
-#[derive(Copy, Clone)]
-pub enum Code<'a> {
-    FnLike(FnLikeNode<'a>),
-    Expr(&'a Expr<'a>),
-}
-
-impl<'a> Code<'a> {
-    pub fn id(&self) -> hir::HirId {
-        match *self {
-            Code::FnLike(node) => node.id(),
-            Code::Expr(block) => block.hir_id,
-        }
-    }
-
-    /// Attempts to construct a Code from presumed FnLike or Expr node input.
-    pub fn from_node(map: &Map<'a>, id: hir::HirId) -> Option<Code<'a>> {
-        match map.get(id) {
-            Node::Block(_) => {
-                //  Use the parent, hopefully an expression node.
-                Code::from_node(map, map.get_parent_node(id))
-            }
-            Node::Expr(expr) => Some(Code::Expr(expr)),
-            node => FnLikeNode::from_node(node).map(Code::FnLike),
-        }
-    }
-}
-
-/// These are all the components one can extract from a fn item for
-/// use when implementing FnLikeNode operations.
-struct ItemFnParts<'a> {
-    ident: Ident,
-    decl: &'a hir::FnDecl<'a>,
-    header: hir::FnHeader,
-    vis: &'a hir::Visibility<'a>,
-    generics: &'a hir::Generics<'a>,
-    body: hir::BodyId,
-    id: hir::HirId,
-    span: Span,
-}
-
-/// These are all the components one can extract from a closure expr
-/// for use when implementing FnLikeNode operations.
-struct ClosureParts<'a> {
-    decl: &'a FnDecl<'a>,
-    body: hir::BodyId,
-    id: hir::HirId,
-    span: Span,
-}
-
-impl<'a> ClosureParts<'a> {
-    fn new(d: &'a FnDecl<'a>, b: hir::BodyId, id: hir::HirId, s: Span) -> Self {
-        ClosureParts { decl: d, body: b, id, span: s }
-    }
-}
-
-impl<'a> FnLikeNode<'a> {
-    /// Attempts to construct a FnLikeNode from presumed FnLike node input.
-    pub fn from_node(node: Node<'_>) -> Option<FnLikeNode<'_>> {
-        let fn_like = match node {
-            Node::Item(item) => item.is_fn_like(),
-            Node::TraitItem(tm) => tm.is_fn_like(),
-            Node::ImplItem(it) => it.is_fn_like(),
-            Node::Expr(e) => e.is_fn_like(),
-            _ => false,
-        };
-        fn_like.then_some(FnLikeNode { node })
-    }
-
-    pub fn body(self) -> hir::BodyId {
-        self.handle(
-            |i: ItemFnParts<'a>| i.body,
-            |_, _, _: &'a hir::FnSig<'a>, _, body: hir::BodyId, _| body,
-            |c: ClosureParts<'a>| c.body,
-        )
-    }
-
-    pub fn decl(self) -> &'a FnDecl<'a> {
-        self.handle(
-            |i: ItemFnParts<'a>| &*i.decl,
-            |_, _, sig: &'a hir::FnSig<'a>, _, _, _| &sig.decl,
-            |c: ClosureParts<'a>| c.decl,
-        )
-    }
-
-    pub fn span(self) -> Span {
-        self.handle(
-            |i: ItemFnParts<'_>| i.span,
-            |_, _, _: &'a hir::FnSig<'a>, _, _, span| span,
-            |c: ClosureParts<'_>| c.span,
-        )
-    }
-
-    pub fn id(self) -> hir::HirId {
-        self.handle(
-            |i: ItemFnParts<'_>| i.id,
-            |id, _, _: &'a hir::FnSig<'a>, _, _, _| id,
-            |c: ClosureParts<'_>| c.id,
-        )
-    }
-
-    pub fn constness(self) -> hir::Constness {
-        self.kind().header().map_or(hir::Constness::NotConst, |header| header.constness)
-    }
-
-    pub fn asyncness(self) -> hir::IsAsync {
-        self.kind().header().map_or(hir::IsAsync::NotAsync, |header| header.asyncness)
-    }
-
-    pub fn unsafety(self) -> hir::Unsafety {
-        self.kind().header().map_or(hir::Unsafety::Normal, |header| header.unsafety)
-    }
-
-    pub fn kind(self) -> FnKind<'a> {
-        let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
-            FnKind::ItemFn(p.ident, p.generics, p.header, p.vis)
-        };
-        let closure = |_: ClosureParts<'a>| FnKind::Closure;
-        let method =
-            |_, ident: Ident, sig: &'a hir::FnSig<'a>, vis, _, _| FnKind::Method(ident, sig, vis);
-        self.handle(item, method, closure)
-    }
-
-    fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A
-    where
-        I: FnOnce(ItemFnParts<'a>) -> A,
-        M: FnOnce(
-            hir::HirId,
-            Ident,
-            &'a hir::FnSig<'a>,
-            Option<&'a hir::Visibility<'a>>,
-            hir::BodyId,
-            Span,
-        ) -> A,
-        C: FnOnce(ClosureParts<'a>) -> A,
-    {
-        match self.node {
-            Node::Item(i) => match i.kind {
-                hir::ItemKind::Fn(ref sig, ref generics, block) => item_fn(ItemFnParts {
-                    id: i.hir_id(),
-                    ident: i.ident,
-                    decl: &sig.decl,
-                    body: block,
-                    vis: &i.vis,
-                    span: i.span,
-                    header: sig.header,
-                    generics,
-                }),
-                _ => bug!("item FnLikeNode that is not fn-like"),
-            },
-            Node::TraitItem(ti) => match ti.kind {
-                hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
-                    method(ti.hir_id(), ti.ident, sig, None, body, ti.span)
-                }
-                _ => bug!("trait method FnLikeNode that is not fn-like"),
-            },
-            Node::ImplItem(ii) => match ii.kind {
-                hir::ImplItemKind::Fn(ref sig, body) => {
-                    method(ii.hir_id(), ii.ident, sig, Some(&ii.vis), body, ii.span)
-                }
-                _ => bug!("impl method FnLikeNode that is not fn-like"),
-            },
-            Node::Expr(e) => match e.kind {
-                hir::ExprKind::Closure(_, ref decl, block, _fn_decl_span, _gen) => {
-                    closure(ClosureParts::new(&decl, block, e.hir_id, e.span))
-                }
-                _ => bug!("expr FnLikeNode that is not fn-like"),
-            },
-            _ => bug!("other FnLikeNode that is not fn-like"),
-        }
-    }
-}
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 38bc01b9b53..fad7e875fa1 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -20,8 +20,6 @@ use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 use std::collections::VecDeque;
 
-pub mod blocks;
-
 fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
     match node {
         Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index ef8bd20d510..e4c2d2dce67 100644
--- a/compiler/rustc_mir_build/src/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
@@ -2,7 +2,6 @@ use rustc_data_structures::graph::iterate::{
     NodeStatus, TriColorDepthFirstSearch, TriColorVisitor,
 };
 use rustc_hir::intravisit::FnKind;
-use rustc_middle::hir::map::blocks::FnLikeNode;
 use rustc_middle::mir::{BasicBlock, Body, Operand, TerminatorKind};
 use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
 use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
@@ -14,8 +13,8 @@ crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
     let def_id = body.source.def_id().expect_local();
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
 
-    if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) {
-        if let FnKind::Closure = fn_like_node.kind() {
+    if let Some(fn_kind) = tcx.hir().get(hir_id).fn_kind() {
+        if let FnKind::Closure = fn_kind {
             // closures can't recur, so they don't matter.
             return;
         }
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 17790ec91c8..63c637af5c2 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -68,11 +68,10 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
             return;
         }
 
-        use rustc_middle::hir::map::blocks::FnLikeNode;
         let def_id = body.source.def_id().expect_local();
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
 
-        let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some();
+        let is_fn_like = tcx.hir().get(hir_id).fn_kind().is_some();
         let is_assoc_const = tcx.def_kind(def_id.to_def_id()) == DefKind::AssocConst;
 
         // Only run const prop on functions, methods, closures and associated constants
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index e980d3d884f..4ac93f71619 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -19,7 +19,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
 use rustc_index::vec::IndexVec;
 use rustc_middle::hir;
-use rustc_middle::hir::map::blocks::FnLikeNode;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::coverage::*;
 use rustc_middle::mir::dump_enabled;
@@ -64,7 +63,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
         }
 
         let hir_id = tcx.hir().local_def_id_to_hir_id(mir_source.def_id().expect_local());
-        let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some();
+        let is_fn_like = tcx.hir().get(hir_id).fn_kind().is_some();
 
         // Only instrument functions, methods, and closures (not constants since they are evaluated
         // at compile time by Miri).
@@ -74,7 +73,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
         // be tricky if const expressions have no corresponding statements in the enclosing MIR.
         // Closures are carved out by their initial `Assign` statement.)
         if !is_fn_like {
-            trace!("InstrumentCoverage skipped for {:?} (not an FnLikeNode)", mir_source.def_id());
+            trace!("InstrumentCoverage skipped for {:?} (not an fn-like)", mir_source.def_id());
             return;
         }
 
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 60135ef2d85..ab1fe6fe077 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -429,8 +429,7 @@ fn mir_drops_elaborated_and_const_checked<'tcx>(
     }
 
     let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
-    use rustc_middle::hir::map::blocks::FnLikeNode;
-    let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some();
+    let is_fn_like = tcx.hir().get(hir_id).fn_kind().is_some();
     if is_fn_like {
         let did = def.did.to_def_id();
         let def = ty::WithOptConstParam::unknown(did);
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 3d3b2743700..bc77c94809e 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -1,7 +1,6 @@
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::hir::map as hir_map;
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{
     self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, WithConstness,
@@ -478,11 +477,11 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
 
     let node = tcx.hir().get(hir_id);
 
-    let fn_like = hir_map::blocks::FnLikeNode::from_node(node).unwrap_or_else(|| {
+    let fn_kind = node.fn_kind().unwrap_or_else(|| {
         bug!("asyncness: expected fn-like node but got `{:?}`", def_id);
     });
 
-    fn_like.asyncness()
+    fn_kind.asyncness()
 }
 
 /// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead.