1
Fork 0

hir::map: simplify matching code

This commit is contained in:
Mazdak Farrokhzad 2020-03-24 06:17:44 +01:00
parent 22b2781fa5
commit 12e4f9f69a

View file

@ -42,79 +42,42 @@ impl<'hir> Entry<'hir> {
fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> { fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
match node { match node {
Node::Item(ref item) => match item.kind { Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
ItemKind::Fn(ref sig, _, _) => Some(&sig.decl), | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
_ => None, | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl),
}, Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. }) => Some(fn_decl),
Node::TraitItem(ref item) => match item.kind {
TraitItemKind::Fn(ref sig, _) => Some(&sig.decl),
_ => None,
},
Node::ImplItem(ref item) => match item.kind {
ImplItemKind::Fn(ref sig, _) => Some(&sig.decl),
_ => None,
},
Node::Expr(ref expr) => match expr.kind {
ExprKind::Closure(_, ref fn_decl, ..) => Some(fn_decl),
_ => None,
},
_ => None, _ => None,
} }
} }
fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> { fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> {
match &node { match &node {
Node::Item(item) => match &item.kind { Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
ItemKind::Fn(sig, _, _) => Some(sig), | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
_ => None, | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(sig),
},
Node::TraitItem(item) => match &item.kind {
TraitItemKind::Fn(sig, _) => Some(sig),
_ => None,
},
Node::ImplItem(item) => match &item.kind {
ImplItemKind::Fn(sig, _) => Some(sig),
_ => None,
},
_ => None, _ => None,
} }
} }
fn associated_body<'hir>(node: Node<'hir>) -> Option<BodyId> { fn associated_body<'hir>(node: Node<'hir>) -> Option<BodyId> {
match node { match node {
Node::Item(item) => match item.kind { Node::Item(Item {
ItemKind::Const(_, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body) => { kind: ItemKind::Const(_, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body),
Some(body) ..
} })
_ => None, | Node::TraitItem(TraitItem {
}, kind:
TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)),
Node::TraitItem(item) => match item.kind { ..
TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)) => { })
Some(body) | Node::ImplItem(ImplItem {
} kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
_ => None, ..
}, })
| Node::Expr(Expr { kind: ExprKind::Closure(.., body, _, _), .. }) => Some(*body),
Node::ImplItem(item) => match item.kind {
ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body) => Some(body),
_ => None,
},
Node::AnonConst(constant) => Some(constant.body), Node::AnonConst(constant) => Some(constant.body),
Node::Expr(expr) => match expr.kind {
ExprKind::Closure(.., body, _, _) => Some(body),
_ => None,
},
_ => None, _ => None,
} }
} }
@ -518,20 +481,21 @@ impl<'hir> Map<'hir> {
} }
pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics<'hir>> { pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics<'hir>> {
self.get_if_local(id).and_then(|node| match node { self.get_if_local(id).and_then(|node| match &node {
Node::ImplItem(ref impl_item) => Some(&impl_item.generics), Node::ImplItem(impl_item) => Some(&impl_item.generics),
Node::TraitItem(ref trait_item) => Some(&trait_item.generics), Node::TraitItem(trait_item) => Some(&trait_item.generics),
Node::Item(ref item) => match item.kind { Node::Item(Item {
ItemKind::Fn(_, ref generics, _) kind:
| ItemKind::TyAlias(_, ref generics) ItemKind::Fn(_, generics, _)
| ItemKind::Enum(_, ref generics) | ItemKind::TyAlias(_, generics)
| ItemKind::Struct(_, ref generics) | ItemKind::Enum(_, generics)
| ItemKind::Union(_, ref generics) | ItemKind::Struct(_, generics)
| ItemKind::Trait(_, _, ref generics, ..) | ItemKind::Union(_, generics)
| ItemKind::TraitAlias(ref generics, _) | ItemKind::Trait(_, _, generics, ..)
| ItemKind::Impl { ref generics, .. } => Some(generics), | ItemKind::TraitAlias(generics, _)
_ => None, | ItemKind::Impl { generics, .. },
}, ..
}) => Some(generics),
_ => None, _ => None,
}) })
} }
@ -571,11 +535,12 @@ impl<'hir> Map<'hir> {
_ => return false, _ => return false,
} }
match self.find(self.get_parent_node(id)) { match self.find(self.get_parent_node(id)) {
Some(Node::Item(_)) | Some(Node::TraitItem(_)) | Some(Node::ImplItem(_)) => true, Some(
Some(Node::Expr(e)) => match e.kind { Node::Item(_)
ExprKind::Closure(..) => true, | Node::TraitItem(_)
_ => false, | Node::ImplItem(_)
}, | Node::Expr(Expr { kind: ExprKind::Closure(..), .. }),
) => true,
_ => false, _ => false,
} }
} }
@ -642,12 +607,8 @@ impl<'hir> Map<'hir> {
if let (Some((_, next_node)), false) = (iter.peek(), ignore_tail) { if let (Some((_, next_node)), false) = (iter.peek(), ignore_tail) {
match next_node { match next_node {
Node::Block(Block { expr: None, .. }) => return None, Node::Block(Block { expr: None, .. }) => return None,
Node::Block(Block { expr: Some(expr), .. }) => { // The current node is not the tail expression of its parent.
if hir_id != expr.hir_id { Node::Block(Block { expr: Some(e), .. }) if hir_id != e.hir_id => return None,
// The current node is not the tail expression of its parent.
return None;
}
}
_ => {} _ => {}
} }
} }
@ -657,14 +618,11 @@ impl<'hir> Map<'hir> {
| Node::TraitItem(_) | Node::TraitItem(_)
| Node::Expr(Expr { kind: ExprKind::Closure(..), .. }) | Node::Expr(Expr { kind: ExprKind::Closure(..), .. })
| Node::ImplItem(_) => return Some(hir_id), | Node::ImplItem(_) => return Some(hir_id),
Node::Expr(ref expr) => { // Ignore `return`s on the first iteration
match expr.kind { Node::Expr(Expr { kind: ExprKind::Loop(..) | ExprKind::Ret(..), .. })
// Ignore `return`s on the first iteration | Node::Local(_) => {
ExprKind::Loop(..) | ExprKind::Ret(..) => return None, return None;
_ => {}
}
} }
Node::Local(_) => return None,
_ => {} _ => {}
} }
} }
@ -708,17 +666,12 @@ impl<'hir> Map<'hir> {
pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&'hir Expr<'hir>> { pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&'hir Expr<'hir>> {
for (_, node) in self.parent_iter(hir_id) { for (_, node) in self.parent_iter(hir_id) {
match node { match node {
Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) | Node::ImplItem(_) => { Node::Item(_)
break; | Node::ForeignItem(_)
} | Node::TraitItem(_)
Node::Expr(expr) => match expr.kind { | Node::ImplItem(_)
ExprKind::Match(_, _, _) => return Some(expr), | Node::Stmt(Stmt { kind: StmtKind::Local(_), .. }) => break,
_ => {} Node::Expr(expr @ Expr { kind: ExprKind::Match(..), .. }) => return Some(expr),
},
Node::Stmt(stmt) => match stmt.kind {
StmtKind::Local(_) => break,
_ => {}
},
_ => {} _ => {}
} }
} }
@ -728,32 +681,22 @@ impl<'hir> Map<'hir> {
/// Returns the nearest enclosing scope. A scope is roughly an item or block. /// Returns the nearest enclosing scope. A scope is roughly an item or block.
pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option<HirId> { pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option<HirId> {
for (hir_id, node) in self.parent_iter(hir_id) { for (hir_id, node) in self.parent_iter(hir_id) {
if match node { if let Node::Item(Item {
Node::Item(i) => match i.kind { kind:
ItemKind::Fn(..) ItemKind::Fn(..)
| ItemKind::Mod(..) | ItemKind::Mod(..)
| ItemKind::Enum(..) | ItemKind::Enum(..)
| ItemKind::Struct(..) | ItemKind::Struct(..)
| ItemKind::Union(..) | ItemKind::Union(..)
| ItemKind::Trait(..) | ItemKind::Trait(..)
| ItemKind::Impl { .. } => true, | ItemKind::Impl { .. },
_ => false, ..
}, })
Node::ForeignItem(fi) => match fi.kind { | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(..), .. })
ForeignItemKind::Fn(..) => true, | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(..), .. })
_ => false, | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(..), .. })
}, | Node::Block(_) = node
Node::TraitItem(ti) => match ti.kind { {
TraitItemKind::Fn(..) => true,
_ => false,
},
Node::ImplItem(ii) => match ii.kind {
ImplItemKind::Fn(..) => true,
_ => false,
},
Node::Block(_) => true,
_ => false,
} {
return Some(hir_id); return Some(hir_id);
} }
} }
@ -769,11 +712,11 @@ impl<'hir> Map<'hir> {
return CRATE_HIR_ID; return CRATE_HIR_ID;
} }
match self.get(scope) { match self.get(scope) {
Node::Item(i) => match i.kind { Node::Item(Item {
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => {} kind: ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }),
_ => break, ..
}, })
Node::Block(_) => {} | Node::Block(_) => {}
_ => break, _ => break,
} }
} }
@ -821,14 +764,11 @@ impl<'hir> Map<'hir> {
pub fn expect_variant_data(&self, id: HirId) -> &'hir VariantData<'hir> { pub fn expect_variant_data(&self, id: HirId) -> &'hir VariantData<'hir> {
match self.find(id) { match self.find(id) {
Some(Node::Item(i)) => match i.kind { Some(
ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { Node::Ctor(vd)
struct_def | Node::Item(Item { kind: ItemKind::Struct(vd, _) | ItemKind::Union(vd, _), .. }),
} ) => vd,
_ => bug!("struct ID bound to non-struct {}", self.node_to_string(id)),
},
Some(Node::Variant(variant)) => &variant.data, Some(Node::Variant(variant)) => &variant.data,
Some(Node::Ctor(data)) => data,
_ => bug!("expected struct or variant, found {}", self.node_to_string(id)), _ => bug!("expected struct or variant, found {}", self.node_to_string(id)),
} }
} }