rework println
This commit is contained in:
parent
a47653214f
commit
154dee2dcc
5 changed files with 63 additions and 9 deletions
|
@ -273,7 +273,11 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("expected `{:?}` but string was terminated", c);
|
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 == '}' {
|
if c == '}' {
|
||||||
self.err_with_note(msg,
|
self.err_with_note(msg,
|
||||||
format!("expected `{:?}`", c),
|
format!("expected `{:?}`", c),
|
||||||
|
|
|
@ -153,9 +153,17 @@ macro_rules! print {
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow_internal_unstable]
|
||||||
macro_rules! println {
|
macro_rules! println {
|
||||||
() => (print!("\n"));
|
() => (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.
|
/// Macro for printing to the standard error.
|
||||||
|
@ -211,7 +219,8 @@ macro_rules! eprint {
|
||||||
#[stable(feature = "eprint", since = "1.19.0")]
|
#[stable(feature = "eprint", since = "1.19.0")]
|
||||||
macro_rules! eprintln {
|
macro_rules! eprintln {
|
||||||
() => (eprint!("\n"));
|
() => (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]
|
#[macro_export]
|
||||||
|
@ -397,6 +406,19 @@ pub mod builtin {
|
||||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
|
($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.
|
/// Inspect an environment variable at compile time.
|
||||||
///
|
///
|
||||||
/// This macro will expand to the value of the named environment variable at
|
/// This macro will expand to the value of the named environment variable at
|
||||||
|
|
|
@ -683,7 +683,20 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
|
||||||
sp = sp.apply_mark(ecx.current_expansion.mark);
|
sp = sp.apply_mark(ecx.current_expansion.mark);
|
||||||
match parse_args(ecx, sp, tts) {
|
match parse_args(ecx, sp, tts) {
|
||||||
Some((efmt, args, names)) => {
|
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),
|
None => DummyResult::expr(sp),
|
||||||
}
|
}
|
||||||
|
@ -695,7 +708,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
efmt: P<ast::Expr>,
|
efmt: P<ast::Expr>,
|
||||||
args: Vec<P<ast::Expr>>,
|
args: Vec<P<ast::Expr>>,
|
||||||
names: HashMap<String, usize>)
|
names: HashMap<String, usize>,
|
||||||
|
append_newline: bool)
|
||||||
-> P<ast::Expr> {
|
-> P<ast::Expr> {
|
||||||
// NOTE: this verbose way of initializing `Vec<Vec<ArgumentType>>` is because
|
// NOTE: this verbose way of initializing `Vec<Vec<ArgumentType>>` is because
|
||||||
// `ArgumentType` does not derive `Clone`.
|
// `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 msg = "format argument must be a string literal";
|
||||||
let fmt_sp = efmt.span;
|
let fmt_sp = efmt.span;
|
||||||
let fmt = match expr_to_spanned_string(ecx, efmt, msg) {
|
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,
|
Ok(fmt) => fmt,
|
||||||
Err(mut err) => {
|
Err(mut err) => {
|
||||||
let sugg_fmt = match args.len() {
|
let sugg_fmt = match args.len() {
|
||||||
|
|
|
@ -139,6 +139,16 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
||||||
unstable_feature: None,
|
unstable_feature: None,
|
||||||
edition: hygiene::default_edition(),
|
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 {
|
for (name, ext) in user_exts {
|
||||||
register(name, ext);
|
register(name, ext);
|
||||||
|
|
|
@ -5,8 +5,8 @@ LL | println!("Hello, World!");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: expanding `println! { "Hello, World!" }`
|
= note: expanding `println! { "Hello, World!" }`
|
||||||
= note: to `print ! ( "{}/n" , format_args ! ( "Hello, World!" ) )`
|
= note: to `{
|
||||||
= note: expanding `print! { "{}/n" , format_args ! ( "Hello, World!" ) }`
|
# [ cfg ( not ( stage0 ) ) ] {
|
||||||
= note: to `$crate :: io :: _print (
|
( $crate :: io :: _print ( format_args_nl ! ( "Hello, World!" ) ) ) ; } # [
|
||||||
format_args ! ( "{}/n" , format_args ! ( "Hello, World!" ) ) )`
|
cfg ( stage0 ) ] { print ! ( "{}/n" , format_args ! ( "Hello, World!" ) ) } }`
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue