Skip to content

rustc: introduce {ast,hir}::AnonConst to consolidate so-called "embedded constants". #50851

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ pub trait Visitor<'v> : Sized {
fn visit_decl(&mut self, d: &'v Decl) {
walk_decl(self, d)
}
fn visit_anon_const(&mut self, c: &'v AnonConst) {
walk_anon_const(self, c)
}
fn visit_expr(&mut self, ex: &'v Expr) {
walk_expr(self, ex)
}
Expand Down Expand Up @@ -547,7 +550,7 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
generics,
parent_item_id,
variant.span);
walk_list!(visitor, visit_nested_body, variant.node.disr_expr);
walk_list!(visitor, visit_anon_const, &variant.node.disr_expr);
walk_list!(visitor, visit_attribute, &variant.node.attrs);
}

Expand Down Expand Up @@ -576,9 +579,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
TyPath(ref qpath) => {
visitor.visit_qpath(qpath, typ.id, typ.span);
}
TyArray(ref ty, length) => {
TyArray(ref ty, ref length) => {
visitor.visit_ty(ty);
visitor.visit_nested_body(length)
visitor.visit_anon_const(length)
}
TyTraitObject(ref bounds, ref lifetime) => {
for bound in bounds {
Expand All @@ -592,8 +595,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
walk_list!(visitor, visit_ty_param_bound, bounds);
walk_list!(visitor, visit_lifetime, lifetimes);
}
TyTypeof(expression) => {
visitor.visit_nested_body(expression)
TyTypeof(ref expression) => {
visitor.visit_anon_const(expression)
}
TyInfer | TyErr => {}
}
Expand Down Expand Up @@ -944,6 +947,11 @@ pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
}
}

pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) {
visitor.visit_id(constant.id);
visitor.visit_nested_body(constant.body);
}

pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor.visit_id(expression.id);
walk_list!(visitor, visit_attribute, expression.attrs.iter());
Expand All @@ -954,9 +962,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
ExprArray(ref subexpressions) => {
walk_list!(visitor, visit_expr, subexpressions);
}
ExprRepeat(ref element, count) => {
ExprRepeat(ref element, ref count) => {
visitor.visit_expr(element);
visitor.visit_nested_body(count)
visitor.visit_anon_const(count)
}
ExprStruct(ref qpath, ref fields, ref optional_base) => {
visitor.visit_qpath(qpath, expression.id, expression.span);
Expand Down
23 changes: 14 additions & 9 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1080,12 +1080,10 @@ impl<'a> LoweringContext<'a> {
}),
)),
TyKind::Array(ref ty, ref length) => {
let length = self.lower_body(None, |this| this.lower_expr(length));
hir::TyArray(self.lower_ty(ty, itctx), length)
hir::TyArray(self.lower_ty(ty, itctx), self.lower_anon_const(length))
}
TyKind::Typeof(ref expr) => {
let expr = self.lower_body(None, |this| this.lower_expr(expr));
hir::TyTypeof(expr)
hir::TyTypeof(self.lower_anon_const(expr))
}
TyKind::TraitObject(ref bounds, kind) => {
let mut lifetime_bound = None;
Expand Down Expand Up @@ -1365,10 +1363,7 @@ impl<'a> LoweringContext<'a> {
name: v.node.ident.name,
attrs: self.lower_attrs(&v.node.attrs),
data: self.lower_variant_data(&v.node.data),
disr_expr: v.node
.disr_expr
.as_ref()
.map(|e| self.lower_body(None, |this| this.lower_expr(e))),
disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
},
span: v.span,
}
Expand Down Expand Up @@ -2927,6 +2922,16 @@ impl<'a> LoweringContext<'a> {
}
}

fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(c.id);

hir::AnonConst {
id: node_id,
hir_id,
body: self.lower_body(None, |this| this.lower_expr(&c.value)),
}
}

fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
let kind = match e.node {
ExprKind::Box(ref inner) => hir::ExprBox(P(self.lower_expr(inner))),
Expand All @@ -2936,7 +2941,7 @@ impl<'a> LoweringContext<'a> {
}
ExprKind::Repeat(ref expr, ref count) => {
let expr = P(self.lower_expr(expr));
let count = self.lower_body(None, |this| this.lower_expr(count));
let count = self.lower_anon_const(count);
hir::ExprRepeat(expr, count)
}
ExprKind::Tup(ref elts) => {
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
NodeImplItem(n) => EntryImplItem(parent, dep_node_index, n),
NodeVariant(n) => EntryVariant(parent, dep_node_index, n),
NodeField(n) => EntryField(parent, dep_node_index, n),
NodeAnonConst(n) => EntryAnonConst(parent, dep_node_index, n),
NodeExpr(n) => EntryExpr(parent, dep_node_index, n),
NodeStmt(n) => EntryStmt(parent, dep_node_index, n),
NodeTy(n) => EntryTy(parent, dep_node_index, n),
Expand Down Expand Up @@ -390,6 +391,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}

fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
self.insert(constant.id, NodeAnonConst(constant));

self.with_parent(constant.id, |this| {
intravisit::walk_anon_const(this, constant);
});
}

fn visit_expr(&mut self, expr: &'hir Expr) {
self.insert(expr.id, NodeExpr(expr));

Expand Down
118 changes: 42 additions & 76 deletions src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ pub struct DefCollector<'a> {
pub struct MacroInvocationData {
pub mark: Mark,
pub def_index: DefIndex,
pub const_expr: bool,
}

impl<'a> DefCollector<'a> {
Expand Down Expand Up @@ -74,25 +73,10 @@ impl<'a> DefCollector<'a> {
self.parent_def = parent;
}

pub fn visit_const_expr(&mut self, expr: &Expr) {
match expr.node {
// Find the node which will be used after lowering.
ExprKind::Paren(ref inner) => return self.visit_const_expr(inner),
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, true),
// FIXME(eddyb) Closures should have separate
// function definition IDs and expression IDs.
ExprKind::Closure(..) => return,
_ => {}
}

self.create_def(expr.id, DefPathData::Initializer, REGULAR_SPACE, expr.span);
}

fn visit_macro_invoc(&mut self, id: NodeId, const_expr: bool) {
fn visit_macro_invoc(&mut self, id: NodeId) {
if let Some(ref mut visit) = self.visit_macro_invoc {
visit(MacroInvocationData {
mark: id.placeholder_to_mark(),
const_expr,
def_index: self.parent_def.unwrap(),
})
}
Expand All @@ -119,7 +103,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
DefPathData::ValueNs(i.ident.name.as_interned_str()),
ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name.as_interned_str()),
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false),
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id),
ItemKind::GlobalAsm(..) => DefPathData::Misc,
ItemKind::Use(..) => {
return visit::walk_item(self, i);
Expand All @@ -129,30 +113,6 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {

self.with_parent(def, |this| {
match i.node {
ItemKind::Enum(ref enum_definition, _) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huzzah 🎉

for v in &enum_definition.variants {
let variant_def_index =
this.create_def(v.node.data.id(),
DefPathData::EnumVariant(v.node.ident
.name.as_interned_str()),
REGULAR_SPACE,
v.span);
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(|| Symbol::intern(&index.to_string()));
this.create_def(field.id,
DefPathData::Field(name.as_interned_str()),
REGULAR_SPACE,
field.span);
}

if let Some(ref expr) = v.node.disr_expr {
this.visit_const_expr(expr);
}
});
}
}
ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
// If this is a tuple-like struct, register the constructor.
if !struct_def.is_struct() {
Expand All @@ -161,15 +121,6 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
REGULAR_SPACE,
i.span);
}

for (index, field) in struct_def.fields().iter().enumerate() {
let name = field.ident.map(|ident| ident.name)
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
this.create_def(field.id,
DefPathData::Field(name.as_interned_str()),
REGULAR_SPACE,
field.span);
}
}
_ => {}
}
Expand All @@ -184,7 +135,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {

fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
if let ForeignItemKind::Macro(_) = foreign_item.node {
return self.visit_macro_invoc(foreign_item.id, false);
return self.visit_macro_invoc(foreign_item.id);
}

let def = self.create_def(foreign_item.id,
Expand All @@ -197,6 +148,28 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
});
}

fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) {
let def = self.create_def(v.node.data.id(),
DefPathData::EnumVariant(v.node.ident
.name.as_interned_str()),
REGULAR_SPACE,
v.span);
self.with_parent(def, |this| visit::walk_variant(this, v, g, item_id));
}

fn visit_variant_data(&mut self, data: &'a VariantData, _: Ident,
_: &'a Generics, _: NodeId, _: Span) {
for (index, field) in data.fields().iter().enumerate() {
let name = field.ident.map(|ident| ident.name)
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
let def = self.create_def(field.id,
DefPathData::Field(name.as_interned_str()),
REGULAR_SPACE,
field.span);
self.with_parent(def, |this| this.visit_struct_field(field));
}
}

fn visit_generic_param(&mut self, param: &'a GenericParam) {
match *param {
GenericParam::Lifetime(ref lifetime_def) => {
Expand Down Expand Up @@ -227,50 +200,45 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
TraitItemKind::Type(..) => {
DefPathData::AssocTypeInTrait(ti.ident.name.as_interned_str())
},
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id),
};

let def = self.create_def(ti.id, def_data, ITEM_LIKE_SPACE, ti.span);
self.with_parent(def, |this| {
if let TraitItemKind::Const(_, Some(ref expr)) = ti.node {
this.visit_const_expr(expr);
}

visit::walk_trait_item(this, ti);
});
self.with_parent(def, |this| visit::walk_trait_item(this, ti));
}

fn visit_impl_item(&mut self, ii: &'a ImplItem) {
let def_data = match ii.node {
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
DefPathData::ValueNs(ii.ident.name.as_interned_str()),
ImplItemKind::Type(..) => DefPathData::AssocTypeInImpl(ii.ident.name.as_interned_str()),
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
};

let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE, ii.span);
self.with_parent(def, |this| {
if let ImplItemKind::Const(_, ref expr) = ii.node {
this.visit_const_expr(expr);
}

visit::walk_impl_item(this, ii);
});
self.with_parent(def, |this| visit::walk_impl_item(this, ii));
}

fn visit_pat(&mut self, pat: &'a Pat) {
match pat.node {
PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false),
PatKind::Mac(..) => return self.visit_macro_invoc(pat.id),
_ => visit::walk_pat(self, pat),
}
}

fn visit_anon_const(&mut self, constant: &'a AnonConst) {
let def = self.create_def(constant.id,
DefPathData::AnonConst,
REGULAR_SPACE,
constant.value.span);
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
}

fn visit_expr(&mut self, expr: &'a Expr) {
let parent_def = self.parent_def;

match expr.node {
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, false),
ExprKind::Repeat(_, ref count) => self.visit_const_expr(count),
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
ExprKind::Closure(..) => {
let def = self.create_def(expr.id,
DefPathData::ClosureExpr,
Expand All @@ -287,20 +255,18 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {

fn visit_ty(&mut self, ty: &'a Ty) {
match ty.node {
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
TyKind::Array(_, ref length) => self.visit_const_expr(length),
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id),
TyKind::ImplTrait(..) => {
self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE, ty.span);
}
TyKind::Typeof(ref expr) => self.visit_const_expr(expr),
_ => {}
}
visit::walk_ty(self, ty);
}

fn visit_stmt(&mut self, stmt: &'a Stmt) {
match stmt.node {
StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id, false),
StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id),
_ => visit::walk_stmt(self, stmt),
}
}
Expand All @@ -310,7 +276,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
match nt.0 {
token::NtExpr(ref expr) => {
if let ExprKind::Mac(..) = expr.node {
self.visit_macro_invoc(expr.id, false);
self.visit_macro_invoc(expr.id);
}
}
_ => {}
Expand Down
Loading