rustc: introduce {ast,hir}::AnonConst to consolidate so-called "embedded constants".
This commit is contained in:
parent
072b0f617f
commit
26aad25487
35 changed files with 334 additions and 306 deletions
|
@ -272,6 +272,9 @@ pub trait Visitor<'v> : Sized {
|
||||||
fn visit_decl(&mut self, d: &'v Decl) {
|
fn visit_decl(&mut self, d: &'v Decl) {
|
||||||
walk_decl(self, d)
|
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) {
|
fn visit_expr(&mut self, ex: &'v Expr) {
|
||||||
walk_expr(self, ex)
|
walk_expr(self, ex)
|
||||||
}
|
}
|
||||||
|
@ -547,7 +550,7 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||||
generics,
|
generics,
|
||||||
parent_item_id,
|
parent_item_id,
|
||||||
variant.span);
|
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);
|
walk_list!(visitor, visit_attribute, &variant.node.attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,9 +579,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
||||||
TyPath(ref qpath) => {
|
TyPath(ref qpath) => {
|
||||||
visitor.visit_qpath(qpath, typ.id, typ.span);
|
visitor.visit_qpath(qpath, typ.id, typ.span);
|
||||||
}
|
}
|
||||||
TyArray(ref ty, length) => {
|
TyArray(ref ty, ref length) => {
|
||||||
visitor.visit_ty(ty);
|
visitor.visit_ty(ty);
|
||||||
visitor.visit_nested_body(length)
|
visitor.visit_anon_const(length)
|
||||||
}
|
}
|
||||||
TyTraitObject(ref bounds, ref lifetime) => {
|
TyTraitObject(ref bounds, ref lifetime) => {
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
|
@ -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_ty_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_lifetime, lifetimes);
|
walk_list!(visitor, visit_lifetime, lifetimes);
|
||||||
}
|
}
|
||||||
TyTypeof(expression) => {
|
TyTypeof(ref expression) => {
|
||||||
visitor.visit_nested_body(expression)
|
visitor.visit_anon_const(expression)
|
||||||
}
|
}
|
||||||
TyInfer | TyErr => {}
|
TyInfer | TyErr => {}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
||||||
visitor.visit_id(expression.id);
|
visitor.visit_id(expression.id);
|
||||||
walk_list!(visitor, visit_attribute, expression.attrs.iter());
|
walk_list!(visitor, visit_attribute, expression.attrs.iter());
|
||||||
|
@ -954,9 +962,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
||||||
ExprArray(ref subexpressions) => {
|
ExprArray(ref subexpressions) => {
|
||||||
walk_list!(visitor, visit_expr, subexpressions);
|
walk_list!(visitor, visit_expr, subexpressions);
|
||||||
}
|
}
|
||||||
ExprRepeat(ref element, count) => {
|
ExprRepeat(ref element, ref count) => {
|
||||||
visitor.visit_expr(element);
|
visitor.visit_expr(element);
|
||||||
visitor.visit_nested_body(count)
|
visitor.visit_anon_const(count)
|
||||||
}
|
}
|
||||||
ExprStruct(ref qpath, ref fields, ref optional_base) => {
|
ExprStruct(ref qpath, ref fields, ref optional_base) => {
|
||||||
visitor.visit_qpath(qpath, expression.id, expression.span);
|
visitor.visit_qpath(qpath, expression.id, expression.span);
|
||||||
|
|
|
@ -1080,12 +1080,10 @@ impl<'a> LoweringContext<'a> {
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
TyKind::Array(ref ty, ref length) => {
|
TyKind::Array(ref ty, ref length) => {
|
||||||
let length = self.lower_body(None, |this| this.lower_expr(length));
|
hir::TyArray(self.lower_ty(ty, itctx), self.lower_anon_const(length))
|
||||||
hir::TyArray(self.lower_ty(ty, itctx), length)
|
|
||||||
}
|
}
|
||||||
TyKind::Typeof(ref expr) => {
|
TyKind::Typeof(ref expr) => {
|
||||||
let expr = self.lower_body(None, |this| this.lower_expr(expr));
|
hir::TyTypeof(self.lower_anon_const(expr))
|
||||||
hir::TyTypeof(expr)
|
|
||||||
}
|
}
|
||||||
TyKind::TraitObject(ref bounds, kind) => {
|
TyKind::TraitObject(ref bounds, kind) => {
|
||||||
let mut lifetime_bound = None;
|
let mut lifetime_bound = None;
|
||||||
|
@ -1365,10 +1363,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
name: v.node.ident.name,
|
name: v.node.ident.name,
|
||||||
attrs: self.lower_attrs(&v.node.attrs),
|
attrs: self.lower_attrs(&v.node.attrs),
|
||||||
data: self.lower_variant_data(&v.node.data),
|
data: self.lower_variant_data(&v.node.data),
|
||||||
disr_expr: v.node
|
disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
|
||||||
.disr_expr
|
|
||||||
.as_ref()
|
|
||||||
.map(|e| self.lower_body(None, |this| this.lower_expr(e))),
|
|
||||||
},
|
},
|
||||||
span: v.span,
|
span: v.span,
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
|
||||||
let kind = match e.node {
|
let kind = match e.node {
|
||||||
ExprKind::Box(ref inner) => hir::ExprBox(P(self.lower_expr(inner))),
|
ExprKind::Box(ref inner) => hir::ExprBox(P(self.lower_expr(inner))),
|
||||||
|
@ -2936,7 +2941,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
}
|
}
|
||||||
ExprKind::Repeat(ref expr, ref count) => {
|
ExprKind::Repeat(ref expr, ref count) => {
|
||||||
let expr = P(self.lower_expr(expr));
|
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)
|
hir::ExprRepeat(expr, count)
|
||||||
}
|
}
|
||||||
ExprKind::Tup(ref elts) => {
|
ExprKind::Tup(ref elts) => {
|
||||||
|
|
|
@ -202,6 +202,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
NodeImplItem(n) => EntryImplItem(parent, dep_node_index, n),
|
NodeImplItem(n) => EntryImplItem(parent, dep_node_index, n),
|
||||||
NodeVariant(n) => EntryVariant(parent, dep_node_index, n),
|
NodeVariant(n) => EntryVariant(parent, dep_node_index, n),
|
||||||
NodeField(n) => EntryField(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),
|
NodeExpr(n) => EntryExpr(parent, dep_node_index, n),
|
||||||
NodeStmt(n) => EntryStmt(parent, dep_node_index, n),
|
NodeStmt(n) => EntryStmt(parent, dep_node_index, n),
|
||||||
NodeTy(n) => EntryTy(parent, dep_node_index, n),
|
NodeTy(n) => EntryTy(parent, dep_node_index, n),
|
||||||
|
@ -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) {
|
fn visit_expr(&mut self, expr: &'hir Expr) {
|
||||||
self.insert(expr.id, NodeExpr(expr));
|
self.insert(expr.id, NodeExpr(expr));
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ pub struct DefCollector<'a> {
|
||||||
pub struct MacroInvocationData {
|
pub struct MacroInvocationData {
|
||||||
pub mark: Mark,
|
pub mark: Mark,
|
||||||
pub def_index: DefIndex,
|
pub def_index: DefIndex,
|
||||||
pub const_expr: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DefCollector<'a> {
|
impl<'a> DefCollector<'a> {
|
||||||
|
@ -74,25 +73,10 @@ impl<'a> DefCollector<'a> {
|
||||||
self.parent_def = parent;
|
self.parent_def = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit_const_expr(&mut self, expr: &Expr) {
|
fn visit_macro_invoc(&mut self, id: NodeId) {
|
||||||
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) {
|
|
||||||
if let Some(ref mut visit) = self.visit_macro_invoc {
|
if let Some(ref mut visit) = self.visit_macro_invoc {
|
||||||
visit(MacroInvocationData {
|
visit(MacroInvocationData {
|
||||||
mark: id.placeholder_to_mark(),
|
mark: id.placeholder_to_mark(),
|
||||||
const_expr,
|
|
||||||
def_index: self.parent_def.unwrap(),
|
def_index: self.parent_def.unwrap(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -119,7 +103,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
|
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
|
||||||
DefPathData::ValueNs(i.ident.name.as_interned_str()),
|
DefPathData::ValueNs(i.ident.name.as_interned_str()),
|
||||||
ItemKind::MacroDef(..) => DefPathData::MacroDef(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::GlobalAsm(..) => DefPathData::Misc,
|
||||||
ItemKind::Use(..) => {
|
ItemKind::Use(..) => {
|
||||||
return visit::walk_item(self, i);
|
return visit::walk_item(self, i);
|
||||||
|
@ -129,30 +113,6 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
|
|
||||||
self.with_parent(def, |this| {
|
self.with_parent(def, |this| {
|
||||||
match i.node {
|
match i.node {
|
||||||
ItemKind::Enum(ref enum_definition, _) => {
|
|
||||||
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, _) => {
|
ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
|
||||||
// If this is a tuple-like struct, register the constructor.
|
// If this is a tuple-like struct, register the constructor.
|
||||||
if !struct_def.is_struct() {
|
if !struct_def.is_struct() {
|
||||||
|
@ -161,15 +121,6 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
REGULAR_SPACE,
|
REGULAR_SPACE,
|
||||||
i.span);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +135,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
|
|
||||||
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
|
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
|
||||||
if let ForeignItemKind::Macro(_) = foreign_item.node {
|
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,
|
let def = self.create_def(foreign_item.id,
|
||||||
|
@ -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) {
|
fn visit_generic_param(&mut self, param: &'a GenericParam) {
|
||||||
match *param {
|
match *param {
|
||||||
GenericParam::Lifetime(ref lifetime_def) => {
|
GenericParam::Lifetime(ref lifetime_def) => {
|
||||||
|
@ -227,7 +200,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
TraitItemKind::Type(..) => {
|
TraitItemKind::Type(..) => {
|
||||||
DefPathData::AssocTypeInTrait(ti.ident.name.as_interned_str())
|
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);
|
let def = self.create_def(ti.id, def_data, ITEM_LIKE_SPACE, ti.span);
|
||||||
|
@ -239,7 +212,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
|
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
|
||||||
DefPathData::ValueNs(ii.ident.name.as_interned_str()),
|
DefPathData::ValueNs(ii.ident.name.as_interned_str()),
|
||||||
ImplItemKind::Type(..) => DefPathData::AssocTypeInImpl(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);
|
let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE, ii.span);
|
||||||
|
@ -248,17 +221,24 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
|
|
||||||
fn visit_pat(&mut self, pat: &'a Pat) {
|
fn visit_pat(&mut self, pat: &'a Pat) {
|
||||||
match pat.node {
|
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),
|
_ => 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) {
|
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||||
let parent_def = self.parent_def;
|
let parent_def = self.parent_def;
|
||||||
|
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, false),
|
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
|
||||||
ExprKind::Repeat(_, ref count) => self.visit_const_expr(count),
|
|
||||||
ExprKind::Closure(..) => {
|
ExprKind::Closure(..) => {
|
||||||
let def = self.create_def(expr.id,
|
let def = self.create_def(expr.id,
|
||||||
DefPathData::ClosureExpr,
|
DefPathData::ClosureExpr,
|
||||||
|
@ -275,12 +255,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||||
match ty.node {
|
match ty.node {
|
||||||
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
|
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id),
|
||||||
TyKind::Array(_, ref length) => self.visit_const_expr(length),
|
|
||||||
TyKind::ImplTrait(..) => {
|
TyKind::ImplTrait(..) => {
|
||||||
self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE, ty.span);
|
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);
|
visit::walk_ty(self, ty);
|
||||||
|
@ -288,7 +266,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
|
|
||||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||||
match stmt.node {
|
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),
|
_ => visit::walk_stmt(self, stmt),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,7 +276,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
match nt.0 {
|
match nt.0 {
|
||||||
token::NtExpr(ref expr) => {
|
token::NtExpr(ref expr) => {
|
||||||
if let ExprKind::Mac(..) = expr.node {
|
if let ExprKind::Mac(..) = expr.node {
|
||||||
self.visit_macro_invoc(expr.id, false);
|
self.visit_macro_invoc(expr.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -231,9 +231,8 @@ impl DefKey {
|
||||||
DefPathData::Misc |
|
DefPathData::Misc |
|
||||||
DefPathData::ClosureExpr |
|
DefPathData::ClosureExpr |
|
||||||
DefPathData::StructCtor |
|
DefPathData::StructCtor |
|
||||||
DefPathData::Initializer |
|
DefPathData::AnonConst |
|
||||||
DefPathData::ImplTrait |
|
DefPathData::ImplTrait => {}
|
||||||
DefPathData::Typeof => {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
disambiguator.hash(&mut hasher);
|
disambiguator.hash(&mut hasher);
|
||||||
|
@ -389,12 +388,10 @@ pub enum DefPathData {
|
||||||
Field(InternedString),
|
Field(InternedString),
|
||||||
/// Implicit ctor for a tuple-like struct
|
/// Implicit ctor for a tuple-like struct
|
||||||
StructCtor,
|
StructCtor,
|
||||||
/// Initializer for a const
|
/// A constant expression (see {ast,hir}::AnonConst).
|
||||||
Initializer,
|
AnonConst,
|
||||||
/// An `impl Trait` type node.
|
/// An `impl Trait` type node.
|
||||||
ImplTrait,
|
ImplTrait,
|
||||||
/// A `typeof` type node.
|
|
||||||
Typeof,
|
|
||||||
|
|
||||||
/// GlobalMetaData identifies a piece of crate metadata that is global to
|
/// GlobalMetaData identifies a piece of crate metadata that is global to
|
||||||
/// a whole crate (as opposed to just one item). GlobalMetaData components
|
/// a whole crate (as opposed to just one item). GlobalMetaData components
|
||||||
|
@ -665,9 +662,8 @@ impl DefPathData {
|
||||||
Misc |
|
Misc |
|
||||||
ClosureExpr |
|
ClosureExpr |
|
||||||
StructCtor |
|
StructCtor |
|
||||||
Initializer |
|
AnonConst |
|
||||||
ImplTrait |
|
ImplTrait => None
|
||||||
Typeof => None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,9 +692,8 @@ impl DefPathData {
|
||||||
Misc => "{{?}}",
|
Misc => "{{?}}",
|
||||||
ClosureExpr => "{{closure}}",
|
ClosureExpr => "{{closure}}",
|
||||||
StructCtor => "{{constructor}}",
|
StructCtor => "{{constructor}}",
|
||||||
Initializer => "{{initializer}}",
|
AnonConst => "{{constant}}",
|
||||||
ImplTrait => "{{impl-Trait}}",
|
ImplTrait => "{{impl-Trait}}",
|
||||||
Typeof => "{{typeof}}",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Symbol::intern(s).as_interned_str()
|
Symbol::intern(s).as_interned_str()
|
||||||
|
|
|
@ -53,6 +53,7 @@ pub enum Node<'hir> {
|
||||||
NodeImplItem(&'hir ImplItem),
|
NodeImplItem(&'hir ImplItem),
|
||||||
NodeVariant(&'hir Variant),
|
NodeVariant(&'hir Variant),
|
||||||
NodeField(&'hir StructField),
|
NodeField(&'hir StructField),
|
||||||
|
NodeAnonConst(&'hir AnonConst),
|
||||||
NodeExpr(&'hir Expr),
|
NodeExpr(&'hir Expr),
|
||||||
NodeStmt(&'hir Stmt),
|
NodeStmt(&'hir Stmt),
|
||||||
NodeTy(&'hir Ty),
|
NodeTy(&'hir Ty),
|
||||||
|
@ -85,6 +86,7 @@ enum MapEntry<'hir> {
|
||||||
EntryImplItem(NodeId, DepNodeIndex, &'hir ImplItem),
|
EntryImplItem(NodeId, DepNodeIndex, &'hir ImplItem),
|
||||||
EntryVariant(NodeId, DepNodeIndex, &'hir Variant),
|
EntryVariant(NodeId, DepNodeIndex, &'hir Variant),
|
||||||
EntryField(NodeId, DepNodeIndex, &'hir StructField),
|
EntryField(NodeId, DepNodeIndex, &'hir StructField),
|
||||||
|
EntryAnonConst(NodeId, DepNodeIndex, &'hir AnonConst),
|
||||||
EntryExpr(NodeId, DepNodeIndex, &'hir Expr),
|
EntryExpr(NodeId, DepNodeIndex, &'hir Expr),
|
||||||
EntryStmt(NodeId, DepNodeIndex, &'hir Stmt),
|
EntryStmt(NodeId, DepNodeIndex, &'hir Stmt),
|
||||||
EntryTy(NodeId, DepNodeIndex, &'hir Ty),
|
EntryTy(NodeId, DepNodeIndex, &'hir Ty),
|
||||||
|
@ -120,6 +122,7 @@ impl<'hir> MapEntry<'hir> {
|
||||||
EntryImplItem(id, _, _) => id,
|
EntryImplItem(id, _, _) => id,
|
||||||
EntryVariant(id, _, _) => id,
|
EntryVariant(id, _, _) => id,
|
||||||
EntryField(id, _, _) => id,
|
EntryField(id, _, _) => id,
|
||||||
|
EntryAnonConst(id, _, _) => id,
|
||||||
EntryExpr(id, _, _) => id,
|
EntryExpr(id, _, _) => id,
|
||||||
EntryStmt(id, _, _) => id,
|
EntryStmt(id, _, _) => id,
|
||||||
EntryTy(id, _, _) => id,
|
EntryTy(id, _, _) => id,
|
||||||
|
@ -147,6 +150,7 @@ impl<'hir> MapEntry<'hir> {
|
||||||
EntryImplItem(_, _, n) => NodeImplItem(n),
|
EntryImplItem(_, _, n) => NodeImplItem(n),
|
||||||
EntryVariant(_, _, n) => NodeVariant(n),
|
EntryVariant(_, _, n) => NodeVariant(n),
|
||||||
EntryField(_, _, n) => NodeField(n),
|
EntryField(_, _, n) => NodeField(n),
|
||||||
|
EntryAnonConst(_, _, n) => NodeAnonConst(n),
|
||||||
EntryExpr(_, _, n) => NodeExpr(n),
|
EntryExpr(_, _, n) => NodeExpr(n),
|
||||||
EntryStmt(_, _, n) => NodeStmt(n),
|
EntryStmt(_, _, n) => NodeStmt(n),
|
||||||
EntryTy(_, _, n) => NodeTy(n),
|
EntryTy(_, _, n) => NodeTy(n),
|
||||||
|
@ -193,6 +197,8 @@ impl<'hir> MapEntry<'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntryAnonConst(_, _, constant) => Some(constant.body),
|
||||||
|
|
||||||
EntryExpr(_, _, expr) => {
|
EntryExpr(_, _, expr) => {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ExprClosure(.., body, _, _) => Some(body),
|
ExprClosure(.., body, _, _) => Some(body),
|
||||||
|
@ -290,6 +296,7 @@ impl<'hir> Map<'hir> {
|
||||||
EntryLifetime(_, dep_node_index, _) |
|
EntryLifetime(_, dep_node_index, _) |
|
||||||
EntryTyParam(_, dep_node_index, _) |
|
EntryTyParam(_, dep_node_index, _) |
|
||||||
EntryVisibility(_, dep_node_index, _) |
|
EntryVisibility(_, dep_node_index, _) |
|
||||||
|
EntryAnonConst(_, dep_node_index, _) |
|
||||||
EntryExpr(_, dep_node_index, _) |
|
EntryExpr(_, dep_node_index, _) |
|
||||||
EntryLocal(_, dep_node_index, _) |
|
EntryLocal(_, dep_node_index, _) |
|
||||||
EntryMacroDef(dep_node_index, _) |
|
EntryMacroDef(dep_node_index, _) |
|
||||||
|
@ -434,6 +441,7 @@ impl<'hir> Map<'hir> {
|
||||||
Some(Def::Variant(def_id))
|
Some(Def::Variant(def_id))
|
||||||
}
|
}
|
||||||
NodeField(_) |
|
NodeField(_) |
|
||||||
|
NodeAnonConst(_) |
|
||||||
NodeExpr(_) |
|
NodeExpr(_) |
|
||||||
NodeStmt(_) |
|
NodeStmt(_) |
|
||||||
NodeTy(_) |
|
NodeTy(_) |
|
||||||
|
@ -495,15 +503,11 @@ impl<'hir> Map<'hir> {
|
||||||
|
|
||||||
/// Returns the `NodeId` that corresponds to the definition of
|
/// Returns the `NodeId` that corresponds to the definition of
|
||||||
/// which this is the body of, i.e. a `fn`, `const` or `static`
|
/// which this is the body of, i.e. a `fn`, `const` or `static`
|
||||||
/// item (possibly associated), or a closure, or the body itself
|
/// item (possibly associated), a closure, or a `hir::AnonConst`.
|
||||||
/// for embedded constant expressions (e.g. `N` in `[T; N]`).
|
|
||||||
pub fn body_owner(&self, BodyId { node_id }: BodyId) -> NodeId {
|
pub fn body_owner(&self, BodyId { node_id }: BodyId) -> NodeId {
|
||||||
let parent = self.get_parent_node(node_id);
|
let parent = self.get_parent_node(node_id);
|
||||||
if self.map[parent.as_usize()].is_body_owner(node_id) {
|
assert!(self.map[parent.as_usize()].is_body_owner(node_id));
|
||||||
parent
|
parent
|
||||||
} else {
|
|
||||||
node_id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body_owner_def_id(&self, id: BodyId) -> DefId {
|
pub fn body_owner_def_id(&self, id: BodyId) -> DefId {
|
||||||
|
@ -520,19 +524,7 @@ impl<'hir> Map<'hir> {
|
||||||
self.dep_graph.read(def_path_hash.to_dep_node(DepKind::HirBody));
|
self.dep_graph.read(def_path_hash.to_dep_node(DepKind::HirBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(body_id) = entry.associated_body() {
|
entry.associated_body()
|
||||||
// For item-like things and closures, the associated
|
|
||||||
// body has its own distinct id, and that is returned
|
|
||||||
// by `associated_body`.
|
|
||||||
Some(body_id)
|
|
||||||
} else {
|
|
||||||
// For some expressions, the expression is its own body.
|
|
||||||
if let EntryExpr(_, _, expr) = entry {
|
|
||||||
Some(BodyId { node_id: expr.id })
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
bug!("no entry for id `{}`", id)
|
bug!("no entry for id `{}`", id)
|
||||||
}
|
}
|
||||||
|
@ -547,17 +539,11 @@ impl<'hir> Map<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body_owner_kind(&self, id: NodeId) -> BodyOwnerKind {
|
pub fn body_owner_kind(&self, id: NodeId) -> BodyOwnerKind {
|
||||||
// Handle constants in enum discriminants, types, and repeat expressions.
|
|
||||||
let def_id = self.local_def_id(id);
|
|
||||||
let def_key = self.def_key(def_id);
|
|
||||||
if def_key.disambiguated_data.data == DefPathData::Initializer {
|
|
||||||
return BodyOwnerKind::Const;
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.get(id) {
|
match self.get(id) {
|
||||||
NodeItem(&Item { node: ItemConst(..), .. }) |
|
NodeItem(&Item { node: ItemConst(..), .. }) |
|
||||||
NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) |
|
NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) |
|
||||||
NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) => {
|
NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) |
|
||||||
|
NodeAnonConst(_) => {
|
||||||
BodyOwnerKind::Const
|
BodyOwnerKind::Const
|
||||||
}
|
}
|
||||||
NodeItem(&Item { node: ItemStatic(_, m, _), .. }) => {
|
NodeItem(&Item { node: ItemStatic(_, m, _), .. }) => {
|
||||||
|
@ -982,6 +968,7 @@ impl<'hir> Map<'hir> {
|
||||||
Some(EntryImplItem(_, _, impl_item)) => impl_item.span,
|
Some(EntryImplItem(_, _, impl_item)) => impl_item.span,
|
||||||
Some(EntryVariant(_, _, variant)) => variant.span,
|
Some(EntryVariant(_, _, variant)) => variant.span,
|
||||||
Some(EntryField(_, _, field)) => field.span,
|
Some(EntryField(_, _, field)) => field.span,
|
||||||
|
Some(EntryAnonConst(_, _, constant)) => self.body(constant.body).value.span,
|
||||||
Some(EntryExpr(_, _, expr)) => expr.span,
|
Some(EntryExpr(_, _, expr)) => expr.span,
|
||||||
Some(EntryStmt(_, _, stmt)) => stmt.span,
|
Some(EntryStmt(_, _, stmt)) => stmt.span,
|
||||||
Some(EntryTy(_, _, ty)) => ty.span,
|
Some(EntryTy(_, _, ty)) => ty.span,
|
||||||
|
@ -1201,6 +1188,7 @@ impl<'a> print::State<'a> {
|
||||||
NodeTraitItem(a) => self.print_trait_item(a),
|
NodeTraitItem(a) => self.print_trait_item(a),
|
||||||
NodeImplItem(a) => self.print_impl_item(a),
|
NodeImplItem(a) => self.print_impl_item(a),
|
||||||
NodeVariant(a) => self.print_variant(&a),
|
NodeVariant(a) => self.print_variant(&a),
|
||||||
|
NodeAnonConst(a) => self.print_anon_const(&a),
|
||||||
NodeExpr(a) => self.print_expr(&a),
|
NodeExpr(a) => self.print_expr(&a),
|
||||||
NodeStmt(a) => self.print_stmt(&a),
|
NodeStmt(a) => self.print_stmt(&a),
|
||||||
NodeTy(a) => self.print_type(&a),
|
NodeTy(a) => self.print_type(&a),
|
||||||
|
@ -1306,6 +1294,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
|
||||||
field.name,
|
field.name,
|
||||||
path_str(), id_str)
|
path_str(), id_str)
|
||||||
}
|
}
|
||||||
|
Some(NodeAnonConst(_)) => {
|
||||||
|
format!("const {}{}", map.node_to_pretty_string(id), id_str)
|
||||||
|
}
|
||||||
Some(NodeExpr(_)) => {
|
Some(NodeExpr(_)) => {
|
||||||
format!("expr {}{}", map.node_to_pretty_string(id), id_str)
|
format!("expr {}{}", map.node_to_pretty_string(id), id_str)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1272,6 +1272,18 @@ pub enum BodyOwnerKind {
|
||||||
Static(Mutability),
|
Static(Mutability),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A constant (expression) that's not an item or associated item,
|
||||||
|
/// but needs its own `DefId` for type-checking, const-eval, etc.
|
||||||
|
/// These are usually found nested inside types (e.g. array lengths)
|
||||||
|
/// or expressions (e.g. repeat counts), and also used to define
|
||||||
|
/// explicit discriminant values for enum variants.
|
||||||
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
|
pub struct AnonConst {
|
||||||
|
pub id: NodeId,
|
||||||
|
pub hir_id: HirId,
|
||||||
|
pub body: BodyId,
|
||||||
|
}
|
||||||
|
|
||||||
/// An expression
|
/// An expression
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
||||||
pub struct Expr {
|
pub struct Expr {
|
||||||
|
@ -1419,7 +1431,7 @@ pub enum Expr_ {
|
||||||
///
|
///
|
||||||
/// For example, `[1; 5]`. The first expression is the element
|
/// For example, `[1; 5]`. The first expression is the element
|
||||||
/// to be repeated; the second is the number of times to repeat it.
|
/// to be repeated; the second is the number of times to repeat it.
|
||||||
ExprRepeat(P<Expr>, BodyId),
|
ExprRepeat(P<Expr>, AnonConst),
|
||||||
|
|
||||||
/// A suspension point for generators. This is `yield <expr>` in Rust.
|
/// A suspension point for generators. This is `yield <expr>` in Rust.
|
||||||
ExprYield(P<Expr>),
|
ExprYield(P<Expr>),
|
||||||
|
@ -1677,7 +1689,7 @@ pub enum Ty_ {
|
||||||
/// A variable length slice (`[T]`)
|
/// A variable length slice (`[T]`)
|
||||||
TySlice(P<Ty>),
|
TySlice(P<Ty>),
|
||||||
/// A fixed length array (`[T; n]`)
|
/// A fixed length array (`[T; n]`)
|
||||||
TyArray(P<Ty>, BodyId),
|
TyArray(P<Ty>, AnonConst),
|
||||||
/// A raw pointer (`*const T` or `*mut T`)
|
/// A raw pointer (`*const T` or `*mut T`)
|
||||||
TyPtr(MutTy),
|
TyPtr(MutTy),
|
||||||
/// A reference (`&'a T` or `&'a mut T`)
|
/// A reference (`&'a T` or `&'a mut T`)
|
||||||
|
@ -1709,7 +1721,7 @@ pub enum Ty_ {
|
||||||
/// so they are resolved directly through the parent `Generics`.
|
/// so they are resolved directly through the parent `Generics`.
|
||||||
TyImplTraitExistential(ExistTy, HirVec<Lifetime>),
|
TyImplTraitExistential(ExistTy, HirVec<Lifetime>),
|
||||||
/// Unused for now
|
/// Unused for now
|
||||||
TyTypeof(BodyId),
|
TyTypeof(AnonConst),
|
||||||
/// TyInfer means the type should be inferred instead of it having been
|
/// TyInfer means the type should be inferred instead of it having been
|
||||||
/// specified. This can appear anywhere in a type.
|
/// specified. This can appear anywhere in a type.
|
||||||
TyInfer,
|
TyInfer,
|
||||||
|
@ -1882,7 +1894,7 @@ pub struct Variant_ {
|
||||||
pub attrs: HirVec<Attribute>,
|
pub attrs: HirVec<Attribute>,
|
||||||
pub data: VariantData,
|
pub data: VariantData,
|
||||||
/// Explicit discriminant, eg `Foo = 1`
|
/// Explicit discriminant, eg `Foo = 1`
|
||||||
pub disr_expr: Option<BodyId>,
|
pub disr_expr: Option<AnonConst>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Variant = Spanned<Variant_>;
|
pub type Variant = Spanned<Variant_>;
|
||||||
|
|
|
@ -416,16 +416,16 @@ impl<'a> State<'a> {
|
||||||
hir::TyImplTraitExistential(ref existty, ref _lifetimes) => {
|
hir::TyImplTraitExistential(ref existty, ref _lifetimes) => {
|
||||||
self.print_bounds("impl", &existty.bounds[..])?;
|
self.print_bounds("impl", &existty.bounds[..])?;
|
||||||
}
|
}
|
||||||
hir::TyArray(ref ty, v) => {
|
hir::TyArray(ref ty, ref length) => {
|
||||||
self.s.word("[")?;
|
self.s.word("[")?;
|
||||||
self.print_type(&ty)?;
|
self.print_type(&ty)?;
|
||||||
self.s.word("; ")?;
|
self.s.word("; ")?;
|
||||||
self.ann.nested(self, Nested::Body(v))?;
|
self.print_anon_const(length)?;
|
||||||
self.s.word("]")?;
|
self.s.word("]")?;
|
||||||
}
|
}
|
||||||
hir::TyTypeof(e) => {
|
hir::TyTypeof(ref e) => {
|
||||||
self.s.word("typeof(")?;
|
self.s.word("typeof(")?;
|
||||||
self.ann.nested(self, Nested::Body(e))?;
|
self.print_anon_const(e)?;
|
||||||
self.s.word(")")?;
|
self.s.word(")")?;
|
||||||
}
|
}
|
||||||
hir::TyInfer => {
|
hir::TyInfer => {
|
||||||
|
@ -871,10 +871,10 @@ impl<'a> State<'a> {
|
||||||
self.head("")?;
|
self.head("")?;
|
||||||
let generics = hir::Generics::empty();
|
let generics = hir::Generics::empty();
|
||||||
self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?;
|
self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?;
|
||||||
if let Some(d) = v.node.disr_expr {
|
if let Some(ref d) = v.node.disr_expr {
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
self.word_space("=")?;
|
self.word_space("=")?;
|
||||||
self.ann.nested(self, Nested::Body(d))?;
|
self.print_anon_const(d)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1091,6 +1091,9 @@ impl<'a> State<'a> {
|
||||||
self.print_else(elseopt)
|
self.print_else(elseopt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_anon_const(&mut self, constant: &hir::AnonConst) -> io::Result<()> {
|
||||||
|
self.ann.nested(self, Nested::Body(constant.body))
|
||||||
|
}
|
||||||
|
|
||||||
fn print_call_post(&mut self, args: &[hir::Expr]) -> io::Result<()> {
|
fn print_call_post(&mut self, args: &[hir::Expr]) -> io::Result<()> {
|
||||||
self.popen()?;
|
self.popen()?;
|
||||||
|
@ -1141,12 +1144,12 @@ impl<'a> State<'a> {
|
||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr_repeat(&mut self, element: &hir::Expr, count: hir::BodyId) -> io::Result<()> {
|
fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::AnonConst) -> io::Result<()> {
|
||||||
self.ibox(indent_unit)?;
|
self.ibox(indent_unit)?;
|
||||||
self.s.word("[")?;
|
self.s.word("[")?;
|
||||||
self.print_expr(element)?;
|
self.print_expr(element)?;
|
||||||
self.word_space(";")?;
|
self.word_space(";")?;
|
||||||
self.ann.nested(self, Nested::Body(count))?;
|
self.print_anon_const(count)?;
|
||||||
self.s.word("]")?;
|
self.s.word("]")?;
|
||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
@ -1288,7 +1291,7 @@ impl<'a> State<'a> {
|
||||||
hir::ExprArray(ref exprs) => {
|
hir::ExprArray(ref exprs) => {
|
||||||
self.print_expr_vec(exprs)?;
|
self.print_expr_vec(exprs)?;
|
||||||
}
|
}
|
||||||
hir::ExprRepeat(ref element, count) => {
|
hir::ExprRepeat(ref element, ref count) => {
|
||||||
self.print_expr_repeat(&element, count)?;
|
self.print_expr_repeat(&element, count)?;
|
||||||
}
|
}
|
||||||
hir::ExprStruct(ref qpath, ref fields, ref wth) => {
|
hir::ExprStruct(ref qpath, ref fields, ref wth) => {
|
||||||
|
|
|
@ -553,6 +553,12 @@ impl_stable_hash_for!(enum hir::UnsafeSource {
|
||||||
UserProvided
|
UserProvided
|
||||||
});
|
});
|
||||||
|
|
||||||
|
impl_stable_hash_for!(struct hir::AnonConst {
|
||||||
|
id,
|
||||||
|
hir_id,
|
||||||
|
body
|
||||||
|
});
|
||||||
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
|
impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
fn hash_stable<W: StableHasherResult>(&self,
|
||||||
hcx: &mut StableHashingContext<'a>,
|
hcx: &mut StableHashingContext<'a>,
|
||||||
|
|
|
@ -214,11 +214,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
data @ DefPathData::LifetimeDef(..) |
|
data @ DefPathData::LifetimeDef(..) |
|
||||||
data @ DefPathData::EnumVariant(..) |
|
data @ DefPathData::EnumVariant(..) |
|
||||||
data @ DefPathData::Field(..) |
|
data @ DefPathData::Field(..) |
|
||||||
data @ DefPathData::Initializer |
|
data @ DefPathData::AnonConst |
|
||||||
data @ DefPathData::MacroDef(..) |
|
data @ DefPathData::MacroDef(..) |
|
||||||
data @ DefPathData::ClosureExpr |
|
data @ DefPathData::ClosureExpr |
|
||||||
data @ DefPathData::ImplTrait |
|
data @ DefPathData::ImplTrait |
|
||||||
data @ DefPathData::Typeof |
|
|
||||||
data @ DefPathData::GlobalMetaData(..) => {
|
data @ DefPathData::GlobalMetaData(..) => {
|
||||||
let parent_def_id = self.parent_def_id(def_id).unwrap();
|
let parent_def_id = self.parent_def_id(def_id).unwrap();
|
||||||
self.push_item_path(buffer, parent_def_id);
|
self.push_item_path(buffer, parent_def_id);
|
||||||
|
|
|
@ -290,9 +290,8 @@ impl PrintContext {
|
||||||
DefPathData::LifetimeDef(_) |
|
DefPathData::LifetimeDef(_) |
|
||||||
DefPathData::Field(_) |
|
DefPathData::Field(_) |
|
||||||
DefPathData::StructCtor |
|
DefPathData::StructCtor |
|
||||||
DefPathData::Initializer |
|
DefPathData::AnonConst |
|
||||||
DefPathData::ImplTrait |
|
DefPathData::ImplTrait |
|
||||||
DefPathData::Typeof |
|
|
||||||
DefPathData::GlobalMetaData(_) => {
|
DefPathData::GlobalMetaData(_) => {
|
||||||
// if we're making a symbol for something, there ought
|
// if we're making a symbol for something, there ought
|
||||||
// to be a value or type-def or something in there
|
// to be a value or type-def or something in there
|
||||||
|
|
|
@ -1359,8 +1359,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_info_for_embedded_const(&mut self, def_id: DefId) -> Entry<'tcx> {
|
fn encode_info_for_anon_const(&mut self, def_id: DefId) -> Entry<'tcx> {
|
||||||
debug!("IsolatedEncoder::encode_info_for_embedded_const({:?})", def_id);
|
debug!("IsolatedEncoder::encode_info_for_anon_const({:?})", def_id);
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
let body_id = tcx.hir.body_owned_by(id);
|
let body_id = tcx.hir.body_owned_by(id);
|
||||||
|
@ -1623,9 +1623,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
|
||||||
id: ast::NodeId) {
|
id: ast::NodeId) {
|
||||||
intravisit::walk_variant(self, v, g, id);
|
intravisit::walk_variant(self, v, g, id);
|
||||||
|
|
||||||
if let Some(discr) = v.node.disr_expr {
|
if let Some(ref discr) = v.node.disr_expr {
|
||||||
let def_id = self.index.tcx.hir.body_owner_def_id(discr);
|
let def_id = self.index.tcx.hir.local_def_id(discr.id);
|
||||||
self.index.record(def_id, IsolatedEncoder::encode_info_for_embedded_const, def_id);
|
self.index.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
||||||
|
@ -1668,9 +1668,9 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||||
let def_id = self.tcx.hir.local_def_id(ty.id);
|
let def_id = self.tcx.hir.local_def_id(ty.id);
|
||||||
self.record(def_id, IsolatedEncoder::encode_info_for_anon_ty, def_id);
|
self.record(def_id, IsolatedEncoder::encode_info_for_anon_ty, def_id);
|
||||||
}
|
}
|
||||||
hir::TyArray(_, len) => {
|
hir::TyArray(_, ref length) => {
|
||||||
let def_id = self.tcx.hir.body_owner_def_id(len);
|
let def_id = self.tcx.hir.local_def_id(length.id);
|
||||||
self.record(def_id, IsolatedEncoder::encode_info_for_embedded_const, def_id);
|
self.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,46 +42,15 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
|
||||||
|
|
||||||
// Figure out what primary body this item has.
|
// Figure out what primary body this item has.
|
||||||
let body_id = match tcx.hir.get(id) {
|
let body_id = match tcx.hir.get(id) {
|
||||||
hir::map::NodeItem(item) => {
|
|
||||||
match item.node {
|
|
||||||
hir::ItemConst(_, body) |
|
|
||||||
hir::ItemStatic(_, _, body) |
|
|
||||||
hir::ItemFn(.., body) => body,
|
|
||||||
_ => unsupported()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::map::NodeTraitItem(item) => {
|
|
||||||
match item.node {
|
|
||||||
hir::TraitItemKind::Const(_, Some(body)) |
|
|
||||||
hir::TraitItemKind::Method(_,
|
|
||||||
hir::TraitMethod::Provided(body)) => body,
|
|
||||||
_ => unsupported()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::map::NodeImplItem(item) => {
|
|
||||||
match item.node {
|
|
||||||
hir::ImplItemKind::Const(_, body) |
|
|
||||||
hir::ImplItemKind::Method(_, body) => body,
|
|
||||||
_ => unsupported()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::map::NodeExpr(expr) => {
|
|
||||||
// FIXME(eddyb) Closures should have separate
|
|
||||||
// function definition IDs and expression IDs.
|
|
||||||
// Type-checking should not let closures get
|
|
||||||
// this far in a constant position.
|
|
||||||
// Assume that everything other than closures
|
|
||||||
// is a constant "initializer" expression.
|
|
||||||
match expr.node {
|
|
||||||
hir::ExprClosure(_, _, body, _, _) => body,
|
|
||||||
_ => hir::BodyId { node_id: expr.id },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::map::NodeVariant(variant) =>
|
hir::map::NodeVariant(variant) =>
|
||||||
return create_constructor_shim(tcx, id, &variant.node.data),
|
return create_constructor_shim(tcx, id, &variant.node.data),
|
||||||
hir::map::NodeStructCtor(ctor) =>
|
hir::map::NodeStructCtor(ctor) =>
|
||||||
return create_constructor_shim(tcx, id, ctor),
|
return create_constructor_shim(tcx, id, ctor),
|
||||||
_ => unsupported(),
|
|
||||||
|
_ => match tcx.hir.maybe_body_owned_by(id) {
|
||||||
|
Some(body) => body,
|
||||||
|
None => unsupported(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
tcx.infer_ctxt().enter(|infcx| {
|
tcx.infer_ctxt().enter(|infcx| {
|
||||||
|
|
|
@ -506,9 +506,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now comes the rote stuff:
|
// Now comes the rote stuff:
|
||||||
hir::ExprRepeat(ref v, count) => {
|
hir::ExprRepeat(ref v, ref count) => {
|
||||||
let c = &cx.tcx.hir.body(count).value;
|
let def_id = cx.tcx.hir.local_def_id(count.id);
|
||||||
let def_id = cx.tcx.hir.body_owner_def_id(count);
|
|
||||||
let substs = Substs::identity_for_item(cx.tcx.global_tcx(), def_id);
|
let substs = Substs::identity_for_item(cx.tcx.global_tcx(), def_id);
|
||||||
let instance = ty::Instance::resolve(
|
let instance = ty::Instance::resolve(
|
||||||
cx.tcx.global_tcx(),
|
cx.tcx.global_tcx(),
|
||||||
|
@ -520,7 +519,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
instance,
|
instance,
|
||||||
promoted: None
|
promoted: None
|
||||||
};
|
};
|
||||||
let count = match cx.tcx.at(c.span).const_eval(cx.param_env.and(global_id)) {
|
let span = cx.tcx.def_span(def_id);
|
||||||
|
let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) {
|
||||||
Ok(cv) => cv.unwrap_usize(cx.tcx),
|
Ok(cv) => cv.unwrap_usize(cx.tcx),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
e.report(cx.tcx, cx.tcx.def_span(def_id), "array length");
|
e.report(cx.tcx, cx.tcx.def_span(def_id), "array length");
|
||||||
|
|
|
@ -802,6 +802,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||||
fn visit_block(&mut self, block: &'tcx Block) {
|
fn visit_block(&mut self, block: &'tcx Block) {
|
||||||
self.resolve_block(block);
|
self.resolve_block(block);
|
||||||
}
|
}
|
||||||
|
fn visit_anon_const(&mut self, constant: &'tcx ast::AnonConst) {
|
||||||
|
self.with_constant_rib(|this| {
|
||||||
|
visit::walk_anon_const(this, constant);
|
||||||
|
});
|
||||||
|
}
|
||||||
fn visit_expr(&mut self, expr: &'tcx Expr) {
|
fn visit_expr(&mut self, expr: &'tcx Expr) {
|
||||||
self.resolve_expr(expr, None);
|
self.resolve_expr(expr, None);
|
||||||
}
|
}
|
||||||
|
@ -819,13 +824,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||||
.map_or(Def::Err, |d| d.def());
|
.map_or(Def::Err, |d| d.def());
|
||||||
self.record_def(ty.id, PathResolution::new(def));
|
self.record_def(ty.id, PathResolution::new(def));
|
||||||
}
|
}
|
||||||
TyKind::Array(ref element, ref length) => {
|
|
||||||
self.visit_ty(element);
|
|
||||||
self.with_constant_rib(|this| {
|
|
||||||
this.visit_expr(length);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
visit::walk_ty(self, ty);
|
visit::walk_ty(self, ty);
|
||||||
|
@ -837,24 +835,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||||
&tref.trait_ref.path, PathSource::Trait(AliasPossibility::Maybe));
|
&tref.trait_ref.path, PathSource::Trait(AliasPossibility::Maybe));
|
||||||
visit::walk_poly_trait_ref(self, tref, m);
|
visit::walk_poly_trait_ref(self, tref, m);
|
||||||
}
|
}
|
||||||
fn visit_variant(&mut self,
|
|
||||||
variant: &'tcx ast::Variant,
|
|
||||||
generics: &'tcx Generics,
|
|
||||||
item_id: ast::NodeId) {
|
|
||||||
if let Some(ref dis_expr) = variant.node.disr_expr {
|
|
||||||
// resolve the discriminator expr as a constant
|
|
||||||
self.with_constant_rib(|this| {
|
|
||||||
this.visit_expr(dis_expr);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// `visit::walk_variant` without the discriminant expression.
|
|
||||||
self.visit_variant_data(&variant.node.data,
|
|
||||||
variant.node.ident,
|
|
||||||
generics,
|
|
||||||
item_id,
|
|
||||||
variant.span);
|
|
||||||
}
|
|
||||||
fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) {
|
fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) {
|
||||||
let type_parameters = match foreign_item.node {
|
let type_parameters = match foreign_item.node {
|
||||||
ForeignItemKind::Fn(_, ref generics) => {
|
ForeignItemKind::Fn(_, ref generics) => {
|
||||||
|
@ -3820,12 +3800,6 @@ impl<'a> Resolver<'a> {
|
||||||
self.visit_path_segment(expr.span, segment);
|
self.visit_path_segment(expr.span, segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprKind::Repeat(ref element, ref count) => {
|
|
||||||
self.visit_expr(element);
|
|
||||||
self.with_constant_rib(|this| {
|
|
||||||
this.visit_expr(count);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ExprKind::Call(ref callee, ref arguments) => {
|
ExprKind::Call(ref callee, ref arguments) => {
|
||||||
self.resolve_expr(callee, Some(expr));
|
self.resolve_expr(callee, Some(expr));
|
||||||
for argument in arguments {
|
for argument in arguments {
|
||||||
|
|
|
@ -45,9 +45,6 @@ use rustc_data_structures::sync::Lrc;
|
||||||
pub struct InvocationData<'a> {
|
pub struct InvocationData<'a> {
|
||||||
pub module: Cell<Module<'a>>,
|
pub module: Cell<Module<'a>>,
|
||||||
pub def_index: DefIndex,
|
pub def_index: DefIndex,
|
||||||
// True if this expansion is in a `const_expr` position, for example `[u32; m!()]`.
|
|
||||||
// c.f. `DefCollector::visit_const_expr`.
|
|
||||||
pub const_expr: bool,
|
|
||||||
// The scope in which the invocation path is resolved.
|
// The scope in which the invocation path is resolved.
|
||||||
pub legacy_scope: Cell<LegacyScope<'a>>,
|
pub legacy_scope: Cell<LegacyScope<'a>>,
|
||||||
// The smallest scope that includes this invocation's expansion,
|
// The smallest scope that includes this invocation's expansion,
|
||||||
|
@ -60,7 +57,6 @@ impl<'a> InvocationData<'a> {
|
||||||
InvocationData {
|
InvocationData {
|
||||||
module: Cell::new(graph_root),
|
module: Cell::new(graph_root),
|
||||||
def_index: CRATE_DEF_INDEX,
|
def_index: CRATE_DEF_INDEX,
|
||||||
const_expr: false,
|
|
||||||
legacy_scope: Cell::new(LegacyScope::Empty),
|
legacy_scope: Cell::new(LegacyScope::Empty),
|
||||||
expansion: Cell::new(LegacyScope::Empty),
|
expansion: Cell::new(LegacyScope::Empty),
|
||||||
}
|
}
|
||||||
|
@ -124,7 +120,6 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
self.invocations.insert(mark, self.arenas.alloc_invocation_data(InvocationData {
|
self.invocations.insert(mark, self.arenas.alloc_invocation_data(InvocationData {
|
||||||
module: Cell::new(module),
|
module: Cell::new(module),
|
||||||
def_index: module.def_id().unwrap().index,
|
def_index: module.def_id().unwrap().index,
|
||||||
const_expr: false,
|
|
||||||
legacy_scope: Cell::new(LegacyScope::Empty),
|
legacy_scope: Cell::new(LegacyScope::Empty),
|
||||||
expansion: Cell::new(LegacyScope::Empty),
|
expansion: Cell::new(LegacyScope::Empty),
|
||||||
}));
|
}));
|
||||||
|
@ -716,13 +711,12 @@ impl<'a> Resolver<'a> {
|
||||||
invocation: &'a InvocationData<'a>,
|
invocation: &'a InvocationData<'a>,
|
||||||
expansion: &Expansion) {
|
expansion: &Expansion) {
|
||||||
let Resolver { ref mut invocations, arenas, graph_root, .. } = *self;
|
let Resolver { ref mut invocations, arenas, graph_root, .. } = *self;
|
||||||
let InvocationData { def_index, const_expr, .. } = *invocation;
|
let InvocationData { def_index, .. } = *invocation;
|
||||||
|
|
||||||
let visit_macro_invoc = &mut |invoc: map::MacroInvocationData| {
|
let visit_macro_invoc = &mut |invoc: map::MacroInvocationData| {
|
||||||
invocations.entry(invoc.mark).or_insert_with(|| {
|
invocations.entry(invoc.mark).or_insert_with(|| {
|
||||||
arenas.alloc_invocation_data(InvocationData {
|
arenas.alloc_invocation_data(InvocationData {
|
||||||
def_index: invoc.def_index,
|
def_index: invoc.def_index,
|
||||||
const_expr: invoc.const_expr,
|
|
||||||
module: Cell::new(graph_root),
|
module: Cell::new(graph_root),
|
||||||
expansion: Cell::new(LegacyScope::Empty),
|
expansion: Cell::new(LegacyScope::Empty),
|
||||||
legacy_scope: Cell::new(LegacyScope::Empty),
|
legacy_scope: Cell::new(LegacyScope::Empty),
|
||||||
|
@ -733,11 +727,6 @@ impl<'a> Resolver<'a> {
|
||||||
let mut def_collector = DefCollector::new(&mut self.definitions, mark);
|
let mut def_collector = DefCollector::new(&mut self.definitions, mark);
|
||||||
def_collector.visit_macro_invoc = Some(visit_macro_invoc);
|
def_collector.visit_macro_invoc = Some(visit_macro_invoc);
|
||||||
def_collector.with_parent(def_index, |def_collector| {
|
def_collector.with_parent(def_index, |def_collector| {
|
||||||
if const_expr {
|
|
||||||
if let Expansion::Expr(ref expr) = *expansion {
|
|
||||||
def_collector.visit_const_expr(expr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expansion.visit_with(def_collector)
|
expansion.visit_with(def_collector)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1516,7 +1516,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
|
||||||
}
|
}
|
||||||
ast::TyKind::Array(ref element, ref length) => {
|
ast::TyKind::Array(ref element, ref length) => {
|
||||||
self.visit_ty(element);
|
self.visit_ty(element);
|
||||||
self.nest_tables(length.id, |v| v.visit_expr(length));
|
self.nest_tables(length.id, |v| v.visit_expr(&length.value));
|
||||||
}
|
}
|
||||||
_ => visit::walk_ty(self, t),
|
_ => visit::walk_ty(self, t),
|
||||||
}
|
}
|
||||||
|
@ -1589,7 +1589,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
|
||||||
}
|
}
|
||||||
ast::ExprKind::Repeat(ref element, ref count) => {
|
ast::ExprKind::Repeat(ref element, ref count) => {
|
||||||
self.visit_expr(element);
|
self.visit_expr(element);
|
||||||
self.nest_tables(count.id, |v| v.visit_expr(count));
|
self.nest_tables(count.id, |v| v.visit_expr(&count.value));
|
||||||
}
|
}
|
||||||
// In particular, we take this branch for call and path expressions,
|
// In particular, we take this branch for call and path expressions,
|
||||||
// where we'll index the idents involved just by continuing to walk.
|
// where we'll index the idents involved just by continuing to walk.
|
||||||
|
|
|
@ -313,7 +313,7 @@ impl Sig for ast::Ty {
|
||||||
}
|
}
|
||||||
ast::TyKind::Array(ref ty, ref v) => {
|
ast::TyKind::Array(ref ty, ref v) => {
|
||||||
let nested_ty = ty.make(offset + 1, id, scx)?;
|
let nested_ty = ty.make(offset + 1, id, scx)?;
|
||||||
let expr = pprust::expr_to_string(v).replace('\n', " ");
|
let expr = pprust::expr_to_string(&v.value).replace('\n', " ");
|
||||||
let text = format!("[{}; {}]", nested_ty.text, expr);
|
let text = format!("[{}; {}]", nested_ty.text, expr);
|
||||||
Ok(replace_text(nested_ty, text))
|
Ok(replace_text(nested_ty, text))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1116,8 +1116,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
};
|
};
|
||||||
self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
|
self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
|
||||||
}
|
}
|
||||||
hir::TyArray(ref ty, length) => {
|
hir::TyArray(ref ty, ref length) => {
|
||||||
let length_def_id = tcx.hir.body_owner_def_id(length);
|
let length_def_id = tcx.hir.local_def_id(length.id);
|
||||||
let substs = Substs::identity_for_item(tcx, length_def_id);
|
let substs = Substs::identity_for_item(tcx, length_def_id);
|
||||||
let length = ty::Const::unevaluated(tcx, length_def_id, substs, tcx.types.usize);
|
let length = ty::Const::unevaluated(tcx, length_def_id, substs, tcx.types.usize);
|
||||||
let array_ty = tcx.mk_ty(ty::TyArray(self.ast_ty_to_ty(&ty), length));
|
let array_ty = tcx.mk_ty(ty::TyArray(self.ast_ty_to_ty(&ty), length));
|
||||||
|
|
|
@ -787,20 +787,7 @@ fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::map::NodeExpr(expr) => {
|
hir::map::NodeAnonConst(constant) => Some((constant.body, None)),
|
||||||
// FIXME(eddyb) Closures should have separate
|
|
||||||
// function definition IDs and expression IDs.
|
|
||||||
// Type-checking should not let closures get
|
|
||||||
// this far in a constant position.
|
|
||||||
// Assume that everything other than closures
|
|
||||||
// is a constant "initializer" expression.
|
|
||||||
match expr.node {
|
|
||||||
hir::ExprClosure(..) =>
|
|
||||||
None,
|
|
||||||
_ =>
|
|
||||||
Some((hir::BodyId { node_id: expr.id }, None)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1674,8 +1661,8 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
for v in vs {
|
for v in vs {
|
||||||
if let Some(e) = v.node.disr_expr {
|
if let Some(ref e) = v.node.disr_expr {
|
||||||
tcx.typeck_tables_of(tcx.hir.local_def_id(e.node_id));
|
tcx.typeck_tables_of(tcx.hir.local_def_id(e.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1686,11 +1673,11 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
|
let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
|
||||||
let variant_i = tcx.hir.expect_variant(variant_i_node_id);
|
let variant_i = tcx.hir.expect_variant(variant_i_node_id);
|
||||||
let i_span = match variant_i.node.disr_expr {
|
let i_span = match variant_i.node.disr_expr {
|
||||||
Some(expr) => tcx.hir.span(expr.node_id),
|
Some(ref expr) => tcx.hir.span(expr.id),
|
||||||
None => tcx.hir.span(variant_i_node_id)
|
None => tcx.hir.span(variant_i_node_id)
|
||||||
};
|
};
|
||||||
let span = match v.node.disr_expr {
|
let span = match v.node.disr_expr {
|
||||||
Some(expr) => tcx.hir.span(expr.node_id),
|
Some(ref expr) => tcx.hir.span(expr.id),
|
||||||
None => v.span
|
None => v.span
|
||||||
};
|
};
|
||||||
struct_span_err!(tcx.sess, span, E0081,
|
struct_span_err!(tcx.sess, span, E0081,
|
||||||
|
@ -3975,8 +3962,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
};
|
};
|
||||||
tcx.mk_array(element_ty, args.len() as u64)
|
tcx.mk_array(element_ty, args.len() as u64)
|
||||||
}
|
}
|
||||||
hir::ExprRepeat(ref element, count) => {
|
hir::ExprRepeat(ref element, ref count) => {
|
||||||
let count_def_id = tcx.hir.body_owner_def_id(count);
|
let count_def_id = tcx.hir.local_def_id(count.id);
|
||||||
let param_env = ty::ParamEnv::empty();
|
let param_env = ty::ParamEnv::empty();
|
||||||
let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
|
let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
|
||||||
let instance = ty::Instance::resolve(
|
let instance = ty::Instance::resolve(
|
||||||
|
|
|
@ -481,8 +481,8 @@ fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
// fill the discriminant values and field types
|
// fill the discriminant values and field types
|
||||||
for variant in variants {
|
for variant in variants {
|
||||||
let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
|
let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
|
||||||
prev_discr = Some(if let Some(e) = variant.node.disr_expr {
|
prev_discr = Some(if let Some(ref e) = variant.node.disr_expr {
|
||||||
let expr_did = tcx.hir.local_def_id(e.node_id);
|
let expr_did = tcx.hir.local_def_id(e.id);
|
||||||
def.eval_explicit_discr(tcx, expr_did)
|
def.eval_explicit_discr(tcx, expr_did)
|
||||||
} else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
|
} else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
|
||||||
Some(discr)
|
Some(discr)
|
||||||
|
@ -565,9 +565,9 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let mut distance_from_explicit = 0;
|
let mut distance_from_explicit = 0;
|
||||||
(AdtKind::Enum, def.variants.iter().map(|v| {
|
(AdtKind::Enum, def.variants.iter().map(|v| {
|
||||||
let did = tcx.hir.local_def_id(v.node.data.id());
|
let did = tcx.hir.local_def_id(v.node.data.id());
|
||||||
let discr = if let Some(e) = v.node.disr_expr {
|
let discr = if let Some(ref e) = v.node.disr_expr {
|
||||||
distance_from_explicit = 0;
|
distance_from_explicit = 0;
|
||||||
ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.node_id))
|
ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.id))
|
||||||
} else {
|
} else {
|
||||||
ty::VariantDiscr::Relative(distance_from_explicit)
|
ty::VariantDiscr::Relative(distance_from_explicit)
|
||||||
};
|
};
|
||||||
|
@ -1102,20 +1102,20 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
tcx.mk_closure(def_id, substs)
|
tcx.mk_closure(def_id, substs)
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
|
NodeAnonConst(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
|
||||||
NodeTy(&hir::Ty { node: TyArray(_, body), .. }) |
|
NodeTy(&hir::Ty { node: TyArray(_, ref constant), .. }) |
|
||||||
NodeTy(&hir::Ty { node: TyTypeof(body), .. }) |
|
NodeTy(&hir::Ty { node: TyTypeof(ref constant), .. }) |
|
||||||
NodeExpr(&hir::Expr { node: ExprRepeat(_, body), .. })
|
NodeExpr(&hir::Expr { node: ExprRepeat(_, ref constant), .. })
|
||||||
if body.node_id == node_id => tcx.types.usize,
|
if constant.id == node_id => tcx.types.usize,
|
||||||
|
|
||||||
NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(e), .. }, .. })
|
NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(ref e), .. }, .. })
|
||||||
if e.node_id == node_id => {
|
if e.id == node_id => {
|
||||||
tcx.adt_def(tcx.hir.get_parent_did(node_id))
|
tcx.adt_def(tcx.hir.get_parent_did(node_id))
|
||||||
.repr.discr_type().to_ty(tcx)
|
.repr.discr_type().to_ty(tcx)
|
||||||
}
|
}
|
||||||
|
|
||||||
x => {
|
x => {
|
||||||
bug!("unexpected expr parent in type_of_def_id(): {:?}", x);
|
bug!("unexpected const parent in type_of_def_id(): {:?}", x);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -2669,19 +2669,19 @@ impl Clean<Type> for hir::Ty {
|
||||||
type_: box m.ty.clean(cx)}
|
type_: box m.ty.clean(cx)}
|
||||||
}
|
}
|
||||||
TySlice(ref ty) => Slice(box ty.clean(cx)),
|
TySlice(ref ty) => Slice(box ty.clean(cx)),
|
||||||
TyArray(ref ty, n) => {
|
TyArray(ref ty, ref length) => {
|
||||||
let def_id = cx.tcx.hir.body_owner_def_id(n);
|
let def_id = cx.tcx.hir.local_def_id(length.id);
|
||||||
let param_env = cx.tcx.param_env(def_id);
|
let param_env = cx.tcx.param_env(def_id);
|
||||||
let substs = Substs::identity_for_item(cx.tcx, def_id);
|
let substs = Substs::identity_for_item(cx.tcx, def_id);
|
||||||
let cid = GlobalId {
|
let cid = GlobalId {
|
||||||
instance: ty::Instance::new(def_id, substs),
|
instance: ty::Instance::new(def_id, substs),
|
||||||
promoted: None
|
promoted: None
|
||||||
};
|
};
|
||||||
let n = cx.tcx.const_eval(param_env.and(cid)).unwrap_or_else(|_| {
|
let length = cx.tcx.const_eval(param_env.and(cid)).unwrap_or_else(|_| {
|
||||||
ty::Const::unevaluated(cx.tcx, def_id, substs, cx.tcx.types.usize)
|
ty::Const::unevaluated(cx.tcx, def_id, substs, cx.tcx.types.usize)
|
||||||
});
|
});
|
||||||
let n = print_const(cx, n);
|
let length = print_const(cx, length);
|
||||||
Array(box ty.clean(cx), n)
|
Array(box ty.clean(cx), length)
|
||||||
},
|
},
|
||||||
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
||||||
TyPath(hir::QPath::Resolved(None, ref path)) => {
|
TyPath(hir::QPath::Resolved(None, ref path)) => {
|
||||||
|
|
|
@ -920,6 +920,18 @@ pub enum UnsafeSource {
|
||||||
UserProvided,
|
UserProvided,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A constant (expression) that's not an item or associated item,
|
||||||
|
/// but needs its own `DefId` for type-checking, const-eval, etc.
|
||||||
|
/// These are usually found nested inside types (e.g. array lengths)
|
||||||
|
/// or expressions (e.g. repeat counts), and also used to define
|
||||||
|
/// explicit discriminant values for enum variants.
|
||||||
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
|
pub struct AnonConst {
|
||||||
|
pub id: NodeId,
|
||||||
|
pub value: P<Expr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// An expression
|
/// An expression
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
|
||||||
pub struct Expr {
|
pub struct Expr {
|
||||||
|
@ -1168,9 +1180,9 @@ pub enum ExprKind {
|
||||||
|
|
||||||
/// An array literal constructed from one repeated element.
|
/// An array literal constructed from one repeated element.
|
||||||
///
|
///
|
||||||
/// For example, `[1; 5]`. The first expression is the element
|
/// For example, `[1; 5]`. The expression is the element to be
|
||||||
/// to be repeated; the second is the number of times to repeat it.
|
/// repeated; the constant is the number of times to repeat it.
|
||||||
Repeat(P<Expr>, P<Expr>),
|
Repeat(P<Expr>, AnonConst),
|
||||||
|
|
||||||
/// No-op: used solely so we can pretty-print faithfully
|
/// No-op: used solely so we can pretty-print faithfully
|
||||||
Paren(P<Expr>),
|
Paren(P<Expr>),
|
||||||
|
@ -1565,7 +1577,7 @@ pub enum TyKind {
|
||||||
/// A variable-length slice (`[T]`)
|
/// A variable-length slice (`[T]`)
|
||||||
Slice(P<Ty>),
|
Slice(P<Ty>),
|
||||||
/// A fixed length array (`[T; n]`)
|
/// A fixed length array (`[T; n]`)
|
||||||
Array(P<Ty>, P<Expr>),
|
Array(P<Ty>, AnonConst),
|
||||||
/// A raw pointer (`*const T` or `*mut T`)
|
/// A raw pointer (`*const T` or `*mut T`)
|
||||||
Ptr(MutTy),
|
Ptr(MutTy),
|
||||||
/// A reference (`&'a T` or `&'a mut T`)
|
/// A reference (`&'a T` or `&'a mut T`)
|
||||||
|
@ -1590,7 +1602,7 @@ pub enum TyKind {
|
||||||
/// No-op; kept solely so that we can pretty-print faithfully
|
/// No-op; kept solely so that we can pretty-print faithfully
|
||||||
Paren(P<Ty>),
|
Paren(P<Ty>),
|
||||||
/// Unused for now
|
/// Unused for now
|
||||||
Typeof(P<Expr>),
|
Typeof(AnonConst),
|
||||||
/// TyKind::Infer means the type should be inferred instead of it having been
|
/// TyKind::Infer means the type should be inferred instead of it having been
|
||||||
/// specified. This can appear anywhere in a type.
|
/// specified. This can appear anywhere in a type.
|
||||||
Infer,
|
Infer,
|
||||||
|
@ -1856,7 +1868,7 @@ pub struct Variant_ {
|
||||||
pub attrs: Vec<Attribute>,
|
pub attrs: Vec<Attribute>,
|
||||||
pub data: VariantData,
|
pub data: VariantData,
|
||||||
/// Explicit discriminant, e.g. `Foo = 1`
|
/// Explicit discriminant, e.g. `Foo = 1`
|
||||||
pub disr_expr: Option<P<Expr>>,
|
pub disr_expr: Option<AnonConst>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Variant = Spanned<Variant_>;
|
pub type Variant = Spanned<Variant_>;
|
||||||
|
|
|
@ -207,7 +207,10 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
|
||||||
span,
|
span,
|
||||||
ast::TyKind::Tup(vec![ty_str.clone(), ty_str])
|
ast::TyKind::Tup(vec![ty_str.clone(), ty_str])
|
||||||
),
|
),
|
||||||
ecx.expr_usize(span, count),
|
ast::AnonConst {
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
value: ecx.expr_usize(span, count),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,10 @@ pub trait Folder : Sized {
|
||||||
noop_fold_pat(p, self)
|
noop_fold_pat(p, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_anon_const(&mut self, c: AnonConst) -> AnonConst {
|
||||||
|
noop_fold_anon_const(c, self)
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
|
fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
|
||||||
e.map(|e| noop_fold_expr(e, self))
|
e.map(|e| noop_fold_expr(e, self))
|
||||||
}
|
}
|
||||||
|
@ -394,11 +398,11 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
|
||||||
});
|
});
|
||||||
TyKind::Path(qself, fld.fold_path(path))
|
TyKind::Path(qself, fld.fold_path(path))
|
||||||
}
|
}
|
||||||
TyKind::Array(ty, e) => {
|
TyKind::Array(ty, length) => {
|
||||||
TyKind::Array(fld.fold_ty(ty), fld.fold_expr(e))
|
TyKind::Array(fld.fold_ty(ty), fld.fold_anon_const(length))
|
||||||
}
|
}
|
||||||
TyKind::Typeof(expr) => {
|
TyKind::Typeof(expr) => {
|
||||||
TyKind::Typeof(fld.fold_expr(expr))
|
TyKind::Typeof(fld.fold_anon_const(expr))
|
||||||
}
|
}
|
||||||
TyKind::TraitObject(bounds, syntax) => {
|
TyKind::TraitObject(bounds, syntax) => {
|
||||||
TyKind::TraitObject(bounds.move_map(|b| fld.fold_ty_param_bound(b)), syntax)
|
TyKind::TraitObject(bounds.move_map(|b| fld.fold_ty_param_bound(b)), syntax)
|
||||||
|
@ -433,7 +437,7 @@ pub fn noop_fold_variant<T: Folder>(v: Variant, fld: &mut T) -> Variant {
|
||||||
ident: fld.fold_ident(v.node.ident),
|
ident: fld.fold_ident(v.node.ident),
|
||||||
attrs: fold_attrs(v.node.attrs, fld),
|
attrs: fold_attrs(v.node.attrs, fld),
|
||||||
data: fld.fold_variant_data(v.node.data),
|
data: fld.fold_variant_data(v.node.data),
|
||||||
disr_expr: v.node.disr_expr.map(|e| fld.fold_expr(e)),
|
disr_expr: v.node.disr_expr.map(|e| fld.fold_anon_const(e)),
|
||||||
},
|
},
|
||||||
span: fld.new_span(v.span),
|
span: fld.new_span(v.span),
|
||||||
}
|
}
|
||||||
|
@ -1170,6 +1174,14 @@ pub fn noop_fold_range_end<T: Folder>(end: RangeEnd, _folder: &mut T) -> RangeEn
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn noop_fold_anon_const<T: Folder>(constant: AnonConst, folder: &mut T) -> AnonConst {
|
||||||
|
let AnonConst {id, value} = constant;
|
||||||
|
AnonConst {
|
||||||
|
id: folder.new_id(id),
|
||||||
|
value: folder.fold_expr(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr {
|
pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr {
|
||||||
Expr {
|
Expr {
|
||||||
node: match node {
|
node: match node {
|
||||||
|
@ -1180,7 +1192,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
|
||||||
ExprKind::Array(folder.fold_exprs(exprs))
|
ExprKind::Array(folder.fold_exprs(exprs))
|
||||||
}
|
}
|
||||||
ExprKind::Repeat(expr, count) => {
|
ExprKind::Repeat(expr, count) => {
|
||||||
ExprKind::Repeat(folder.fold_expr(expr), folder.fold_expr(count))
|
ExprKind::Repeat(folder.fold_expr(expr), folder.fold_anon_const(count))
|
||||||
}
|
}
|
||||||
ExprKind::Tup(exprs) => ExprKind::Tup(folder.fold_exprs(exprs)),
|
ExprKind::Tup(exprs) => ExprKind::Tup(folder.fold_exprs(exprs)),
|
||||||
ExprKind::Call(f, args) => {
|
ExprKind::Call(f, args) => {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_target::spec::abi::{self, Abi};
|
||||||
use ast::{AngleBracketedParameterData, ParenthesizedParameterData, AttrStyle, BareFnTy};
|
use ast::{AngleBracketedParameterData, ParenthesizedParameterData, AttrStyle, BareFnTy};
|
||||||
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||||
use ast::Unsafety;
|
use ast::Unsafety;
|
||||||
use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind};
|
use ast::{Mod, AnonConst, Arg, Arm, Attribute, BindingMode, TraitItemKind};
|
||||||
use ast::Block;
|
use ast::Block;
|
||||||
use ast::{BlockCheckMode, CaptureBy, Movability};
|
use ast::{BlockCheckMode, CaptureBy, Movability};
|
||||||
use ast::{Constness, Crate};
|
use ast::{Constness, Crate};
|
||||||
|
@ -1543,7 +1543,10 @@ impl<'a> Parser<'a> {
|
||||||
// Parse optional `; EXPR` in `[TYPE; EXPR]`
|
// Parse optional `; EXPR` in `[TYPE; EXPR]`
|
||||||
let t = match self.maybe_parse_fixed_length_of_vec()? {
|
let t = match self.maybe_parse_fixed_length_of_vec()? {
|
||||||
None => TyKind::Slice(t),
|
None => TyKind::Slice(t),
|
||||||
Some(suffix) => TyKind::Array(t, suffix),
|
Some(length) => TyKind::Array(t, AnonConst {
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
value: length,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
self.expect(&token::CloseDelim(token::Bracket))?;
|
self.expect(&token::CloseDelim(token::Bracket))?;
|
||||||
t
|
t
|
||||||
|
@ -1555,7 +1558,10 @@ impl<'a> Parser<'a> {
|
||||||
// `typeof(EXPR)`
|
// `typeof(EXPR)`
|
||||||
// In order to not be ambiguous, the type must be surrounded by parens.
|
// In order to not be ambiguous, the type must be surrounded by parens.
|
||||||
self.expect(&token::OpenDelim(token::Paren))?;
|
self.expect(&token::OpenDelim(token::Paren))?;
|
||||||
let e = self.parse_expr()?;
|
let e = AnonConst {
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
value: self.parse_expr()?,
|
||||||
|
};
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
self.expect(&token::CloseDelim(token::Paren))?;
|
||||||
TyKind::Typeof(e)
|
TyKind::Typeof(e)
|
||||||
} else if self.eat_keyword(keywords::Underscore) {
|
} else if self.eat_keyword(keywords::Underscore) {
|
||||||
|
@ -2264,7 +2270,10 @@ impl<'a> Parser<'a> {
|
||||||
if self.check(&token::Semi) {
|
if self.check(&token::Semi) {
|
||||||
// Repeating array syntax: [ 0; 512 ]
|
// Repeating array syntax: [ 0; 512 ]
|
||||||
self.bump();
|
self.bump();
|
||||||
let count = self.parse_expr()?;
|
let count = AnonConst {
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
value: self.parse_expr()?,
|
||||||
|
};
|
||||||
self.expect(&token::CloseDelim(token::Bracket))?;
|
self.expect(&token::CloseDelim(token::Bracket))?;
|
||||||
ex = ExprKind::Repeat(first_expr, count);
|
ex = ExprKind::Repeat(first_expr, count);
|
||||||
} else if self.check(&token::Comma) {
|
} else if self.check(&token::Comma) {
|
||||||
|
@ -6353,8 +6362,11 @@ impl<'a> Parser<'a> {
|
||||||
struct_def = VariantData::Tuple(self.parse_tuple_struct_body()?,
|
struct_def = VariantData::Tuple(self.parse_tuple_struct_body()?,
|
||||||
ast::DUMMY_NODE_ID);
|
ast::DUMMY_NODE_ID);
|
||||||
} else if self.eat(&token::Eq) {
|
} else if self.eat(&token::Eq) {
|
||||||
disr_expr = Some(self.parse_expr()?);
|
disr_expr = Some(AnonConst {
|
||||||
any_disr = disr_expr.as_ref().map(|expr| expr.span);
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
value: self.parse_expr()?,
|
||||||
|
});
|
||||||
|
any_disr = disr_expr.as_ref().map(|c| c.value.span);
|
||||||
struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
|
struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
|
||||||
} else {
|
} else {
|
||||||
struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
|
struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
|
||||||
|
|
|
@ -1076,16 +1076,16 @@ impl<'a> State<'a> {
|
||||||
ast::TyKind::ImplTrait(ref bounds) => {
|
ast::TyKind::ImplTrait(ref bounds) => {
|
||||||
self.print_bounds("impl", &bounds[..])?;
|
self.print_bounds("impl", &bounds[..])?;
|
||||||
}
|
}
|
||||||
ast::TyKind::Array(ref ty, ref v) => {
|
ast::TyKind::Array(ref ty, ref length) => {
|
||||||
self.s.word("[")?;
|
self.s.word("[")?;
|
||||||
self.print_type(ty)?;
|
self.print_type(ty)?;
|
||||||
self.s.word("; ")?;
|
self.s.word("; ")?;
|
||||||
self.print_expr(v)?;
|
self.print_expr(&length.value)?;
|
||||||
self.s.word("]")?;
|
self.s.word("]")?;
|
||||||
}
|
}
|
||||||
ast::TyKind::Typeof(ref e) => {
|
ast::TyKind::Typeof(ref e) => {
|
||||||
self.s.word("typeof(")?;
|
self.s.word("typeof(")?;
|
||||||
self.print_expr(e)?;
|
self.print_expr(&e.value)?;
|
||||||
self.s.word(")")?;
|
self.s.word(")")?;
|
||||||
}
|
}
|
||||||
ast::TyKind::Infer => {
|
ast::TyKind::Infer => {
|
||||||
|
@ -1552,7 +1552,7 @@ impl<'a> State<'a> {
|
||||||
Some(ref d) => {
|
Some(ref d) => {
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
self.word_space("=")?;
|
self.word_space("=")?;
|
||||||
self.print_expr(d)
|
self.print_expr(&d.value)
|
||||||
}
|
}
|
||||||
_ => Ok(())
|
_ => Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1905,14 +1905,14 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
fn print_expr_repeat(&mut self,
|
fn print_expr_repeat(&mut self,
|
||||||
element: &ast::Expr,
|
element: &ast::Expr,
|
||||||
count: &ast::Expr,
|
count: &ast::AnonConst,
|
||||||
attrs: &[Attribute]) -> io::Result<()> {
|
attrs: &[Attribute]) -> io::Result<()> {
|
||||||
self.ibox(INDENT_UNIT)?;
|
self.ibox(INDENT_UNIT)?;
|
||||||
self.s.word("[")?;
|
self.s.word("[")?;
|
||||||
self.print_inner_attributes_inline(attrs)?;
|
self.print_inner_attributes_inline(attrs)?;
|
||||||
self.print_expr(element)?;
|
self.print_expr(element)?;
|
||||||
self.word_space(";")?;
|
self.word_space(";")?;
|
||||||
self.print_expr(count)?;
|
self.print_expr(&count.value)?;
|
||||||
self.s.word("]")?;
|
self.s.word("]")?;
|
||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ pub trait Visitor<'ast>: Sized {
|
||||||
fn visit_stmt(&mut self, s: &'ast Stmt) { walk_stmt(self, s) }
|
fn visit_stmt(&mut self, s: &'ast Stmt) { walk_stmt(self, s) }
|
||||||
fn visit_arm(&mut self, a: &'ast Arm) { walk_arm(self, a) }
|
fn visit_arm(&mut self, a: &'ast Arm) { walk_arm(self, a) }
|
||||||
fn visit_pat(&mut self, p: &'ast Pat) { walk_pat(self, p) }
|
fn visit_pat(&mut self, p: &'ast Pat) { walk_pat(self, p) }
|
||||||
|
fn visit_anon_const(&mut self, c: &'ast AnonConst) { walk_anon_const(self, c) }
|
||||||
fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) }
|
fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) }
|
||||||
fn visit_expr_post(&mut self, _ex: &'ast Expr) { }
|
fn visit_expr_post(&mut self, _ex: &'ast Expr) { }
|
||||||
fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) }
|
fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) }
|
||||||
|
@ -296,7 +297,7 @@ pub fn walk_variant<'a, V>(visitor: &mut V,
|
||||||
visitor.visit_ident(variant.node.ident);
|
visitor.visit_ident(variant.node.ident);
|
||||||
visitor.visit_variant_data(&variant.node.data, variant.node.ident,
|
visitor.visit_variant_data(&variant.node.data, variant.node.ident,
|
||||||
generics, item_id, variant.span);
|
generics, item_id, variant.span);
|
||||||
walk_list!(visitor, visit_expr, &variant.node.disr_expr);
|
walk_list!(visitor, visit_anon_const, &variant.node.disr_expr);
|
||||||
walk_list!(visitor, visit_attribute, &variant.node.attrs);
|
walk_list!(visitor, visit_attribute, &variant.node.attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,16 +327,16 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
|
||||||
}
|
}
|
||||||
visitor.visit_path(path, typ.id);
|
visitor.visit_path(path, typ.id);
|
||||||
}
|
}
|
||||||
TyKind::Array(ref ty, ref expression) => {
|
TyKind::Array(ref ty, ref length) => {
|
||||||
visitor.visit_ty(ty);
|
visitor.visit_ty(ty);
|
||||||
visitor.visit_expr(expression)
|
visitor.visit_anon_const(length)
|
||||||
}
|
}
|
||||||
TyKind::TraitObject(ref bounds, ..) |
|
TyKind::TraitObject(ref bounds, ..) |
|
||||||
TyKind::ImplTrait(ref bounds) => {
|
TyKind::ImplTrait(ref bounds) => {
|
||||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||||
}
|
}
|
||||||
TyKind::Typeof(ref expression) => {
|
TyKind::Typeof(ref expression) => {
|
||||||
visitor.visit_expr(expression)
|
visitor.visit_anon_const(expression)
|
||||||
}
|
}
|
||||||
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
|
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
|
||||||
TyKind::Mac(ref mac) => {
|
TyKind::Mac(ref mac) => {
|
||||||
|
@ -647,6 +648,10 @@ pub fn walk_mac<'a, V: Visitor<'a>>(_: &mut V, _: &Mac) {
|
||||||
// Empty!
|
// Empty!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_anon_const<'a, V: Visitor<'a>>(visitor: &mut V, constant: &'a AnonConst) {
|
||||||
|
visitor.visit_expr(&constant.value);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||||
for attr in expression.attrs.iter() {
|
for attr in expression.attrs.iter() {
|
||||||
visitor.visit_attribute(attr);
|
visitor.visit_attribute(attr);
|
||||||
|
@ -660,7 +665,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||||
}
|
}
|
||||||
ExprKind::Repeat(ref element, ref count) => {
|
ExprKind::Repeat(ref element, ref count) => {
|
||||||
visitor.visit_expr(element);
|
visitor.visit_expr(element);
|
||||||
visitor.visit_expr(count)
|
visitor.visit_anon_const(count)
|
||||||
}
|
}
|
||||||
ExprKind::Struct(ref path, ref fields, ref optional_base) => {
|
ExprKind::Struct(ref path, ref fields, ref optional_base) => {
|
||||||
visitor.visit_path(path, expression.id);
|
visitor.visit_path(path, expression.id);
|
||||||
|
|
15
src/test/compile-fail/issue-48838.rs
Normal file
15
src/test/compile-fail/issue-48838.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
enum Functions {
|
||||||
|
Square = |x| x, //~ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
src/test/compile-fail/issue-50600.rs
Normal file
15
src/test/compile-fail/issue-50600.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct Foo (
|
||||||
|
fn([u8; |x: u8| {}]), //~ ERROR mismatched types
|
||||||
|
);
|
||||||
|
|
||||||
|
fn main() {}
|
13
src/test/compile-fail/issue-50688.rs
Normal file
13
src/test/compile-fail/issue-50688.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
[1; || {}]; //~ ERROR mismatched types
|
||||||
|
}
|
17
src/test/run-pass/issue-50689.rs
Normal file
17
src/test/run-pass/issue-50689.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
enum Foo {
|
||||||
|
Bar = (|x: i32| { }, 42).1,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(Foo::Bar as usize, 42);
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0391]: cycle detected when processing `X::A::{{initializer}}`
|
error[E0391]: cycle detected when processing `X::A::{{constant}}`
|
||||||
--> $DIR/issue-23302-1.rs:14:9
|
--> $DIR/issue-23302-1.rs:14:9
|
||||||
|
|
|
|
||||||
LL | A = X::A as isize, //~ ERROR E0391
|
LL | A = X::A as isize, //~ ERROR E0391
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: ...which again requires processing `X::A::{{initializer}}`, completing the cycle
|
= note: ...which again requires processing `X::A::{{constant}}`, completing the cycle
|
||||||
note: cycle used when const-evaluating `X::A::{{initializer}}`
|
note: cycle used when const-evaluating `X::A::{{constant}}`
|
||||||
--> $DIR/issue-23302-1.rs:14:9
|
--> $DIR/issue-23302-1.rs:14:9
|
||||||
|
|
|
|
||||||
LL | A = X::A as isize, //~ ERROR E0391
|
LL | A = X::A as isize, //~ ERROR E0391
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0391]: cycle detected when processing `Y::A::{{initializer}}`
|
error[E0391]: cycle detected when processing `Y::A::{{constant}}`
|
||||||
--> $DIR/issue-23302-2.rs:14:9
|
--> $DIR/issue-23302-2.rs:14:9
|
||||||
|
|
|
|
||||||
LL | A = Y::B as isize, //~ ERROR E0391
|
LL | A = Y::B as isize, //~ ERROR E0391
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: ...which again requires processing `Y::A::{{initializer}}`, completing the cycle
|
= note: ...which again requires processing `Y::A::{{constant}}`, completing the cycle
|
||||||
note: cycle used when const-evaluating `Y::A::{{initializer}}`
|
note: cycle used when const-evaluating `Y::A::{{constant}}`
|
||||||
--> $DIR/issue-23302-2.rs:14:9
|
--> $DIR/issue-23302-2.rs:14:9
|
||||||
|
|
|
|
||||||
LL | A = Y::B as isize, //~ ERROR E0391
|
LL | A = Y::B as isize, //~ ERROR E0391
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0391]: cycle detected when processing `Foo::B::{{initializer}}`
|
error[E0391]: cycle detected when processing `Foo::B::{{constant}}`
|
||||||
--> $DIR/issue-36163.rs:14:9
|
--> $DIR/issue-36163.rs:14:9
|
||||||
|
|
|
|
||||||
LL | B = A, //~ ERROR E0391
|
LL | B = A, //~ ERROR E0391
|
||||||
|
@ -9,8 +9,8 @@ note: ...which requires processing `A`...
|
||||||
|
|
|
|
||||||
LL | const A: isize = Foo::B as isize;
|
LL | const A: isize = Foo::B as isize;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
= note: ...which again requires processing `Foo::B::{{initializer}}`, completing the cycle
|
= note: ...which again requires processing `Foo::B::{{constant}}`, completing the cycle
|
||||||
note: cycle used when const-evaluating `Foo::B::{{initializer}}`
|
note: cycle used when const-evaluating `Foo::B::{{constant}}`
|
||||||
--> $DIR/issue-36163.rs:14:9
|
--> $DIR/issue-36163.rs:14:9
|
||||||
|
|
|
|
||||||
LL | B = A, //~ ERROR E0391
|
LL | B = A, //~ ERROR E0391
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue