1111//! nested within a uniquely determined `FnLike`), and users can ask
1212//! for the `Code` associated with a particular NodeId.
1313
14- use crate :: hir:: map:: Map ;
1514use rustc_hir as hir;
1615use rustc_hir:: intravisit:: FnKind ;
17- use rustc_hir:: { Expr , FnDecl , Node } ;
18- use rustc_span:: symbol:: Ident ;
19- use rustc_span:: Span ;
16+ use rustc_hir:: Node ;
2017
2118/// An FnLikeNode is a Node that is like a fn, in that it has a decl
2219/// and a body (as well as a NodeId, a span, etc).
@@ -33,139 +30,21 @@ pub struct FnLikeNode<'a> {
3330 node : Node < ' a > ,
3431}
3532
36- /// MaybeFnLike wraps a method that indicates if an object
37- /// corresponds to some FnLikeNode.
38- trait MaybeFnLike {
39- fn is_fn_like ( & self ) -> bool ;
40- }
41-
42- impl MaybeFnLike for hir:: Item < ' _ > {
43- fn is_fn_like ( & self ) -> bool {
44- matches ! ( self . kind, hir:: ItemKind :: Fn ( ..) )
45- }
46- }
47-
48- impl MaybeFnLike for hir:: ImplItem < ' _ > {
49- fn is_fn_like ( & self ) -> bool {
50- matches ! ( self . kind, hir:: ImplItemKind :: Fn ( ..) )
51- }
52- }
53-
54- impl MaybeFnLike for hir:: TraitItem < ' _ > {
55- fn is_fn_like ( & self ) -> bool {
56- matches ! ( self . kind, hir:: TraitItemKind :: Fn ( _, hir:: TraitFn :: Provided ( _) ) )
57- }
58- }
59-
60- impl MaybeFnLike for hir:: Expr < ' _ > {
61- fn is_fn_like ( & self ) -> bool {
62- matches ! ( self . kind, hir:: ExprKind :: Closure ( ..) )
63- }
64- }
65-
66- /// Carries either an FnLikeNode or an Expr, as these are the two
67- /// constructs that correspond to "code" (as in, something from which
68- /// we can construct a control-flow graph).
69- #[ derive( Copy , Clone ) ]
70- pub enum Code < ' a > {
71- FnLike ( FnLikeNode < ' a > ) ,
72- Expr ( & ' a Expr < ' a > ) ,
73- }
74-
75- impl < ' a > Code < ' a > {
76- pub fn id ( & self ) -> hir:: HirId {
77- match * self {
78- Code :: FnLike ( node) => node. id ( ) ,
79- Code :: Expr ( block) => block. hir_id ,
80- }
81- }
82-
83- /// Attempts to construct a Code from presumed FnLike or Expr node input.
84- pub fn from_node ( map : & Map < ' a > , id : hir:: HirId ) -> Option < Code < ' a > > {
85- match map. get ( id) {
86- Node :: Block ( _) => {
87- // Use the parent, hopefully an expression node.
88- Code :: from_node ( map, map. get_parent_node ( id) )
89- }
90- Node :: Expr ( expr) => Some ( Code :: Expr ( expr) ) ,
91- node => FnLikeNode :: from_node ( node) . map ( Code :: FnLike ) ,
92- }
93- }
94- }
95-
96- /// These are all the components one can extract from a fn item for
97- /// use when implementing FnLikeNode operations.
98- struct ItemFnParts < ' a > {
99- ident : Ident ,
100- decl : & ' a hir:: FnDecl < ' a > ,
101- header : hir:: FnHeader ,
102- vis : & ' a hir:: Visibility < ' a > ,
103- generics : & ' a hir:: Generics < ' a > ,
104- body : hir:: BodyId ,
105- id : hir:: HirId ,
106- span : Span ,
107- }
108-
109- /// These are all the components one can extract from a closure expr
110- /// for use when implementing FnLikeNode operations.
111- struct ClosureParts < ' a > {
112- decl : & ' a FnDecl < ' a > ,
113- body : hir:: BodyId ,
114- id : hir:: HirId ,
115- span : Span ,
116- }
117-
118- impl < ' a > ClosureParts < ' a > {
119- fn new ( d : & ' a FnDecl < ' a > , b : hir:: BodyId , id : hir:: HirId , s : Span ) -> Self {
120- ClosureParts { decl : d, body : b, id, span : s }
121- }
122- }
123-
12433impl < ' a > FnLikeNode < ' a > {
12534 /// Attempts to construct a FnLikeNode from presumed FnLike node input.
12635 pub fn from_node ( node : Node < ' _ > ) -> Option < FnLikeNode < ' _ > > {
12736 let fn_like = match node {
128- Node :: Item ( item) => item. is_fn_like ( ) ,
129- Node :: TraitItem ( tm) => tm. is_fn_like ( ) ,
130- Node :: ImplItem ( it) => it. is_fn_like ( ) ,
131- Node :: Expr ( e) => e. is_fn_like ( ) ,
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 ( ..) ) ,
13243 _ => false ,
13344 } ;
13445 fn_like. then_some ( FnLikeNode { node } )
13546 }
13647
137- pub fn body ( self ) -> hir:: BodyId {
138- self . handle (
139- |i : ItemFnParts < ' a > | i. body ,
140- |_, _, _: & ' a hir:: FnSig < ' a > , _, body : hir:: BodyId , _| body,
141- |c : ClosureParts < ' a > | c. body ,
142- )
143- }
144-
145- pub fn decl ( self ) -> & ' a FnDecl < ' a > {
146- self . handle (
147- |i : ItemFnParts < ' a > | & * i. decl ,
148- |_, _, sig : & ' a hir:: FnSig < ' a > , _, _, _| & sig. decl ,
149- |c : ClosureParts < ' a > | c. decl ,
150- )
151- }
152-
153- pub fn span ( self ) -> Span {
154- self . handle (
155- |i : ItemFnParts < ' _ > | i. span ,
156- |_, _, _: & ' a hir:: FnSig < ' a > , _, _, span| span,
157- |c : ClosureParts < ' _ > | c. span ,
158- )
159- }
160-
161- pub fn id ( self ) -> hir:: HirId {
162- self . handle (
163- |i : ItemFnParts < ' _ > | i. id ,
164- |id, _, _: & ' a hir:: FnSig < ' a > , _, _, _| id,
165- |c : ClosureParts < ' _ > | c. id ,
166- )
167- }
168-
16948 pub fn constness ( self ) -> hir:: Constness {
17049 self . kind ( ) . header ( ) . map_or ( hir:: Constness :: NotConst , |header| header. constness )
17150 }
@@ -174,63 +53,26 @@ impl<'a> FnLikeNode<'a> {
17453 self . kind ( ) . header ( ) . map_or ( hir:: IsAsync :: NotAsync , |header| header. asyncness )
17554 }
17655
177- pub fn unsafety ( self ) -> hir:: Unsafety {
178- self . kind ( ) . header ( ) . map_or ( hir:: Unsafety :: Normal , |header| header. unsafety )
179- }
180-
18156 pub fn kind ( self ) -> FnKind < ' a > {
182- let item = |p : ItemFnParts < ' a > | -> FnKind < ' a > {
183- FnKind :: ItemFn ( p. ident , p. generics , p. header , p. vis )
184- } ;
185- let closure = |_: ClosureParts < ' a > | FnKind :: Closure ;
186- let method =
187- |_, ident : Ident , sig : & ' a hir:: FnSig < ' a > , vis, _, _| FnKind :: Method ( ident, sig, vis) ;
188- self . handle ( item, method, closure)
189- }
190-
191- fn handle < A , I , M , C > ( self , item_fn : I , method : M , closure : C ) -> A
192- where
193- I : FnOnce ( ItemFnParts < ' a > ) -> A ,
194- M : FnOnce (
195- hir:: HirId ,
196- Ident ,
197- & ' a hir:: FnSig < ' a > ,
198- Option < & ' a hir:: Visibility < ' a > > ,
199- hir:: BodyId ,
200- Span ,
201- ) -> A ,
202- C : FnOnce ( ClosureParts < ' a > ) -> A ,
203- {
20457 match self . node {
20558 Node :: Item ( i) => match i. kind {
206- hir:: ItemKind :: Fn ( ref sig, ref generics, block) => item_fn ( ItemFnParts {
207- id : i. hir_id ( ) ,
208- ident : i. ident ,
209- decl : & sig. decl ,
210- body : block,
211- vis : & i. vis ,
212- span : i. span ,
213- header : sig. header ,
214- generics,
215- } ) ,
59+ hir:: ItemKind :: Fn ( ref sig, ref generics, _) => {
60+ FnKind :: ItemFn ( i. ident , generics, sig. header , & i. vis )
61+ }
21662 _ => bug ! ( "item FnLikeNode that is not fn-like" ) ,
21763 } ,
21864 Node :: TraitItem ( ti) => match ti. kind {
219- hir:: TraitItemKind :: Fn ( ref sig, hir:: TraitFn :: Provided ( body ) ) => {
220- method ( ti. hir_id ( ) , ti . ident , sig, None , body , ti . span )
65+ hir:: TraitItemKind :: Fn ( ref sig, hir:: TraitFn :: Provided ( _ ) ) => {
66+ FnKind :: Method ( ti. ident , sig, None )
22167 }
22268 _ => bug ! ( "trait method FnLikeNode that is not fn-like" ) ,
22369 } ,
22470 Node :: ImplItem ( ii) => match ii. kind {
225- hir:: ImplItemKind :: Fn ( ref sig, body) => {
226- method ( ii. hir_id ( ) , ii. ident , sig, Some ( & ii. vis ) , body, ii. span )
227- }
71+ hir:: ImplItemKind :: Fn ( ref sig, _) => FnKind :: Method ( ii. ident , sig, Some ( & ii. vis ) ) ,
22872 _ => bug ! ( "impl method FnLikeNode that is not fn-like" ) ,
22973 } ,
23074 Node :: Expr ( e) => match e. kind {
231- hir:: ExprKind :: Closure ( _, ref decl, block, _fn_decl_span, _gen) => {
232- closure ( ClosureParts :: new ( & decl, block, e. hir_id , e. span ) )
233- }
75+ hir:: ExprKind :: Closure ( ..) => FnKind :: Closure ,
23476 _ => bug ! ( "expr FnLikeNode that is not fn-like" ) ,
23577 } ,
23678 _ => bug ! ( "other FnLikeNode that is not fn-like" ) ,
0 commit comments