From 072b0f617fdd2ccb3bc6dd08718acf9504b7ed3a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 17 May 2018 21:30:15 +0300 Subject: [PATCH 1/2] rustc: removed unused `DefPathData::Initializer` DefId's for associated constants. --- src/librustc/hir/map/def_collector.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index ebd8e6235825c..810fa04fac445 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -231,13 +231,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { }; let def = self.create_def(ti.id, def_data, ITEM_LIKE_SPACE, ti.span); - self.with_parent(def, |this| { - if let TraitItemKind::Const(_, Some(ref expr)) = ti.node { - this.visit_const_expr(expr); - } - - visit::walk_trait_item(this, ti); - }); + self.with_parent(def, |this| visit::walk_trait_item(this, ti)); } fn visit_impl_item(&mut self, ii: &'a ImplItem) { @@ -249,13 +243,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { }; let def = self.create_def(ii.id, def_data, ITEM_LIKE_SPACE, ii.span); - self.with_parent(def, |this| { - if let ImplItemKind::Const(_, ref expr) = ii.node { - this.visit_const_expr(expr); - } - - visit::walk_impl_item(this, ii); - }); + self.with_parent(def, |this| visit::walk_impl_item(this, ii)); } fn visit_pat(&mut self, pat: &'a Pat) { From 26aad254875464ff352a4e18d16f668b5bd9b7cb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 17 May 2018 21:28:50 +0300 Subject: [PATCH 2/2] rustc: introduce {ast,hir}::AnonConst to consolidate so-called "embedded constants". --- src/librustc/hir/intravisit.rs | 22 +++-- src/librustc/hir/lowering.rs | 23 +++-- src/librustc/hir/map/collector.rs | 9 ++ src/librustc/hir/map/def_collector.rs | 102 ++++++++------------- src/librustc/hir/map/definitions.rs | 19 ++-- src/librustc/hir/map/mod.rs | 47 ++++------ src/librustc/hir/mod.rs | 20 +++- src/librustc/hir/print.rs | 21 +++-- src/librustc/ich/impls_hir.rs | 6 ++ src/librustc/ty/item_path.rs | 3 +- src/librustc/util/ppaux.rs | 3 +- src/librustc_metadata/encoder.rs | 16 ++-- src/librustc_mir/build/mod.rs | 41 +-------- src/librustc_mir/hair/cx/expr.rs | 8 +- src/librustc_resolve/lib.rs | 36 +------- src/librustc_resolve/macros.rs | 13 +-- src/librustc_save_analysis/dump_visitor.rs | 4 +- src/librustc_save_analysis/sig.rs | 2 +- src/librustc_typeck/astconv.rs | 4 +- src/librustc_typeck/check/mod.rs | 27 ++---- src/librustc_typeck/collect.rs | 24 ++--- src/librustdoc/clean/mod.rs | 10 +- src/libsyntax/ast.rs | 24 +++-- src/libsyntax/diagnostics/plugin.rs | 5 +- src/libsyntax/fold.rs | 22 ++++- src/libsyntax/parse/parser.rs | 24 +++-- src/libsyntax/print/pprust.rs | 12 +-- src/libsyntax/visit.rs | 15 ++- src/test/compile-fail/issue-48838.rs | 15 +++ src/test/compile-fail/issue-50600.rs | 15 +++ src/test/compile-fail/issue-50688.rs | 13 +++ src/test/run-pass/issue-50689.rs | 17 ++++ src/test/ui/issue-23302-1.stderr | 6 +- src/test/ui/issue-23302-2.stderr | 6 +- src/test/ui/issue-36163.stderr | 6 +- 35 files changed, 334 insertions(+), 306 deletions(-) create mode 100644 src/test/compile-fail/issue-48838.rs create mode 100644 src/test/compile-fail/issue-50600.rs create mode 100644 src/test/compile-fail/issue-50688.rs create mode 100644 src/test/run-pass/issue-50689.rs diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 59b058e98611c..2ef022cecdf49 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -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); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 45d429612a1db..02c2aa1c71ba0 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -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) => { diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 38de8548f30d1..8f28dfab1e772 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -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)); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 810fa04fac445..03b6dc1676fb3 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -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); } } _ => {} diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 616dc22486d92..e380a7bfbfebe 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -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() diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index a9613a60a57c0..951bb6ad1501b 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -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) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index edd5e668d5e67..caae79961a6d1 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -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, BodyId), + ExprRepeat(P, AnonConst), /// A suspension point for generators. This is `yield ` in Rust. ExprYield(P), @@ -1677,7 +1689,7 @@ pub enum Ty_ { /// A variable length slice (`[T]`) TySlice(P), /// A fixed length array (`[T; n]`) - TyArray(P, BodyId), + TyArray(P, 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), /// 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, pub data: VariantData, /// Explicit discriminant, eg `Foo = 1` - pub disr_expr: Option, + pub disr_expr: Option, } pub type Variant = Spanned; diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 940a68e8ce5ca..8173ec48045c3 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -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) => { diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 30f725a6b50af..21c1af919de9a 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -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> for hir::Expr { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 41625afec86a0..93d78210b1ad0 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -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); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index c66dd79cbf5e4..b8345b6c2d9a3 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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 diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d00f4f32c109f..a8836694933e2 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -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); } _ => {} } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 3bbf73ec8b5e2..2da2d3f697f2e 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -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| { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 97a4e0f37249f..0d93634981f56 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -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"); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e13e6bc6b7456..a8ac940765daa 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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 { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 0fc963a136712..296d1a5828a26 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -45,9 +45,6 @@ use rustc_data_structures::sync::Lrc; pub struct InvocationData<'a> { pub module: Cell>, 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>, // 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) }); } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 2ef294fe43089..279ee403cc625 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -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. diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 829ed320d753b..e3545e8f1a9b8 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -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)) } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c1868467503f8..e6ccbd61bd58e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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)); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 39de09fe34f40..1088ec1b2acb9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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( diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 157f3ab76ca0c..4d691de2037ca 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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); } }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6beb64dced16e..ae53b9ded4eee 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2669,19 +2669,19 @@ impl Clean 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)) => { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1817726d6a110..0ce9763ded8bf 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -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, +} + + /// 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, P), + /// For example, `[1; 5]`. The expression is the element to be + /// repeated; the constant is the number of times to repeat it. + Repeat(P, AnonConst), /// No-op: used solely so we can pretty-print faithfully Paren(P), @@ -1565,7 +1577,7 @@ pub enum TyKind { /// A variable-length slice (`[T]`) Slice(P), /// A fixed length array (`[T; n]`) - Array(P, P), + Array(P, 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), /// Unused for now - Typeof(P), + 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, pub data: VariantData, /// Explicit discriminant, e.g. `Foo = 1` - pub disr_expr: Option>, + pub disr_expr: Option, } pub type Variant = Spanned; diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index aecf32ab6afb7..6c3117b963fed 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -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), + }, ), ); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 29cc208c06b1a..28fb95f165fde 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -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) -> P { e.map(|e| noop_fold_expr(e, self)) } @@ -394,11 +398,11 @@ pub fn noop_fold_ty(t: P, fld: &mut T) -> P { }); 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(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(end: RangeEnd, _folder: &mut T) -> RangeEn end } +pub fn noop_fold_anon_const(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(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr { Expr { node: match node { @@ -1180,7 +1192,7 @@ pub fn noop_fold_expr(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) => { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7b91c49170068..aca23581d95e3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 17f83a09c77b7..be3408ce56599 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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() } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 2013e838c05cc..b6eb649daa24d 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -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); diff --git a/src/test/compile-fail/issue-48838.rs b/src/test/compile-fail/issue-48838.rs new file mode 100644 index 0000000000000..ab52a32869f21 --- /dev/null +++ b/src/test/compile-fail/issue-48838.rs @@ -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 or the MIT license +// , 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() {} diff --git a/src/test/compile-fail/issue-50600.rs b/src/test/compile-fail/issue-50600.rs new file mode 100644 index 0000000000000..6169a7770bfc4 --- /dev/null +++ b/src/test/compile-fail/issue-50600.rs @@ -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 or the MIT license +// , 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() {} diff --git a/src/test/compile-fail/issue-50688.rs b/src/test/compile-fail/issue-50688.rs new file mode 100644 index 0000000000000..ff45cf639decd --- /dev/null +++ b/src/test/compile-fail/issue-50688.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + [1; || {}]; //~ ERROR mismatched types +} diff --git a/src/test/run-pass/issue-50689.rs b/src/test/run-pass/issue-50689.rs new file mode 100644 index 0000000000000..d437b9d88f4d7 --- /dev/null +++ b/src/test/run-pass/issue-50689.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/test/ui/issue-23302-1.stderr b/src/test/ui/issue-23302-1.stderr index 6ff46a7e21fda..dcf021de57e56 100644 --- a/src/test/ui/issue-23302-1.stderr +++ b/src/test/ui/issue-23302-1.stderr @@ -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 diff --git a/src/test/ui/issue-23302-2.stderr b/src/test/ui/issue-23302-2.stderr index 6b72a5b544dce..146f86127c5e4 100644 --- a/src/test/ui/issue-23302-2.stderr +++ b/src/test/ui/issue-23302-2.stderr @@ -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 diff --git a/src/test/ui/issue-36163.stderr b/src/test/ui/issue-36163.stderr index 7199fffd386b4..5623437669f06 100644 --- a/src/test/ui/issue-36163.stderr +++ b/src/test/ui/issue-36163.stderr @@ -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