Skip to content

Commit 154dee2

Browse files
author
Esteban Küber
committed
rework println
1 parent a476532 commit 154dee2

File tree

5 files changed

+63
-9
lines changed

5 files changed

+63
-9
lines changed

src/libfmt_macros/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,11 @@ impl<'a> Parser<'a> {
273273
}
274274
} else {
275275
let msg = format!("expected `{:?}` but string was terminated", c);
276-
let pos = self.input.len() + 1; // point at closing `"`
276+
// point at closing `"`, unless the last char is `\n` to account for `println`
277+
let pos = match self.input.chars().last() {
278+
Some('\n') => self.input.len(),
279+
_ => self.input.len() + 1,
280+
};
277281
if c == '}' {
278282
self.err_with_note(msg,
279283
format!("expected `{:?}`", c),

src/libstd/macros.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,17 @@ macro_rules! print {
153153
/// ```
154154
#[macro_export]
155155
#[stable(feature = "rust1", since = "1.0.0")]
156+
#[allow_internal_unstable]
156157
macro_rules! println {
157158
() => (print!("\n"));
158-
($($arg:tt)*) => (print!("{}\n", format_args!($($arg)*)));
159+
($($arg:tt)*) => ({
160+
#[cfg(not(stage0))] {
161+
($crate::io::_print(format_args_nl!($($arg)*)));
162+
}
163+
#[cfg(stage0)] {
164+
print!("{}\n", format_args!($($arg)*))
165+
}
166+
})
159167
}
160168

161169
/// Macro for printing to the standard error.
@@ -211,7 +219,8 @@ macro_rules! eprint {
211219
#[stable(feature = "eprint", since = "1.19.0")]
212220
macro_rules! eprintln {
213221
() => (eprint!("\n"));
214-
($($arg:tt)*) => (eprint!("{}\n", format_args!($($arg)*)));
222+
($fmt:expr) => (eprint!(concat!($fmt, "\n")));
223+
($fmt:expr, $($arg:tt)*) => (eprint!(concat!($fmt, "\n"), $($arg)*));
215224
}
216225

217226
#[macro_export]
@@ -397,6 +406,19 @@ pub mod builtin {
397406
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
398407
}
399408

409+
/// Internal version of [`format_args`].
410+
///
411+
/// This macro differs from [`format_args`] in that it appends a newline to the format string
412+
/// and nothing more. It is perma-unstable.
413+
///
414+
/// [`format_args`]: ../std/macro.format_args.html
415+
#[doc(hidden)]
416+
#[unstable(feature = "println_format_args", issue="0")]
417+
#[macro_export]
418+
macro_rules! format_args_nl {
419+
($fmt:expr) => ({ /* compiler built-in */ });
420+
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
421+
}
400422
/// Inspect an environment variable at compile time.
401423
///
402424
/// This macro will expand to the value of the named environment variable at

src/libsyntax_ext/format.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,20 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
683683
sp = sp.apply_mark(ecx.current_expansion.mark);
684684
match parse_args(ecx, sp, tts) {
685685
Some((efmt, args, names)) => {
686-
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names))
686+
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, false))
687+
}
688+
None => DummyResult::expr(sp),
689+
}
690+
}
691+
692+
pub fn expand_format_args_nl<'cx>(ecx: &'cx mut ExtCtxt,
693+
mut sp: Span,
694+
tts: &[tokenstream::TokenTree])
695+
-> Box<dyn base::MacResult + 'cx> {
696+
sp = sp.apply_mark(ecx.current_expansion.mark);
697+
match parse_args(ecx, sp, tts) {
698+
Some((efmt, args, names)) => {
699+
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, true))
687700
}
688701
None => DummyResult::expr(sp),
689702
}
@@ -695,7 +708,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
695708
sp: Span,
696709
efmt: P<ast::Expr>,
697710
args: Vec<P<ast::Expr>>,
698-
names: HashMap<String, usize>)
711+
names: HashMap<String, usize>,
712+
append_newline: bool)
699713
-> P<ast::Expr> {
700714
// NOTE: this verbose way of initializing `Vec<Vec<ArgumentType>>` is because
701715
// `ArgumentType` does not derive `Clone`.
@@ -706,6 +720,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
706720
let msg = "format argument must be a string literal";
707721
let fmt_sp = efmt.span;
708722
let fmt = match expr_to_spanned_string(ecx, efmt, msg) {
723+
Ok(mut fmt) if append_newline => {
724+
fmt.node.0 = Symbol::intern(&format!("{}\n", fmt.node.0));
725+
fmt
726+
}
709727
Ok(fmt) => fmt,
710728
Err(mut err) => {
711729
let sugg_fmt = match args.len() {

src/libsyntax_ext/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
139139
unstable_feature: None,
140140
edition: hygiene::default_edition(),
141141
});
142+
register(Symbol::intern("format_args_nl"),
143+
NormalTT {
144+
expander: Box::new(format::expand_format_args_nl),
145+
def_info: None,
146+
allow_internal_unstable: true,
147+
allow_internal_unsafe: false,
148+
local_inner_macros: false,
149+
unstable_feature: None,
150+
edition: hygiene::default_edition(),
151+
});
142152

143153
for (name, ext) in user_exts {
144154
register(name, ext);

src/test/ui/macros/trace-macro.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ LL | println!("Hello, World!");
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: expanding `println! { "Hello, World!" }`
8-
= note: to `print ! ( "{}/n" , format_args ! ( "Hello, World!" ) )`
9-
= note: expanding `print! { "{}/n" , format_args ! ( "Hello, World!" ) }`
10-
= note: to `$crate :: io :: _print (
11-
format_args ! ( "{}/n" , format_args ! ( "Hello, World!" ) ) )`
8+
= note: to `{
9+
# [ cfg ( not ( stage0 ) ) ] {
10+
( $crate :: io :: _print ( format_args_nl ! ( "Hello, World!" ) ) ) ; } # [
11+
cfg ( stage0 ) ] { print ! ( "{}/n" , format_args ! ( "Hello, World!" ) ) } }`
1212

0 commit comments

Comments
 (0)