Auto merge of #63228 - Centril:rollup-x39p5ga, r=Centril
Rollup of 7 pull requests Successful merges: - #63107 (Added support for armv7-unknown-linux-gnueabi/musleabi) - #63121 (On `format!()` arg count mismatch provide extra info) - #63196 (build_helper: try less confusing method names) - #63206 (remove unsupported test case) - #63208 (Round generator sizes to a multiple of their alignment) - #63212 (Pretty print attributes in `print_arg`) - #63215 (Clarify semantics of mem::zeroed) Failed merges: r? @ghost
This commit is contained in:
commit
d9bd4b289f
@ -125,7 +125,9 @@ v("musl-root-armhf", "target.arm-unknown-linux-musleabihf.musl-root",
|
||||
"arm-unknown-linux-musleabihf install directory")
|
||||
v("musl-root-armv5te", "target.armv5te-unknown-linux-musleabi.musl-root",
|
||||
"armv5te-unknown-linux-musleabi install directory")
|
||||
v("musl-root-armv7", "target.armv7-unknown-linux-musleabihf.musl-root",
|
||||
v("musl-root-armv7", "target.armv7-unknown-linux-musleabi.musl-root",
|
||||
"armv7-unknown-linux-musleabi install directory")
|
||||
v("musl-root-armv7hf", "target.armv7-unknown-linux-musleabihf.musl-root",
|
||||
"armv7-unknown-linux-musleabihf install directory")
|
||||
v("musl-root-aarch64", "target.aarch64-unknown-linux-musl.musl-root",
|
||||
"aarch64-unknown-linux-musl install directory")
|
||||
|
@ -125,7 +125,7 @@ use std::os::unix::fs::symlink as symlink_file;
|
||||
use std::os::windows::fs::symlink_file;
|
||||
|
||||
use build_helper::{
|
||||
mtime, output, run_silent, run_suppressed, t, try_run_silent, try_run_suppressed,
|
||||
mtime, output, run, run_suppressed, t, try_run, try_run_suppressed,
|
||||
};
|
||||
use filetime::FileTime;
|
||||
|
||||
@ -682,7 +682,7 @@ impl Build {
|
||||
fn run(&self, cmd: &mut Command) {
|
||||
if self.config.dry_run { return; }
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
run_silent(cmd)
|
||||
run(cmd)
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if it fails.
|
||||
@ -698,7 +698,7 @@ impl Build {
|
||||
fn try_run(&self, cmd: &mut Command) -> bool {
|
||||
if self.config.dry_run { return true; }
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
try_run_silent(cmd)
|
||||
try_run(cmd)
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if it fails.
|
||||
|
@ -1527,7 +1527,7 @@ impl Step for RustcGuide {
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let src = builder.src.join("src/doc/rustc-guide");
|
||||
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
|
||||
try_run_quiet(builder, rustbook_cmd.arg("linkcheck").arg(&src));
|
||||
try_run(builder, rustbook_cmd.arg("linkcheck").arg(&src));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,18 +45,19 @@ pub fn restore_library_path() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(cmd: &mut Command) {
|
||||
/// Run the command, printing what we are running.
|
||||
pub fn run_verbose(cmd: &mut Command) {
|
||||
println!("running: {:?}", cmd);
|
||||
run_silent(cmd);
|
||||
run(cmd);
|
||||
}
|
||||
|
||||
pub fn run_silent(cmd: &mut Command) {
|
||||
if !try_run_silent(cmd) {
|
||||
pub fn run(cmd: &mut Command) {
|
||||
if !try_run(cmd) {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_run_silent(cmd: &mut Command) -> bool {
|
||||
pub fn try_run(cmd: &mut Command) -> bool {
|
||||
let status = match cmd.status() {
|
||||
Ok(status) => status,
|
||||
Err(e) => fail(&format!(
|
||||
|
@ -64,7 +64,7 @@ RUN env \
|
||||
env \
|
||||
CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \
|
||||
CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv7-a" \
|
||||
bash musl.sh armv7 && \
|
||||
bash musl.sh armv7hf && \
|
||||
env \
|
||||
CC=aarch64-linux-gnu-gcc \
|
||||
CXX=aarch64-linux-gnu-g++ \
|
||||
@ -137,7 +137,7 @@ ENV RUST_CONFIGURE_ARGS \
|
||||
--musl-root-armv5te=/musl-armv5te \
|
||||
--musl-root-arm=/musl-arm \
|
||||
--musl-root-armhf=/musl-armhf \
|
||||
--musl-root-armv7=/musl-armv7 \
|
||||
--musl-root-armv7hf=/musl-armv7hf \
|
||||
--musl-root-aarch64=/musl-aarch64 \
|
||||
--musl-root-mips=/musl-mips \
|
||||
--musl-root-mipsel=/musl-mipsel \
|
||||
|
@ -8,7 +8,8 @@ RUN sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
gcc-multilib \
|
||||
# gcc-multilib can not be installed together with gcc-arm-linux-gnueabi
|
||||
gcc-7-multilib \
|
||||
libedit-dev \
|
||||
libgmp-dev \
|
||||
libisl-dev \
|
||||
@ -21,11 +22,20 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no
|
||||
unzip \
|
||||
# Needed for apt-key to work:
|
||||
dirmngr \
|
||||
gpg-agent
|
||||
gpg-agent \
|
||||
g++-7-arm-linux-gnueabi
|
||||
|
||||
RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486
|
||||
RUN add-apt-repository -y 'deb http://apt.dilos.org/dilos dilos2 main'
|
||||
|
||||
WORKDIR /build
|
||||
COPY scripts/musl.sh /build
|
||||
RUN env \
|
||||
CC=arm-linux-gnueabi-gcc-7 CFLAGS="-march=armv7-a" \
|
||||
CXX=arm-linux-gnueabi-g++-7 CXXFLAGS="-march=armv7-a" \
|
||||
bash musl.sh armv7 && \
|
||||
rm -rf /build/*
|
||||
|
||||
WORKDIR /tmp
|
||||
COPY dist-various-2/shared.sh /tmp/
|
||||
COPY dist-various-2/build-cloudabi-toolchain.sh /tmp/
|
||||
@ -58,7 +68,11 @@ ENV \
|
||||
CXX_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-g++ \
|
||||
AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar \
|
||||
CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \
|
||||
CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++
|
||||
CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ \
|
||||
CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-7 \
|
||||
CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-7 \
|
||||
CC=gcc-7 \
|
||||
CXX=g++-7
|
||||
|
||||
ENV CARGO_TARGET_X86_64_FUCHSIA_AR /usr/local/bin/llvm-ar
|
||||
ENV CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS \
|
||||
@ -81,9 +95,19 @@ ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
|
||||
ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi
|
||||
ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx
|
||||
ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda
|
||||
ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi
|
||||
ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi
|
||||
|
||||
ENV X86_FORTANIX_SGX_LIBS="/x86_64-fortanix-unknown-sgx/lib/"
|
||||
|
||||
# As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
|
||||
# we need asm in the search path for gcc-7 (for gnux32) but not in the search path of the
|
||||
# cross compilers.
|
||||
# Luckily one of the folders is /usr/local/include so symlink /usr/include/asm-generic there
|
||||
RUN ln -s /usr/include/asm-generic /usr/local/include/asm
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs \
|
||||
--set target.wasm32-wasi.wasi-root=/wasm32-wasi
|
||||
--set target.wasm32-wasi.wasi-root=/wasm32-wasi \
|
||||
--musl-root-armv7=/musl-armv7
|
||||
|
||||
ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
|
||||
|
@ -414,10 +414,10 @@ pub const fn needs_drop<T>() -> bool {
|
||||
intrinsics::needs_drop::<T>()
|
||||
}
|
||||
|
||||
/// Creates a value whose bytes are all zero.
|
||||
/// Returns the value of type `T` represented by the all-zero byte-pattern.
|
||||
///
|
||||
/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed].
|
||||
/// It is useful for FFI sometimes, but should generally be avoided.
|
||||
/// This means that, for example, the padding byte in `(u8, u16)` is not
|
||||
/// necessarily zeroed.
|
||||
///
|
||||
/// There is no guarantee that an all-zero byte-pattern represents a valid value of
|
||||
/// some type `T`. For example, the all-zero byte-pattern is not a valid value
|
||||
@ -425,6 +425,9 @@ pub const fn needs_drop<T>() -> bool {
|
||||
/// causes immediate [undefined behavior][ub] because [the Rust compiler assumes][inv]
|
||||
/// that there always is a valid value in a variable it considers initialized.
|
||||
///
|
||||
/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed].
|
||||
/// It is useful for FFI sometimes, but should generally be avoided.
|
||||
///
|
||||
/// [zeroed]: union.MaybeUninit.html#method.zeroed
|
||||
/// [ub]: ../../reference/behavior-considered-undefined.html
|
||||
/// [inv]: union.MaybeUninit.html#initialization-invariant
|
||||
|
@ -56,16 +56,20 @@ pub struct Argument<'a> {
|
||||
/// Specification for the formatting of an argument in the format string.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub struct FormatSpec<'a> {
|
||||
/// Optionally specified character to fill alignment with
|
||||
/// Optionally specified character to fill alignment with.
|
||||
pub fill: Option<char>,
|
||||
/// Optionally specified alignment
|
||||
/// Optionally specified alignment.
|
||||
pub align: Alignment,
|
||||
/// Packed version of various flags provided
|
||||
/// Packed version of various flags provided.
|
||||
pub flags: u32,
|
||||
/// The integer precision to use
|
||||
/// The integer precision to use.
|
||||
pub precision: Count,
|
||||
/// The string width requested for the resulting format
|
||||
/// The span of the precision formatting flag (for diagnostics).
|
||||
pub precision_span: Option<InnerSpan>,
|
||||
/// The string width requested for the resulting format.
|
||||
pub width: Count,
|
||||
/// The span of the width formatting flag (for diagnostics).
|
||||
pub width_span: Option<InnerSpan>,
|
||||
/// The descriptor string representing the name of the format desired for
|
||||
/// this argument, this can be empty or any number of characters, although
|
||||
/// it is required to be one word.
|
||||
@ -282,19 +286,24 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Optionally consumes the specified character. If the character is not at
|
||||
/// the current position, then the current iterator isn't moved and false is
|
||||
/// returned, otherwise the character is consumed and true is returned.
|
||||
/// the current position, then the current iterator isn't moved and `false` is
|
||||
/// returned, otherwise the character is consumed and `true` is returned.
|
||||
fn consume(&mut self, c: char) -> bool {
|
||||
if let Some(&(_, maybe)) = self.cur.peek() {
|
||||
self.consume_pos(c).is_some()
|
||||
}
|
||||
|
||||
/// Optionally consumes the specified character. If the character is not at
|
||||
/// the current position, then the current iterator isn't moved and `None` is
|
||||
/// returned, otherwise the character is consumed and the current position is
|
||||
/// returned.
|
||||
fn consume_pos(&mut self, c: char) -> Option<usize> {
|
||||
if let Some(&(pos, maybe)) = self.cur.peek() {
|
||||
if c == maybe {
|
||||
self.cur.next();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
return Some(pos);
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn to_span_index(&self, pos: usize) -> InnerOffset {
|
||||
@ -462,7 +471,9 @@ impl<'a> Parser<'a> {
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
precision_span: None,
|
||||
width: CountImplied,
|
||||
width_span: None,
|
||||
ty: &self.input[..0],
|
||||
};
|
||||
if !self.consume(':') {
|
||||
@ -499,6 +510,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
// Width and precision
|
||||
let mut havewidth = false;
|
||||
|
||||
if self.consume('0') {
|
||||
// small ambiguity with '0$' as a format string. In theory this is a
|
||||
// '0' flag and then an ill-formatted format string with just a '$'
|
||||
@ -512,17 +524,28 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
if !havewidth {
|
||||
spec.width = self.count();
|
||||
let width_span_start = if let Some((pos, _)) = self.cur.peek() {
|
||||
*pos
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let (w, sp) = self.count(width_span_start);
|
||||
spec.width = w;
|
||||
spec.width_span = sp;
|
||||
}
|
||||
if self.consume('.') {
|
||||
if self.consume('*') {
|
||||
if let Some(start) = self.consume_pos('.') {
|
||||
if let Some(end) = self.consume_pos('*') {
|
||||
// Resolve `CountIsNextParam`.
|
||||
// We can do this immediately as `position` is resolved later.
|
||||
let i = self.curarg;
|
||||
self.curarg += 1;
|
||||
spec.precision = CountIsParam(i);
|
||||
spec.precision_span =
|
||||
Some(self.to_span_index(start).to(self.to_span_index(end + 1)));
|
||||
} else {
|
||||
spec.precision = self.count();
|
||||
let (p, sp) = self.count(start);
|
||||
spec.precision = p;
|
||||
spec.precision_span = sp;
|
||||
}
|
||||
}
|
||||
// Optional radix followed by the actual format specifier
|
||||
@ -551,24 +574,25 @@ impl<'a> Parser<'a> {
|
||||
/// Parses a Count parameter at the current position. This does not check
|
||||
/// for 'CountIsNextParam' because that is only used in precision, not
|
||||
/// width.
|
||||
fn count(&mut self) -> Count {
|
||||
fn count(&mut self, start: usize) -> (Count, Option<InnerSpan>) {
|
||||
if let Some(i) = self.integer() {
|
||||
if self.consume('$') {
|
||||
CountIsParam(i)
|
||||
if let Some(end) = self.consume_pos('$') {
|
||||
let span = self.to_span_index(start).to(self.to_span_index(end + 1));
|
||||
(CountIsParam(i), Some(span))
|
||||
} else {
|
||||
CountIs(i)
|
||||
(CountIs(i), None)
|
||||
}
|
||||
} else {
|
||||
let tmp = self.cur.clone();
|
||||
let word = self.word();
|
||||
if word.is_empty() {
|
||||
self.cur = tmp;
|
||||
CountImplied
|
||||
(CountImplied, None)
|
||||
} else if self.consume('$') {
|
||||
CountIsName(Symbol::intern(word))
|
||||
(CountIsName(Symbol::intern(word)), None)
|
||||
} else {
|
||||
self.cur = tmp;
|
||||
CountImplied
|
||||
(CountImplied, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ fn fmtdflt() -> FormatSpec<'static> {
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "",
|
||||
};
|
||||
}
|
||||
@ -79,165 +81,204 @@ fn format_position_nothing_else() {
|
||||
}
|
||||
#[test]
|
||||
fn format_type() {
|
||||
same("{3:a}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
ty: "a",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{3:a}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "a",
|
||||
},
|
||||
})]);
|
||||
}
|
||||
#[test]
|
||||
fn format_align_fill() {
|
||||
same("{3:>}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignRight,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
ty: "",
|
||||
},
|
||||
})]);
|
||||
same("{3:0<}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: Some('0'),
|
||||
align: AlignLeft,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
ty: "",
|
||||
},
|
||||
})]);
|
||||
same("{3:*<abcd}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: Some('*'),
|
||||
align: AlignLeft,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
ty: "abcd",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{3:>}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignRight,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{3:0<}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: Some('0'),
|
||||
align: AlignLeft,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{3:*<abcd}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: Some('*'),
|
||||
align: AlignLeft,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "abcd",
|
||||
},
|
||||
})]);
|
||||
}
|
||||
#[test]
|
||||
fn format_counts() {
|
||||
use syntax_pos::{GLOBALS, Globals, edition};
|
||||
GLOBALS.set(&Globals::new(edition::DEFAULT_EDITION), || {
|
||||
same("{:10s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountIs(10),
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same("{:10$.10s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountIs(10),
|
||||
width: CountIsParam(10),
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same("{:.*s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(1),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountIsParam(0),
|
||||
width: CountImplied,
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same("{:.10$s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountIsParam(10),
|
||||
width: CountImplied,
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same("{:a$.b$s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountIsName(Symbol::intern("b")),
|
||||
width: CountIsName(Symbol::intern("a")),
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{:10s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountIs(10),
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{:10$.10s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountIs(10),
|
||||
width: CountIsParam(10),
|
||||
precision_span: None,
|
||||
width_span: Some(InnerSpan::new(3, 6)),
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{:.*s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(1),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountIsParam(0),
|
||||
width: CountImplied,
|
||||
precision_span: Some(InnerSpan::new(3, 5)),
|
||||
width_span: None,
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{:.10$s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountIsParam(10),
|
||||
width: CountImplied,
|
||||
precision_span: Some(InnerSpan::new(3, 7)),
|
||||
width_span: None,
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{:a$.b$s}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountIsName(Symbol::intern("b")),
|
||||
width: CountIsName(Symbol::intern("a")),
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "s",
|
||||
},
|
||||
})]);
|
||||
});
|
||||
}
|
||||
#[test]
|
||||
fn format_flags() {
|
||||
same("{:-}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: (1 << FlagSignMinus as u32),
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
ty: "",
|
||||
},
|
||||
})]);
|
||||
same("{:+#}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: (1 << FlagSignPlus as u32) | (1 << FlagAlternate as u32),
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
ty: "",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{:-}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: (1 << FlagSignMinus as u32),
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "",
|
||||
},
|
||||
})]);
|
||||
same(
|
||||
"{:+#}",
|
||||
&[NextArgument(Argument {
|
||||
position: ArgumentImplicitlyIs(0),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: (1 << FlagSignPlus as u32) | (1 << FlagAlternate as u32),
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "",
|
||||
},
|
||||
})]);
|
||||
}
|
||||
#[test]
|
||||
fn format_mixture() {
|
||||
same("abcd {3:a} efg",
|
||||
&[String("abcd "),
|
||||
NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
ty: "a",
|
||||
},
|
||||
}),
|
||||
String(" efg")]);
|
||||
same(
|
||||
"abcd {3:a} efg",
|
||||
&[
|
||||
String("abcd "),
|
||||
NextArgument(Argument {
|
||||
position: ArgumentIs(3),
|
||||
format: FormatSpec {
|
||||
fill: None,
|
||||
align: AlignUnknown,
|
||||
flags: 0,
|
||||
precision: CountImplied,
|
||||
width: CountImplied,
|
||||
precision_span: None,
|
||||
width_span: None,
|
||||
ty: "a",
|
||||
},
|
||||
}),
|
||||
String(" efg"),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -1540,6 +1540,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
Ok(variant)
|
||||
}).collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
|
||||
|
||||
size = size.align_to(align.abi);
|
||||
|
||||
let abi = if prefix.abi.is_uninhabited() ||
|
||||
variants.iter().all(|v| v.abi.is_uninhabited()) {
|
||||
Abi::Uninhabited
|
||||
|
29
src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs
Normal file
29
src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||
|
||||
// This target is for glibc Linux on ARMv7 without thumb-mode, NEON or
|
||||
// hardfloat.
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
let base = super::linux_base::opts();
|
||||
Ok(Target {
|
||||
llvm_target: "armv7-unknown-linux-gnueabi".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_pointer_width: "32".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||
arch: "arm".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
target_env: "gnu".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
linker_flavor: LinkerFlavor::Gcc,
|
||||
|
||||
options: TargetOptions {
|
||||
features: "+v7,+thumb2,+soft-float,-neon".to_string(),
|
||||
cpu: "generic".to_string(),
|
||||
max_atomic_width: Some(64),
|
||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
|
||||
.. base
|
||||
}
|
||||
})
|
||||
}
|
34
src/librustc_target/spec/armv7_unknown_linux_musleabi.rs
Normal file
34
src/librustc_target/spec/armv7_unknown_linux_musleabi.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||
|
||||
// This target is for musl Linux on ARMv7 without thumb-mode, NEON or
|
||||
// hardfloat.
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
let base = super::linux_musl_base::opts();
|
||||
// Most of these settings are copied from the armv7_unknown_linux_gnueabi
|
||||
// target.
|
||||
Ok(Target {
|
||||
// It's important we use "gnueabi" and not "musleabi" here. LLVM uses it
|
||||
// to determine the calling convention and float ABI, and it doesn't
|
||||
// support the "musleabi" value.
|
||||
llvm_target: "armv7-unknown-linux-gnueabi".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_pointer_width: "32".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||
arch: "arm".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
target_env: "musl".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
linker_flavor: LinkerFlavor::Gcc,
|
||||
|
||||
options: TargetOptions {
|
||||
features: "+v7,+thumb2,+soft-float,-neon".to_string(),
|
||||
cpu: "generic".to_string(),
|
||||
max_atomic_width: Some(64),
|
||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||
target_mcount: "\u{1}mcount".to_string(),
|
||||
.. base
|
||||
}
|
||||
})
|
||||
}
|
@ -359,8 +359,10 @@ supported_targets! {
|
||||
("armv4t-unknown-linux-gnueabi", armv4t_unknown_linux_gnueabi),
|
||||
("armv5te-unknown-linux-gnueabi", armv5te_unknown_linux_gnueabi),
|
||||
("armv5te-unknown-linux-musleabi", armv5te_unknown_linux_musleabi),
|
||||
("armv7-unknown-linux-gnueabi", armv7_unknown_linux_gnueabi),
|
||||
("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf),
|
||||
("thumbv7neon-unknown-linux-gnueabihf", thumbv7neon_unknown_linux_gnueabihf),
|
||||
("armv7-unknown-linux-musleabi", armv7_unknown_linux_musleabi),
|
||||
("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf),
|
||||
("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu),
|
||||
("aarch64-unknown-linux-musl", aarch64_unknown_linux_musl),
|
||||
|
@ -403,67 +403,3 @@ impl ExitCode {
|
||||
self.0 as i32
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, not(target_os = "emscripten")))]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::ffi::OsStr;
|
||||
use crate::mem;
|
||||
use crate::ptr;
|
||||
use crate::sys::cvt;
|
||||
|
||||
macro_rules! t {
|
||||
($e:expr) => {
|
||||
match $e {
|
||||
Ok(t) => t,
|
||||
Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern {
|
||||
fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;
|
||||
fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_mask() {
|
||||
unsafe {
|
||||
// Test to make sure that a signal mask does not get inherited.
|
||||
let mut cmd = Command::new(OsStr::new("cat"));
|
||||
|
||||
let mut set: libc::sigset_t = mem::uninitialized();
|
||||
let mut old_set: libc::sigset_t = mem::uninitialized();
|
||||
t!(cvt(sigemptyset(&mut set)));
|
||||
t!(cvt(sigaddset(&mut set, libc::SIGINT)));
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
|
||||
|
||||
cmd.stdin(Stdio::MakePipe);
|
||||
cmd.stdout(Stdio::MakePipe);
|
||||
|
||||
let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true));
|
||||
let stdin_write = pipes.stdin.take().unwrap();
|
||||
let stdout_read = pipes.stdout.take().unwrap();
|
||||
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
|
||||
ptr::null_mut())));
|
||||
|
||||
t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
|
||||
// We need to wait until SIGINT is definitely delivered. The
|
||||
// easiest way is to write something to cat, and try to read it
|
||||
// back: if SIGINT is unmasked, it'll get delivered when cat is
|
||||
// next scheduled.
|
||||
let _ = stdin_write.write(b"Hello");
|
||||
drop(stdin_write);
|
||||
|
||||
// Either EOF or failure (EPIPE) is okay.
|
||||
let mut buf = [0; 5];
|
||||
if let Ok(ret) = stdout_read.read(&mut buf) {
|
||||
assert_eq!(ret, 0);
|
||||
}
|
||||
|
||||
t!(cat.wait());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2622,27 +2622,23 @@ impl<'a> State<'a> {
|
||||
self.s.word("<");
|
||||
|
||||
self.commasep(Inconsistent, &generic_params, |s, param| {
|
||||
s.print_outer_attributes_inline(¶m.attrs);
|
||||
|
||||
match param.kind {
|
||||
ast::GenericParamKind::Lifetime => {
|
||||
s.print_outer_attributes_inline(¶m.attrs);
|
||||
let lt = ast::Lifetime { id: param.id, ident: param.ident };
|
||||
s.print_lifetime_bounds(lt, ¶m.bounds)
|
||||
}
|
||||
ast::GenericParamKind::Type { ref default } => {
|
||||
s.print_outer_attributes_inline(¶m.attrs);
|
||||
s.print_ident(param.ident);
|
||||
s.print_type_bounds(":", ¶m.bounds);
|
||||
match default {
|
||||
Some(ref default) => {
|
||||
s.s.space();
|
||||
s.word_space("=");
|
||||
s.print_type(default)
|
||||
}
|
||||
_ => {}
|
||||
if let Some(ref default) = default {
|
||||
s.s.space();
|
||||
s.word_space("=");
|
||||
s.print_type(default)
|
||||
}
|
||||
}
|
||||
ast::GenericParamKind::Const { ref ty } => {
|
||||
s.print_outer_attributes_inline(¶m.attrs);
|
||||
s.word_space("const");
|
||||
s.print_ident(param.ident);
|
||||
s.s.space();
|
||||
@ -2743,6 +2739,9 @@ impl<'a> State<'a> {
|
||||
|
||||
crate fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) {
|
||||
self.ibox(INDENT_UNIT);
|
||||
|
||||
self.print_outer_attributes_inline(&input.attrs);
|
||||
|
||||
match input.ty.node {
|
||||
ast::TyKind::Infer if is_closure => self.print_pat(&input.pat),
|
||||
_ => {
|
||||
|
@ -109,6 +109,8 @@ struct Context<'a, 'b> {
|
||||
invalid_refs: Vec<(usize, usize)>,
|
||||
/// Spans of all the formatting arguments, in order.
|
||||
arg_spans: Vec<Span>,
|
||||
/// All the formatting arguments that have formatting flags set, in order for diagnostics.
|
||||
arg_with_formatting: Vec<parse::FormatSpec<'a>>,
|
||||
/// Whether this formatting string is a literal or it comes from a macro.
|
||||
is_literal: bool,
|
||||
}
|
||||
@ -273,31 +275,44 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
} else {
|
||||
MultiSpan::from_span(self.fmtsp)
|
||||
};
|
||||
let refs_len = self.invalid_refs.len();
|
||||
let mut refs = self
|
||||
let refs = self
|
||||
.invalid_refs
|
||||
.iter()
|
||||
.map(|(r, pos)| (r.to_string(), self.arg_spans.get(*pos)));
|
||||
|
||||
if self.names.is_empty() && !numbered_position_args {
|
||||
let mut zero_based_note = false;
|
||||
|
||||
let count = self.pieces.len() + self.arg_with_formatting
|
||||
.iter()
|
||||
.filter(|fmt| fmt.precision_span.is_some())
|
||||
.count();
|
||||
if self.names.is_empty() && !numbered_position_args && count != self.args.len() {
|
||||
e = self.ecx.mut_span_err(
|
||||
sp,
|
||||
&format!(
|
||||
"{} positional argument{} in format string, but {}",
|
||||
self.pieces.len(),
|
||||
if self.pieces.len() > 1 { "s" } else { "" },
|
||||
self.describe_num_args()
|
||||
count,
|
||||
if count > 1 { "s" } else { "" },
|
||||
self.describe_num_args(),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
let (arg_list, mut sp) = if refs_len == 1 {
|
||||
let (reg, pos) = refs.next().unwrap();
|
||||
let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip();
|
||||
// Avoid `invalid reference to positional arguments 7 and 7 (there is 1 argument)`
|
||||
// for `println!("{7:7$}", 1);`
|
||||
refs.sort();
|
||||
refs.dedup();
|
||||
let (arg_list, mut sp) = if refs.len() == 1 {
|
||||
let spans: Vec<_> = spans.into_iter().filter_map(|sp| sp.map(|sp| *sp)).collect();
|
||||
(
|
||||
format!("argument {}", reg),
|
||||
MultiSpan::from_span(*pos.unwrap_or(&self.fmtsp)),
|
||||
format!("argument {}", refs[0]),
|
||||
if spans.is_empty() {
|
||||
MultiSpan::from_span(self.fmtsp)
|
||||
} else {
|
||||
MultiSpan::from_spans(spans)
|
||||
},
|
||||
)
|
||||
} else {
|
||||
let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip();
|
||||
let pos = MultiSpan::from_spans(spans.into_iter().map(|s| *s.unwrap()).collect());
|
||||
let reg = refs.pop().unwrap();
|
||||
(
|
||||
@ -317,9 +332,70 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
&format!("invalid reference to positional {} ({})",
|
||||
arg_list,
|
||||
self.describe_num_args()));
|
||||
e.note("positional arguments are zero-based");
|
||||
zero_based_note = true;
|
||||
};
|
||||
|
||||
for fmt in &self.arg_with_formatting {
|
||||
if let Some(span) = fmt.precision_span {
|
||||
let span = self.fmtsp.from_inner(span);
|
||||
match fmt.precision {
|
||||
parse::CountIsParam(pos) if pos > self.args.len() => {
|
||||
e.span_label(span, &format!(
|
||||
"this precision flag expects an `usize` argument at position {}, \
|
||||
but {}",
|
||||
pos,
|
||||
self.describe_num_args(),
|
||||
));
|
||||
zero_based_note = true;
|
||||
}
|
||||
parse::CountIsParam(pos) => {
|
||||
let count = self.pieces.len() + self.arg_with_formatting
|
||||
.iter()
|
||||
.filter(|fmt| fmt.precision_span.is_some())
|
||||
.count();
|
||||
e.span_label(span, &format!(
|
||||
"this precision flag adds an extra required argument at position {}, \
|
||||
which is why there {} expected",
|
||||
pos,
|
||||
if count == 1 {
|
||||
"is 1 argument".to_string()
|
||||
} else {
|
||||
format!("are {} arguments", count)
|
||||
},
|
||||
));
|
||||
e.span_label(
|
||||
self.args[pos].span,
|
||||
"this parameter corresponds to the precision flag",
|
||||
);
|
||||
zero_based_note = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if let Some(span) = fmt.width_span {
|
||||
let span = self.fmtsp.from_inner(span);
|
||||
match fmt.width {
|
||||
parse::CountIsParam(pos) if pos > self.args.len() => {
|
||||
e.span_label(span, &format!(
|
||||
"this width flag expects an `usize` argument at position {}, \
|
||||
but {}",
|
||||
pos,
|
||||
self.describe_num_args(),
|
||||
));
|
||||
zero_based_note = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if zero_based_note {
|
||||
e.note("positional arguments are zero-based");
|
||||
}
|
||||
if !self.arg_with_formatting.is_empty() {
|
||||
e.note("for information about formatting flags, visit \
|
||||
https://doc.rust-lang.org/std/fmt/index.html");
|
||||
}
|
||||
|
||||
e.emit();
|
||||
}
|
||||
|
||||
@ -435,10 +511,11 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
|
||||
/// Builds a static `rt::Argument` from a `parse::Piece` or append
|
||||
/// to the `literal` string.
|
||||
fn build_piece(&mut self,
|
||||
piece: &parse::Piece<'_>,
|
||||
arg_index_consumed: &mut Vec<usize>)
|
||||
-> Option<P<ast::Expr>> {
|
||||
fn build_piece(
|
||||
&mut self,
|
||||
piece: &parse::Piece<'a>,
|
||||
arg_index_consumed: &mut Vec<usize>,
|
||||
) -> Option<P<ast::Expr>> {
|
||||
let sp = self.macsp;
|
||||
match *piece {
|
||||
parse::String(s) => {
|
||||
@ -496,7 +573,9 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
align: parse::AlignUnknown,
|
||||
flags: 0,
|
||||
precision: parse::CountImplied,
|
||||
precision_span: None,
|
||||
width: parse::CountImplied,
|
||||
width_span: None,
|
||||
ty: arg.format.ty,
|
||||
},
|
||||
};
|
||||
@ -506,6 +585,9 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
let pos_simple =
|
||||
arg.position.index() == simple_arg.position.index();
|
||||
|
||||
if arg.format.precision_span.is_some() || arg.format.width_span.is_some() {
|
||||
self.arg_with_formatting.push(arg.format);
|
||||
}
|
||||
if !pos_simple || arg.format != simple_arg.format || fill != ' ' {
|
||||
self.all_pieces_simple = false;
|
||||
}
|
||||
@ -530,7 +612,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "FormatSpec"));
|
||||
let fmt = self.ecx.expr_struct(
|
||||
sp,
|
||||
path,
|
||||
path,
|
||||
vec![
|
||||
self.ecx.field_imm(sp, self.ecx.ident_of("fill"), fill),
|
||||
self.ecx.field_imm(sp, self.ecx.ident_of("align"), align),
|
||||
@ -657,12 +739,13 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
self.ecx.expr_call_global(self.macsp, path, fn_args)
|
||||
}
|
||||
|
||||
fn format_arg(ecx: &ExtCtxt<'_>,
|
||||
macsp: Span,
|
||||
mut sp: Span,
|
||||
ty: &ArgumentType,
|
||||
arg: ast::Ident)
|
||||
-> P<ast::Expr> {
|
||||
fn format_arg(
|
||||
ecx: &ExtCtxt<'_>,
|
||||
macsp: Span,
|
||||
mut sp: Span,
|
||||
ty: &ArgumentType,
|
||||
arg: ast::Ident,
|
||||
) -> P<ast::Expr> {
|
||||
sp = sp.apply_mark(ecx.current_expansion.id);
|
||||
let arg = ecx.expr_ident(sp, arg);
|
||||
let trait_ = match *ty {
|
||||
@ -678,7 +761,21 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
"x" => "LowerHex",
|
||||
"X" => "UpperHex",
|
||||
_ => {
|
||||
ecx.span_err(sp, &format!("unknown format trait `{}`", *tyname));
|
||||
let mut err = ecx.struct_span_err(
|
||||
sp,
|
||||
&format!("unknown format trait `{}`", *tyname),
|
||||
);
|
||||
err.note("the only appropriate formatting traits are:\n\
|
||||
- ``, which uses the `Display` trait\n\
|
||||
- `?`, which uses the `Debug` trait\n\
|
||||
- `e`, which uses the `LowerExp` trait\n\
|
||||
- `E`, which uses the `UpperExp` trait\n\
|
||||
- `o`, which uses the `Octal` trait\n\
|
||||
- `p`, which uses the `Pointer` trait\n\
|
||||
- `b`, which uses the `Binary` trait\n\
|
||||
- `x`, which uses the `LowerHex` trait\n\
|
||||
- `X`, which uses the `UpperHex` trait");
|
||||
err.emit();
|
||||
return DummyResult::raw_expr(sp, true);
|
||||
}
|
||||
}
|
||||
@ -941,6 +1038,7 @@ pub fn expand_preparsed_format_args(
|
||||
fmtsp: fmt.span,
|
||||
invalid_refs: Vec::new(),
|
||||
arg_spans,
|
||||
arg_with_formatting: Vec::new(),
|
||||
is_literal,
|
||||
};
|
||||
|
||||
|
@ -1402,6 +1402,7 @@ pub struct MalformedSourceMapPositions {
|
||||
pub end_pos: BytePos
|
||||
}
|
||||
|
||||
/// Range inside of a `Span` used for diagnostics when we only have access to relative positions.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct InnerSpan {
|
||||
pub start: usize,
|
||||
|
29
src/test/ui/async-await/issue-62658.rs
Normal file
29
src/test/ui/async-await/issue-62658.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// This test created a generator whose size was not rounded to a multiple of its
|
||||
// alignment. This caused an assertion error in codegen.
|
||||
|
||||
// build-pass
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await)]
|
||||
|
||||
async fn noop() {}
|
||||
|
||||
async fn foo() {
|
||||
// This suspend should be the largest variant.
|
||||
{
|
||||
let x = [0u8; 17];
|
||||
noop().await;
|
||||
println!("{:?}", x);
|
||||
}
|
||||
|
||||
// Add one variant that's aligned to 8 bytes.
|
||||
{
|
||||
let x = 0u64;
|
||||
noop().await;
|
||||
println!("{:?}", x);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = foo();
|
||||
}
|
@ -75,4 +75,15 @@ ninth number: {
|
||||
tenth number: {}",
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
//~^^ ERROR: invalid format string
|
||||
println!("{} {:.*} {}", 1, 3.2, 4);
|
||||
//~^ ERROR 4 positional arguments in format string, but there are 3 arguments
|
||||
//~| ERROR mismatched types
|
||||
println!("{} {:07$.*} {}", 1, 3.2, 4);
|
||||
//~^ ERROR 4 positional arguments in format string, but there are 3 arguments
|
||||
//~| ERROR mismatched types
|
||||
println!("{} {:07$} {}", 1, 3.2, 4);
|
||||
//~^ ERROR invalid reference to positional argument 7 (there are 3 arguments)
|
||||
println!("{:foo}", 1); //~ ERROR unknown format trait `foo`
|
||||
println!("{5} {:4$} {6:7$}", 1);
|
||||
//~^ ERROR invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument)
|
||||
}
|
||||
|
@ -220,5 +220,87 @@ LL | tenth number: {}",
|
||||
|
|
||||
= note: if you intended to print `{`, you can escape it using `{{`
|
||||
|
||||
error: aborting due to 28 previous errors
|
||||
error: 4 positional arguments in format string, but there are 3 arguments
|
||||
--> $DIR/ifmt-bad-arg.rs:78:15
|
||||
|
|
||||
LL | println!("{} {:.*} {}", 1, 3.2, 4);
|
||||
| ^^ ^^--^ ^^ --- this parameter corresponds to the precision flag
|
||||
| |
|
||||
| this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected
|
||||
|
|
||||
= note: positional arguments are zero-based
|
||||
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
|
||||
|
||||
error: 4 positional arguments in format string, but there are 3 arguments
|
||||
--> $DIR/ifmt-bad-arg.rs:81:15
|
||||
|
|
||||
LL | println!("{} {:07$.*} {}", 1, 3.2, 4);
|
||||
| ^^ ^^^----^ ^^ --- this parameter corresponds to the precision flag
|
||||
| | |
|
||||
| | this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected
|
||||
| this width flag expects an `usize` argument at position 7, but there are 3 arguments
|
||||
|
|
||||
= note: positional arguments are zero-based
|
||||
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
|
||||
|
||||
error: invalid reference to positional argument 7 (there are 3 arguments)
|
||||
--> $DIR/ifmt-bad-arg.rs:84:18
|
||||
|
|
||||
LL | println!("{} {:07$} {}", 1, 3.2, 4);
|
||||
| ^^^--^
|
||||
| |
|
||||
| this width flag expects an `usize` argument at position 7, but there are 3 arguments
|
||||
|
|
||||
= note: positional arguments are zero-based
|
||||
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
|
||||
|
||||
error: unknown format trait `foo`
|
||||
--> $DIR/ifmt-bad-arg.rs:86:24
|
||||
|
|
||||
LL | println!("{:foo}", 1);
|
||||
| ^
|
||||
|
|
||||
= note: the only appropriate formatting traits are:
|
||||
- ``, which uses the `Display` trait
|
||||
- `?`, which uses the `Debug` trait
|
||||
- `e`, which uses the `LowerExp` trait
|
||||
- `E`, which uses the `UpperExp` trait
|
||||
- `o`, which uses the `Octal` trait
|
||||
- `p`, which uses the `Pointer` trait
|
||||
- `b`, which uses the `Binary` trait
|
||||
- `x`, which uses the `LowerHex` trait
|
||||
- `X`, which uses the `UpperHex` trait
|
||||
|
||||
error: invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument)
|
||||
--> $DIR/ifmt-bad-arg.rs:87:15
|
||||
|
|
||||
LL | println!("{5} {:4$} {6:7$}", 1);
|
||||
| ^^^ ^^--^ ^^^--^
|
||||
| | |
|
||||
| | this width flag expects an `usize` argument at position 7, but there is 1 argument
|
||||
| this width flag expects an `usize` argument at position 4, but there is 1 argument
|
||||
|
|
||||
= note: positional arguments are zero-based
|
||||
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ifmt-bad-arg.rs:78:32
|
||||
|
|
||||
LL | println!("{} {:.*} {}", 1, 3.2, 4);
|
||||
| ^^^ expected usize, found floating-point number
|
||||
|
|
||||
= note: expected type `&usize`
|
||||
found type `&{float}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ifmt-bad-arg.rs:81:35
|
||||
|
|
||||
LL | println!("{} {:07$.*} {}", 1, 3.2, 4);
|
||||
| ^^^ expected usize, found floating-point number
|
||||
|
|
||||
= note: expected type `&usize`
|
||||
found type `&{float}`
|
||||
|
||||
error: aborting due to 35 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -3,6 +3,17 @@ error: unknown format trait `notimplemented`
|
||||
|
|
||||
LL | format!("{:notimplemented}", "3");
|
||||
| ^^^
|
||||
|
|
||||
= note: the only appropriate formatting traits are:
|
||||
- ``, which uses the `Display` trait
|
||||
- `?`, which uses the `Debug` trait
|
||||
- `e`, which uses the `LowerExp` trait
|
||||
- `E`, which uses the `UpperExp` trait
|
||||
- `o`, which uses the `Octal` trait
|
||||
- `p`, which uses the `Pointer` trait
|
||||
- `b`, which uses the `Binary` trait
|
||||
- `x`, which uses the `LowerHex` trait
|
||||
- `X`, which uses the `UpperHex` trait
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
34
src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs
Normal file
34
src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
macro_rules! checker {
|
||||
($attr_name:ident, $expected:literal) => {
|
||||
#[proc_macro_attribute]
|
||||
pub fn $attr_name(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(input.to_string(), $expected);
|
||||
TokenStream::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checker!(attr_extern, r#"extern "C" {
|
||||
fn ffi(#[a1] arg1: i32, #[a2] ...);
|
||||
}"#);
|
||||
checker!(attr_extern_cvar, r#"unsafe extern "C" fn cvar(arg1: i32, #[a1] mut args: ...) { }"#);
|
||||
checker!(attr_alias, "type Alias = fn(#[a1] u8, #[a2] ...);");
|
||||
checker!(attr_free, "fn free(#[a1] arg1: u8) { let lam = |#[a2] W(x), #[a3] y| (); }");
|
||||
checker!(attr_inherent_1, "fn inherent1(#[a1] self, #[a2] arg1: u8) { }");
|
||||
checker!(attr_inherent_2, "fn inherent2(#[a1] &self, #[a2] arg1: u8) { }");
|
||||
checker!(attr_inherent_3, "fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) { }");
|
||||
checker!(attr_inherent_4, "fn inherent4<'a>(#[a1] self: Box<Self>, #[a2] arg1: u8) { }");
|
||||
checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1: u8);");
|
||||
checker!(attr_trait_2, "fn trait2(#[a1] &self, #[a2] arg1: u8);");
|
||||
checker!(attr_trait_3, "fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8);");
|
||||
checker!(attr_trait_4, "fn trait4<'a>(#[a1] self: Box<Self>, #[a2] arg1: u8, #[a3] Vec<u8>);");
|
56
src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
Normal file
56
src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
Normal file
@ -0,0 +1,56 @@
|
||||
// aux-build:param-attrs.rs
|
||||
|
||||
// check-pass
|
||||
|
||||
#![feature(param_attrs)]
|
||||
#![feature(c_variadic)]
|
||||
|
||||
extern crate param_attrs;
|
||||
|
||||
use param_attrs::*;
|
||||
|
||||
struct W(u8);
|
||||
|
||||
#[attr_extern]
|
||||
extern "C" { fn ffi(#[a1] arg1: i32, #[a2] ...); }
|
||||
|
||||
#[attr_extern_cvar]
|
||||
unsafe extern "C" fn cvar(arg1: i32, #[a1] mut args: ...) {}
|
||||
|
||||
#[attr_alias]
|
||||
type Alias = fn(#[a1] u8, #[a2] ...);
|
||||
|
||||
#[attr_free]
|
||||
fn free(#[a1] arg1: u8) {
|
||||
let lam = |#[a2] W(x), #[a3] y| ();
|
||||
}
|
||||
|
||||
impl W {
|
||||
#[attr_inherent_1]
|
||||
fn inherent1(#[a1] self, #[a2] arg1: u8) {}
|
||||
|
||||
#[attr_inherent_2]
|
||||
fn inherent2(#[a1] &self, #[a2] arg1: u8) {}
|
||||
|
||||
#[attr_inherent_3]
|
||||
fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) {}
|
||||
|
||||
#[attr_inherent_4]
|
||||
fn inherent4<'a>(#[a1] self: Box<Self>, #[a2] arg1: u8) {}
|
||||
}
|
||||
|
||||
trait A {
|
||||
#[attr_trait_1]
|
||||
fn trait1(#[a1] self, #[a2] arg1: u8);
|
||||
|
||||
#[attr_trait_2]
|
||||
fn trait2(#[a1] &self, #[a2] arg1: u8);
|
||||
|
||||
#[attr_trait_3]
|
||||
fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8);
|
||||
|
||||
#[attr_trait_4]
|
||||
fn trait4<'a>(#[a1] self: Box<Self>, #[a2] arg1: u8, #[a3] Vec<u8>);
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -56,8 +56,10 @@ static TARGETS: &[&str] = &[
|
||||
"armv7-apple-ios",
|
||||
"armv7-linux-androideabi",
|
||||
"thumbv7neon-linux-androideabi",
|
||||
"armv7-unknown-linux-gnueabi",
|
||||
"armv7-unknown-linux-gnueabihf",
|
||||
"thumbv7neon-unknown-linux-gnueabihf",
|
||||
"armv7-unknown-linux-musleabi",
|
||||
"armv7-unknown-linux-musleabihf",
|
||||
"armebv7r-none-eabi",
|
||||
"armebv7r-none-eabihf",
|
||||
|
Loading…
x
Reference in New Issue
Block a user