Add inline to TransFnAttrs

Part of #47320
This commit is contained in:
Wesley Wiser 2018-01-30 22:39:23 -05:00
parent e8cd6cc237
commit 4f840a683a
13 changed files with 149 additions and 137 deletions

View file

@ -36,6 +36,7 @@ use syntax::codemap::{self, Spanned};
use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
use syntax::attr::InlineAttr;
use syntax::ext::hygiene::SyntaxContext;
use syntax::ptr::P;
use syntax::symbol::{Symbol, keywords};
@ -2214,6 +2215,7 @@ pub fn provide(providers: &mut Providers) {
#[derive(Clone, RustcEncodable, RustcDecodable, Hash)]
pub struct TransFnAttrs {
pub flags: TransFnAttrFlags,
pub inline: InlineAttr,
}
bitflags! {
@ -2231,6 +2233,15 @@ impl TransFnAttrs {
pub fn new() -> TransFnAttrs {
TransFnAttrs {
flags: TransFnAttrFlags::empty(),
inline: InlineAttr::None,
}
}
/// True if `#[inline]` or `#[inline(always)]` is present.
pub fn requests_inline(&self) -> bool {
match self.inline {
InlineAttr::Hint | InlineAttr::Always => true,
InlineAttr::None | InlineAttr::Never => false,
}
}
}

View file

@ -19,6 +19,7 @@ use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
StableHasher, StableHasherResult};
use std::mem;
use syntax::ast;
use syntax::attr;
impl<'gcx> HashStable<StableHashingContext<'gcx>> for DefId {
#[inline]
@ -1145,9 +1146,11 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrs
hasher: &mut StableHasher<W>) {
let hir::TransFnAttrs {
flags,
inline,
} = *self;
flags.hash_stable(hcx, hasher);
inline.hash_stable(hcx, hasher);
}
}
@ -1160,6 +1163,14 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrFlags
}
}
impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
}
}
impl_stable_hash_for!(struct hir::Freevar {
def,
span

View file

@ -15,6 +15,7 @@
// makes all other generics or inline functions that it references
// reachable as well.
use hir::TransFnAttrs;
use hir::map as hir_map;
use hir::def::Def;
use hir::def_id::{DefId, CrateNum};
@ -43,8 +44,8 @@ fn generics_require_inlining(generics: &hir::Generics) -> bool {
// Returns true if the given item must be inlined because it may be
// monomorphized or it was marked with `#[inline]`. This will only return
// true for functions.
fn item_might_be_inlined(item: &hir::Item) -> bool {
if attr::requests_inline(&item.attrs) {
fn item_might_be_inlined(item: &hir::Item, attrs: TransFnAttrs) -> bool {
if attrs.requests_inline() {
return true
}
@ -60,14 +61,15 @@ fn item_might_be_inlined(item: &hir::Item) -> bool {
fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_item: &hir::ImplItem,
impl_src: DefId) -> bool {
if attr::requests_inline(&impl_item.attrs) ||
let trans_fn_attrs = tcx.trans_fn_attrs(impl_item.hir_id.owner_def_id());
if trans_fn_attrs.requests_inline() ||
generics_require_inlining(&impl_item.generics) {
return true
}
if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
match tcx.hir.find(impl_node_id) {
Some(hir_map::NodeItem(item)) =>
item_might_be_inlined(&item),
item_might_be_inlined(&item, trans_fn_attrs),
Some(..) | None =>
span_bug!(impl_item.span, "impl did is not an item")
}
@ -160,7 +162,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match self.tcx.hir.find(node_id) {
Some(hir_map::NodeItem(item)) => {
match item.node {
hir::ItemFn(..) => item_might_be_inlined(&item),
hir::ItemFn(..) =>
item_might_be_inlined(&item, self.tcx.trans_fn_attrs(def_id)),
_ => false,
}
}
@ -176,8 +179,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match impl_item.node {
hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Method(..) => {
let attrs = self.tcx.trans_fn_attrs(def_id);
if generics_require_inlining(&impl_item.generics) ||
attr::requests_inline(&impl_item.attrs) {
attrs.requests_inline() {
true
} else {
let impl_did = self.tcx
@ -246,7 +250,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir_map::NodeItem(item) => {
match item.node {
hir::ItemFn(.., body) => {
if item_might_be_inlined(&item) {
let def_id = self.tcx.hir.local_def_id(item.id);
if item_might_be_inlined(&item, self.tcx.trans_fn_attrs(def_id)) {
self.visit_nested_body(body);
}
}

View file

@ -96,7 +96,6 @@ impl<'tcx> InstanceDef<'tcx> {
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>
) -> bool {
use syntax::attr::requests_inline;
if self.is_inline(tcx) {
return true
}
@ -106,8 +105,8 @@ impl<'tcx> InstanceDef<'tcx> {
// available to normal end-users.
return true
}
requests_inline(&self.attrs(tcx)[..]) ||
tcx.is_const_fn(self.def_id())
let trans_fn_attrs = tcx.trans_fn_attrs(self.def_id());
trans_fn_attrs.requests_inline() || tcx.is_const_fn(self.def_id())
}
}