Skip to content

Commit d0ae2c8

Browse files
committed
Refactor inlined items some more
They don't implement FnLikeNode anymore, instead are handled differently further up in the call tree. Also, keep less information (just def ids for the args).
1 parent dd1491c commit d0ae2c8

File tree

6 files changed

+91
-102
lines changed

6 files changed

+91
-102
lines changed

src/librustc/hir/map/blocks.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use hir as ast;
2525
use hir::map::{self, Node};
2626
use hir::{Expr, FnDecl};
2727
use hir::intravisit::FnKind;
28-
use middle::cstore::{InlinedItem, InlinedItemKind};
2928
use syntax::abi;
3029
use syntax::ast::{Attribute, Name, NodeId};
3130
use syntax_pos::Span;
@@ -152,7 +151,6 @@ impl<'a> FnLikeNode<'a> {
152151
map::NodeTraitItem(tm) => tm.is_fn_like(),
153152
map::NodeImplItem(_) => true,
154153
map::NodeExpr(e) => e.is_fn_like(),
155-
map::NodeInlinedItem(ii) => ii.is_fn(),
156154
_ => false
157155
};
158156
if fn_like {
@@ -175,21 +173,12 @@ impl<'a> FnLikeNode<'a> {
175173
}
176174

177175
pub fn body(self) -> ast::ExprId {
178-
if let map::NodeInlinedItem(ii) = self.node {
179-
return ast::ExprId(ii.body.id);
180-
}
181176
self.handle(|i: ItemFnParts<'a>| i.body,
182177
|_, _, _: &'a ast::MethodSig, _, body: ast::ExprId, _, _| body,
183178
|c: ClosureParts<'a>| c.body)
184179
}
185180

186181
pub fn decl(self) -> &'a FnDecl {
187-
if let map::NodeInlinedItem(&InlinedItem {
188-
kind: InlinedItemKind::Fn(ref decl),
189-
..
190-
}) = self.node {
191-
return &decl;
192-
}
193182
self.handle(|i: ItemFnParts<'a>| &*i.decl,
194183
|_, _, sig: &'a ast::MethodSig, _, _, _, _| &sig.decl,
195184
|c: ClosureParts<'a>| c.decl)
@@ -208,9 +197,6 @@ impl<'a> FnLikeNode<'a> {
208197
}
209198

210199
pub fn constness(self) -> ast::Constness {
211-
if let map::NodeInlinedItem(..) = self.node {
212-
return ast::Constness::Const;
213-
}
214200
match self.kind() {
215201
FnKind::ItemFn(_, _, _, constness, ..) => {
216202
constness

src/librustc/hir/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,12 @@ pub struct Expr {
870870
pub attrs: ThinVec<Attribute>,
871871
}
872872

873+
impl Expr {
874+
pub fn expr_id(&self) -> ExprId {
875+
ExprId(self.id)
876+
}
877+
}
878+
873879
impl fmt::Debug for Expr {
874880
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
875881
write!(f, "expr({}: {})", self.id, print::expr_to_string(self))

src/librustc/middle/cstore.rs

Lines changed: 24 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use syntax::symbol::Symbol;
4343
use syntax_pos::Span;
4444
use rustc_back::target::Target;
4545
use hir;
46-
use hir::intravisit::{self, Visitor};
46+
use hir::intravisit::Visitor;
4747
use rustc_back::PanicStrategy;
4848

4949
pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
@@ -140,54 +140,47 @@ pub struct NativeLibrary {
140140
pub struct InlinedItem {
141141
pub def_id: DefId,
142142
pub body: P<hir::Expr>,
143-
pub kind: InlinedItemKind,
144-
}
145-
146-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
147-
pub enum InlinedItemKind {
148-
Const(P<hir::Ty>),
149-
Fn(P<hir::FnDecl>)
143+
pub const_fn_args: Vec<DefId>,
150144
}
151145

152146
/// A borrowed version of `hir::InlinedItem`. This is what's encoded when saving
153147
/// a crate; it then gets read as an InlinedItem.
154-
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, Hash, Debug)]
148+
#[derive(Clone, PartialEq, Eq, RustcEncodable, Hash, Debug)]
155149
pub struct InlinedItemRef<'a> {
156150
pub def_id: DefId,
157151
pub body: &'a hir::Expr,
158-
pub kind: InlinedItemKindRef<'a>,
152+
pub const_fn_args: Vec<DefId>,
159153
}
160154

161-
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, Hash, Debug)]
162-
pub enum InlinedItemKindRef<'a> {
163-
Const(&'a hir::Ty),
164-
Fn(&'a hir::FnDecl)
155+
fn get_fn_args(tcx: TyCtxt, decl: &hir::FnDecl) -> Vec<DefId> {
156+
decl.inputs.iter().map(|arg| tcx.expect_def(arg.pat.id).def_id()).collect()
165157
}
166158

167159
impl<'a> InlinedItemRef<'a> {
168-
pub fn from_item<'ast: 'a>(def_id: DefId,
160+
pub fn from_item<'b, 'tcx>(def_id: DefId,
169161
item: &'a hir::Item,
170-
map: &hir_map::Map<'ast>)
162+
tcx: TyCtxt<'b, 'a, 'tcx>)
171163
-> InlinedItemRef<'a> {
172-
let (body, kind) = match item.node {
164+
let (body, args) = match item.node {
173165
hir::ItemFn(ref decl, _, _, _, _, body_id) =>
174-
(map.expr(body_id), InlinedItemKindRef::Fn(&decl)),
175-
hir::ItemConst(ref ty, ref body) => (&**body, InlinedItemKindRef::Const(ty)),
166+
(tcx.map.expr(body_id), get_fn_args(tcx, decl)),
167+
hir::ItemConst(_, ref body) => (&**body, Vec::new()),
176168
_ => bug!("InlinedItemRef::from_item wrong kind")
177169
};
178170
InlinedItemRef {
179171
def_id: def_id,
180172
body: body,
181-
kind: kind
173+
const_fn_args: args
182174
}
183175
}
184176

185177
pub fn from_trait_item(def_id: DefId,
186178
item: &'a hir::TraitItem,
187-
_map: &hir_map::Map)
179+
_tcx: TyCtxt)
188180
-> InlinedItemRef<'a> {
189-
let (body, kind) = match item.node {
190-
hir::ConstTraitItem(ref ty, Some(ref body)) => (&**body, InlinedItemKindRef::Const(ty)),
181+
let (body, args) = match item.node {
182+
hir::ConstTraitItem(_, Some(ref body)) =>
183+
(&**body, Vec::new()),
191184
hir::ConstTraitItem(_, None) => {
192185
bug!("InlinedItemRef::from_trait_item called for const without body")
193186
},
@@ -196,35 +189,32 @@ impl<'a> InlinedItemRef<'a> {
196189
InlinedItemRef {
197190
def_id: def_id,
198191
body: body,
199-
kind: kind
192+
const_fn_args: args
200193
}
201194
}
202195

203-
pub fn from_impl_item<'ast: 'a>(def_id: DefId,
196+
pub fn from_impl_item<'b, 'tcx>(def_id: DefId,
204197
item: &'a hir::ImplItem,
205-
map: &hir_map::Map<'ast>)
198+
tcx: TyCtxt<'b, 'a, 'tcx>)
206199
-> InlinedItemRef<'a> {
207-
let (body, kind) = match item.node {
200+
let (body, args) = match item.node {
208201
hir::ImplItemKind::Method(ref sig, body_id) =>
209-
(map.expr(body_id), InlinedItemKindRef::Fn(&sig.decl)),
210-
hir::ImplItemKind::Const(ref ty, ref body) => (&**body, InlinedItemKindRef::Const(ty)),
202+
(tcx.map.expr(body_id), get_fn_args(tcx, &sig.decl)),
203+
hir::ImplItemKind::Const(_, ref body) =>
204+
(&**body, Vec::new()),
211205
_ => bug!("InlinedItemRef::from_impl_item wrong kind")
212206
};
213207
InlinedItemRef {
214208
def_id: def_id,
215209
body: body,
216-
kind: kind
210+
const_fn_args: args
217211
}
218212
}
219213

220214
pub fn visit<V>(&self, visitor: &mut V)
221215
where V: Visitor<'a>
222216
{
223217
visitor.visit_expr(&self.body);
224-
match self.kind {
225-
InlinedItemKindRef::Const(ty) => visitor.visit_ty(ty),
226-
InlinedItemKindRef::Fn(decl) => intravisit::walk_fn_decl(visitor, decl)
227-
}
228218
}
229219
}
230220

@@ -233,17 +223,6 @@ impl InlinedItem {
233223
where V: Visitor<'ast>
234224
{
235225
visitor.visit_expr(&self.body);
236-
match self.kind {
237-
InlinedItemKind::Const(ref ty) => visitor.visit_ty(ty),
238-
InlinedItemKind::Fn(ref decl) => intravisit::walk_fn_decl(visitor, decl)
239-
}
240-
}
241-
242-
pub fn is_fn(&self) -> bool {
243-
match self.kind {
244-
InlinedItemKind::Const(_) => false,
245-
InlinedItemKind::Fn(_) => true
246-
}
247226
}
248227
}
249228

src/librustc_const_eval/eval.rs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use self::EvalHint::*;
1717

1818
use rustc::hir::map as ast_map;
1919
use rustc::hir::map::blocks::FnLikeNode;
20-
use rustc::middle::cstore::{InlinedItem, InlinedItemKind};
20+
use rustc::middle::cstore::InlinedItem;
2121
use rustc::traits;
2222
use rustc::hir::def::{Def, CtorKind};
2323
use rustc::hir::def_id::DefId;
@@ -142,9 +142,8 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
142142
}
143143
let mut used_substs = false;
144144
let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
145-
Some((&InlinedItem { body: ref const_expr,
146-
kind: InlinedItemKind::Const(ref ty), .. }, _)) => {
147-
Some((&**const_expr, tcx.ast_ty_to_prim_ty(ty)))
145+
Some((&InlinedItem { body: ref const_expr, .. }, _)) => {
146+
Some((&**const_expr, Some(tcx.sess.cstore.item_type(tcx, def_id))))
148147
}
149148
_ => None
150149
};
@@ -166,8 +165,9 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
166165
} else {
167166
expr_ty
168167
}
169-
}
170-
_ => expr_ty
168+
},
169+
Some(Def::Const(..)) => expr_ty,
170+
_ => None
171171
};
172172
// If we used the substitutions, particularly to choose an impl
173173
// of a trait-associated const, don't cache that, because the next
@@ -195,23 +195,29 @@ fn inline_const_fn_from_external_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
195195
return None;
196196
}
197197

198-
let fn_id = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
199-
Some((&InlinedItem { kind: InlinedItemKind::Fn(_), .. }, node_id)) => Some(node_id),
200-
_ => None
201-
};
198+
let fn_id = tcx.sess.cstore.maybe_get_item_ast(tcx, def_id).map(|t| t.1);
202199
tcx.extern_const_fns.borrow_mut().insert(def_id,
203200
fn_id.unwrap_or(ast::DUMMY_NODE_ID));
204201
fn_id
205202
}
206203

204+
pub enum ConstFnNode<'tcx> {
205+
Local(FnLikeNode<'tcx>),
206+
Inlined(&'tcx InlinedItem)
207+
}
208+
207209
pub fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
208-
-> Option<FnLikeNode<'tcx>>
210+
-> Option<ConstFnNode<'tcx>>
209211
{
210212
let fn_id = if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
211213
node_id
212214
} else {
213215
if let Some(fn_id) = inline_const_fn_from_external_crate(tcx, def_id) {
214-
fn_id
216+
if let ast_map::NodeInlinedItem(ii) = tcx.map.get(fn_id) {
217+
return Some(ConstFnNode::Inlined(ii));
218+
} else {
219+
bug!("Got const fn from external crate, but it's not inlined")
220+
}
215221
} else {
216222
return None;
217223
}
@@ -223,7 +229,7 @@ pub fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI
223229
};
224230

225231
if fn_like.constness() == hir::Constness::Const {
226-
Some(fn_like)
232+
Some(ConstFnNode::Local(fn_like))
227233
} else {
228234
None
229235
}
@@ -858,16 +864,19 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
858864
Struct(_) => signal!(e, UnimplementedConstVal("tuple struct constructors")),
859865
callee => signal!(e, CallOn(callee)),
860866
};
861-
let (decl, body_id) = if let Some(fn_like) = lookup_const_fn_by_id(tcx, did) {
862-
(fn_like.decl(), fn_like.body())
863-
} else {
864-
signal!(e, NonConstPath)
867+
let (arg_defs, body_id) = match lookup_const_fn_by_id(tcx, did) {
868+
Some(ConstFnNode::Inlined(ii)) => (ii.const_fn_args.clone(), ii.body.expr_id()),
869+
Some(ConstFnNode::Local(fn_like)) =>
870+
(fn_like.decl().inputs.iter()
871+
.map(|arg| tcx.expect_def(arg.pat.id).def_id()).collect(),
872+
fn_like.body()),
873+
None => signal!(e, NonConstPath),
865874
};
866875
let result = tcx.map.expr(body_id);
867-
assert_eq!(decl.inputs.len(), args.len());
876+
assert_eq!(arg_defs.len(), args.len());
868877

869878
let mut call_args = DefIdMap();
870-
for (arg, arg_expr) in decl.inputs.iter().zip(args.iter()) {
879+
for (arg, arg_expr) in arg_defs.iter().zip(args.iter()) {
871880
let arg_hint = ty_hint.erase_hint();
872881
let arg_val = eval_const_expr_partial(
873882
tcx,

src/librustc_metadata/encoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
521521
// (InlinedItemRef::from_trait_item panics otherwise)
522522
let trait_def_id = trait_item.container.id();
523523
Some(self.encode_inlined_item(
524-
InlinedItemRef::from_trait_item(trait_def_id, ast_item, &tcx.map)
524+
InlinedItemRef::from_trait_item(trait_def_id, ast_item, tcx)
525525
))
526526
} else {
527527
None
@@ -594,7 +594,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
594594

595595
ast: if ast {
596596
Some(self.encode_inlined_item(
597-
InlinedItemRef::from_impl_item(impl_def_id, ast_item, &tcx.map)
597+
InlinedItemRef::from_impl_item(impl_def_id, ast_item, tcx)
598598
))
599599
} else {
600600
None
@@ -826,7 +826,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
826826
hir::ItemConst(..) |
827827
hir::ItemFn(_, _, hir::Constness::Const, ..) => {
828828
Some(self.encode_inlined_item(
829-
InlinedItemRef::from_item(def_id, item, &tcx.map)
829+
InlinedItemRef::from_item(def_id, item, tcx)
830830
))
831831
}
832832
_ => None,

0 commit comments

Comments
 (0)