mir: build MIR for constants and static initializers.
This commit is contained in:
parent
cde2f5f116
commit
d434688516
5 changed files with 176 additions and 24 deletions
|
|
@ -97,6 +97,31 @@ impl<'ast> DefCollector<'ast> {
|
|||
f(self);
|
||||
self.parent_def = parent;
|
||||
}
|
||||
|
||||
fn visit_ast_const_integer(&mut self, expr: &'ast Expr) {
|
||||
// Find the node which will be used after lowering.
|
||||
if let ExprKind::Paren(ref inner) = expr.node {
|
||||
return self.visit_ast_const_integer(inner);
|
||||
}
|
||||
|
||||
// FIXME(eddyb) Closures should have separate
|
||||
// function definition IDs and expression IDs.
|
||||
if let ExprKind::Closure(..) = expr.node {
|
||||
return;
|
||||
}
|
||||
|
||||
self.create_def(expr.id, DefPathData::Initializer);
|
||||
}
|
||||
|
||||
fn visit_hir_const_integer(&mut self, expr: &'ast hir::Expr) {
|
||||
// FIXME(eddyb) Closures should have separate
|
||||
// function definition IDs and expression IDs.
|
||||
if let hir::ExprClosure(..) = expr.node {
|
||||
return;
|
||||
}
|
||||
|
||||
self.create_def(expr.id, DefPathData::Initializer);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
||||
|
|
@ -126,14 +151,17 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
let variant_def_index =
|
||||
this.create_def(v.node.data.id(),
|
||||
DefPathData::EnumVariant(v.node.name.name));
|
||||
this.with_parent(variant_def_index, |this| {
|
||||
for (index, field) in v.node.data.fields().iter().enumerate() {
|
||||
let name = field.ident.map(|ident| ident.name)
|
||||
.unwrap_or_else(|| token::intern(&index.to_string()));
|
||||
this.create_def(field.id, DefPathData::Field(name));
|
||||
}
|
||||
|
||||
for (index, field) in v.node.data.fields().iter().enumerate() {
|
||||
let name = field.ident.map(|ident| ident.name)
|
||||
.unwrap_or(token::intern(&index.to_string()));
|
||||
this.create_def_with_parent(Some(variant_def_index),
|
||||
field.id,
|
||||
DefPathData::Field(name));
|
||||
}
|
||||
if let Some(ref expr) = v.node.disr_expr {
|
||||
this.visit_ast_const_integer(expr);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
ItemKind::Struct(ref struct_def, _) => {
|
||||
|
|
@ -221,6 +249,10 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
fn visit_expr(&mut self, expr: &'ast Expr) {
|
||||
let parent_def = self.parent_def;
|
||||
|
||||
if let ExprKind::Repeat(_, ref count) = expr.node {
|
||||
self.visit_ast_const_integer(count);
|
||||
}
|
||||
|
||||
if let ExprKind::Closure(..) = expr.node {
|
||||
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
|
||||
self.parent_def = Some(def);
|
||||
|
|
@ -230,6 +262,13 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
self.parent_def = parent_def;
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'ast Ty) {
|
||||
if let TyKind::FixedLengthVec(_, ref length) = ty.node {
|
||||
self.visit_ast_const_integer(length);
|
||||
}
|
||||
visit::walk_ty(self, ty);
|
||||
}
|
||||
|
||||
fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) {
|
||||
self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name));
|
||||
}
|
||||
|
|
@ -276,11 +315,15 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
|
|||
this.create_def(v.node.data.id(),
|
||||
DefPathData::EnumVariant(v.node.name));
|
||||
|
||||
for field in v.node.data.fields() {
|
||||
this.create_def_with_parent(Some(variant_def_index),
|
||||
field.id,
|
||||
DefPathData::Field(field.name));
|
||||
}
|
||||
this.with_parent(variant_def_index, |this| {
|
||||
for field in v.node.data.fields() {
|
||||
this.create_def(field.id,
|
||||
DefPathData::Field(field.name));
|
||||
}
|
||||
if let Some(ref expr) = v.node.disr_expr {
|
||||
this.visit_hir_const_integer(expr);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
hir::ItemStruct(ref struct_def, _) => {
|
||||
|
|
@ -365,6 +408,10 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
|
|||
fn visit_expr(&mut self, expr: &'ast hir::Expr) {
|
||||
let parent_def = self.parent_def;
|
||||
|
||||
if let hir::ExprRepeat(_, ref count) = expr.node {
|
||||
self.visit_hir_const_integer(count);
|
||||
}
|
||||
|
||||
if let hir::ExprClosure(..) = expr.node {
|
||||
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
|
||||
self.parent_def = Some(def);
|
||||
|
|
@ -374,6 +421,13 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
|
|||
self.parent_def = parent_def;
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'ast hir::Ty) {
|
||||
if let hir::TyFixedLengthVec(_, ref length) = ty.node {
|
||||
self.visit_hir_const_integer(length);
|
||||
}
|
||||
intravisit::walk_ty(self, ty);
|
||||
}
|
||||
|
||||
fn visit_lifetime_def(&mut self, def: &'ast hir::LifetimeDef) {
|
||||
self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name));
|
||||
}
|
||||
|
|
@ -381,4 +435,4 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
|
|||
fn visit_macro_def(&mut self, macro_def: &'ast hir::MacroDef) {
|
||||
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use middle::cstore::{self, LOCAL_CRATE};
|
|||
use hir::def::{self, Def, ExportMap};
|
||||
use hir::def_id::DefId;
|
||||
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
|
||||
use middle::region::{CodeExtent};
|
||||
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
|
||||
use traits;
|
||||
use ty;
|
||||
use ty::subst::{Subst, Substs, VecPerParamSpace};
|
||||
|
|
@ -1376,6 +1376,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
|
|||
}
|
||||
hir::ItemEnum(..) |
|
||||
hir::ItemStruct(..) |
|
||||
hir::ItemTy(..) |
|
||||
hir::ItemImpl(..) |
|
||||
hir::ItemConst(..) |
|
||||
hir::ItemStatic(..) => {
|
||||
|
|
@ -1408,6 +1409,15 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
|
|||
// This is a convenience to allow closures to work.
|
||||
ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
|
||||
}
|
||||
Some(ast_map::NodeForeignItem(item)) => {
|
||||
let def_id = cx.map.local_def_id(id);
|
||||
let scheme = cx.lookup_item_type(def_id);
|
||||
let predicates = cx.lookup_predicates(def_id);
|
||||
cx.construct_parameter_environment(item.span,
|
||||
&scheme.generics,
|
||||
&predicates,
|
||||
ROOT_CODE_EXTENT)
|
||||
}
|
||||
_ => {
|
||||
bug!("ParameterEnvironment::from_item(): \
|
||||
`{}` is not an item",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue