rustc: introduce {ast,hir}::AnonConst to consolidate so-called "embedded constants".
This commit is contained in:
parent
072b0f617f
commit
26aad25487
|
@ -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)
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 => {}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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))),
|
||||
|
@ -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) => {
|
||||
|
|
|
@ -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),
|
||||
|
@ -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));
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
@ -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(),
|
||||
})
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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, _) => {
|
||||
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() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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) => {
|
||||
|
@ -227,7 +200,7 @@ 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);
|
||||
|
@ -239,7 +212,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||
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);
|
||||
|
@ -248,17 +221,24 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||
|
||||
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,
|
||||
|
@ -275,12 +255,10 @@ 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);
|
||||
|
@ -288,7 +266,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
@ -298,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);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -231,9 +231,8 @@ impl DefKey {
|
|||
DefPathData::Misc |
|
||||
DefPathData::ClosureExpr |
|
||||
DefPathData::StructCtor |
|
||||
DefPathData::Initializer |
|
||||
DefPathData::ImplTrait |
|
||||
DefPathData::Typeof => {}
|
||||
DefPathData::AnonConst |
|
||||
DefPathData::ImplTrait => {}
|
||||
};
|
||||
|
||||
disambiguator.hash(&mut hasher);
|
||||
|
@ -389,12 +388,10 @@ pub enum DefPathData {
|
|||
Field(InternedString),
|
||||
/// Implicit ctor for a tuple-like struct
|
||||
StructCtor,
|
||||
/// Initializer for a const
|
||||
Initializer,
|
||||
/// A constant expression (see {ast,hir}::AnonConst).
|
||||
AnonConst,
|
||||
/// An `impl Trait` type node.
|
||||
ImplTrait,
|
||||
/// A `typeof` type node.
|
||||
Typeof,
|
||||
|
||||
/// GlobalMetaData identifies a piece of crate metadata that is global to
|
||||
/// a whole crate (as opposed to just one item). GlobalMetaData components
|
||||
|
@ -665,9 +662,8 @@ impl DefPathData {
|
|||
Misc |
|
||||
ClosureExpr |
|
||||
StructCtor |
|
||||
Initializer |
|
||||
ImplTrait |
|
||||
Typeof => None
|
||||
AnonConst |
|
||||
ImplTrait => None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -696,9 +692,8 @@ impl DefPathData {
|
|||
Misc => "{{?}}",
|
||||
ClosureExpr => "{{closure}}",
|
||||
StructCtor => "{{constructor}}",
|
||||
Initializer => "{{initializer}}",
|
||||
AnonConst => "{{constant}}",
|
||||
ImplTrait => "{{impl-Trait}}",
|
||||
Typeof => "{{typeof}}",
|
||||
};
|
||||
|
||||
Symbol::intern(s).as_interned_str()
|
||||
|
|
|
@ -53,6 +53,7 @@ pub enum Node<'hir> {
|
|||
NodeImplItem(&'hir ImplItem),
|
||||
NodeVariant(&'hir Variant),
|
||||
NodeField(&'hir StructField),
|
||||
NodeAnonConst(&'hir AnonConst),
|
||||
NodeExpr(&'hir Expr),
|
||||
NodeStmt(&'hir Stmt),
|
||||
NodeTy(&'hir Ty),
|
||||
|
@ -85,6 +86,7 @@ enum MapEntry<'hir> {
|
|||
EntryImplItem(NodeId, DepNodeIndex, &'hir ImplItem),
|
||||
EntryVariant(NodeId, DepNodeIndex, &'hir Variant),
|
||||
EntryField(NodeId, DepNodeIndex, &'hir StructField),
|
||||
EntryAnonConst(NodeId, DepNodeIndex, &'hir AnonConst),
|
||||
EntryExpr(NodeId, DepNodeIndex, &'hir Expr),
|
||||
EntryStmt(NodeId, DepNodeIndex, &'hir Stmt),
|
||||
EntryTy(NodeId, DepNodeIndex, &'hir Ty),
|
||||
|
@ -120,6 +122,7 @@ impl<'hir> MapEntry<'hir> {
|
|||
EntryImplItem(id, _, _) => id,
|
||||
EntryVariant(id, _, _) => id,
|
||||
EntryField(id, _, _) => id,
|
||||
EntryAnonConst(id, _, _) => id,
|
||||
EntryExpr(id, _, _) => id,
|
||||
EntryStmt(id, _, _) => id,
|
||||
EntryTy(id, _, _) => id,
|
||||
|
@ -147,6 +150,7 @@ impl<'hir> MapEntry<'hir> {
|
|||
EntryImplItem(_, _, n) => NodeImplItem(n),
|
||||
EntryVariant(_, _, n) => NodeVariant(n),
|
||||
EntryField(_, _, n) => NodeField(n),
|
||||
EntryAnonConst(_, _, n) => NodeAnonConst(n),
|
||||
EntryExpr(_, _, n) => NodeExpr(n),
|
||||
EntryStmt(_, _, n) => NodeStmt(n),
|
||||
EntryTy(_, _, n) => NodeTy(n),
|
||||
|
@ -193,6 +197,8 @@ impl<'hir> MapEntry<'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
EntryAnonConst(_, _, constant) => Some(constant.body),
|
||||
|
||||
EntryExpr(_, _, expr) => {
|
||||
match expr.node {
|
||||
ExprClosure(.., body, _, _) => Some(body),
|
||||
|
@ -290,6 +296,7 @@ impl<'hir> Map<'hir> {
|
|||
EntryLifetime(_, dep_node_index, _) |
|
||||
EntryTyParam(_, dep_node_index, _) |
|
||||
EntryVisibility(_, dep_node_index, _) |
|
||||
EntryAnonConst(_, dep_node_index, _) |
|
||||
EntryExpr(_, dep_node_index, _) |
|
||||
EntryLocal(_, dep_node_index, _) |
|
||||
EntryMacroDef(dep_node_index, _) |
|
||||
|
@ -434,6 +441,7 @@ impl<'hir> Map<'hir> {
|
|||
Some(Def::Variant(def_id))
|
||||
}
|
||||
NodeField(_) |
|
||||
NodeAnonConst(_) |
|
||||
NodeExpr(_) |
|
||||
NodeStmt(_) |
|
||||
NodeTy(_) |
|
||||
|
@ -495,15 +503,11 @@ impl<'hir> Map<'hir> {
|
|||
|
||||
/// Returns the `NodeId` that corresponds to the definition of
|
||||
/// which this is the body of, i.e. a `fn`, `const` or `static`
|
||||
/// item (possibly associated), or a closure, or the body itself
|
||||
/// for embedded constant expressions (e.g. `N` in `[T; N]`).
|
||||
/// item (possibly associated), a closure, or a `hir::AnonConst`.
|
||||
pub fn body_owner(&self, BodyId { node_id }: BodyId) -> NodeId {
|
||||
let parent = self.get_parent_node(node_id);
|
||||
if self.map[parent.as_usize()].is_body_owner(node_id) {
|
||||
parent
|
||||
} else {
|
||||
node_id
|
||||
}
|
||||
assert!(self.map[parent.as_usize()].is_body_owner(node_id));
|
||||
parent
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
if let Some(body_id) = 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
|
||||
}
|
||||
}
|
||||
entry.associated_body()
|
||||
} else {
|
||||
bug!("no entry for id `{}`", id)
|
||||
}
|
||||
|
@ -547,17 +539,11 @@ impl<'hir> Map<'hir> {
|
|||
}
|
||||
|
||||
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) {
|
||||
NodeItem(&Item { node: ItemConst(..), .. }) |
|
||||
NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) |
|
||||
NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) => {
|
||||
NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) |
|
||||
NodeAnonConst(_) => {
|
||||
BodyOwnerKind::Const
|
||||
}
|
||||
NodeItem(&Item { node: ItemStatic(_, m, _), .. }) => {
|
||||
|
@ -982,6 +968,7 @@ impl<'hir> Map<'hir> {
|
|||
Some(EntryImplItem(_, _, impl_item)) => impl_item.span,
|
||||
Some(EntryVariant(_, _, variant)) => variant.span,
|
||||
Some(EntryField(_, _, field)) => field.span,
|
||||
Some(EntryAnonConst(_, _, constant)) => self.body(constant.body).value.span,
|
||||
Some(EntryExpr(_, _, expr)) => expr.span,
|
||||
Some(EntryStmt(_, _, stmt)) => stmt.span,
|
||||
Some(EntryTy(_, _, ty)) => ty.span,
|
||||
|
@ -1201,6 +1188,7 @@ impl<'a> print::State<'a> {
|
|||
NodeTraitItem(a) => self.print_trait_item(a),
|
||||
NodeImplItem(a) => self.print_impl_item(a),
|
||||
NodeVariant(a) => self.print_variant(&a),
|
||||
NodeAnonConst(a) => self.print_anon_const(&a),
|
||||
NodeExpr(a) => self.print_expr(&a),
|
||||
NodeStmt(a) => self.print_stmt(&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,
|
||||
path_str(), id_str)
|
||||
}
|
||||
Some(NodeAnonConst(_)) => {
|
||||
format!("const {}{}", map.node_to_pretty_string(id), id_str)
|
||||
}
|
||||
Some(NodeExpr(_)) => {
|
||||
format!("expr {}{}", map.node_to_pretty_string(id), id_str)
|
||||
}
|
||||
|
|
|
@ -1272,6 +1272,18 @@ pub enum BodyOwnerKind {
|
|||
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
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
||||
pub struct Expr {
|
||||
|
@ -1419,7 +1431,7 @@ pub enum Expr_ {
|
|||
///
|
||||
/// For example, `[1; 5]`. The first expression is the element
|
||||
/// 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.
|
||||
ExprYield(P<Expr>),
|
||||
|
@ -1677,7 +1689,7 @@ pub enum Ty_ {
|
|||
/// A variable length slice (`[T]`)
|
||||
TySlice(P<Ty>),
|
||||
/// A fixed length array (`[T; n]`)
|
||||
TyArray(P<Ty>, BodyId),
|
||||
TyArray(P<Ty>, AnonConst),
|
||||
/// A raw pointer (`*const T` or `*mut T`)
|
||||
TyPtr(MutTy),
|
||||
/// A reference (`&'a T` or `&'a mut T`)
|
||||
|
@ -1709,7 +1721,7 @@ pub enum Ty_ {
|
|||
/// so they are resolved directly through the parent `Generics`.
|
||||
TyImplTraitExistential(ExistTy, HirVec<Lifetime>),
|
||||
/// Unused for now
|
||||
TyTypeof(BodyId),
|
||||
TyTypeof(AnonConst),
|
||||
/// TyInfer means the type should be inferred instead of it having been
|
||||
/// specified. This can appear anywhere in a type.
|
||||
TyInfer,
|
||||
|
@ -1882,7 +1894,7 @@ pub struct Variant_ {
|
|||
pub attrs: HirVec<Attribute>,
|
||||
pub data: VariantData,
|
||||
/// Explicit discriminant, eg `Foo = 1`
|
||||
pub disr_expr: Option<BodyId>,
|
||||
pub disr_expr: Option<AnonConst>,
|
||||
}
|
||||
|
||||
pub type Variant = Spanned<Variant_>;
|
||||
|
|
|
@ -416,16 +416,16 @@ impl<'a> State<'a> {
|
|||
hir::TyImplTraitExistential(ref existty, ref _lifetimes) => {
|
||||
self.print_bounds("impl", &existty.bounds[..])?;
|
||||
}
|
||||
hir::TyArray(ref ty, v) => {
|
||||
hir::TyArray(ref ty, ref length) => {
|
||||
self.s.word("[")?;
|
||||
self.print_type(&ty)?;
|
||||
self.s.word("; ")?;
|
||||
self.ann.nested(self, Nested::Body(v))?;
|
||||
self.print_anon_const(length)?;
|
||||
self.s.word("]")?;
|
||||
}
|
||||
hir::TyTypeof(e) => {
|
||||
hir::TyTypeof(ref e) => {
|
||||
self.s.word("typeof(")?;
|
||||
self.ann.nested(self, Nested::Body(e))?;
|
||||
self.print_anon_const(e)?;
|
||||
self.s.word(")")?;
|
||||
}
|
||||
hir::TyInfer => {
|
||||
|
@ -871,10 +871,10 @@ impl<'a> State<'a> {
|
|||
self.head("")?;
|
||||
let generics = hir::Generics::empty();
|
||||
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.word_space("=")?;
|
||||
self.ann.nested(self, Nested::Body(d))?;
|
||||
self.print_anon_const(d)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1091,6 +1091,9 @@ impl<'a> State<'a> {
|
|||
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<()> {
|
||||
self.popen()?;
|
||||
|
@ -1141,12 +1144,12 @@ impl<'a> State<'a> {
|
|||
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.s.word("[")?;
|
||||
self.print_expr(element)?;
|
||||
self.word_space(";")?;
|
||||
self.ann.nested(self, Nested::Body(count))?;
|
||||
self.print_anon_const(count)?;
|
||||
self.s.word("]")?;
|
||||
self.end()
|
||||
}
|
||||
|
@ -1288,7 +1291,7 @@ impl<'a> State<'a> {
|
|||
hir::ExprArray(ref exprs) => {
|
||||
self.print_expr_vec(exprs)?;
|
||||
}
|
||||
hir::ExprRepeat(ref element, count) => {
|
||||
hir::ExprRepeat(ref element, ref count) => {
|
||||
self.print_expr_repeat(&element, count)?;
|
||||
}
|
||||
hir::ExprStruct(ref qpath, ref fields, ref wth) => {
|
||||
|
|
|
@ -553,6 +553,12 @@ impl_stable_hash_for!(enum hir::UnsafeSource {
|
|||
UserProvided
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct hir::AnonConst {
|
||||
id,
|
||||
hir_id,
|
||||
body
|
||||
});
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
|
|
|
@ -214,11 +214,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
data @ DefPathData::LifetimeDef(..) |
|
||||
data @ DefPathData::EnumVariant(..) |
|
||||
data @ DefPathData::Field(..) |
|
||||
data @ DefPathData::Initializer |
|
||||
data @ DefPathData::AnonConst |
|
||||
data @ DefPathData::MacroDef(..) |
|
||||
data @ DefPathData::ClosureExpr |
|
||||
data @ DefPathData::ImplTrait |
|
||||
data @ DefPathData::Typeof |
|
||||
data @ DefPathData::GlobalMetaData(..) => {
|
||||
let parent_def_id = self.parent_def_id(def_id).unwrap();
|
||||
self.push_item_path(buffer, parent_def_id);
|
||||
|
|
|
@ -290,9 +290,8 @@ impl PrintContext {
|
|||
DefPathData::LifetimeDef(_) |
|
||||
DefPathData::Field(_) |
|
||||
DefPathData::StructCtor |
|
||||
DefPathData::Initializer |
|
||||
DefPathData::AnonConst |
|
||||
DefPathData::ImplTrait |
|
||||
DefPathData::Typeof |
|
||||
DefPathData::GlobalMetaData(_) => {
|
||||
// if we're making a symbol for something, there ought
|
||||
// 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> {
|
||||
debug!("IsolatedEncoder::encode_info_for_embedded_const({:?})", def_id);
|
||||
fn encode_info_for_anon_const(&mut self, def_id: DefId) -> Entry<'tcx> {
|
||||
debug!("IsolatedEncoder::encode_info_for_anon_const({:?})", def_id);
|
||||
let tcx = self.tcx;
|
||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
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) {
|
||||
intravisit::walk_variant(self, v, g, id);
|
||||
|
||||
if let Some(discr) = v.node.disr_expr {
|
||||
let def_id = self.index.tcx.hir.body_owner_def_id(discr);
|
||||
self.index.record(def_id, IsolatedEncoder::encode_info_for_embedded_const, def_id);
|
||||
if let Some(ref discr) = v.node.disr_expr {
|
||||
let def_id = self.index.tcx.hir.local_def_id(discr.id);
|
||||
self.index.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id);
|
||||
}
|
||||
}
|
||||
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);
|
||||
self.record(def_id, IsolatedEncoder::encode_info_for_anon_ty, def_id);
|
||||
}
|
||||
hir::TyArray(_, len) => {
|
||||
let def_id = self.tcx.hir.body_owner_def_id(len);
|
||||
self.record(def_id, IsolatedEncoder::encode_info_for_embedded_const, def_id);
|
||||
hir::TyArray(_, ref length) => {
|
||||
let def_id = self.tcx.hir.local_def_id(length.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.
|
||||
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) =>
|
||||
return create_constructor_shim(tcx, id, &variant.node.data),
|
||||
hir::map::NodeStructCtor(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| {
|
||||
|
|
|
@ -506,9 +506,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
}
|
||||
|
||||
// Now comes the rote stuff:
|
||||
hir::ExprRepeat(ref v, count) => {
|
||||
let c = &cx.tcx.hir.body(count).value;
|
||||
let def_id = cx.tcx.hir.body_owner_def_id(count);
|
||||
hir::ExprRepeat(ref v, ref count) => {
|
||||
let def_id = cx.tcx.hir.local_def_id(count.id);
|
||||
let substs = Substs::identity_for_item(cx.tcx.global_tcx(), def_id);
|
||||
let instance = ty::Instance::resolve(
|
||||
cx.tcx.global_tcx(),
|
||||
|
@ -520,7 +519,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
instance,
|
||||
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),
|
||||
Err(e) => {
|
||||
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) {
|
||||
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) {
|
||||
self.resolve_expr(expr, None);
|
||||
}
|
||||
|
@ -819,13 +824,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
|||
.map_or(Def::Err, |d| d.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);
|
||||
|
@ -837,24 +835,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
|||
&tref.trait_ref.path, PathSource::Trait(AliasPossibility::Maybe));
|
||||
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) {
|
||||
let type_parameters = match foreign_item.node {
|
||||
ForeignItemKind::Fn(_, ref generics) => {
|
||||
|
@ -3820,12 +3800,6 @@ impl<'a> Resolver<'a> {
|
|||
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) => {
|
||||
self.resolve_expr(callee, Some(expr));
|
||||
for argument in arguments {
|
||||
|
|
|
@ -45,9 +45,6 @@ use rustc_data_structures::sync::Lrc;
|
|||
pub struct InvocationData<'a> {
|
||||
pub module: Cell<Module<'a>>,
|
||||
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.
|
||||
pub legacy_scope: Cell<LegacyScope<'a>>,
|
||||
// The smallest scope that includes this invocation's expansion,
|
||||
|
@ -60,7 +57,6 @@ impl<'a> InvocationData<'a> {
|
|||
InvocationData {
|
||||
module: Cell::new(graph_root),
|
||||
def_index: CRATE_DEF_INDEX,
|
||||
const_expr: false,
|
||||
legacy_scope: 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 {
|
||||
module: Cell::new(module),
|
||||
def_index: module.def_id().unwrap().index,
|
||||
const_expr: false,
|
||||
legacy_scope: Cell::new(LegacyScope::Empty),
|
||||
expansion: Cell::new(LegacyScope::Empty),
|
||||
}));
|
||||
|
@ -716,13 +711,12 @@ impl<'a> Resolver<'a> {
|
|||
invocation: &'a InvocationData<'a>,
|
||||
expansion: &Expansion) {
|
||||
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| {
|
||||
invocations.entry(invoc.mark).or_insert_with(|| {
|
||||
arenas.alloc_invocation_data(InvocationData {
|
||||
def_index: invoc.def_index,
|
||||
const_expr: invoc.const_expr,
|
||||
module: Cell::new(graph_root),
|
||||
expansion: 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);
|
||||
def_collector.visit_macro_invoc = Some(visit_macro_invoc);
|
||||
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)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
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),
|
||||
}
|
||||
|
@ -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) => {
|
||||
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,
|
||||
// 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) => {
|
||||
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);
|
||||
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
|
||||
}
|
||||
hir::TyArray(ref ty, length) => {
|
||||
let length_def_id = tcx.hir.body_owner_def_id(length);
|
||||
hir::TyArray(ref ty, ref length) => {
|
||||
let length_def_id = tcx.hir.local_def_id(length.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 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,
|
||||
}
|
||||
}
|
||||
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(..) =>
|
||||
None,
|
||||
_ =>
|
||||
Some((hir::BodyId { node_id: expr.id }, None)),
|
||||
}
|
||||
}
|
||||
hir::map::NodeAnonConst(constant) => Some((constant.body, None)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1674,8 +1661,8 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
|
||||
for v in vs {
|
||||
if let Some(e) = v.node.disr_expr {
|
||||
tcx.typeck_tables_of(tcx.hir.local_def_id(e.node_id));
|
||||
if let Some(ref e) = v.node.disr_expr {
|
||||
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 = tcx.hir.expect_variant(variant_i_node_id);
|
||||
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)
|
||||
};
|
||||
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
|
||||
};
|
||||
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)
|
||||
}
|
||||
hir::ExprRepeat(ref element, count) => {
|
||||
let count_def_id = tcx.hir.body_owner_def_id(count);
|
||||
hir::ExprRepeat(ref element, ref count) => {
|
||||
let count_def_id = tcx.hir.local_def_id(count.id);
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
|
||||
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
|
||||
for variant in variants {
|
||||
let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
|
||||
prev_discr = Some(if let Some(e) = variant.node.disr_expr {
|
||||
let expr_did = tcx.hir.local_def_id(e.node_id);
|
||||
prev_discr = Some(if let Some(ref e) = variant.node.disr_expr {
|
||||
let expr_did = tcx.hir.local_def_id(e.id);
|
||||
def.eval_explicit_discr(tcx, expr_did)
|
||||
} else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
|
||||
Some(discr)
|
||||
|
@ -565,9 +565,9 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let mut distance_from_explicit = 0;
|
||||
(AdtKind::Enum, def.variants.iter().map(|v| {
|
||||
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;
|
||||
ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.node_id))
|
||||
ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.id))
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
|
||||
NodeExpr(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
|
||||
NodeTy(&hir::Ty { node: TyArray(_, body), .. }) |
|
||||
NodeTy(&hir::Ty { node: TyTypeof(body), .. }) |
|
||||
NodeExpr(&hir::Expr { node: ExprRepeat(_, body), .. })
|
||||
if body.node_id == node_id => tcx.types.usize,
|
||||
NodeAnonConst(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
|
||||
NodeTy(&hir::Ty { node: TyArray(_, ref constant), .. }) |
|
||||
NodeTy(&hir::Ty { node: TyTypeof(ref constant), .. }) |
|
||||
NodeExpr(&hir::Expr { node: ExprRepeat(_, ref constant), .. })
|
||||
if constant.id == node_id => tcx.types.usize,
|
||||
|
||||
NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(e), .. }, .. })
|
||||
if e.node_id == node_id => {
|
||||
NodeVariant(&Spanned { node: Variant_ { disr_expr: Some(ref e), .. }, .. })
|
||||
if e.id == node_id => {
|
||||
tcx.adt_def(tcx.hir.get_parent_did(node_id))
|
||||
.repr.discr_type().to_ty(tcx)
|
||||
}
|
||||
|
||||
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)}
|
||||
}
|
||||
TySlice(ref ty) => Slice(box ty.clean(cx)),
|
||||
TyArray(ref ty, n) => {
|
||||
let def_id = cx.tcx.hir.body_owner_def_id(n);
|
||||
TyArray(ref ty, ref length) => {
|
||||
let def_id = cx.tcx.hir.local_def_id(length.id);
|
||||
let param_env = cx.tcx.param_env(def_id);
|
||||
let substs = Substs::identity_for_item(cx.tcx, def_id);
|
||||
let cid = GlobalId {
|
||||
instance: ty::Instance::new(def_id, substs),
|
||||
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)
|
||||
});
|
||||
let n = print_const(cx, n);
|
||||
Array(box ty.clean(cx), n)
|
||||
let length = print_const(cx, length);
|
||||
Array(box ty.clean(cx), length)
|
||||
},
|
||||
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
||||
TyPath(hir::QPath::Resolved(None, ref path)) => {
|
||||
|
|
|
@ -920,6 +920,18 @@ pub enum UnsafeSource {
|
|||
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
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
|
||||
pub struct Expr {
|
||||
|
@ -1168,9 +1180,9 @@ pub enum ExprKind {
|
|||
|
||||
/// An array literal constructed from one repeated element.
|
||||
///
|
||||
/// For example, `[1; 5]`. The first expression is the element
|
||||
/// to be repeated; the second is the number of times to repeat it.
|
||||
Repeat(P<Expr>, P<Expr>),
|
||||
/// For example, `[1; 5]`. The expression is the element to be
|
||||
/// repeated; the constant is the number of times to repeat it.
|
||||
Repeat(P<Expr>, AnonConst),
|
||||
|
||||
/// No-op: used solely so we can pretty-print faithfully
|
||||
Paren(P<Expr>),
|
||||
|
@ -1565,7 +1577,7 @@ pub enum TyKind {
|
|||
/// A variable-length slice (`[T]`)
|
||||
Slice(P<Ty>),
|
||||
/// A fixed length array (`[T; n]`)
|
||||
Array(P<Ty>, P<Expr>),
|
||||
Array(P<Ty>, AnonConst),
|
||||
/// A raw pointer (`*const T` or `*mut T`)
|
||||
Ptr(MutTy),
|
||||
/// 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
|
||||
Paren(P<Ty>),
|
||||
/// Unused for now
|
||||
Typeof(P<Expr>),
|
||||
Typeof(AnonConst),
|
||||
/// TyKind::Infer means the type should be inferred instead of it having been
|
||||
/// specified. This can appear anywhere in a type.
|
||||
Infer,
|
||||
|
@ -1856,7 +1868,7 @@ pub struct Variant_ {
|
|||
pub attrs: Vec<Attribute>,
|
||||
pub data: VariantData,
|
||||
/// Explicit discriminant, e.g. `Foo = 1`
|
||||
pub disr_expr: Option<P<Expr>>,
|
||||
pub disr_expr: Option<AnonConst>,
|
||||
}
|
||||
|
||||
pub type Variant = Spanned<Variant_>;
|
||||
|
|
|
@ -207,7 +207,10 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
|
|||
span,
|
||||
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)
|
||||
}
|
||||
|
||||
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> {
|
||||
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::Array(ty, e) => {
|
||||
TyKind::Array(fld.fold_ty(ty), fld.fold_expr(e))
|
||||
TyKind::Array(ty, length) => {
|
||||
TyKind::Array(fld.fold_ty(ty), fld.fold_anon_const(length))
|
||||
}
|
||||
TyKind::Typeof(expr) => {
|
||||
TyKind::Typeof(fld.fold_expr(expr))
|
||||
TyKind::Typeof(fld.fold_anon_const(expr))
|
||||
}
|
||||
TyKind::TraitObject(bounds, 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),
|
||||
attrs: fold_attrs(v.node.attrs, fld),
|
||||
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),
|
||||
}
|
||||
|
@ -1170,6 +1174,14 @@ pub fn noop_fold_range_end<T: Folder>(end: RangeEnd, _folder: &mut T) -> RangeEn
|
|||
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 {
|
||||
Expr {
|
||||
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::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::Call(f, args) => {
|
||||
|
|
|
@ -12,7 +12,7 @@ use rustc_target::spec::abi::{self, Abi};
|
|||
use ast::{AngleBracketedParameterData, ParenthesizedParameterData, AttrStyle, BareFnTy};
|
||||
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
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::{BlockCheckMode, CaptureBy, Movability};
|
||||
use ast::{Constness, Crate};
|
||||
|
@ -1543,7 +1543,10 @@ impl<'a> Parser<'a> {
|
|||
// Parse optional `; EXPR` in `[TYPE; EXPR]`
|
||||
let t = match self.maybe_parse_fixed_length_of_vec()? {
|
||||
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))?;
|
||||
t
|
||||
|
@ -1555,7 +1558,10 @@ impl<'a> Parser<'a> {
|
|||
// `typeof(EXPR)`
|
||||
// In order to not be ambiguous, the type must be surrounded by parens.
|
||||
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))?;
|
||||
TyKind::Typeof(e)
|
||||
} else if self.eat_keyword(keywords::Underscore) {
|
||||
|
@ -2264,7 +2270,10 @@ impl<'a> Parser<'a> {
|
|||
if self.check(&token::Semi) {
|
||||
// Repeating array syntax: [ 0; 512 ]
|
||||
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))?;
|
||||
ex = ExprKind::Repeat(first_expr, count);
|
||||
} else if self.check(&token::Comma) {
|
||||
|
@ -6353,8 +6362,11 @@ impl<'a> Parser<'a> {
|
|||
struct_def = VariantData::Tuple(self.parse_tuple_struct_body()?,
|
||||
ast::DUMMY_NODE_ID);
|
||||
} else if self.eat(&token::Eq) {
|
||||
disr_expr = Some(self.parse_expr()?);
|
||||
any_disr = disr_expr.as_ref().map(|expr| expr.span);
|
||||
disr_expr = Some(AnonConst {
|
||||
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);
|
||||
} else {
|
||||
struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
|
||||
|
|
|
@ -1076,16 +1076,16 @@ impl<'a> State<'a> {
|
|||
ast::TyKind::ImplTrait(ref bounds) => {
|
||||
self.print_bounds("impl", &bounds[..])?;
|
||||
}
|
||||
ast::TyKind::Array(ref ty, ref v) => {
|
||||
ast::TyKind::Array(ref ty, ref length) => {
|
||||
self.s.word("[")?;
|
||||
self.print_type(ty)?;
|
||||
self.s.word("; ")?;
|
||||
self.print_expr(v)?;
|
||||
self.print_expr(&length.value)?;
|
||||
self.s.word("]")?;
|
||||
}
|
||||
ast::TyKind::Typeof(ref e) => {
|
||||
self.s.word("typeof(")?;
|
||||
self.print_expr(e)?;
|
||||
self.print_expr(&e.value)?;
|
||||
self.s.word(")")?;
|
||||
}
|
||||
ast::TyKind::Infer => {
|
||||
|
@ -1552,7 +1552,7 @@ impl<'a> State<'a> {
|
|||
Some(ref d) => {
|
||||
self.s.space()?;
|
||||
self.word_space("=")?;
|
||||
self.print_expr(d)
|
||||
self.print_expr(&d.value)
|
||||
}
|
||||
_ => Ok(())
|
||||
}
|
||||
|
@ -1905,14 +1905,14 @@ impl<'a> State<'a> {
|
|||
|
||||
fn print_expr_repeat(&mut self,
|
||||
element: &ast::Expr,
|
||||
count: &ast::Expr,
|
||||
count: &ast::AnonConst,
|
||||
attrs: &[Attribute]) -> io::Result<()> {
|
||||
self.ibox(INDENT_UNIT)?;
|
||||
self.s.word("[")?;
|
||||
self.print_inner_attributes_inline(attrs)?;
|
||||
self.print_expr(element)?;
|
||||
self.word_space(";")?;
|
||||
self.print_expr(count)?;
|
||||
self.print_expr(&count.value)?;
|
||||
self.s.word("]")?;
|
||||
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_arm(&mut self, a: &'ast Arm) { walk_arm(self, a) }
|
||||
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_post(&mut self, _ex: &'ast Expr) { }
|
||||
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_variant_data(&variant.node.data, variant.node.ident,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -326,16 +327,16 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
|
|||
}
|
||||
visitor.visit_path(path, typ.id);
|
||||
}
|
||||
TyKind::Array(ref ty, ref expression) => {
|
||||
TyKind::Array(ref ty, ref length) => {
|
||||
visitor.visit_ty(ty);
|
||||
visitor.visit_expr(expression)
|
||||
visitor.visit_anon_const(length)
|
||||
}
|
||||
TyKind::TraitObject(ref bounds, ..) |
|
||||
TyKind::ImplTrait(ref bounds) => {
|
||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||
}
|
||||
TyKind::Typeof(ref expression) => {
|
||||
visitor.visit_expr(expression)
|
||||
visitor.visit_anon_const(expression)
|
||||
}
|
||||
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
|
||||
TyKind::Mac(ref mac) => {
|
||||
|
@ -647,6 +648,10 @@ pub fn walk_mac<'a, V: Visitor<'a>>(_: &mut V, _: &Mac) {
|
|||
// 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) {
|
||||
for attr in expression.attrs.iter() {
|
||||
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) => {
|
||||
visitor.visit_expr(element);
|
||||
visitor.visit_expr(count)
|
||||
visitor.visit_anon_const(count)
|
||||
}
|
||||
ExprKind::Struct(ref path, ref fields, ref optional_base) => {
|
||||
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
|
||||
|
|
||||
LL | A = X::A as isize, //~ ERROR E0391
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: ...which again requires processing `X::A::{{initializer}}`, completing the cycle
|
||||
note: cycle used when const-evaluating `X::A::{{initializer}}`
|
||||
= note: ...which again requires processing `X::A::{{constant}}`, completing the cycle
|
||||
note: cycle used when const-evaluating `X::A::{{constant}}`
|
||||
--> $DIR/issue-23302-1.rs:14:9
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | A = Y::B as isize, //~ ERROR E0391
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: ...which again requires processing `Y::A::{{initializer}}`, completing the cycle
|
||||
note: cycle used when const-evaluating `Y::A::{{initializer}}`
|
||||
= note: ...which again requires processing `Y::A::{{constant}}`, completing the cycle
|
||||
note: cycle used when const-evaluating `Y::A::{{constant}}`
|
||||
--> $DIR/issue-23302-2.rs:14:9
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | B = A, //~ ERROR E0391
|
||||
|
@ -9,8 +9,8 @@ note: ...which requires processing `A`...
|
|||
|
|
||||
LL | const A: isize = Foo::B as isize;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= note: ...which again requires processing `Foo::B::{{initializer}}`, completing the cycle
|
||||
note: cycle used when const-evaluating `Foo::B::{{initializer}}`
|
||||
= note: ...which again requires processing `Foo::B::{{constant}}`, completing the cycle
|
||||
note: cycle used when const-evaluating `Foo::B::{{constant}}`
|
||||
--> $DIR/issue-36163.rs:14:9
|
||||
|
|
||||
LL | B = A, //~ ERROR E0391
|
||||
|
|
Loading…
Reference in a new issue