diff options
Diffstat (limited to 'src/libsyntax_ext')
34 files changed, 373 insertions, 499 deletions
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 2ff9fb487c4..41ee6e91b3d 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -1,19 +1,10 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - // Inline assembly support. // use self::State::*; use rustc_data_structures::thin_vec::ThinVec; +use errors::DiagnosticBuilder; use syntax::ast; use syntax::ext::base; use syntax::ext::base::*; @@ -59,9 +50,36 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_ASM); - return DummyResult::expr(sp); } + let mut inline_asm = match parse_inline_asm(cx, sp, tts) { + Ok(Some(inline_asm)) => inline_asm, + Ok(None) => return DummyResult::expr(sp), + Err(mut err) => { + err.emit(); + return DummyResult::expr(sp); + } + }; + + // If there are no outputs, the inline assembly is executed just for its side effects, + // so ensure that it is volatile + if inline_asm.outputs.is_empty() { + inline_asm.volatile = true; + } + + MacEager::expr(P(ast::Expr { + id: ast::DUMMY_NODE_ID, + node: ast::ExprKind::InlineAsm(P(inline_asm)), + span: sp, + attrs: ThinVec::new(), + })) +} + +fn parse_inline_asm<'a>( + cx: &mut ExtCtxt<'a>, + sp: Span, + tts: &[tokenstream::TokenTree], +) -> Result<Option<ast::InlineAsm>, DiagnosticBuilder<'a>> { // Split the tts before the first colon, to avoid `asm!("x": y)` being // parsed as `asm!(z)` with `z = "x": y` which is type ascription. let first_colon = tts.iter() @@ -91,22 +109,33 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, if asm_str_style.is_some() { // If we already have a string with instructions, // ending up in Asm state again is an error. - span_err!(cx, sp, E0660, "malformed inline assembly"); - return DummyResult::expr(sp); + return Err(struct_span_err!( + cx.parse_sess.span_diagnostic, + sp, + E0660, + "malformed inline assembly" + )); } // Nested parser, stop before the first colon (see above). let mut p2 = cx.new_parser_from_tts(&tts[..first_colon]); - let (s, style) = match expr_to_string(cx, - panictry!(p2.parse_expr()), - "inline assembly must be a string literal") { - Some((s, st)) => (s, st), - // let compilation continue - None => return DummyResult::expr(sp), - }; + + if p2.token == token::Eof { + let mut err = + cx.struct_span_err(sp, "macro requires a string literal as an argument"); + err.span_label(sp, "string literal required"); + return Err(err); + } + + let expr = p2.parse_expr()?; + let (s, style) = + match expr_to_string(cx, expr, "inline assembly must be a string literal") { + Some((s, st)) => (s, st), + None => return Ok(None), + }; // This is most likely malformed. if p2.token != token::Eof { - let mut extra_tts = panictry!(p2.parse_all_token_trees()); + let mut extra_tts = p2.parse_all_token_trees()?; extra_tts.extend(tts[first_colon..].iter().cloned()); p = parse::stream_to_parser(cx.parse_sess, extra_tts.into_iter().collect()); } @@ -116,18 +145,17 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, } Outputs => { while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !outputs.is_empty() { p.eat(&token::Comma); } - let (constraint, _str_style) = panictry!(p.parse_str()); + let (constraint, _) = p.parse_str()?; let span = p.prev_span; - panictry!(p.expect(&token::OpenDelim(token::Paren))); - let out = panictry!(p.parse_expr()); - panictry!(p.expect(&token::CloseDelim(token::Paren))); + p.expect(&token::OpenDelim(token::Paren))?; + let expr = p.parse_expr()?; + p.expect(&token::CloseDelim(token::Paren))?; // Expands a read+write operand into two operands. // @@ -154,7 +182,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, let is_indirect = constraint_str.contains("*"); outputs.push(ast::InlineAsmOutput { constraint: output.unwrap_or(constraint), - expr: out, + expr, is_rw, is_indirect, }); @@ -162,12 +190,11 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, } Inputs => { while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !inputs.is_empty() { p.eat(&token::Comma); } - let (constraint, _str_style) = panictry!(p.parse_str()); + let (constraint, _) = p.parse_str()?; if constraint.as_str().starts_with("=") { span_err!(cx, p.prev_span, E0662, @@ -177,21 +204,20 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, "input operand constraint contains '+'"); } - panictry!(p.expect(&token::OpenDelim(token::Paren))); - let input = panictry!(p.parse_expr()); - panictry!(p.expect(&token::CloseDelim(token::Paren))); + p.expect(&token::OpenDelim(token::Paren))?; + let input = p.parse_expr()?; + p.expect(&token::CloseDelim(token::Paren))?; inputs.push((constraint, input)); } } Clobbers => { while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !clobs.is_empty() { p.eat(&token::Comma); } - let (s, _str_style) = panictry!(p.parse_str()); + let (s, _) = p.parse_str()?; if OPTIONS.iter().any(|&opt| s == opt) { cx.span_warn(p.prev_span, "expected a clobber, found an option"); @@ -204,7 +230,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, } } Options => { - let (option, _str_style) = panictry!(p.parse_str()); + let (option, _) = p.parse_str()?; if option == "volatile" { // Indicates that the inline assembly has side effects @@ -245,26 +271,15 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, } } - // If there are no outputs, the inline assembly is executed just for its side effects, - // so ensure that it is volatile - if outputs.is_empty() { - volatile = true; - } - - MacEager::expr(P(ast::Expr { - id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::InlineAsm(P(ast::InlineAsm { - asm, - asm_str_style: asm_str_style.unwrap(), - outputs, - inputs, - clobbers: clobs, - volatile, - alignstack, - dialect, - ctxt: cx.backtrace(), - })), - span: sp, - attrs: ThinVec::new(), + Ok(Some(ast::InlineAsm { + asm, + asm_str_style: asm_str_style.unwrap(), + outputs, + inputs, + clobbers: clobs, + volatile, + alignstack, + dialect, + ctxt: cx.backtrace(), })) } diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs index a2384b59048..b27f495322a 100644 --- a/src/libsyntax_ext/assert.rs +++ b/src/libsyntax_ext/assert.rs @@ -1,19 +1,11 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use syntax::ast::*; +use errors::DiagnosticBuilder; +use syntax::ast::{self, *}; use syntax::source_map::Spanned; use syntax::ext::base::*; use syntax::ext::build::AstBuilder; use syntax::parse::token; use syntax::print::pprust; +use syntax::ptr::P; use syntax::symbol::Symbol; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax_pos::{Span, DUMMY_SP}; @@ -23,33 +15,18 @@ pub fn expand_assert<'cx>( sp: Span, tts: &[TokenTree], ) -> Box<dyn MacResult + 'cx> { - let mut parser = cx.new_parser_from_tts(tts); - - if parser.token == token::Eof { - cx.struct_span_err(sp, "macro requires a boolean expression as an argument") - .span_label(sp, "boolean expression required") - .emit(); - return DummyResult::expr(sp); - } - - let cond_expr = panictry!(parser.parse_expr()); - let custom_msg_args = if parser.eat(&token::Comma) { - let ts = parser.parse_tokens(); - if !ts.is_empty() { - Some(ts) - } else { - None + let Assert { cond_expr, custom_message } = match parse_assert(cx, sp, tts) { + Ok(assert) => assert, + Err(mut err) => { + err.emit(); + return DummyResult::expr(sp); } - } else { - None }; let sp = sp.apply_mark(cx.current_expansion.mark); let panic_call = Mac_ { path: Path::from_ident(Ident::new(Symbol::intern("panic"), sp)), - tts: if let Some(ts) = custom_msg_args { - ts.into() - } else { + tts: custom_message.unwrap_or_else(|| { TokenStream::from(TokenTree::Token( DUMMY_SP, token::Literal( @@ -59,8 +36,8 @@ pub fn expand_assert<'cx>( ))), None, ), - )).into() - }, + )) + }).into(), delim: MacDelimiter::Parenthesis, }; let if_expr = cx.expr_if( @@ -77,3 +54,36 @@ pub fn expand_assert<'cx>( ); MacEager::expr(if_expr) } + +struct Assert { + cond_expr: P<ast::Expr>, + custom_message: Option<TokenStream>, +} + +fn parse_assert<'a>( + cx: &mut ExtCtxt<'a>, + sp: Span, + tts: &[TokenTree] +) -> Result<Assert, DiagnosticBuilder<'a>> { + let mut parser = cx.new_parser_from_tts(tts); + + if parser.token == token::Eof { + let mut err = cx.struct_span_err(sp, "macro requires a boolean expression as an argument"); + err.span_label(sp, "boolean expression required"); + return Err(err); + } + + Ok(Assert { + cond_expr: parser.parse_expr()?, + custom_message: if parser.eat(&token::Comma) { + let ts = parser.parse_tokens(); + if !ts.is_empty() { + Some(ts) + } else { + None + } + } else { + None + }, + }) +} diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs index 2384b6a796e..3b47b03cbe8 100644 --- a/src/libsyntax_ext/cfg.rs +++ b/src/libsyntax_ext/cfg.rs @@ -1,17 +1,9 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - /// The compiler code necessary to support the cfg! extension, which expands to /// a literal `true` or `false` based on whether the given cfg matches the /// current compilation environment. +use errors::DiagnosticBuilder; +use syntax::ast; use syntax::ext::base::*; use syntax::ext::base; use syntax::ext::build::AstBuilder; @@ -25,16 +17,39 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt, tts: &[tokenstream::TokenTree]) -> Box<dyn base::MacResult + 'static> { let sp = sp.apply_mark(cx.current_expansion.mark); + + match parse_cfg(cx, sp, tts) { + Ok(cfg) => { + let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features); + MacEager::expr(cx.expr_bool(sp, matches_cfg)) + } + Err(mut err) => { + err.emit(); + DummyResult::expr(sp) + } + } +} + +fn parse_cfg<'a>( + cx: &mut ExtCtxt<'a>, + sp: Span, + tts: &[tokenstream::TokenTree], +) -> Result<ast::MetaItem, DiagnosticBuilder<'a>> { let mut p = cx.new_parser_from_tts(tts); - let cfg = panictry!(p.parse_meta_item()); + + if p.token == token::Eof { + let mut err = cx.struct_span_err(sp, "macro requires a cfg-pattern as an argument"); + err.span_label(sp, "cfg-pattern required"); + return Err(err); + } + + let cfg = p.parse_meta_item()?; let _ = p.eat(&token::Comma); if !p.eat(&token::Eof) { - cx.span_err(sp, "expected 1 cfg-pattern"); - return DummyResult::expr(sp); + return Err(cx.struct_span_err(sp, "expected 1 cfg-pattern")); } - let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features); - MacEager::expr(cx.expr_bool(sp, matches_cfg)) + Ok(cfg) } diff --git a/src/libsyntax_ext/compile_error.rs b/src/libsyntax_ext/compile_error.rs index ce7fb400bd5..8f7f5deb091 100644 --- a/src/libsyntax_ext/compile_error.rs +++ b/src/libsyntax_ext/compile_error.rs @@ -1,13 +1,3 @@ -// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - // The compiler code necessary to support the compile_error! extension. use syntax::ext::base::*; @@ -20,7 +10,7 @@ pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt, tts: &[tokenstream::TokenTree]) -> Box<dyn base::MacResult + 'cx> { let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") { - None => return DummyResult::expr(sp), + None => return DummyResult::any(sp), Some(v) => v, }; diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index dcdd2c590e0..807f190cb6a 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -1,13 +1,3 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use syntax::ast; use syntax::ext::base; use syntax::ext::build::AstBuilder; @@ -28,6 +18,7 @@ pub fn expand_syntax_ext( }; let mut accumulator = String::new(); let mut missing_literal = vec![]; + let mut has_errors = false; for e in es { match e.node { ast::ExprKind::Lit(ref lit) => match lit.node { @@ -51,6 +42,9 @@ pub fn expand_syntax_ext( cx.span_err(e.span, "cannot concatenate a byte string literal"); } }, + ast::ExprKind::Err => { + has_errors = true; + } _ => { missing_literal.push(e.span); } @@ -60,6 +54,9 @@ pub fn expand_syntax_ext( let mut err = cx.struct_span_err(missing_literal, "expected a literal"); err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`"); err.emit(); + return base::DummyResult::expr(sp); + } else if has_errors { + return base::DummyResult::expr(sp); } let sp = sp.apply_mark(cx.current_expansion.mark); 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 c8cc11e4354..de96de4bdc2 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -1,13 +1,3 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use rustc_data_structures::thin_vec::ThinVec; use syntax::ast; @@ -30,12 +20,11 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_CONCAT_IDENTS); - return base::DummyResult::expr(sp); } if tts.is_empty() { cx.span_err(sp, "concat_idents! takes 1 or more arguments."); - return DummyResult::expr(sp); + return DummyResult::any(sp); } let mut res_str = String::new(); @@ -45,7 +34,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, TokenTree::Token(_, token::Comma) => {} _ => { cx.span_err(sp, "concat_idents! expecting comma."); - return DummyResult::expr(sp); + return DummyResult::any(sp); } } } else { @@ -54,7 +43,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, res_str.push_str(&ident.as_str()), _ => { cx.span_err(sp, "concat_idents! requires ident args."); - return DummyResult::expr(sp); + return DummyResult::any(sp); } } } diff --git a/src/libsyntax_ext/deriving/bounds.rs b/src/libsyntax_ext/deriving/bounds.rs index 41e980b3346..dcfc6ab0391 100644 --- a/src/libsyntax_ext/deriving/bounds.rs +++ b/src/libsyntax_ext/deriving/bounds.rs @@ -1,13 +1,3 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use deriving::path_std; use deriving::generic::*; use deriving::generic::ty::*; diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index b9e0933331c..38d433e842c 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -1,13 +1,3 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use deriving::path_std; use deriving::generic::*; use deriving::generic::ty::*; diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index f202bc4e524..dbba8c3b7a0 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -1,13 +1,3 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use deriving::path_std; use deriving::generic::*; use deriving::generic::ty::*; diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs index 117bedf453e..21bd56710ac 100644 --- a/src/libsyntax_ext/deriving/cmp/ord.rs +++ b/src/libsyntax_ext/deriving/cmp/ord.rs @@ -1,13 +1,3 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use deriving::path_std; use deriving::generic::*; use deriving::generic::ty::*; diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 24a3a7542fb..4ec24bce4cd 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -1,13 +1,3 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use deriving::{path_local, path_std}; use deriving::generic::*; use deriving::generic::ty::*; diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index 196cfa5fe35..9ef481edf51 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -1,13 +1,3 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - pub use self::OrderingOp::*; use deriving::{path_local, pathvec_std, path_std}; diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index cc2fa685687..2f20814ef3e 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -1,13 +1,3 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use errors::FatalError; use syntax::ast::{self, ItemKind, Attribute, Mac}; use syntax::attr::{mark_used, mark_known}; diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index df9c351ef1c..b3e5bd9283e 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -1,13 +1,3 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use deriving::path_std; use deriving::generic::*; use deriving::generic::ty::*; diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs index c2b92944999..89c630e9915 100644 --- a/src/libsyntax_ext/deriving/decodable.rs +++ b/src/libsyntax_ext/deriving/decodable.rs @@ -1,13 +1,3 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more. use deriving::{self, pathvec_std}; diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs index adbc5828b8f..32d02bec798 100644 --- a/src/libsyntax_ext/deriving/default.rs +++ b/src/libsyntax_ext/deriving/default.rs @@ -1,19 +1,9 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use deriving::path_std; use deriving::generic::*; use deriving::generic::ty::*; use syntax::ast::{Expr, MetaItem}; -use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::ext::base::{Annotatable, DummyResult, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::Symbol; @@ -79,7 +69,7 @@ fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructur span_err!(cx, trait_span, E0665, "`Default` cannot be derived for enums, only structs"); // let compilation continue - cx.expr_usize(trait_span, 0) + DummyResult::raw_expr(trait_span, true) } _ => cx.span_bug(trait_span, "Non-static method in `derive(Default)`"), }; diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index 5438c8b52af..c8935874158 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -1,13 +1,3 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! The compiler code necessary to implement the `#[derive(Encodable)]` //! (and `Decodable`, in decodable.rs) extension. The idea here is that //! type-defining items may be tagged with `#[derive(Encodable, Decodable)]`. diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 443fd48120e..22643db5016 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -1,13 +1,3 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! Some code that abstracts away much of the boilerplate of writing //! `derive` instances for traits. Among other things it manages getting //! access to the fields of the 4 different sorts of structs and enum diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 11689a98a79..83ec99b3573 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -1,13 +1,3 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use //! when specifying impls to be derived. diff --git a/src/libsyntax_ext/deriving/hash.rs b/src/libsyntax_ext/deriving/hash.rs index 950e8c84f17..4af2bd57b00 100644 --- a/src/libsyntax_ext/deriving/hash.rs +++ b/src/libsyntax_ext/deriving/hash.rs @@ -1,13 +1,3 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use deriving::{self, pathvec_std, path_std}; use deriving::generic::*; use deriving::generic::ty::*; diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index ae47a028bc3..7548d43f184 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -1,13 +1,3 @@ -// 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 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! The compiler code necessary to implement the `#[derive]` extensions. use rustc_data_structures::sync::Lrc; @@ -163,6 +153,5 @@ fn call_intrinsic(cx: &ExtCtxt, id: ast::DUMMY_NODE_ID, rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated), span, - recovered: false, })) } diff --git a/src/libsyntax_ext/diagnostics.rs b/src/libsyntax_ext/diagnostics.rs index f99a6c3c216..e8ad4af6850 100644 --- a/src/libsyntax_ext/diagnostics.rs +++ b/src/libsyntax_ext/diagnostics.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - #![allow(non_snake_case)] // Error messages for EXXXX errors. diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index 8f26b2402aa..16fb64a5f39 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -1,13 +1,3 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - // The compiler code necessary to support the env! extension. Eventually this // should all get sucked into either the compiler syntax extension plugin // interface. @@ -89,7 +79,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, let e = match env::var(&*var.as_str()) { Err(_) => { cx.span_err(sp, &msg.as_str()); - cx.expr_usize(sp, 0) + return DummyResult::expr(sp); } Ok(s) => cx.expr_str(sp, Symbol::intern(&s)), }; diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 41799eede9e..61722ba5516 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -1,18 +1,9 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use self::ArgumentType::*; use self::Position::*; use fmt_macros as parse; +use errors::DiagnosticBuilder; use syntax::ast; use syntax::ext::base::{self, *}; use syntax::ext::build::AstBuilder; @@ -122,7 +113,7 @@ struct Context<'a, 'b: 'a> { is_literal: bool, } -/// Parses the arguments from the given list of tokens, returning None +/// Parses the arguments from the given list of tokens, returning the diagnostic /// if there's a parse error so we can continue parsing other format! /// expressions. /// @@ -131,27 +122,26 @@ struct Context<'a, 'b: 'a> { /// ```text /// Some((fmtstr, parsed arguments, index map for named arguments)) /// ``` -fn parse_args(ecx: &mut ExtCtxt, - sp: Span, - tts: &[tokenstream::TokenTree]) - -> Option<(P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<String, usize>)> { +fn parse_args<'a>( + ecx: &mut ExtCtxt<'a>, + sp: Span, + tts: &[tokenstream::TokenTree] +) -> Result<(P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<String, usize>), DiagnosticBuilder<'a>> { let mut args = Vec::<P<ast::Expr>>::new(); let mut names = FxHashMap::<String, usize>::default(); let mut p = ecx.new_parser_from_tts(tts); if p.token == token::Eof { - ecx.span_err(sp, "requires at least a format string argument"); - return None; + return Err(ecx.struct_span_err(sp, "requires at least a format string argument")); } - let fmtstr = panictry!(p.parse_expr()); + let fmtstr = p.parse_expr()?; let mut named = false; while p.token != token::Eof { if !p.eat(&token::Comma) { - ecx.span_err(p.span, "expected token: `,`"); - return None; + return Err(ecx.struct_span_err(p.span, "expected token: `,`")); } if p.token == token::Eof { break; @@ -162,16 +152,15 @@ fn parse_args(ecx: &mut ExtCtxt, p.bump(); i } else { - ecx.span_err( + return Err(ecx.struct_span_err( p.span, "expected ident, positional arguments cannot follow named arguments", - ); - return None; + )); }; let name: &str = &ident.as_str(); - panictry!(p.expect(&token::Eq)); - let e = panictry!(p.parse_expr()); + p.expect(&token::Eq).unwrap(); + let e = p.parse_expr()?; if let Some(prev) = names.get(name) { ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", name)) .span_note(args[*prev].span, "previously here") @@ -187,10 +176,11 @@ fn parse_args(ecx: &mut ExtCtxt, names.insert(name.to_string(), slot); args.push(e); } else { - args.push(panictry!(p.parse_expr())); + let e = p.parse_expr()?; + args.push(e); } } - Some((fmtstr, args, names)) + Ok((fmtstr, args, names)) } impl<'a, 'b> Context<'a, 'b> { @@ -676,7 +666,7 @@ impl<'a, 'b> Context<'a, 'b> { "X" => "UpperHex", _ => { ecx.span_err(sp, &format!("unknown format trait `{}`", *tyname)); - "Dummy" + return DummyResult::raw_expr(sp, true); } } } @@ -699,10 +689,13 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, -> Box<dyn base::MacResult + 'cx> { sp = sp.apply_mark(ecx.current_expansion.mark); match parse_args(ecx, sp, tts) { - Some((efmt, args, names)) => { + Ok((efmt, args, names)) => { MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, false)) } - None => DummyResult::expr(sp), + Err(mut err) => { + err.emit(); + DummyResult::expr(sp) + } } } @@ -723,14 +716,16 @@ pub fn expand_format_args_nl<'cx>( sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_FORMAT_ARGS_NL); - return base::DummyResult::expr(sp); } sp = sp.apply_mark(ecx.current_expansion.mark); match parse_args(ecx, sp, tts) { - Some((efmt, args, names)) => { + Ok((efmt, args, names)) => { MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, true)) } - None => DummyResult::expr(sp), + Err(mut err) => { + err.emit(); + DummyResult::expr(sp) + } } } @@ -759,34 +754,137 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, fmt } Ok(fmt) => fmt, - Err(mut err) => { - let sugg_fmt = match args.len() { - 0 => "{}".to_string(), - _ => format!("{}{{}}", "{} ".repeat(args.len())), - }; - err.span_suggestion_with_applicability( - fmt_sp.shrink_to_lo(), - "you might be missing a string literal to format with", - format!("\"{}\", ", sugg_fmt), - Applicability::MaybeIncorrect, - ); - err.emit(); - return DummyResult::raw_expr(sp); + Err(err) => { + if let Some(mut err) = err { + let sugg_fmt = match args.len() { + 0 => "{}".to_string(), + _ => format!("{}{{}}", "{} ".repeat(args.len())), + }; + err.span_suggestion_with_applicability( + fmt_sp.shrink_to_lo(), + "you might be missing a string literal to format with", + format!("\"{}\", ", sugg_fmt), + Applicability::MaybeIncorrect, + ); + err.emit(); + } + return DummyResult::raw_expr(sp, true); } }; - let is_literal = match ecx.source_map().span_to_snippet(fmt_sp) { - Ok(ref s) if s.starts_with("\"") || s.starts_with("r#") => true, - _ => false, + let (is_literal, fmt_snippet) = match ecx.source_map().span_to_snippet(fmt_sp) { + Ok(s) => (s.starts_with("\"") || s.starts_with("r#"), Some(s)), + _ => (false, None), }; - let fmt_str = &*fmt.node.0.as_str(); let str_style = match fmt.node.1 { ast::StrStyle::Cooked => None, - ast::StrStyle::Raw(raw) => Some(raw as usize), + ast::StrStyle::Raw(raw) => { + Some(raw as usize) + }, + }; + + /// Find the indices of all characters that have been processed and differ between the actual + /// written code (code snippet) and the `InternedString` that get's processed in the `Parser` + /// in order to properly synthethise the intra-string `Span`s for error diagnostics. + fn find_skips(snippet: &str, is_raw: bool) -> Vec<usize> { + let mut eat_ws = false; + let mut s = snippet.chars().enumerate().peekable(); + let mut skips = vec![]; + while let Some((pos, c)) = s.next() { + match (c, s.peek()) { + // skip whitespace and empty lines ending in '\\' + ('\\', Some((next_pos, '\n'))) if !is_raw => { + eat_ws = true; + skips.push(pos); + skips.push(*next_pos); + let _ = s.next(); + } + ('\\', Some((next_pos, '\n'))) | + ('\\', Some((next_pos, 'n'))) | + ('\\', Some((next_pos, 't'))) if eat_ws => { + skips.push(pos); + skips.push(*next_pos); + let _ = s.next(); + } + (' ', _) | + ('\n', _) | + ('\t', _) if eat_ws => { + skips.push(pos); + } + ('\\', Some((next_pos, 'n'))) | + ('\\', Some((next_pos, 't'))) | + ('\\', Some((next_pos, '0'))) | + ('\\', Some((next_pos, '\\'))) | + ('\\', Some((next_pos, '\''))) | + ('\\', Some((next_pos, '\"'))) => { + skips.push(*next_pos); + let _ = s.next(); + } + ('\\', Some((_, 'x'))) if !is_raw => { + for _ in 0..3 { // consume `\xAB` literal + if let Some((pos, _)) = s.next() { + skips.push(pos); + } else { + break; + } + } + } + ('\\', Some((_, 'u'))) if !is_raw => { + if let Some((pos, _)) = s.next() { + skips.push(pos); + } + if let Some((next_pos, next_c)) = s.next() { + if next_c == '{' { + skips.push(next_pos); + let mut i = 0; // consume up to 6 hexanumeric chars + closing `}` + while let (Some((next_pos, c)), true) = (s.next(), i < 7) { + if c.is_digit(16) { + skips.push(next_pos); + } else if c == '}' { + skips.push(next_pos); + break; + } else { + break; + } + i += 1; + } + } else if next_c.is_digit(16) { + skips.push(next_pos); + // We suggest adding `{` and `}` when appropriate, accept it here as if + // it were correct + let mut i = 0; // consume up to 6 hexanumeric chars + while let (Some((next_pos, c)), _) = (s.next(), i < 6) { + if c.is_digit(16) { + skips.push(next_pos); + } else { + break; + } + i += 1; + } + } + } + } + _ if eat_ws => { // `take_while(|c| c.is_whitespace())` + eat_ws = false; + } + _ => {} + } + } + skips + } + + let skips = if let (true, Some(ref snippet)) = (is_literal, fmt_snippet.as_ref()) { + let r_start = str_style.map(|r| r + 1).unwrap_or(0); + let r_end = str_style.map(|r| r).unwrap_or(0); + let s = &snippet[r_start + 1..snippet.len() - r_end - 1]; + find_skips(s, str_style.is_some()) + } else { + vec![] }; - let mut parser = parse::Parser::new(fmt_str, str_style); + let fmt_str = &*fmt.node.0.as_str(); // for the suggestions below + let mut parser = parse::Parser::new(fmt_str, str_style, skips.clone(), append_newline); let mut unverified_pieces = Vec::new(); while let Some(piece) = parser.next() { @@ -799,18 +897,25 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, if !parser.errors.is_empty() { let err = parser.errors.remove(0); - let sp = fmt.span.from_inner_byte_pos(err.start, err.end); - let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}", err.description)); + let sp = fmt.span.from_inner_byte_pos(err.start.unwrap(), err.end.unwrap()); + let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}", + err.description)); e.span_label(sp, err.label + " in format string"); if let Some(note) = err.note { e.note(¬e); } + if let Some((label, start, end)) = err.secondary_label { + let sp = fmt.span.from_inner_byte_pos(start.unwrap(), end.unwrap()); + e.span_label(sp, label); + } e.emit(); - return DummyResult::raw_expr(sp); + return DummyResult::raw_expr(sp, true); } let arg_spans = parser.arg_places.iter() - .map(|&(start, end)| fmt.span.from_inner_byte_pos(start, end)) + .map(|&(parse::SpanIndex(start), parse::SpanIndex(end))| { + fmt.span.from_inner_byte_pos(start, end) + }) .collect(); let mut cx = Context { @@ -904,13 +1009,18 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, let mut diag = { if errs_len == 1 { let (sp, msg) = errs.into_iter().next().unwrap(); - cx.ecx.struct_span_err(sp, msg) + let mut diag = cx.ecx.struct_span_err(sp, msg); + diag.span_label(sp, msg); + diag } else { let mut diag = cx.ecx.struct_span_err( errs.iter().map(|&(sp, _)| sp).collect::<Vec<Span>>(), "multiple unused formatting arguments", ); diag.span_label(cx.fmtsp, "multiple missing formatting specifiers"); + for (sp, msg) in errs { + diag.span_label(sp, msg); + } diag } }; diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs index 9c854019de6..8ac6d460ec3 100644 --- a/src/libsyntax_ext/format_foreign.rs +++ b/src/libsyntax_ext/format_foreign.rs @@ -1,13 +1,3 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - pub mod printf { use super::strcursor::StrCursor as Cur; diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs index 000bede7348..0a12e27c4fc 100644 --- a/src/libsyntax_ext/global_asm.rs +++ b/src/libsyntax_ext/global_asm.rs @@ -1,13 +1,3 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - /// Module-level assembly support. /// /// The macro defined here allows you to specify "top-level", @@ -18,11 +8,13 @@ /// LLVM's `module asm "some assembly here"`. All of LLVM's caveats /// therefore apply. +use errors::DiagnosticBuilder; use syntax::ast; use syntax::source_map::respan; use syntax::ext::base; use syntax::ext::base::*; use syntax::feature_gate; +use syntax::parse::token; use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; @@ -39,27 +31,49 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_GLOBAL_ASM); - return DummyResult::any(sp); } + match parse_global_asm(cx, sp, tts) { + Ok(Some(global_asm)) => { + MacEager::items(smallvec![P(ast::Item { + ident: ast::Ident::with_empty_ctxt(Symbol::intern("")), + attrs: Vec::new(), + id: ast::DUMMY_NODE_ID, + node: ast::ItemKind::GlobalAsm(P(global_asm)), + vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited), + span: sp, + tokens: None, + })]) + } + Ok(None) => DummyResult::any(sp), + Err(mut err) => { + err.emit(); + DummyResult::any(sp) + } + } +} + +fn parse_global_asm<'a>( + cx: &mut ExtCtxt<'a>, + sp: Span, + tts: &[tokenstream::TokenTree] +) -> Result<Option<ast::GlobalAsm>, DiagnosticBuilder<'a>> { let mut p = cx.new_parser_from_tts(tts); - let (asm, _) = match expr_to_string(cx, - panictry!(p.parse_expr()), - "inline assembly must be a string literal") { + + if p.token == token::Eof { + let mut err = cx.struct_span_err(sp, "macro requires a string literal as an argument"); + err.span_label(sp, "string literal required"); + return Err(err); + } + + let expr = p.parse_expr()?; + let (asm, _) = match expr_to_string(cx, expr, "inline assembly must be a string literal") { Some((s, st)) => (s, st), - None => return DummyResult::any(sp), + None => return Ok(None), }; - MacEager::items(smallvec![P(ast::Item { - ident: ast::Ident::with_empty_ctxt(Symbol::intern("")), - attrs: Vec::new(), - id: ast::DUMMY_NODE_ID, - node: ast::ItemKind::GlobalAsm(P(ast::GlobalAsm { - asm, - ctxt: cx.backtrace(), - })), - vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited), - span: sp, - tokens: None, - })]) + Ok(Some(ast::GlobalAsm { + asm, + ctxt: cx.backtrace(), + })) } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index c49d5772531..17996f23691 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -1,13 +1,3 @@ -// Copyright 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 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! Syntax extensions in the Rust compiler. #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", @@ -24,6 +14,8 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] +#![recursion_limit="256"] + extern crate fmt_macros; #[macro_use] extern crate syntax; diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs index 7b76b1e8914..a143186b945 100644 --- a/src/libsyntax_ext/log_syntax.rs +++ b/src/libsyntax_ext/log_syntax.rs @@ -1,13 +1,3 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use syntax::ext::base; use syntax::feature_gate; use syntax::print; @@ -24,11 +14,10 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_LOG_SYNTAX); - return base::DummyResult::any(sp); } println!("{}", print::pprust::tts_to_string(tts)); // any so that `log_syntax` can be invoked as an expression and item. - base::DummyResult::any(sp) + base::DummyResult::any_valid(sp) } diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index f4ff0989b5d..38f7ca500b2 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -1,13 +1,3 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use std::mem; use errors; diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs index 43ef31a00ba..60d167d01ee 100644 --- a/src/libsyntax_ext/proc_macro_impl.rs +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -1,14 +1,3 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - use errors::FatalError; use syntax::source_map::Span; diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index ca960cbe41b..afd86a4f746 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use errors::{self, Diagnostic, DiagnosticBuilder}; use std::panic; @@ -21,7 +11,7 @@ use syntax::ast; use syntax::ext::base::ExtCtxt; use syntax::parse::lexer::comments; use syntax::parse::{self, token, ParseSess}; -use syntax::tokenstream::{self, DelimSpan, TokenStream}; +use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream}; use syntax_pos::hygiene::{SyntaxContext, Transparency}; use syntax_pos::symbol::{keywords, Symbol}; use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span}; @@ -278,11 +268,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> { }; let tree = tokenstream::TokenTree::Token(span, token); - if joint { - tree.joint() - } else { - tree.into() - } + TokenStream::Tree(tree, if joint { Joint } else { NonJoint }) } } diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index 1f2e6fc81c8..cf842dddeb3 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -1,13 +1,3 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - /// The expansion from a test function to the appropriate test struct for libtest /// Ideally, this code would be in libtest but for efficiency and error messages it lives here. diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs index 0128db7dd78..04e33671872 100644 --- a/src/libsyntax_ext/test_case.rs +++ b/src/libsyntax_ext/test_case.rs @@ -1,13 +1,5 @@ - -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. // #[test_case] is used by custom test authors to mark tests // When building for test, it needs to make the item public and gensym the name @@ -39,8 +31,6 @@ pub fn expand( attr_sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS); - - return vec![anno_item]; } if !ecx.ecfg.should_test { return vec![]; } diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs index 256b525b8be..638d7b5568b 100644 --- a/src/libsyntax_ext/trace_macros.rs +++ b/src/libsyntax_ext/trace_macros.rs @@ -1,13 +1,3 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use syntax::ext::base::ExtCtxt; use syntax::ext::base; use syntax::feature_gate; @@ -25,7 +15,6 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt, sp, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_TRACE_MACROS); - return base::DummyResult::any(sp); } match (tt.len(), tt.first()) { @@ -38,5 +27,5 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt, _ => cx.span_err(sp, "trace_macros! accepts only `true` or `false`"), } - base::DummyResult::any(sp) + base::DummyResult::any_valid(sp) } |
