Skip to content

Commit

Permalink
Rollup merge of rust-lang#67795 - Mark-Simulacrum:fmt-argument, r=dto…
Browse files Browse the repository at this point in the history
…lnay

Cleanup formatting code

This removes a few leftover positional enum variants that were no longer used.

All details that are changed are unstable (and `#[doc(hidden)]`), so this should
not impact downstream code.
  • Loading branch information
JohnTitor authored Jan 20, 2020
2 parents ec7f209 + a804a45 commit e1bd9b3
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 86 deletions.
75 changes: 34 additions & 41 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -234,8 +233,6 @@ pub struct Formatter<'a> {
precision: Option<usize>,

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,
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
}
Expand All @@ -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<usize> {
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 {
Expand Down Expand Up @@ -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<usize> {
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(),
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/libcore/fmt/rt/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

#[derive(Copy, Clone)]
pub struct Argument {
#[cfg(bootstrap)]
pub position: Position,
#[cfg(not(bootstrap))]
pub position: usize,
pub format: FormatSpec,
}

Expand Down Expand Up @@ -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),
}
13 changes: 1 addition & 12 deletions src/librustc_builtin_macros/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
15 changes: 7 additions & 8 deletions src/test/ui/async-await/async-fn-nonsend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(_: &T) {}

Expand Down Expand Up @@ -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
}
24 changes: 1 addition & 23 deletions src/test/ui/async-await/async-fn-nonsend.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit e1bd9b3

Please sign in to comment.