diff options
| author | bors <bors@rust-lang.org> | 2016-11-21 08:08:47 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-11-21 08:08:47 -0600 |
| commit | ebec55406ba94faf8b2cd23b27a8f74df97d1ca4 (patch) | |
| tree | 446c06caed20d58ba039ba0e7739a89a136e74aa /src/libsyntax_ext | |
| parent | 59b87b3975c97820b32ba6ebee8eac2a13ab883b (diff) | |
| parent | a8e86f0f816c9666915c73e80969dbf85a5afd56 (diff) | |
| download | rust-ebec55406ba94faf8b2cd23b27a8f74df97d1ca4.tar.gz rust-ebec55406ba94faf8b2cd23b27a8f74df97d1ca4.zip | |
Auto merge of #37824 - jseyfried:symbols, r=eddyb
Clean up `ast::Attribute`, `ast::CrateConfig`, and string interning This PR - removes `ast::Attribute_` (changing `Attribute` from `Spanned<Attribute_>` to a struct), - moves a `MetaItem`'s name from the `MetaItemKind` variants to a field of `MetaItem`, - avoids needlessly wrapping `ast::MetaItem` with `P`, - moves string interning into `syntax::symbol` (`ast::Name` is a reexport of `symbol::Symbol` for now), - replaces `InternedString` with `Symbol` in the AST, HIR, and various other places, and - refactors `ast::CrateConfig` from a `Vec` to a `HashSet`. r? @eddyb
Diffstat (limited to 'src/libsyntax_ext')
| -rw-r--r-- | src/libsyntax_ext/asm.rs | 23 | ||||
| -rw-r--r-- | src/libsyntax_ext/concat.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax_ext/concat_idents.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/clone.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/cmp/eq.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/cmp/ord.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/cmp/partial_eq.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/cmp/partial_ord.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/custom.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/debug.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/decodable.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/default.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/encodable.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/generic/mod.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/mod.rs | 60 | ||||
| -rw-r--r-- | src/libsyntax_ext/env.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax_ext/format.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax_ext/lib.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax_ext/proc_macro_registrar.rs | 29 | ||||
| -rw-r--r-- | src/libsyntax_ext/trace_macros.rs | 2 |
20 files changed, 125 insertions, 138 deletions
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index e4d0cb74046..a5e083f926a 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -17,9 +17,9 @@ use syntax::codemap; use syntax::ext::base; use syntax::ext::base::*; use syntax::feature_gate; -use syntax::parse::token::intern; use syntax::parse::{self, token}; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax::ast::AsmDialect; use syntax_pos::Span; use syntax::tokenstream; @@ -73,7 +73,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, }) .unwrap_or(tts.len()); let mut p = cx.new_parser_from_tts(&tts[first_colon..]); - let mut asm = token::InternedString::new(""); + let mut asm = Symbol::intern(""); let mut asm_str_style = None; let mut outputs = Vec::new(); let mut inputs = Vec::new(); @@ -135,11 +135,12 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, // It's the opposite of '=&' which means that the memory // cannot be shared with any other operand (usually when // a register is clobbered early.) - let mut ch = constraint.chars(); + let constraint_str = constraint.as_str(); + let mut ch = constraint_str.chars(); let output = match ch.next() { Some('=') => None, Some('+') => { - Some(token::intern_and_get_ident(&format!("={}", ch.as_str()))) + Some(Symbol::intern(&format!("={}", ch.as_str()))) } _ => { cx.span_err(span, "output operand constraint lacks '=' or '+'"); @@ -148,9 +149,9 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, }; let is_rw = output.is_some(); - let is_indirect = constraint.contains("*"); + let is_indirect = constraint_str.contains("*"); outputs.push(ast::InlineAsmOutput { - constraint: output.unwrap_or(constraint.clone()), + constraint: output.unwrap_or(constraint), expr: out, is_rw: is_rw, is_indirect: is_indirect, @@ -166,9 +167,9 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, let (constraint, _str_style) = panictry!(p.parse_str()); - if constraint.starts_with("=") { + if constraint.as_str().starts_with("=") { cx.span_err(p.prev_span, "input operand constraint contains '='"); - } else if constraint.starts_with("+") { + } else if constraint.as_str().starts_with("+") { cx.span_err(p.prev_span, "input operand constraint contains '+'"); } @@ -190,7 +191,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, if OPTIONS.iter().any(|&opt| s == opt) { cx.span_warn(p.prev_span, "expected a clobber, found an option"); - } else if s.starts_with("{") || s.ends_with("}") { + } else if s.as_str().starts_with("{") || s.as_str().ends_with("}") { cx.span_err(p.prev_span, "clobber should not be surrounded by braces"); } @@ -242,7 +243,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { call_site: sp, callee: codemap::NameAndSpan { - format: codemap::MacroBang(intern("asm")), + format: codemap::MacroBang(Symbol::intern("asm")), span: None, allow_internal_unstable: false, }, @@ -251,7 +252,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, MacEager::expr(P(ast::Expr { id: ast::DUMMY_NODE_ID, node: ast::ExprKind::InlineAsm(P(ast::InlineAsm { - asm: token::intern_and_get_ident(&asm), + asm: asm, asm_str_style: asm_str_style.unwrap(), outputs: outputs, inputs: inputs, diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index 02b44f2d012..bfe18dc4060 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -11,7 +11,7 @@ use syntax::ast; use syntax::ext::base; use syntax::ext::build::AstBuilder; -use syntax::parse::token; +use syntax::symbol::Symbol; use syntax_pos; use syntax::tokenstream; @@ -33,7 +33,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, ast::LitKind::Str(ref s, _) | ast::LitKind::Float(ref s, _) | ast::LitKind::FloatUnsuffixed(ref s) => { - accumulator.push_str(&s); + accumulator.push_str(&s.as_str()); } ast::LitKind::Char(c) => { accumulator.push(c); @@ -57,5 +57,5 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, } } } - base::MacEager::expr(cx.expr_str(sp, token::intern_and_get_ident(&accumulator[..]))) + base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator))) } diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index e56c6e2229a..b26e33eb384 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -13,7 +13,6 @@ use syntax::ext::base::*; use syntax::ext::base; use syntax::feature_gate; use syntax::parse::token; -use syntax::parse::token::str_to_ident; use syntax::ptr::P; use syntax_pos::Span; use syntax::tokenstream::TokenTree; @@ -51,7 +50,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, } } } - let res = str_to_ident(&res_str); + let res = ast::Ident::from_str(&res_str); struct Result { ident: ast::Ident, diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index d7bc2a6faee..d14b59d6c70 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -15,8 +15,8 @@ use syntax::ast::{self, Expr, Generics, ItemKind, MetaItem, VariantData}; use syntax::attr; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token::{keywords, InternedString}; use syntax::ptr::P; +use syntax::symbol::{Symbol, keywords}; use syntax_pos::Span; pub fn expand_deriving_clone(cx: &mut ExtCtxt, @@ -74,7 +74,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt, _ => cx.span_bug(span, "#[derive(Clone)] on trait item or impl item"), } - let inline = cx.meta_word(span, InternedString::new("inline")); + let inline = cx.meta_word(span, Symbol::intern("inline")); let attrs = vec![cx.attribute(span, inline)]; let trait_def = TraitDef { span: span, diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index fa0fb2492c5..6ab5987a159 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -14,8 +14,8 @@ use deriving::generic::ty::*; use syntax::ast::{self, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token::InternedString; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::Span; pub fn expand_deriving_eq(cx: &mut ExtCtxt, @@ -23,9 +23,9 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt, mitem: &MetaItem, item: &Annotatable, push: &mut FnMut(Annotatable)) { - let inline = cx.meta_word(span, InternedString::new("inline")); - let hidden = cx.meta_list_item_word(span, InternedString::new("hidden")); - let doc = cx.meta_list(span, InternedString::new("doc"), vec![hidden]); + let inline = cx.meta_word(span, Symbol::intern("inline")); + let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden")); + let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]); let attrs = vec![cx.attribute(span, inline), cx.attribute(span, doc)]; let trait_def = TraitDef { span: span, diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs index 6b2e36e63b6..9fc3d997585 100644 --- a/src/libsyntax_ext/deriving/cmp/ord.rs +++ b/src/libsyntax_ext/deriving/cmp/ord.rs @@ -14,8 +14,8 @@ use deriving::generic::ty::*; use syntax::ast::{self, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token::InternedString; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::Span; pub fn expand_deriving_ord(cx: &mut ExtCtxt, @@ -23,7 +23,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt, mitem: &MetaItem, item: &Annotatable, push: &mut FnMut(Annotatable)) { - let inline = cx.meta_word(span, InternedString::new("inline")); + let inline = cx.meta_word(span, Symbol::intern("inline")); let attrs = vec![cx.attribute(span, inline)]; let trait_def = TraitDef { span: span, diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index c46d4b34173..f2a050ce971 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -14,8 +14,8 @@ use deriving::generic::ty::*; use syntax::ast::{BinOpKind, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token::InternedString; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::Span; pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt, @@ -64,7 +64,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt, macro_rules! md { ($name:expr, $f:ident) => { { - let inline = cx.meta_word(span, InternedString::new("inline")); + let inline = cx.meta_word(span, Symbol::intern("inline")); let attrs = vec![cx.attribute(span, inline)]; MethodDef { name: $name, diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index 597ff306b3d..ce4d549d696 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -16,8 +16,8 @@ use deriving::generic::ty::*; use syntax::ast::{self, BinOpKind, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token::InternedString; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::Span; pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt, @@ -27,7 +27,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt, push: &mut FnMut(Annotatable)) { macro_rules! md { ($name:expr, $op:expr, $equal:expr) => { { - let inline = cx.meta_word(span, InternedString::new("inline")); + let inline = cx.meta_word(span, Symbol::intern("inline")); let attrs = vec![cx.attribute(span, inline)]; MethodDef { name: $name, @@ -51,7 +51,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt, vec![Box::new(ordering_ty)], true)); - let inline = cx.meta_word(span, InternedString::new("inline")); + let inline = cx.meta_word(span, Symbol::intern("inline")); let attrs = vec![cx.attribute(span, inline)]; let partial_cmp_def = MethodDef { diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index e101757ad23..1076a6a6d63 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -17,10 +17,9 @@ use syntax::attr::{mark_used, mark_known}; use syntax::codemap::Span; use syntax::ext::base::*; use syntax::fold::Folder; -use syntax::parse::token::InternedString; use syntax::visit::Visitor; -struct MarkAttrs<'a>(&'a [InternedString]); +struct MarkAttrs<'a>(&'a [ast::Name]); impl<'a> Visitor for MarkAttrs<'a> { fn visit_attribute(&mut self, attr: &Attribute) { @@ -33,13 +32,11 @@ impl<'a> Visitor for MarkAttrs<'a> { pub struct CustomDerive { inner: fn(TokenStream) -> TokenStream, - attrs: Vec<InternedString>, + attrs: Vec<ast::Name>, } impl CustomDerive { - pub fn new(inner: fn(TokenStream) -> TokenStream, - attrs: Vec<InternedString>) - -> CustomDerive { + pub fn new(inner: fn(TokenStream) -> TokenStream, attrs: Vec<ast::Name>) -> CustomDerive { CustomDerive { inner: inner, attrs: attrs } } } diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index f367fed9cc2..a767716466c 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -11,11 +11,10 @@ use deriving::generic::*; use deriving::generic::ty::*; -use syntax::ast; +use syntax::ast::{self, Ident}; use syntax::ast::{Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token; use syntax::ptr::P; use syntax_pos::{DUMMY_SP, Span}; @@ -69,9 +68,8 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<E // We want to make sure we have the expn_id set so that we can use unstable methods let span = Span { expn_id: cx.backtrace(), ..span }; - let name = cx.expr_lit(span, - ast::LitKind::Str(ident.name.as_str(), ast::StrStyle::Cooked)); - let builder = token::str_to_ident("builder"); + let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked)); + let builder = Ident::from_str("builder"); let builder_expr = cx.expr_ident(span, builder.clone()); let fmt = substr.nonself_args[0].clone(); @@ -83,7 +81,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<E if !is_struct { // tuple struct/"normal" variant let expr = - cx.expr_method_call(span, fmt, token::str_to_ident("debug_tuple"), vec![name]); + cx.expr_method_call(span, fmt, Ident::from_str("debug_tuple"), vec![name]); stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr)); for field in fields { @@ -93,7 +91,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<E let expr = cx.expr_method_call(span, builder_expr.clone(), - token::str_to_ident("field"), + Ident::from_str("field"), vec![field]); // Use `let _ = expr;` to avoid triggering the @@ -103,12 +101,12 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<E } else { // normal struct/struct variant let expr = - cx.expr_method_call(span, fmt, token::str_to_ident("debug_struct"), vec![name]); + cx.expr_method_call(span, fmt, Ident::from_str("debug_struct"), vec![name]); stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr)); for field in fields { let name = cx.expr_lit(field.span, - ast::LitKind::Str(field.name.unwrap().name.as_str(), + ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked)); // Use double indirection to make sure this works for unsized types @@ -116,7 +114,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<E let field = cx.expr_addr_of(field.span, field); let expr = cx.expr_method_call(span, builder_expr.clone(), - token::str_to_ident("field"), + Ident::from_str("field"), vec![name, field]); stmts.push(stmt_let_undescore(cx, span, expr)); } @@ -126,7 +124,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<E _ => unreachable!(), }; - let expr = cx.expr_method_call(span, builder_expr, token::str_to_ident("finish"), vec![]); + let expr = cx.expr_method_call(span, builder_expr, Ident::from_str("finish"), vec![]); stmts.push(cx.stmt_expr(expr)); let block = cx.block(span, stmts); diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs index dc1f7b4e620..e2634c60dca 100644 --- a/src/libsyntax_ext/deriving/decodable.rs +++ b/src/libsyntax_ext/deriving/decodable.rs @@ -18,9 +18,8 @@ use syntax::ast; use syntax::ast::{Expr, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token::InternedString; -use syntax::parse::token; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::Span; pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt, @@ -131,7 +130,7 @@ fn decodable_substructure(cx: &mut ExtCtxt, cx.expr_method_call(trait_span, decoder, cx.ident_of("read_struct"), - vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()), + vec![cx.expr_str(trait_span, substr.type_ident.name), cx.expr_usize(trait_span, nfields), cx.lambda1(trait_span, result, blkarg)]) } @@ -143,7 +142,7 @@ fn decodable_substructure(cx: &mut ExtCtxt, let rvariant_arg = cx.ident_of("read_enum_variant_arg"); for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() { - variants.push(cx.expr_str(v_span, ident.name.as_str())); + variants.push(cx.expr_str(v_span, ident.name)); let path = cx.path(trait_span, vec![substr.type_ident, ident]); let decoded = decode_static_fields(cx, v_span, path, parts, |cx, span, _, field| { @@ -175,7 +174,7 @@ fn decodable_substructure(cx: &mut ExtCtxt, cx.expr_method_call(trait_span, decoder, cx.ident_of("read_enum"), - vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()), + vec![cx.expr_str(trait_span, substr.type_ident.name), cx.lambda1(trait_span, result, blkarg)]) } _ => cx.bug("expected StaticEnum or StaticStruct in derive(Decodable)"), @@ -191,7 +190,7 @@ fn decode_static_fields<F>(cx: &mut ExtCtxt, fields: &StaticFields, mut getarg: F) -> P<Expr> - where F: FnMut(&mut ExtCtxt, Span, InternedString, usize) -> P<Expr> + where F: FnMut(&mut ExtCtxt, Span, Symbol, usize) -> P<Expr> { match *fields { Unnamed(ref fields, is_tuple) => { @@ -202,10 +201,7 @@ fn decode_static_fields<F>(cx: &mut ExtCtxt, let fields = fields.iter() .enumerate() .map(|(i, &span)| { - getarg(cx, - span, - token::intern_and_get_ident(&format!("_field{}", i)), - i) + getarg(cx, span, Symbol::intern(&format!("_field{}", i)), i) }) .collect(); @@ -217,7 +213,7 @@ fn decode_static_fields<F>(cx: &mut ExtCtxt, let fields = fields.iter() .enumerate() .map(|(i, &(ident, span))| { - let arg = getarg(cx, span, ident.name.as_str(), i); + let arg = getarg(cx, span, ident.name, i); cx.field_imm(span, ident, arg) }) .collect(); diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs index b15fd2b49a6..69391f48c22 100644 --- a/src/libsyntax_ext/deriving/default.rs +++ b/src/libsyntax_ext/deriving/default.rs @@ -14,8 +14,8 @@ use deriving::generic::ty::*; use syntax::ast::{Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token::InternedString; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::Span; pub fn expand_deriving_default(cx: &mut ExtCtxt, @@ -23,7 +23,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt, mitem: &MetaItem, item: &Annotatable, push: &mut FnMut(Annotatable)) { - let inline = cx.meta_word(span, InternedString::new("inline")); + let inline = cx.meta_word(span, Symbol::intern("inline")); let attrs = vec![cx.attribute(span, inline)]; let trait_def = TraitDef { span: span, diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index ebbddc6e480..092738ab8a0 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -95,8 +95,8 @@ use deriving::generic::ty::*; use syntax::ast::{Expr, ExprKind, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::parse::token; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::Span; pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt, @@ -192,8 +192,8 @@ fn encodable_substructure(cx: &mut ExtCtxt, let mut stmts = Vec::new(); for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() { let name = match name { - Some(id) => id.name.as_str(), - None => token::intern_and_get_ident(&format!("_field{}", i)), + Some(id) => id.name, + None => Symbol::intern(&format!("_field{}", i)), }; let self_ref = cx.expr_addr_of(span, self_.clone()); let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]); @@ -226,7 +226,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, cx.expr_method_call(trait_span, encoder, cx.ident_of("emit_struct"), - vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()), + vec![cx.expr_str(trait_span, substr.type_ident.name), cx.expr_usize(trait_span, fields.len()), blk]) } @@ -265,7 +265,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, } let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg); - let name = cx.expr_str(trait_span, variant.node.name.name.as_str()); + let name = cx.expr_str(trait_span, variant.node.name.name); let call = cx.expr_method_call(trait_span, blkencoder, cx.ident_of("emit_enum_variant"), @@ -277,8 +277,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, let ret = cx.expr_method_call(trait_span, encoder, cx.ident_of("emit_enum"), - vec![cx.expr_str(trait_span, - substr.type_ident.name.as_str()), + vec![cx.expr_str(trait_span ,substr.type_ident.name), blk]); cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)])) } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index e6b63be3efc..63cd7678321 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -198,8 +198,8 @@ use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::codemap::{self, dummy_spanned, respan}; use syntax::util::move_map::MoveMap; -use syntax::parse::token::{InternedString, keywords}; use syntax::ptr::P; +use syntax::symbol::{Symbol, keywords}; use syntax_pos::{DUMMY_SP, Span}; use errors::Handler; @@ -442,7 +442,7 @@ impl<'a> TraitDef<'a> { attrs.extend(item.attrs .iter() .filter(|a| { - match &a.name()[..] { + match &*a.name().as_str() { "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true, _ => false, } @@ -639,15 +639,15 @@ impl<'a> TraitDef<'a> { let attr = cx.attribute(self.span, cx.meta_word(self.span, - InternedString::new("automatically_derived"))); + Symbol::intern("automatically_derived"))); // Just mark it now since we know that it'll end up used downstream attr::mark_used(&attr); let opt_trait_ref = Some(trait_ref); - let unused_qual = cx.attribute(self.span, - cx.meta_list(self.span, - InternedString::new("allow"), - vec![cx.meta_list_item_word(self.span, - InternedString::new("unused_qualifications"))])); + let unused_qual = { + let word = cx.meta_list_item_word(self.span, Symbol::intern("unused_qualifications")); + cx.attribute(self.span, cx.meta_list(self.span, Symbol::intern("allow"), vec![word])) + }; + let mut a = vec![attr, unused_qual]; a.extend(self.attributes.iter().cloned()); diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index b1d473820f7..535d7de19e3 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -16,8 +16,8 @@ use syntax::codemap; use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension}; use syntax::ext::build::AstBuilder; use syntax::feature_gate::{self, emit_feature_err}; -use syntax::parse::token::{intern, intern_and_get_ident}; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::Span; macro_rules! pathvec { @@ -80,7 +80,7 @@ fn allow_unstable(cx: &mut ExtCtxt, span: Span, attr_name: &str) -> Span { expn_id: cx.codemap().record_expansion(codemap::ExpnInfo { call_site: span, callee: codemap::NameAndSpan { - format: codemap::MacroAttribute(intern(attr_name)), + format: codemap::MacroAttribute(Symbol::intern(attr_name)), span: Some(span), allow_internal_unstable: true, }, @@ -105,9 +105,10 @@ pub fn expand_derive(cx: &mut ExtCtxt, } }; + let derive = Symbol::intern("derive"); let mut derive_attrs = Vec::new(); item = item.map_attrs(|attrs| { - let partition = attrs.into_iter().partition(|attr| &attr.name() == "derive"); + let partition = attrs.into_iter().partition(|attr| attr.name() == derive); derive_attrs = partition.0; partition.1 }); @@ -115,7 +116,7 @@ pub fn expand_derive(cx: &mut ExtCtxt, // Expand `#[derive]`s after other attribute macro invocations. if cx.resolver.find_attr_invoc(&mut item.attrs.clone()).is_some() { return vec![Annotatable::Item(item.map_attrs(|mut attrs| { - attrs.push(cx.attribute(span, P(mitem.clone()))); + attrs.push(cx.attribute(span, mitem.clone())); attrs.extend(derive_attrs); attrs }))]; @@ -135,7 +136,7 @@ pub fn expand_derive(cx: &mut ExtCtxt, let mut traits = get_traits(mitem, cx); for derive_attr in derive_attrs { - traits.extend(get_traits(&derive_attr.node.value, cx)); + traits.extend(get_traits(&derive_attr.value, cx)); } // First, weed out malformed #[derive] @@ -158,9 +159,8 @@ pub fn expand_derive(cx: &mut ExtCtxt, let tword = titem.word().unwrap(); let tname = tword.name(); - if is_builtin_trait(&tname) || { - let derive_mode = - ast::Path::from_ident(titem.span, ast::Ident::with_empty_ctxt(intern(&tname))); + if is_builtin_trait(tname) || { + let derive_mode = ast::Path::from_ident(titem.span, ast::Ident::with_empty_ctxt(tname)); cx.resolver.resolve_macro(cx.current_expansion.mark, &derive_mode, false).map(|ext| { if let SyntaxExtension::CustomDerive(_) = *ext { true } else { false } }).unwrap_or(false) @@ -176,7 +176,7 @@ pub fn expand_derive(cx: &mut ExtCtxt, feature_gate::EXPLAIN_CUSTOM_DERIVE); } else { cx.span_warn(titem.span, feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE); - let name = intern_and_get_ident(&format!("derive_{}", tname)); + let name = Symbol::intern(&format!("derive_{}", tname)); let mitem = cx.meta_word(titem.span, name); new_attributes.push(cx.attribute(mitem.span, mitem)); } @@ -186,9 +186,7 @@ pub fn expand_derive(cx: &mut ExtCtxt, item = item.map(|mut i| { i.attrs.extend(new_attributes); if traits.len() > 0 { - let list = cx.meta_list(mitem.span, - intern_and_get_ident("derive"), - traits); + let list = cx.meta_list(mitem.span, derive, traits); i.attrs.push(cx.attribute(mitem.span, list)); } i @@ -217,7 +215,7 @@ pub fn expand_derive(cx: &mut ExtCtxt, let macros_11_derive = traits.iter() .cloned() .enumerate() - .filter(|&(_, ref name)| !is_builtin_trait(&name.name().unwrap())) + .filter(|&(_, ref name)| !is_builtin_trait(name.name().unwrap())) .next(); if let Some((i, titem)) = macros_11_derive { if !cx.ecfg.features.unwrap().proc_macro { @@ -226,24 +224,20 @@ pub fn expand_derive(cx: &mut ExtCtxt, emit_feature_err(cx.parse_sess, "proc_macro", titem.span, issue, msg); } - let tname = ast::Ident::with_empty_ctxt(intern(&titem.name().unwrap())); + let tname = ast::Ident::with_empty_ctxt(titem.name().unwrap()); let path = ast::Path::from_ident(titem.span, tname); let ext = cx.resolver.resolve_macro(cx.current_expansion.mark, &path, false).unwrap(); traits.remove(i); if traits.len() > 0 { item = item.map(|mut i| { - let list = cx.meta_list(mitem.span, - intern_and_get_ident("derive"), - traits); + let list = cx.meta_list(mitem.span, derive, traits); i.attrs.push(cx.attribute(mitem.span, list)); i }); } let titem = cx.meta_list_item_word(titem.span, titem.name().unwrap()); - let mitem = cx.meta_list(titem.span, - intern_and_get_ident("derive"), - vec![titem]); + let mitem = cx.meta_list(titem.span, derive, vec![titem]); let item = Annotatable::Item(item); if let SyntaxExtension::CustomDerive(ref ext) = *ext { return ext.expand(cx, mitem.span, &mitem, item); @@ -257,9 +251,10 @@ pub fn expand_derive(cx: &mut ExtCtxt, // RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted) // `#[structural_match]` attribute. - if traits.iter().filter_map(|t| t.name()).any(|t| t == "PartialEq") && - traits.iter().filter_map(|t| t.name()).any(|t| t == "Eq") { - let structural_match = intern_and_get_ident("structural_match"); + let (partial_eq, eq) = (Symbol::intern("PartialEq"), Symbol::intern("Eq")); + if traits.iter().any(|t| t.name() == Some(partial_eq)) && + traits.iter().any(|t| t.name() == Some(eq)) { + let structural_match = Symbol::intern("structural_match"); let span = allow_unstable(cx, span, "derive(PartialEq, Eq)"); let meta = cx.meta_word(span, structural_match); item = item.map(|mut i| { @@ -272,9 +267,10 @@ pub fn expand_derive(cx: &mut ExtCtxt, // the same as the copy implementation. // // Add a marker attribute here picked up during #[derive(Clone)] - if traits.iter().filter_map(|t| t.name()).any(|t| t == "Clone") && - traits.iter().filter_map(|t| t.name()).any(|t| t == "Copy") { - let marker = intern_and_get_ident("rustc_copy_clone_marker"); + let (copy, clone) = (Symbol::intern("Copy"), Symbol::intern("Clone")); + if traits.iter().any(|t| t.name() == Some(clone)) && + traits.iter().any(|t| t.name() == Some(copy)) { + let marker = Symbol::intern("rustc_copy_clone_marker"); let span = allow_unstable(cx, span, "derive(Copy, Clone)"); let meta = cx.meta_word(span, marker); item = item.map(|mut i| { @@ -286,14 +282,14 @@ pub fn expand_derive(cx: &mut ExtCtxt, let mut items = Vec::new(); for titem in traits.iter() { let tname = titem.word().unwrap().name(); - let name = intern_and_get_ident(&format!("derive({})", tname)); + let name = Symbol::intern(&format!("derive({})", tname)); let mitem = cx.meta_word(titem.span, name); let span = Span { expn_id: cx.codemap().record_expansion(codemap::ExpnInfo { call_site: titem.span, callee: codemap::NameAndSpan { - format: codemap::MacroAttribute(intern(&format!("derive({})", tname))), + format: codemap::MacroAttribute(Symbol::intern(&format!("derive({})", tname))), span: Some(titem.span), allow_internal_unstable: true, }, @@ -302,7 +298,7 @@ pub fn expand_derive(cx: &mut ExtCtxt, }; let my_item = Annotatable::Item(item); - expand_builtin(&tname, cx, span, &mitem, &my_item, &mut |a| { + expand_builtin(&tname.as_str(), cx, span, &mitem, &my_item, &mut |a| { items.push(a); }); item = my_item.expect_item(); @@ -314,8 +310,8 @@ pub fn expand_derive(cx: &mut ExtCtxt, macro_rules! derive_traits { ($( $name:expr => $func:path, )+) => { - pub fn is_builtin_trait(name: &str) -> bool { - match name { + pub fn is_builtin_trait(name: ast::Name) -> bool { + match &*name.as_str() { $( $name )|+ => true, _ => false, } @@ -412,7 +408,7 @@ fn call_intrinsic(cx: &ExtCtxt, span.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { call_site: span, callee: codemap::NameAndSpan { - format: codemap::MacroAttribute(intern("derive")), + format: codemap::MacroAttribute(Symbol::intern("derive")), span: Some(span), allow_internal_unstable: true, }, diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index 5c081b98962..ecf0a8f377e 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -17,7 +17,7 @@ use syntax::ast; use syntax::ext::base::*; use syntax::ext::base; use syntax::ext::build::AstBuilder; -use syntax::parse::token; +use syntax::symbol::Symbol; use syntax_pos::Span; use syntax::tokenstream; @@ -32,7 +32,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, Some(v) => v, }; - let e = match env::var(&var[..]) { + let e = match env::var(&*var.as_str()) { Err(..) => { cx.expr_path(cx.path_all(sp, true, @@ -49,7 +49,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, Ok(s) => { cx.expr_call_global(sp, cx.std_path(&["option", "Option", "Some"]), - vec![cx.expr_str(sp, token::intern_and_get_ident(&s[..]))]) + vec![cx.expr_str(sp, Symbol::intern(&s))]) } }; MacEager::expr(e) @@ -73,7 +73,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, Some((v, _style)) => v, }; let msg = match exprs.next() { - None => token::intern_and_get_ident(&format!("environment variable `{}` not defined", var)), + None => Symbol::intern(&format!("environment variable `{}` not defined", var)), Some(second) => { match expr_to_string(cx, second, "expected string literal") { None => return DummyResult::expr(sp), @@ -87,12 +87,12 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, return DummyResult::expr(sp); } - let e = match env::var(&var[..]) { + let e = match env::var(&*var.as_str()) { Err(_) => { - cx.span_err(sp, &msg); + cx.span_err(sp, &msg.as_str()); cx.expr_usize(sp, 0) } - Ok(s) => cx.expr_str(sp, token::intern_and_get_ident(&s)), + Ok(s) => cx.expr_str(sp, Symbol::intern(&s)), }; MacEager::expr(e) } diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 6eba8baf5b8..d2afa08cada 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -17,8 +17,9 @@ use syntax::ast; use syntax::ext::base::*; use syntax::ext::base; use syntax::ext::build::AstBuilder; -use syntax::parse::token::{self, keywords}; +use syntax::parse::token; use syntax::ptr::P; +use syntax::symbol::{Symbol, keywords}; use syntax_pos::{Span, DUMMY_SP}; use syntax::tokenstream; @@ -369,7 +370,7 @@ impl<'a, 'b> Context<'a, 'b> { /// Translate the accumulated string literals to a literal expression fn trans_literal_string(&mut self) -> P<ast::Expr> { let sp = self.fmtsp; - let s = token::intern_and_get_ident(&self.literal); + let s = Symbol::intern(&self.literal); self.literal.clear(); self.ecx.expr_str(sp, s) } @@ -727,7 +728,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, fmtsp: fmt.span, }; - let mut parser = parse::Parser::new(&fmt.node.0); + let fmt_str = &*fmt.node.0.as_str(); + let mut parser = parse::Parser::new(fmt_str); let mut pieces = vec![]; loop { @@ -808,7 +810,6 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, // Decide if we want to look for foreign formatting directives. if args_used < args_unused { use super::format_foreign as foreign; - let fmt_str = &fmt.node.0[..]; // The set of foreign substitutions we've explained. This prevents spamming the user // with `%d should be written as {}` over and over again. diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 1ebac19b4f0..e83fd55cd71 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -53,7 +53,7 @@ use std::rc::Rc; use syntax::ast; use syntax::ext::base::{MacroExpanderFn, NormalTT, IdentTT, MultiModifier, NamedSyntaxExtension}; use syntax::ext::tt::macro_rules::MacroRulesExpander; -use syntax::parse::token::intern; +use syntax::symbol::Symbol; pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, user_exts: Vec<NamedSyntaxExtension>, @@ -62,11 +62,11 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, resolver.add_ext(ast::Ident::with_empty_ctxt(name), Rc::new(ext)); }; - register(intern("macro_rules"), IdentTT(Box::new(MacroRulesExpander), None, false)); + register(Symbol::intern("macro_rules"), IdentTT(Box::new(MacroRulesExpander), None, false)); macro_rules! register { ($( $name:ident: $f:expr, )*) => { $( - register(intern(stringify!($name)), + register(Symbol::intern(stringify!($name)), NormalTT(Box::new($f as MacroExpanderFn), None, false)); )* } } @@ -112,9 +112,10 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, } // format_args uses `unstable` things internally. - register(intern("format_args"), NormalTT(Box::new(format::expand_format_args), None, true)); + register(Symbol::intern("format_args"), + NormalTT(Box::new(format::expand_format_args), None, true)); - register(intern("derive"), MultiModifier(Box::new(deriving::expand_derive))); + register(Symbol::intern("derive"), MultiModifier(Box::new(deriving::expand_derive))); for (name, ext) in user_exts { register(name, ext); diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs index 36fd6408b4f..bbdbda701ae 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -17,20 +17,20 @@ use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; use syntax::parse::ParseSess; -use syntax::parse::token::{self, InternedString}; use syntax::feature_gate::Features; use syntax::fold::Folder; use syntax::ptr::P; +use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; use syntax::visit::{self, Visitor}; use deriving; struct CustomDerive { - trait_name: InternedString, + trait_name: ast::Name, function_name: Ident, span: Span, - attrs: Vec<InternedString>, + attrs: Vec<ast::Name>, } struct CollectCustomDerives<'a> { @@ -183,7 +183,7 @@ impl<'a> Visitor for CollectCustomDerives<'a> { self.handler.span_err(trait_attr.span(), "must only be one word"); } - if deriving::is_builtin_trait(&trait_name) { + if deriving::is_builtin_trait(trait_name) { self.handler.span_err(trait_attr.span(), "cannot override a built-in #[derive] mode"); } @@ -271,29 +271,29 @@ fn mk_registrar(cx: &mut ExtCtxt, let eid = cx.codemap().record_expansion(ExpnInfo { call_site: DUMMY_SP, callee: NameAndSpan { - format: MacroAttribute(token::intern("proc_macro")), + format: MacroAttribute(Symbol::intern("proc_macro")), span: None, allow_internal_unstable: true, } }); let span = Span { expn_id: eid, ..DUMMY_SP }; - let proc_macro = token::str_to_ident("proc_macro"); + let proc_macro = Ident::from_str("proc_macro"); let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None)); - let __internal = token::str_to_ident("__internal"); - let registry = token::str_to_ident("Registry"); - let registrar = token::str_to_ident("registrar"); - let register_custom_derive = token::str_to_ident("register_custom_derive"); + let __internal = Ident::from_str("__internal"); + let registry = Ident::from_str("Registry"); + let registrar = Ident::from_str("registrar"); + let register_custom_derive = Ident::from_str("register_custom_derive"); let stmts = custom_derives.iter().map(|cd| { let path = cx.path_global(cd.span, vec![cd.function_name]); - let trait_name = cx.expr_str(cd.span, cd.trait_name.clone()); + let trait_name = cx.expr_str(cd.span, cd.trait_name); let attrs = cx.expr_vec_slice( span, - cd.attrs.iter().map(|s| cx.expr_str(cd.span, s.clone())).collect::<Vec<_>>() + cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>() ); (path, trait_name, attrs) }).map(|(path, trait_name, attrs)| { @@ -316,15 +316,14 @@ fn mk_registrar(cx: &mut ExtCtxt, cx.ty(span, ast::TyKind::Tup(Vec::new())), cx.block(span, stmts)); - let derive_registrar = token::intern_and_get_ident("rustc_derive_registrar"); - let derive_registrar = cx.meta_word(span, derive_registrar); + let derive_registrar = cx.meta_word(span, Symbol::intern("rustc_derive_registrar")); let derive_registrar = cx.attribute(span, derive_registrar); let func = func.map(|mut i| { i.attrs.push(derive_registrar); i.vis = ast::Visibility::Public; i }); - let ident = ast::Ident::with_empty_ctxt(token::gensym("registrar")); + let ident = ast::Ident::with_empty_ctxt(Symbol::gensym("registrar")); let module = cx.item_mod(span, span, ident, Vec::new(), vec![krate, func]).map(|mut i| { i.vis = ast::Visibility::Public; i diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs index 9578af68100..48be8e0c53c 100644 --- a/src/libsyntax_ext/trace_macros.rs +++ b/src/libsyntax_ext/trace_macros.rs @@ -11,7 +11,7 @@ use syntax::ext::base::ExtCtxt; use syntax::ext::base; use syntax::feature_gate; -use syntax::parse::token::keywords; +use syntax::symbol::keywords; use syntax_pos::Span; use syntax::tokenstream::TokenTree; |
