]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/hir/map/blocks.rs
Cleanup dead code in hir::map::blocks.
[rust.git] / compiler / rustc_middle / src / hir / map / blocks.rs
1 //! This module provides a simplified abstraction for working with
2 //! code blocks identified by their integer `NodeId`. In particular,
3 //! it captures a common set of attributes that all "function-like
4 //! things" (represented by `FnLike` instances) share. For example,
5 //! all `FnLike` instances have a type signature (be it explicit or
6 //! inferred). And all `FnLike` instances have a body, i.e., the code
7 //! that is run when the function-like thing it represents is invoked.
8 //!
9 //! With the above abstraction in place, one can treat the program
10 //! text as a collection of blocks of code (and most such blocks are
11 //! nested within a uniquely determined `FnLike`), and users can ask
12 //! for the `Code` associated with a particular NodeId.
13
14 use rustc_hir as hir;
15 use rustc_hir::intravisit::FnKind;
16 use rustc_hir::Node;
17
18 /// An FnLikeNode is a Node that is like a fn, in that it has a decl
19 /// and a body (as well as a NodeId, a span, etc).
20 ///
21 /// More specifically, it is one of either:
22 ///
23 ///   - A function item,
24 ///   - A closure expr (i.e., an ExprKind::Closure), or
25 ///   - The default implementation for a trait method.
26 ///
27 /// To construct one, use the `Code::from_node` function.
28 #[derive(Copy, Clone, Debug)]
29 pub struct FnLikeNode<'a> {
30     node: Node<'a>,
31 }
32
33 impl<'a> FnLikeNode<'a> {
34     /// Attempts to construct a FnLikeNode from presumed FnLike node input.
35     pub fn from_node(node: Node<'_>) -> Option<FnLikeNode<'_>> {
36         let fn_like = match node {
37             Node::Item(item) => matches!(item.kind, hir::ItemKind::Fn(..)),
38             Node::TraitItem(tm) => {
39                 matches!(tm.kind, hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)))
40             }
41             Node::ImplItem(it) => matches!(it.kind, hir::ImplItemKind::Fn(..)),
42             Node::Expr(e) => matches!(e.kind, hir::ExprKind::Closure(..)),
43             _ => false,
44         };
45         fn_like.then_some(FnLikeNode { node })
46     }
47
48     pub fn constness(self) -> hir::Constness {
49         self.kind().header().map_or(hir::Constness::NotConst, |header| header.constness)
50     }
51
52     pub fn asyncness(self) -> hir::IsAsync {
53         self.kind().header().map_or(hir::IsAsync::NotAsync, |header| header.asyncness)
54     }
55
56     pub fn kind(self) -> FnKind<'a> {
57         match self.node {
58             Node::Item(i) => match i.kind {
59                 hir::ItemKind::Fn(ref sig, ref generics, _) => {
60                     FnKind::ItemFn(i.ident, generics, sig.header, &i.vis)
61                 }
62                 _ => bug!("item FnLikeNode that is not fn-like"),
63             },
64             Node::TraitItem(ti) => match ti.kind {
65                 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(_)) => {
66                     FnKind::Method(ti.ident, sig, None)
67                 }
68                 _ => bug!("trait method FnLikeNode that is not fn-like"),
69             },
70             Node::ImplItem(ii) => match ii.kind {
71                 hir::ImplItemKind::Fn(ref sig, _) => FnKind::Method(ii.ident, sig, Some(&ii.vis)),
72                 _ => bug!("impl method FnLikeNode that is not fn-like"),
73             },
74             Node::Expr(e) => match e.kind {
75                 hir::ExprKind::Closure(..) => FnKind::Closure,
76                 _ => bug!("expr FnLikeNode that is not fn-like"),
77             },
78             _ => bug!("other FnLikeNode that is not fn-like"),
79         }
80     }
81 }