diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index e68f3c58a3e07..900ef63f1dfcc 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -10,7 +10,6 @@ use crate::mem; use crate::num::flt2dec; use crate::ops::Deref; use crate::result; -use crate::slice; use crate::str; mod builders; @@ -234,8 +233,6 @@ pub struct Formatter<'a> { precision: Option, buf: &'a mut (dyn Write + 'a), - curarg: slice::Iter<'a, ArgumentV1<'a>>, - args: &'a [ArgumentV1<'a>], } // NB. Argument is essentially an optimized partially applied formatting function, @@ -1043,8 +1040,6 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { buf: output, align: rt::v1::Alignment::Unknown, fill: ' ', - args: args.args, - curarg: args.args.iter(), }; let mut idx = 0; @@ -1063,7 +1058,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { // a string piece. for (arg, piece) in fmt.iter().zip(args.pieces.iter()) { formatter.buf.write_str(*piece)?; - formatter.run(arg)?; + run(&mut formatter, arg, &args.args)?; idx += 1; } } @@ -1077,6 +1072,39 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { Ok(()) } +fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result { + fmt.fill = arg.format.fill; + fmt.align = arg.format.align; + fmt.flags = arg.format.flags; + fmt.width = getcount(args, &arg.format.width); + fmt.precision = getcount(args, &arg.format.precision); + + // Extract the correct argument + let value = { + #[cfg(bootstrap)] + { + match arg.position { + rt::v1::Position::At(i) => args[i], + } + } + #[cfg(not(bootstrap))] + { + args[arg.position] + } + }; + + // Then actually do some printing + (value.formatter)(value.value, fmt) +} + +fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option { + match *cnt { + rt::v1::Count::Is(n) => Some(n), + rt::v1::Count::Implied => None, + rt::v1::Count::Param(i) => args[i].as_usize(), + } +} + /// Padding after the end of something. Returned by `Formatter::padding`. #[must_use = "don't forget to write the post padding"] struct PostPadding { @@ -1114,41 +1142,6 @@ impl<'a> Formatter<'a> { align: self.align, width: self.width, precision: self.precision, - - // These only exist in the struct for the `run` method, - // which won’t be used together with this method. - curarg: self.curarg.clone(), - args: self.args, - } - } - - // First up is the collection of functions used to execute a format string - // at runtime. This consumes all of the compile-time statics generated by - // the format! syntax extension. - fn run(&mut self, arg: &rt::v1::Argument) -> Result { - // Fill in the format parameters into the formatter - self.fill = arg.format.fill; - self.align = arg.format.align; - self.flags = arg.format.flags; - self.width = self.getcount(&arg.format.width); - self.precision = self.getcount(&arg.format.precision); - - // Extract the correct argument - let value = match arg.position { - rt::v1::Position::Next => *self.curarg.next().unwrap(), - rt::v1::Position::At(i) => self.args[i], - }; - - // Then actually do some printing - (value.formatter)(value.value, self) - } - - fn getcount(&mut self, cnt: &rt::v1::Count) -> Option { - match *cnt { - rt::v1::Count::Is(n) => Some(n), - rt::v1::Count::Implied => None, - rt::v1::Count::Param(i) => self.args[i].as_usize(), - rt::v1::Count::NextParam => self.curarg.next()?.as_usize(), } } diff --git a/src/libcore/fmt/rt/v1.rs b/src/libcore/fmt/rt/v1.rs index 826ae36d2d100..fd81f93242b89 100644 --- a/src/libcore/fmt/rt/v1.rs +++ b/src/libcore/fmt/rt/v1.rs @@ -7,7 +7,10 @@ #[derive(Copy, Clone)] pub struct Argument { + #[cfg(bootstrap)] pub position: Position, + #[cfg(not(bootstrap))] + pub position: usize, pub format: FormatSpec, } @@ -37,12 +40,11 @@ pub enum Alignment { pub enum Count { Is(usize), Param(usize), - NextParam, Implied, } +#[cfg(bootstrap)] #[derive(Copy, Clone)] pub enum Position { - Next, At(usize), } diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs index 6fca74e223944..3f4e24ca993db 100644 --- a/src/librustc_builtin_macros/format.rs +++ b/src/librustc_builtin_macros/format.rs @@ -590,17 +590,6 @@ impl<'a, 'b> Context<'a, 'b> { parse::NextArgument(ref arg) => { // Build the position let pos = { - let pos = |c, arg| { - let mut path = Context::rtpath(self.ecx, "Position"); - path.push(self.ecx.ident_of(c, sp)); - match arg { - Some(i) => { - let arg = self.ecx.expr_usize(sp, i); - self.ecx.expr_call_global(sp, path, vec![arg]) - } - None => self.ecx.expr_path(self.ecx.path_global(sp, path)), - } - }; match arg.position { parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => { // Map to index in final generated argument array @@ -615,7 +604,7 @@ impl<'a, 'b> Context<'a, 'b> { arg_idx } }; - pos("At", Some(arg_idx)) + self.ecx.expr_usize(sp, arg_idx) } // should never be the case, because names are already diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs index 645c903c6bab2..ceeebbca5195a 100644 --- a/src/test/ui/async-await/async-fn-nonsend.rs +++ b/src/test/ui/async-await/async-fn-nonsend.rs @@ -2,15 +2,15 @@ // edition:2018 // compile-flags: --crate-type lib -use std::{ - cell::RefCell, - fmt::Debug, - rc::Rc, -}; +use std::{cell::RefCell, fmt::Debug, rc::Rc}; -fn non_sync() -> impl Debug { RefCell::new(()) } +fn non_sync() -> impl Debug { + RefCell::new(()) +} -fn non_send() -> impl Debug { Rc::new(()) } +fn non_send() -> impl Debug { + Rc::new(()) +} fn take_ref(_: &T) {} @@ -53,5 +53,4 @@ pub fn pass_assert() { //~^ ERROR future cannot be sent between threads safely assert_send(non_sync_with_method_call()); //~^ ERROR future cannot be sent between threads safely - //~^^ ERROR future cannot be sent between threads safely } diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr index 5c870ca2d0276..105fd23ecfb66 100644 --- a/src/test/ui/async-await/async-fn-nonsend.stderr +++ b/src/test/ui/async-await/async-fn-nonsend.stderr @@ -62,27 +62,5 @@ LL | } LL | } | - `f` is later dropped here -error: future cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:54:5 - | -LL | fn assert_send(_: impl Send) {} - | ----------- ---- required by this bound in `assert_send` -... -LL | assert_send(non_sync_with_method_call()); - | ^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` - | - = help: within `std::fmt::ArgumentV1<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)` -note: future is not `Send` as this value is used across an await - --> $DIR/async-fn-nonsend.rs:43:9 - | -LL | let f: &mut std::fmt::Formatter = panic!(); - | - has type `&mut std::fmt::Formatter<'_>` -LL | if non_sync().fmt(f).unwrap() == () { -LL | fut().await; - | ^^^^^^^^^^^ await occurs here, with `f` maybe used later -LL | } -LL | } - | - `f` is later dropped here - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors