diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2018-05-17 21:28:50 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2018-05-19 20:34:42 +0300 |
| commit | 26aad254875464ff352a4e18d16f668b5bd9b7cb (patch) | |
| tree | 82c41e684745a322d3a33156dd00016136a5ce45 /src/libsyntax | |
| parent | 072b0f617fdd2ccb3bc6dd08718acf9504b7ed3a (diff) | |
| download | rust-26aad254875464ff352a4e18d16f668b5bd9b7cb.tar.gz rust-26aad254875464ff352a4e18d16f668b5bd9b7cb.zip | |
rustc: introduce {ast,hir}::AnonConst to consolidate so-called "embedded constants".
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/diagnostics/plugin.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 15 |
6 files changed, 73 insertions, 29 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1817726d6a1..0ce9763ded8 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<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_>; diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index aecf32ab6af..6c3117b963f 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 29cc208c06b..28fb95f165f 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<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) => { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7b91c491700..aca23581d95 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 17f83a09c77..be3408ce565 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 2013e838c05..b6eb649daa2 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); |
