diff options
| author | Esteban Küber <esteban@commure.com> | 2018-07-19 18:53:26 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@commure.com> | 2018-07-19 23:18:07 -0700 |
| commit | 154dee2dccd45f929b0a3d2ce2d45739513f77c8 (patch) | |
| tree | 4170231db8b43d3c03f074eb1521ec7f010c2720 /src | |
| parent | a47653214f8f8561196acf25b8898e7148f1c052 (diff) | |
| download | rust-154dee2dccd45f929b0a3d2ce2d45739513f77c8.tar.gz rust-154dee2dccd45f929b0a3d2ce2d45739513f77c8.zip | |
rework println
Diffstat (limited to 'src')
| -rw-r--r-- | src/libfmt_macros/lib.rs | 6 | ||||
| -rw-r--r-- | src/libstd/macros.rs | 26 | ||||
| -rw-r--r-- | src/libsyntax_ext/format.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax_ext/lib.rs | 10 | ||||
| -rw-r--r-- | src/test/ui/macros/trace-macro.stderr | 8 |
5 files changed, 63 insertions, 9 deletions
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 51c3efb41ad..ee590bc3b5e 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -273,7 +273,11 @@ impl<'a> Parser<'a> { } } else { let msg = format!("expected `{:?}` but string was terminated", c); - let pos = self.input.len() + 1; // point at closing `"` + // point at closing `"`, unless the last char is `\n` to account for `println` + let pos = match self.input.chars().last() { + Some('\n') => self.input.len(), + _ => self.input.len() + 1, + }; if c == '}' { self.err_with_note(msg, format!("expected `{:?}`", c), diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 527bab759b0..a4bcf7fd26c 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -153,9 +153,17 @@ macro_rules! print { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] +#[allow_internal_unstable] macro_rules! println { () => (print!("\n")); - ($($arg:tt)*) => (print!("{}\n", format_args!($($arg)*))); + ($($arg:tt)*) => ({ + #[cfg(not(stage0))] { + ($crate::io::_print(format_args_nl!($($arg)*))); + } + #[cfg(stage0)] { + print!("{}\n", format_args!($($arg)*)) + } + }) } /// Macro for printing to the standard error. @@ -211,7 +219,8 @@ macro_rules! eprint { #[stable(feature = "eprint", since = "1.19.0")] macro_rules! eprintln { () => (eprint!("\n")); - ($($arg:tt)*) => (eprint!("{}\n", format_args!($($arg)*))); + ($fmt:expr) => (eprint!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => (eprint!(concat!($fmt, "\n"), $($arg)*)); } #[macro_export] @@ -397,6 +406,19 @@ pub mod builtin { ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }); } + /// Internal version of [`format_args`]. + /// + /// This macro differs from [`format_args`] in that it appends a newline to the format string + /// and nothing more. It is perma-unstable. + /// + /// [`format_args`]: ../std/macro.format_args.html + #[doc(hidden)] + #[unstable(feature = "println_format_args", issue="0")] + #[macro_export] + macro_rules! format_args_nl { + ($fmt:expr) => ({ /* compiler built-in */ }); + ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }); + } /// Inspect an environment variable at compile time. /// /// This macro will expand to the value of the named environment variable at diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 6abf987d0ab..d3e5adf6835 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -683,7 +683,20 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, sp = sp.apply_mark(ecx.current_expansion.mark); match parse_args(ecx, sp, tts) { Some((efmt, args, names)) => { - MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names)) + MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, false)) + } + None => DummyResult::expr(sp), + } +} + +pub fn expand_format_args_nl<'cx>(ecx: &'cx mut ExtCtxt, + mut sp: Span, + tts: &[tokenstream::TokenTree]) + -> Box<dyn base::MacResult + 'cx> { + sp = sp.apply_mark(ecx.current_expansion.mark); + match parse_args(ecx, sp, tts) { + Some((efmt, args, names)) => { + MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, true)) } None => DummyResult::expr(sp), } @@ -695,7 +708,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, efmt: P<ast::Expr>, args: Vec<P<ast::Expr>>, - names: HashMap<String, usize>) + names: HashMap<String, usize>, + append_newline: bool) -> P<ast::Expr> { // NOTE: this verbose way of initializing `Vec<Vec<ArgumentType>>` is because // `ArgumentType` does not derive `Clone`. @@ -706,6 +720,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, let msg = "format argument must be a string literal"; let fmt_sp = efmt.span; let fmt = match expr_to_spanned_string(ecx, efmt, msg) { + Ok(mut fmt) if append_newline => { + fmt.node.0 = Symbol::intern(&format!("{}\n", fmt.node.0)); + fmt + } Ok(fmt) => fmt, Err(mut err) => { let sugg_fmt = match args.len() { diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index bdf7a8d7040..ff76e788b3c 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -139,6 +139,16 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, unstable_feature: None, edition: hygiene::default_edition(), }); + register(Symbol::intern("format_args_nl"), + NormalTT { + expander: Box::new(format::expand_format_args_nl), + def_info: None, + allow_internal_unstable: true, + allow_internal_unsafe: false, + local_inner_macros: false, + unstable_feature: None, + edition: hygiene::default_edition(), + }); for (name, ext) in user_exts { register(name, ext); diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr index 6d8a329be80..2a30d983751 100644 --- a/src/test/ui/macros/trace-macro.stderr +++ b/src/test/ui/macros/trace-macro.stderr @@ -5,8 +5,8 @@ LL | println!("Hello, World!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expanding `println! { "Hello, World!" }` - = note: to `print ! ( "{}/n" , format_args ! ( "Hello, World!" ) )` - = note: expanding `print! { "{}/n" , format_args ! ( "Hello, World!" ) }` - = note: to `$crate :: io :: _print ( - format_args ! ( "{}/n" , format_args ! ( "Hello, World!" ) ) )` + = note: to `{ + # [ cfg ( not ( stage0 ) ) ] { + ( $crate :: io :: _print ( format_args_nl ! ( "Hello, World!" ) ) ) ; } # [ + cfg ( stage0 ) ] { print ! ( "{}/n" , format_args ! ( "Hello, World!" ) ) } }` |
