From 86be954fafafa93c343b4891e940d75ad99c4667 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 28 Aug 2015 08:34:22 -0700 Subject: [PATCH] Sync with rust (6f28232) --- syntex_syntax/src/ast.rs | 60 +----------- syntex_syntax/src/ast_util.rs | 8 +- syntex_syntax/src/codemap.rs | 43 +++++++-- syntex_syntax/src/diagnostic.rs | 8 +- syntex_syntax/src/entry.rs | 42 ++++++++ syntex_syntax/src/ext/asm.rs | 5 +- syntex_syntax/src/ext/base.rs | 9 +- syntex_syntax/src/ext/deriving/generic/mod.rs | 13 ++- syntex_syntax/src/ext/expand.rs | 60 +++++------- syntex_syntax/src/ext/tt/macro_parser.rs | 96 ++++++++++--------- syntex_syntax/src/lib.rs | 1 + syntex_syntax/src/print/pprust.rs | 33 ++++++- syntex_syntax/src/std_inject.rs | 6 +- syntex_syntax/src/test.rs | 85 ++++++++++------ syntex_syntax/src/visit.rs | 11 +-- 15 files changed, 272 insertions(+), 208 deletions(-) create mode 100644 syntex_syntax/src/entry.rs diff --git a/syntex_syntax/src/ast.rs b/syntex_syntax/src/ast.rs index 2d72c8fe..66faa122 100644 --- a/syntex_syntax/src/ast.rs +++ b/syntex_syntax/src/ast.rs @@ -65,7 +65,6 @@ use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use print::pprust; use ptr::P; -use std::cell::Cell; use std::fmt; use std::rc::Rc; use serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -371,37 +370,7 @@ pub type CrateNum = u32; pub type NodeId = u32; -#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, - RustcDecodable, Hash, Copy)] -pub struct DefId { - pub krate: CrateNum, - pub node: NodeId, -} - -fn default_def_id_debug(_: DefId, _: &mut fmt::Formatter) -> fmt::Result { Ok(()) } - -thread_local!(pub static DEF_ID_DEBUG: Cell fmt::Result> = - Cell::new(default_def_id_debug)); - -impl fmt::Debug for DefId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "DefId {{ krate: {}, node: {} }}", - self.krate, self.node)); - DEF_ID_DEBUG.with(|def_id_debug| def_id_debug.get()(*self, f)) - } -} - -impl DefId { - /// Read the node id, asserting that this def-id is krate-local. - pub fn local_id(&self) -> NodeId { - assert_eq!(self.krate, LOCAL_CRATE); - self.node - } -} - -/// Item definitions in the currently-compiled crate would have the CrateNum -/// LOCAL_CRATE in their DefId. -pub const LOCAL_CRATE: CrateNum = 0; +/// Node id used to represent the root of the crate. pub const CRATE_NODE_ID: NodeId = 0; /// When parsing and doing expansions, we initially give all AST nodes this AST @@ -1216,16 +1185,6 @@ pub enum LitIntType { UnsuffixedIntLit(Sign) } -impl LitIntType { - pub fn suffix_len(&self) -> usize { - match *self { - UnsuffixedIntLit(_) => 0, - SignedIntLit(s, _) => s.suffix_len(), - UnsignedIntLit(u) => u.suffix_len() - } - } -} - #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Lit_ { /// A string literal (`"foo"`) @@ -1333,12 +1292,6 @@ impl fmt::Display for IntTy { } impl IntTy { - pub fn suffix_len(&self) -> usize { - match *self { - TyIs | TyI8 => 2, - TyI16 | TyI32 | TyI64 => 3, - } - } pub fn bit_width(&self) -> Option { Some(match *self { TyIs => return None, @@ -1360,12 +1313,6 @@ pub enum UintTy { } impl UintTy { - pub fn suffix_len(&self) -> usize { - match *self { - TyUs | TyU8 => 2, - TyU16 | TyU32 | TyU64 => 3, - } - } pub fn bit_width(&self) -> Option { Some(match *self { TyUs => return None, @@ -1408,11 +1355,6 @@ impl fmt::Display for FloatTy { } impl FloatTy { - pub fn suffix_len(&self) -> usize { - match *self { - TyF32 | TyF64 => 3, // add F128 handling here - } - } pub fn bit_width(&self) -> usize { match *self { TyF32 => 32, diff --git a/syntex_syntax/src/ast_util.rs b/syntex_syntax/src/ast_util.rs index 7aff92ec..61c182f6 100644 --- a/syntex_syntax/src/ast_util.rs +++ b/syntex_syntax/src/ast_util.rs @@ -28,12 +28,6 @@ pub fn path_name_i(idents: &[Ident]) -> String { idents.iter().map(|i| i.to_string()).collect::>().join("::") } -pub fn local_def(id: NodeId) -> DefId { - ast::DefId { krate: LOCAL_CRATE, node: id } -} - -pub fn is_local(did: ast::DefId) -> bool { did.krate == LOCAL_CRATE } - pub fn stmt_id(s: &Stmt) -> NodeId { match s.node { StmtDecl(_, id) => id, @@ -444,7 +438,7 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { visit::FkMethod(_, sig, _) => { self.visit_generics_helper(&sig.generics) } - visit::FkFnBlock => {} + visit::FkClosure => {} } for argument in &function_declaration.inputs { diff --git a/syntex_syntax/src/codemap.rs b/syntex_syntax/src/codemap.rs index 0aeb572b..e07cd7b5 100644 --- a/syntex_syntax/src/codemap.rs +++ b/syntex_syntax/src/codemap.rs @@ -29,6 +29,8 @@ use std::io::{self, Read}; use serialize::{Encodable, Decodable, Encoder, Decoder}; +use parse::token::intern; +use ast::Name; // _____________________________________________________________________________ // Pos, BytePos, CharPos @@ -257,21 +259,38 @@ pub struct FileMapAndBytePos { pub fm: Rc, pub pos: BytePos } // /// The source of expansion. -#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)] +#[derive(Clone, Hash, Debug, PartialEq, Eq)] pub enum ExpnFormat { /// e.g. #[derive(...)] - MacroAttribute, + MacroAttribute(Name), /// e.g. `format!()` - MacroBang, + MacroBang(Name), /// Syntax sugar expansion performed by the compiler (libsyntax::expand). - CompilerExpansion, + CompilerExpansion(CompilerExpansionFormat), +} + +#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)] +pub enum CompilerExpansionFormat { + IfLet, + PlacementIn, + WhileLet, + ForLoop, + Closure, } +impl CompilerExpansionFormat { + pub fn name(self) -> &'static str { + match self { + CompilerExpansionFormat::IfLet => "if let expansion", + CompilerExpansionFormat::PlacementIn => "placement-in expansion", + CompilerExpansionFormat::WhileLet => "while let expansion", + CompilerExpansionFormat::ForLoop => "for loop expansion", + CompilerExpansionFormat::Closure => "closure expansion", + } + } +} #[derive(Clone, Hash, Debug)] pub struct NameAndSpan { - /// The name of the macro that was invoked to create the thing - /// with this Span. - pub name: String, /// The format with which the macro was invoked. pub format: ExpnFormat, /// Whether the macro is allowed to use #[unstable]/feature-gated @@ -284,6 +303,16 @@ pub struct NameAndSpan { pub span: Option } +impl NameAndSpan { + pub fn name(&self) -> Name { + match self.format { + ExpnFormat::MacroAttribute(s) => s, + ExpnFormat::MacroBang(s) => s, + ExpnFormat::CompilerExpansion(ce) => intern(ce.name()), + } + } +} + /// Extra information for tracking spans of macro and syntax sugar expansion #[derive(Hash, Debug)] pub struct ExpnInfo { diff --git a/syntex_syntax/src/diagnostic.rs b/syntex_syntax/src/diagnostic.rs index 7476302b..067e3fff 100644 --- a/syntex_syntax/src/diagnostic.rs +++ b/syntex_syntax/src/diagnostic.rs @@ -733,14 +733,14 @@ impl EmitterWriter { let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span)); let (pre, post) = match ei.callee.format { - codemap::MacroAttribute => ("#[", "]"), - codemap::MacroBang => ("", "!"), - codemap::CompilerExpansion => ("", ""), + codemap::MacroAttribute(..) => ("#[", "]"), + codemap::MacroBang(..) => ("", "!"), + codemap::CompilerExpansion(..) => ("", ""), }; try!(self.print_diagnostic(&ss, Note, &format!("in expansion of {}{}{}", pre, - ei.callee.name, + ei.callee.name(), post), None)); let ss = cm.span_to_string(ei.call_site); diff --git a/syntex_syntax/src/entry.rs b/syntex_syntax/src/entry.rs new file mode 100644 index 00000000..b6c5d006 --- /dev/null +++ b/syntex_syntax/src/entry.rs @@ -0,0 +1,42 @@ +// Copyright 2012-2015 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. + +use attr; +use ast::{Item, ItemFn}; + +pub enum EntryPointType { + None, + MainNamed, + MainAttr, + Start, + OtherMain, // Not an entry point, but some other function named main +} + +pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType { + match item.node { + ItemFn(..) => { + if attr::contains_name(&item.attrs, "start") { + EntryPointType::Start + } else if attr::contains_name(&item.attrs, "main") { + EntryPointType::MainAttr + } else if item.ident.name == "main" { + if depth == 1 { + // This is a top-level function so can be 'main' + EntryPointType::MainNamed + } else { + EntryPointType::OtherMain + } + } else { + EntryPointType::None + } + } + _ => EntryPointType::None, + } +} diff --git a/syntex_syntax/src/ext/asm.rs b/syntex_syntax/src/ext/asm.rs index 69159690..c48b740d 100644 --- a/syntex_syntax/src/ext/asm.rs +++ b/syntex_syntax/src/ext/asm.rs @@ -19,7 +19,7 @@ use codemap::Span; use ext::base; use ext::base::*; use feature_gate; -use parse::token::InternedString; +use parse::token::{intern, InternedString}; use parse::token; use ptr::P; @@ -211,8 +211,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { call_site: sp, callee: codemap::NameAndSpan { - name: "asm".to_string(), - format: codemap::MacroBang, + format: codemap::MacroBang(intern("asm")), span: None, allow_internal_unstable: false, }, diff --git a/syntex_syntax/src/ext/base.rs b/syntex_syntax/src/ext/base.rs index ef11a2bd..ef49ef11 100644 --- a/syntex_syntax/src/ext/base.rs +++ b/syntex_syntax/src/ext/base.rs @@ -714,13 +714,14 @@ impl<'a> ExtCtxt<'a> { loop { if self.codemap().with_expn_info(expn_id, |info| { info.map_or(None, |i| { - if i.callee.name == "include" { + if i.callee.name() == "include" { // Stop going up the backtrace once include! is encountered return None; } expn_id = i.call_site.expn_id; - if i.callee.format != CompilerExpansion { - last_macro = Some(i.call_site) + match i.callee.format { + CompilerExpansion(..) => (), + _ => last_macro = Some(i.call_site), } return Some(()); }) @@ -744,7 +745,7 @@ impl<'a> ExtCtxt<'a> { if self.recursion_count > self.ecfg.recursion_limit { panic!(self.span_fatal(ei.call_site, &format!("recursion limit reached while expanding the macro `{}`", - ei.callee.name))); + ei.callee.name()))); } let mut call_site = ei.call_site; diff --git a/syntex_syntax/src/ext/deriving/generic/mod.rs b/syntex_syntax/src/ext/deriving/generic/mod.rs index f8f63e94..3196380e 100644 --- a/syntex_syntax/src/ext/deriving/generic/mod.rs +++ b/syntex_syntax/src/ext/deriving/generic/mod.rs @@ -205,7 +205,7 @@ use codemap::Span; use diagnostic::SpanHandler; use fold::MoveMap; use owned_slice::OwnedSlice; -use parse::token::InternedString; +use parse::token::{intern, InternedString}; use parse::token::special_idents; use ptr::P; @@ -617,7 +617,13 @@ impl<'a> TraitDef<'a> { attr::mark_used(&attr); let opt_trait_ref = Some(trait_ref); let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&*self_type)); - let mut a = vec![attr]; + let unused_qual = cx.attribute( + self.span, + cx.meta_list(self.span, + InternedString::new("allow"), + vec![cx.meta_word(self.span, + InternedString::new("unused_qualifications"))])); + let mut a = vec![attr, unused_qual]; a.extend(self.attributes.iter().cloned()); cx.item( self.span, @@ -1430,8 +1436,7 @@ impl<'a> TraitDef<'a> { to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { call_site: to_set, callee: codemap::NameAndSpan { - name: format!("derive({})", trait_name), - format: codemap::MacroAttribute, + format: codemap::MacroAttribute(intern(&format!("derive({})", trait_name))), span: Some(self.span), allow_internal_unstable: false, } diff --git a/syntex_syntax/src/ext/expand.rs b/syntex_syntax/src/ext/expand.rs index 4f89b349..3459caec 100644 --- a/syntex_syntax/src/ext/expand.rs +++ b/syntex_syntax/src/ext/expand.rs @@ -19,7 +19,8 @@ use ext::build::AstBuilder; use attr; use attr::AttrMetaMethods; use codemap; -use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute, CompilerExpansion}; +use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute}; +use codemap::{CompilerExpansion, CompilerExpansionFormat}; use ext::base::*; use feature_gate::{self, Features, GatedCfg}; use fold; @@ -43,12 +44,12 @@ fn mk_core_path(fld: &mut MacroExpander, } pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { - fn push_compiler_expansion(fld: &mut MacroExpander, span: Span, expansion_desc: &str) { + fn push_compiler_expansion(fld: &mut MacroExpander, span: Span, + expansion_type: CompilerExpansionFormat) { fld.cx.bt_push(ExpnInfo { call_site: span, callee: NameAndSpan { - name: expansion_desc.to_string(), - format: CompilerExpansion, + format: CompilerExpansion(expansion_type), // This does *not* mean code generated after // `push_compiler_expansion` is automatically exempt @@ -111,7 +112,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { &fld.cx.parse_sess.span_diagnostic, expr_span); - push_compiler_expansion(fld, expr_span, "placement-in expansion"); + push_compiler_expansion(fld, expr_span, CompilerExpansionFormat::PlacementIn); let value_span = value_expr.span; let placer_span = placer.span; @@ -223,7 +224,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // } // } - push_compiler_expansion(fld, span, "while let expansion"); + push_compiler_expansion(fld, span, CompilerExpansionFormat::WhileLet); // ` => ` let pat_arm = { @@ -262,7 +263,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // _ => [ | ()] // } - push_compiler_expansion(fld, span, "if let expansion"); + push_compiler_expansion(fld, span, CompilerExpansionFormat::IfLet); // ` => ` let pat_arm = { @@ -334,7 +335,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { ast::ExprIf(cond, blk, elseopt) => { let elseopt = elseopt.map(|els| els.and_then(|els| match els.node { ast::ExprIfLet(..) => { - push_compiler_expansion(fld, span, "if let expansion"); + push_compiler_expansion(fld, span, CompilerExpansionFormat::IfLet); // wrap the if-let expr in a block let span = els.span; let blk = P(ast::Block { @@ -378,7 +379,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // result // } - push_compiler_expansion(fld, span, "for loop expansion"); + push_compiler_expansion(fld, span, CompilerExpansionFormat::ForLoop); let span = fld.new_span(span); @@ -458,7 +459,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { } ast::ExprClosure(capture_clause, fn_decl, block) => { - push_compiler_expansion(fld, span, "closure expansion"); + push_compiler_expansion(fld, span, CompilerExpansionFormat::Closure); let (rewritten_fn_decl, rewritten_block) = expand_and_rename_fn_decl_and_block(fn_decl, block, fld); let new_node = ast::ExprClosure(capture_clause, @@ -542,8 +543,7 @@ fn expand_mac_invoc(mac: ast::Mac, fld.cx.bt_push(ExpnInfo { call_site: span, callee: NameAndSpan { - name: extname.to_string(), - format: MacroBang, + format: MacroBang(extname), span: exp_span, allow_internal_unstable: allow_internal_unstable, }, @@ -721,8 +721,7 @@ pub fn expand_item_mac(it: P, fld.cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { - name: extname.to_string(), - format: MacroBang, + format: MacroBang(extname), span: span, allow_internal_unstable: allow_internal_unstable, } @@ -741,8 +740,7 @@ pub fn expand_item_mac(it: P, fld.cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { - name: extname.to_string(), - format: MacroBang, + format: MacroBang(extname), span: span, allow_internal_unstable: allow_internal_unstable, } @@ -762,8 +760,7 @@ pub fn expand_item_mac(it: P, fld.cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { - name: extname.to_string(), - format: MacroBang, + format: MacroBang(extname), span: None, // `macro_rules!` doesn't directly allow // unstable (this is orthogonal to whether @@ -1090,8 +1087,7 @@ fn expand_pat(p: P, fld: &mut MacroExpander) -> P { fld.cx.bt_push(ExpnInfo { call_site: span, callee: NameAndSpan { - name: extname.to_string(), - format: MacroBang, + format: MacroBang(extname), span: tt_span, allow_internal_unstable: allow_internal_unstable, } @@ -1293,8 +1289,8 @@ fn expand_decorators(a: Annotatable, new_attrs: &mut Vec) { for attr in a.attrs() { - let mname = attr.name(); - match fld.cx.syntax_env.find(&intern(&mname)) { + let mname = intern(&attr.name()); + match fld.cx.syntax_env.find(&mname) { Some(rc) => match *rc { Decorator(ref dec) => { attr::mark_used(&attr); @@ -1302,8 +1298,7 @@ fn expand_decorators(a: Annotatable, fld.cx.bt_push(ExpnInfo { call_site: attr.span, callee: NameAndSpan { - name: mname.to_string(), - format: MacroAttribute, + format: MacroAttribute(mname), span: Some(attr.span), // attributes can do whatever they like, // for now. @@ -1330,8 +1325,7 @@ fn expand_decorators(a: Annotatable, fld.cx.bt_push(ExpnInfo { call_site: attr.span, callee: NameAndSpan { - name: mname.to_string(), - format: MacroAttribute, + format: MacroAttribute(mname), span: Some(attr.span), // attributes can do whatever they like, // for now. @@ -1372,17 +1366,16 @@ fn expand_item_multi_modifier(mut it: Annotatable, } for attr in &modifiers { - let mname = attr.name(); + let mname = intern(&attr.name()); - match fld.cx.syntax_env.find(&intern(&mname)) { + match fld.cx.syntax_env.find(&mname) { Some(rc) => match *rc { MultiModifier(ref mac) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { call_site: attr.span, callee: NameAndSpan { - name: mname.to_string(), - format: MacroAttribute, + format: MacroAttribute(mname), span: Some(attr.span), // attributes can do whatever they like, // for now @@ -1421,17 +1414,16 @@ fn expand_item_modifiers(mut it: P, } for attr in &modifiers { - let mname = attr.name(); + let mname = intern(&attr.name()); - match fld.cx.syntax_env.find(&intern(&mname)) { + match fld.cx.syntax_env.find(&mname) { Some(rc) => match *rc { Modifier(ref mac) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { call_site: attr.span, callee: NameAndSpan { - name: mname.to_string(), - format: MacroAttribute, + format: MacroAttribute(mname), span: Some(attr.span), // attributes can do whatever they like, // for now diff --git a/syntex_syntax/src/ext/tt/macro_parser.rs b/syntex_syntax/src/ext/tt/macro_parser.rs index 26b4181e..f6513cc3 100644 --- a/syntex_syntax/src/ext/tt/macro_parser.rs +++ b/syntex_syntax/src/ext/tt/macro_parser.rs @@ -401,7 +401,7 @@ pub fn parse(sess: &ParseSess, } } TtToken(sp, SubstNt(..)) => { - return Error(sp, "Cannot transcribe in macro LHS".to_string()) + return Error(sp, "missing fragment specifier".to_string()) } seq @ TtDelimited(..) | seq @ TtToken(_, DocComment(..)) => { let lower_elts = mem::replace(&mut ei.top_elts, Tt(seq)); @@ -440,20 +440,24 @@ pub fn parse(sess: &ParseSess, } else { if (!bb_eis.is_empty() && !next_eis.is_empty()) || bb_eis.len() > 1 { - let nts = bb_eis.iter().map(|ei| { - match ei.top_elts.get_tt(ei.idx) { - TtToken(_, MatchNt(bind, name, _, _)) => { + let nts = bb_eis.iter().map(|ei| match ei.top_elts.get_tt(ei.idx) { + TtToken(_, MatchNt(bind, name, _, _)) => { format!("{} ('{}')", name, bind) - } - _ => panic!() - } }).collect::>().join(" or "); + } + _ => panic!() + }).collect::>().join(" or "); + return Error(sp, format!( - "local ambiguity: multiple parsing options: \ - built-in NTs {} or {} other options.", - nts, next_eis.len()).to_string()); + "local ambiguity: multiple parsing options: {}", + match next_eis.len() { + 0 => format!("built-in NTs {}.", nts), + 1 => format!("built-in NTs {} or 1 other option.", nts), + n => format!("built-in NTs {} or {} other options.", nts, n), + } + )) } else if bb_eis.is_empty() && next_eis.is_empty() { return Failure(sp, format!("no rules expected the token `{}`", - pprust::token_to_string(&tok)).to_string()); + pprust::token_to_string(&tok))); } else if !next_eis.is_empty() { /* Now process the next token */ while !next_eis.is_empty() { @@ -465,14 +469,14 @@ pub fn parse(sess: &ParseSess, let mut ei = bb_eis.pop().unwrap(); match ei.top_elts.get_tt(ei.idx) { - TtToken(span, MatchNt(_, ident, _, _)) => { - let match_cur = ei.match_cur; - (&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal( - parse_nt(&mut rust_parser, span, &ident.name.as_str())))); - ei.idx += 1; - ei.match_cur += 1; - } - _ => panic!() + TtToken(span, MatchNt(_, ident, _, _)) => { + let match_cur = ei.match_cur; + (&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal( + parse_nt(&mut rust_parser, span, &ident.name.as_str())))); + ei.idx += 1; + ei.match_cur += 1; + } + _ => panic!() } cur_eis.push(ei); @@ -499,37 +503,37 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { // check at the beginning and the parser checks after each bump panictry!(p.check_unknown_macro_variable()); match name { - "item" => match p.parse_item() { - Some(i) => token::NtItem(i), - None => panic!(p.fatal("expected an item keyword")) - }, - "block" => token::NtBlock(panictry!(p.parse_block())), - "stmt" => match p.parse_stmt() { - Some(s) => token::NtStmt(s), - None => panic!(p.fatal("expected a statement")) - }, - "pat" => token::NtPat(p.parse_pat()), - "expr" => token::NtExpr(p.parse_expr()), - "ty" => token::NtTy(p.parse_ty()), - // this could be handled like a token, since it is one - "ident" => match p.token { - token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(Box::new(sn),b) } + "item" => match p.parse_item() { + Some(i) => token::NtItem(i), + None => panic!(p.fatal("expected an item keyword")) + }, + "block" => token::NtBlock(panictry!(p.parse_block())), + "stmt" => match p.parse_stmt() { + Some(s) => token::NtStmt(s), + None => panic!(p.fatal("expected a statement")) + }, + "pat" => token::NtPat(p.parse_pat()), + "expr" => token::NtExpr(p.parse_expr()), + "ty" => token::NtTy(p.parse_ty()), + // this could be handled like a token, since it is one + "ident" => match p.token { + token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(Box::new(sn),b) } + _ => { + let token_str = pprust::token_to_string(&p.token); + panic!(p.fatal(&format!("expected ident, found {}", + &token_str[..]))) + } + }, + "path" => { + token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons)))) + }, + "meta" => token::NtMeta(p.parse_meta_item()), _ => { - let token_str = pprust::token_to_string(&p.token); - panic!(p.fatal(&format!("expected ident, found {}", - &token_str[..]))) - } - }, - "path" => { - token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons)))) - } - "meta" => token::NtMeta(p.parse_meta_item()), - _ => { - panic!(p.span_fatal_help(sp, + panic!(p.span_fatal_help(sp, &format!("invalid fragment specifier `{}`", name), "valid fragment specifiers are `ident`, `block`, \ `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \ and `item`")) - } + } } } diff --git a/syntex_syntax/src/lib.rs b/syntex_syntax/src/lib.rs index 0d1fa6dd..d1c862ad 100644 --- a/syntex_syntax/src/lib.rs +++ b/syntex_syntax/src/lib.rs @@ -90,6 +90,7 @@ pub mod attr; pub mod codemap; pub mod config; pub mod diagnostic; +pub mod entry; pub mod feature_gate; pub mod fold; pub mod owned_slice; diff --git a/syntex_syntax/src/print/pprust.rs b/syntex_syntax/src/print/pprust.rs index 8b01c10b..b93a244d 100644 --- a/syntex_syntax/src/print/pprust.rs +++ b/syntex_syntax/src/print/pprust.rs @@ -1555,6 +1555,21 @@ impl<'a> State<'a> { self.pclose() } + pub fn check_expr_bin_needs_paren(&mut self, sub_expr: &ast::Expr, + binop: ast::BinOp) -> bool { + match sub_expr.node { + ast::ExprBinary(ref sub_op, _, _) => { + if ast_util::operator_prec(sub_op.node) < + ast_util::operator_prec(binop.node) { + true + } else { + false + } + } + _ => true + } + } + pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> io::Result<()> { let needs_par = needs_parentheses(expr); if needs_par { @@ -1670,10 +1685,18 @@ impl<'a> State<'a> { op: ast::BinOp, lhs: &ast::Expr, rhs: &ast::Expr) -> io::Result<()> { - try!(self.print_expr(lhs)); + if self.check_expr_bin_needs_paren(lhs, op) { + try!(self.print_expr_maybe_paren(lhs)); + } else { + try!(self.print_expr(lhs)); + } try!(space(&mut self.s)); try!(self.word_space(ast_util::binop_to_string(op.node))); - self.print_expr(rhs) + if self.check_expr_bin_needs_paren(rhs, op) { + self.print_expr_maybe_paren(rhs) + } else { + self.print_expr(rhs) + } } fn print_expr_unary(&mut self, @@ -1730,7 +1753,11 @@ impl<'a> State<'a> { try!(self.print_literal(&**lit)); } ast::ExprCast(ref expr, ref ty) => { - try!(self.print_expr(&**expr)); + if let ast::ExprCast(..) = expr.node { + try!(self.print_expr(&**expr)); + } else { + try!(self.print_expr_maybe_paren(&**expr)); + } try!(space(&mut self.s)); try!(self.word_space("as")); try!(self.print_type(&**ty)); diff --git a/syntex_syntax/src/std_inject.rs b/syntex_syntax/src/std_inject.rs index d41a8ff1..d6974abd 100644 --- a/syntex_syntax/src/std_inject.rs +++ b/syntex_syntax/src/std_inject.rs @@ -14,8 +14,7 @@ use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; use codemap; use fold::Folder; use fold; -use parse::token::InternedString; -use parse::token::special_idents; +use parse::token::{intern, InternedString, special_idents}; use parse::{token, ParseSess}; use ptr::P; use util::small_vector::SmallVector; @@ -27,8 +26,7 @@ fn ignored_span(sess: &ParseSess, sp: Span) -> Span { let info = ExpnInfo { call_site: DUMMY_SP, callee: NameAndSpan { - name: "std_inject".to_string(), - format: MacroAttribute, + format: MacroAttribute(intern("std_inject")), span: None, allow_internal_unstable: true, } diff --git a/syntex_syntax/src/test.rs b/syntex_syntax/src/test.rs index 26fb287c..7cd44e5f 100644 --- a/syntex_syntax/src/test.rs +++ b/syntex_syntax/src/test.rs @@ -14,6 +14,7 @@ #![allow(unused_imports)] use self::HasTestSignature::*; +use std::iter; use std::slice; use std::mem; use std::vec; @@ -24,13 +25,14 @@ use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; use codemap; use diagnostic; use config; +use entry::{self, EntryPointType}; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::expand::ExpansionConfig; use fold::{Folder, MoveMap}; use fold; use owned_slice::OwnedSlice; -use parse::token::InternedString; +use parse::token::{intern, InternedString}; use parse::{token, ParseSess}; use print::pprust; use {ast, ast_util}; @@ -173,28 +175,6 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { let tests = mem::replace(&mut self.tests, tests); let tested_submods = mem::replace(&mut self.tested_submods, tested_submods); - // Remove any #[main] from the AST so it doesn't clash with - // the one we're going to add. Only if compiling an executable. - - mod_folded.items = mem::replace(&mut mod_folded.items, vec![]).move_map(|item| { - item.map(|ast::Item {id, ident, attrs, node, vis, span}| { - ast::Item { - id: id, - ident: ident, - attrs: attrs.into_iter().filter_map(|attr| { - if !attr.check_name("main") { - Some(attr) - } else { - None - } - }).collect(), - node: node, - vis: vis, - span: span - } - }) - }); - if !tests.is_empty() || !tested_submods.is_empty() { let (it, sym) = mk_reexport_mod(&mut self.cx, tests, tested_submods); mod_folded.items.push(it); @@ -211,6 +191,55 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { } } +struct EntryPointCleaner { + // Current depth in the ast + depth: usize, +} + +impl fold::Folder for EntryPointCleaner { + fn fold_item(&mut self, i: P) -> SmallVector> { + self.depth += 1; + let folded = fold::noop_fold_item(i, self).expect_one("noop did something"); + self.depth -= 1; + + // Remove any #[main] or #[start] from the AST so it doesn't + // clash with the one we're going to add, but mark it as + // #[allow(dead_code)] to avoid printing warnings. + let folded = match entry::entry_point_type(&*folded, self.depth) { + EntryPointType::MainNamed | + EntryPointType::MainAttr | + EntryPointType::Start => + folded.map(|ast::Item {id, ident, attrs, node, vis, span}| { + let allow_str = InternedString::new("allow"); + let dead_code_str = InternedString::new("dead_code"); + let allow_dead_code_item = + attr::mk_list_item(allow_str, + vec![attr::mk_word_item(dead_code_str)]); + let allow_dead_code = attr::mk_attr_outer(attr::mk_attr_id(), + allow_dead_code_item); + + ast::Item { + id: id, + ident: ident, + attrs: attrs.into_iter() + .filter(|attr| { + !attr.check_name("main") && !attr.check_name("start") + }) + .chain(iter::once(allow_dead_code)) + .collect(), + node: node, + vis: vis, + span: span + } + }), + EntryPointType::None | + EntryPointType::OtherMain => folded, + }; + + SmallVector::one(folded) + } +} + fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec, tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P, ast::Ident) { let super_ = token::str_to_ident("super"); @@ -246,6 +275,10 @@ fn generate_test_harness(sess: &ParseSess, krate: ast::Crate, cfg: &ast::CrateConfig, sd: &diagnostic::SpanHandler) -> ast::Crate { + // Remove the entry points + let mut cleaner = EntryPointCleaner { depth: 0 }; + let krate = cleaner.fold_crate(krate); + let mut feature_gated_cfgs = vec![]; let mut cx: TestCtxt = TestCtxt { sess: sess, @@ -265,8 +298,7 @@ fn generate_test_harness(sess: &ParseSess, cx.ext_cx.bt_push(ExpnInfo { call_site: DUMMY_SP, callee: NameAndSpan { - name: "test".to_string(), - format: MacroAttribute, + format: MacroAttribute(intern("test")), span: None, allow_internal_unstable: false, } @@ -298,8 +330,7 @@ fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { let info = ExpnInfo { call_site: DUMMY_SP, callee: NameAndSpan { - name: "test".to_string(), - format: MacroAttribute, + format: MacroAttribute(intern("test")), span: None, allow_internal_unstable: true, } diff --git a/syntex_syntax/src/visit.rs b/syntex_syntax/src/visit.rs index 25956433..824aee74 100644 --- a/syntex_syntax/src/visit.rs +++ b/syntex_syntax/src/visit.rs @@ -32,7 +32,7 @@ use codemap::Span; use ptr::P; use owned_slice::OwnedSlice; -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> { /// fn foo() or extern "Abi" fn foo() FkItemFn(Ident, &'a Generics, Unsafety, Constness, Abi, Visibility), @@ -40,9 +40,8 @@ pub enum FnKind<'a> { /// fn foo(&self) FkMethod(Ident, &'a MethodSig, Option), - /// |x, y| ... - /// proc(x, y) ... - FkFnBlock, + /// |x, y| {} + FkClosure, } /// Each method of the Visitor trait is a hook to be potentially @@ -616,7 +615,7 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, visitor.visit_generics(&sig.generics); visitor.visit_explicit_self(&sig.explicit_self); } - FkFnBlock(..) => {} + FkClosure(..) => {} } visitor.visit_block(function_body) @@ -817,7 +816,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { } } ExprClosure(_, ref function_declaration, ref body) => { - visitor.visit_fn(FkFnBlock, + visitor.visit_fn(FkClosure, &**function_declaration, &**body, expression.span,