Replace FnLikeNode by FnKind.
This commit is contained in:
parent
05eb6f36f1
commit
6e98688e68
11 changed files with 47 additions and 102 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,81 +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 rustc_hir as hir;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::Node;
|
||||
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
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) => matches!(item.kind, hir::ItemKind::Fn(..)),
|
||||
Node::TraitItem(tm) => {
|
||||
matches!(tm.kind, hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)))
|
||||
}
|
||||
Node::ImplItem(it) => matches!(it.kind, hir::ImplItemKind::Fn(..)),
|
||||
Node::Expr(e) => matches!(e.kind, hir::ExprKind::Closure(..)),
|
||||
_ => false,
|
||||
};
|
||||
fn_like.then_some(FnLikeNode { node })
|
||||
}
|
||||
|
||||
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 kind(self) -> FnKind<'a> {
|
||||
match self.node {
|
||||
Node::Item(i) => match i.kind {
|
||||
hir::ItemKind::Fn(ref sig, ref generics, _) => {
|
||||
FnKind::ItemFn(i.ident, generics, sig.header, &i.vis)
|
||||
}
|
||||
_ => bug!("item FnLikeNode that is not fn-like"),
|
||||
},
|
||||
Node::TraitItem(ti) => match ti.kind {
|
||||
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(_)) => {
|
||||
FnKind::Method(ti.ident, sig, None)
|
||||
}
|
||||
_ => bug!("trait method FnLikeNode that is not fn-like"),
|
||||
},
|
||||
Node::ImplItem(ii) => match ii.kind {
|
||||
hir::ImplItemKind::Fn(ref sig, _) => FnKind::Method(ii.ident, sig, Some(&ii.vis)),
|
||||
_ => bug!("impl method FnLikeNode that is not fn-like"),
|
||||
},
|
||||
Node::Expr(e) => match e.kind {
|
||||
hir::ExprKind::Closure(..) => FnKind::Closure,
|
||||
_ => bug!("expr FnLikeNode that is not fn-like"),
|
||||
},
|
||||
_ => bug!("other FnLikeNode that is not fn-like"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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, _, _), .. })
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -428,8 +428,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);
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue