Auto merge of #91692 - matthiaskrgr:rollup-u7dvh0n, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #87599 (Implement concat_bytes!) - #89999 (Update std::env::temp_dir to use GetTempPath2 on Windows when available.) - #90796 (Remove the reg_thumb register class for asm! on ARM) - #91042 (Use Vec extend instead of repeated pushes on several places) - #91634 (Do not attempt to suggest help for overly malformed struct/function call) - #91685 (Install llvm tools to sysroot when assembling local toolchain) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
600820da45
26 changed files with 542 additions and 98 deletions
167
compiler/rustc_builtin_macros/src/concat_bytes.rs
Normal file
167
compiler/rustc_builtin_macros/src/concat_bytes.rs
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
use rustc_ast as ast;
|
||||||
|
use rustc_ast::{ptr::P, tokenstream::TokenStream};
|
||||||
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_expand::base::{self, DummyResult};
|
||||||
|
|
||||||
|
/// Emits errors for literal expressions that are invalid inside and outside of an array.
|
||||||
|
fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_nested: bool) {
|
||||||
|
let lit = if let ast::ExprKind::Lit(lit) = &expr.kind {
|
||||||
|
lit
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
match lit.kind {
|
||||||
|
ast::LitKind::Char(_) => {
|
||||||
|
let mut err = cx.struct_span_err(expr.span, "cannot concatenate character literals");
|
||||||
|
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||||
|
err.span_suggestion(
|
||||||
|
expr.span,
|
||||||
|
"try using a byte character",
|
||||||
|
format!("b{}", snippet),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::LitKind::Str(_, _) => {
|
||||||
|
let mut err = cx.struct_span_err(expr.span, "cannot concatenate string literals");
|
||||||
|
// suggestion would be invalid if we are nested
|
||||||
|
if !is_nested {
|
||||||
|
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||||
|
err.span_suggestion(
|
||||||
|
expr.span,
|
||||||
|
"try using a byte string",
|
||||||
|
format!("b{}", snippet),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
ast::LitKind::Float(_, _) => {
|
||||||
|
cx.span_err(expr.span, "cannot concatenate float literals");
|
||||||
|
}
|
||||||
|
ast::LitKind::Bool(_) => {
|
||||||
|
cx.span_err(expr.span, "cannot concatenate boolean literals");
|
||||||
|
}
|
||||||
|
ast::LitKind::Err(_) => {}
|
||||||
|
ast::LitKind::Int(_, _) if !is_nested => {
|
||||||
|
let mut err = cx.struct_span_err(expr.span, "cannot concatenate numeric literals");
|
||||||
|
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||||
|
err.span_suggestion(
|
||||||
|
expr.span,
|
||||||
|
"try wrapping the number in an array",
|
||||||
|
format!("[{}]", snippet),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
ast::LitKind::Int(
|
||||||
|
val,
|
||||||
|
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
|
||||||
|
) => {
|
||||||
|
assert!(val > u8::MAX.into()); // must be an error
|
||||||
|
cx.span_err(expr.span, "numeric literal is out of bounds");
|
||||||
|
}
|
||||||
|
ast::LitKind::Int(_, _) => {
|
||||||
|
cx.span_err(expr.span, "numeric literal is not a `u8`");
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expand_concat_bytes(
|
||||||
|
cx: &mut base::ExtCtxt<'_>,
|
||||||
|
sp: rustc_span::Span,
|
||||||
|
tts: TokenStream,
|
||||||
|
) -> Box<dyn base::MacResult + 'static> {
|
||||||
|
let es = match base::get_exprs_from_tts(cx, sp, tts) {
|
||||||
|
Some(e) => e,
|
||||||
|
None => return DummyResult::any(sp),
|
||||||
|
};
|
||||||
|
let mut accumulator = Vec::new();
|
||||||
|
let mut missing_literals = vec![];
|
||||||
|
let mut has_errors = false;
|
||||||
|
for e in es {
|
||||||
|
match e.kind {
|
||||||
|
ast::ExprKind::Array(ref exprs) => {
|
||||||
|
for expr in exprs {
|
||||||
|
match expr.kind {
|
||||||
|
ast::ExprKind::Array(_) => {
|
||||||
|
if !has_errors {
|
||||||
|
cx.span_err(expr.span, "cannot concatenate doubly nested array");
|
||||||
|
}
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||||
|
ast::LitKind::Int(
|
||||||
|
val,
|
||||||
|
ast::LitIntType::Unsuffixed
|
||||||
|
| ast::LitIntType::Unsigned(ast::UintTy::U8),
|
||||||
|
) if val <= u8::MAX.into() => {
|
||||||
|
accumulator.push(val as u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast::LitKind::Byte(val) => {
|
||||||
|
accumulator.push(val);
|
||||||
|
}
|
||||||
|
ast::LitKind::ByteStr(_) => {
|
||||||
|
if !has_errors {
|
||||||
|
cx.struct_span_err(
|
||||||
|
expr.span,
|
||||||
|
"cannot concatenate doubly nested array",
|
||||||
|
)
|
||||||
|
.note("byte strings are treated as arrays of bytes")
|
||||||
|
.help("try flattening the array")
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if !has_errors {
|
||||||
|
invalid_type_err(cx, expr, true);
|
||||||
|
}
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
missing_literals.push(expr.span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::ExprKind::Lit(ref lit) => match lit.kind {
|
||||||
|
ast::LitKind::Byte(val) => {
|
||||||
|
accumulator.push(val);
|
||||||
|
}
|
||||||
|
ast::LitKind::ByteStr(ref bytes) => {
|
||||||
|
accumulator.extend_from_slice(&bytes);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if !has_errors {
|
||||||
|
invalid_type_err(cx, &e, false);
|
||||||
|
}
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ast::ExprKind::Err => {
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
missing_literals.push(e.span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !missing_literals.is_empty() {
|
||||||
|
let mut err = cx.struct_span_err(missing_literals.clone(), "expected a byte literal");
|
||||||
|
err.note("only byte literals (like `b\"foo\"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`");
|
||||||
|
err.emit();
|
||||||
|
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
|
||||||
|
} else if has_errors {
|
||||||
|
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
|
||||||
|
}
|
||||||
|
let sp = cx.with_def_site_ctxt(sp);
|
||||||
|
base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(accumulator))))
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ mod cfg_accessible;
|
||||||
mod cfg_eval;
|
mod cfg_eval;
|
||||||
mod compile_error;
|
mod compile_error;
|
||||||
mod concat;
|
mod concat;
|
||||||
|
mod concat_bytes;
|
||||||
mod concat_idents;
|
mod concat_idents;
|
||||||
mod derive;
|
mod derive;
|
||||||
mod deriving;
|
mod deriving;
|
||||||
|
@ -65,6 +66,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
||||||
cfg: cfg::expand_cfg,
|
cfg: cfg::expand_cfg,
|
||||||
column: source_util::expand_column,
|
column: source_util::expand_column,
|
||||||
compile_error: compile_error::expand_compile_error,
|
compile_error: compile_error::expand_compile_error,
|
||||||
|
concat_bytes: concat_bytes::expand_concat_bytes,
|
||||||
concat_idents: concat_idents::expand_concat_idents,
|
concat_idents: concat_idents::expand_concat_idents,
|
||||||
concat: concat::expand_concat,
|
concat: concat::expand_concat,
|
||||||
env: env::expand_env,
|
env: env::expand_env,
|
||||||
|
|
|
@ -568,7 +568,6 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
|
||||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => unimplemented!(),
|
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => unimplemented!(),
|
||||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => unimplemented!(),
|
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => unimplemented!(),
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => unimplemented!(),
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => unimplemented!(),
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => unimplemented!(),
|
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
|
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => unimplemented!(),
|
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => unimplemented!(),
|
||||||
|
@ -628,8 +627,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
|
||||||
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
|
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)=> cx.type_i32(),
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => cx.type_i32(),
|
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
|
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
||||||
|
@ -737,8 +735,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
|
||||||
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
|
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => unimplemented!(),
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => unimplemented!(),
|
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => unimplemented!(),
|
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => unimplemented!(),
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
||||||
|
|
|
@ -632,7 +632,6 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
|
||||||
unreachable!("clobber-only")
|
unreachable!("clobber-only")
|
||||||
}
|
}
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r",
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r",
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => "l",
|
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
|
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => "t",
|
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => "t",
|
||||||
|
@ -703,8 +702,7 @@ fn modifier_to_llvm(
|
||||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
|
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
|
||||||
unreachable!("clobber-only")
|
unreachable!("clobber-only")
|
||||||
}
|
}
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => None,
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => None,
|
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => None,
|
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => None,
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
||||||
|
@ -785,8 +783,7 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
|
||||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
|
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
|
||||||
unreachable!("clobber-only")
|
unreachable!("clobber-only")
|
||||||
}
|
}
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => cx.type_i32(),
|
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
||||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
|
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
|
||||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
||||||
|
|
|
@ -35,6 +35,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
||||||
// since it should be enabled per-function using #[instruction_set], not
|
// since it should be enabled per-function using #[instruction_set], not
|
||||||
// #[target_feature].
|
// #[target_feature].
|
||||||
("thumb-mode", Some(sym::arm_target_feature)),
|
("thumb-mode", Some(sym::arm_target_feature)),
|
||||||
|
("thumb2", Some(sym::arm_target_feature)),
|
||||||
];
|
];
|
||||||
|
|
||||||
const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
||||||
|
|
|
@ -1100,30 +1100,37 @@ impl<'a> Parser<'a> {
|
||||||
snapshot.bump(); // `(`
|
snapshot.bump(); // `(`
|
||||||
match snapshot.parse_struct_fields(path, false, token::Paren) {
|
match snapshot.parse_struct_fields(path, false, token::Paren) {
|
||||||
Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => {
|
Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => {
|
||||||
// We have are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
|
// We are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
|
||||||
// `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`.
|
// `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`.
|
||||||
*self = snapshot;
|
*self = snapshot;
|
||||||
let close_paren = self.prev_token.span;
|
let close_paren = self.prev_token.span;
|
||||||
let span = lo.to(self.prev_token.span);
|
let span = lo.to(self.prev_token.span);
|
||||||
err.cancel();
|
if !fields.is_empty() {
|
||||||
self.struct_span_err(
|
err.cancel();
|
||||||
span,
|
let mut err = self.struct_span_err(
|
||||||
"invalid `struct` delimiters or `fn` call arguments",
|
span,
|
||||||
)
|
"invalid `struct` delimiters or `fn` call arguments",
|
||||||
.multipart_suggestion(
|
);
|
||||||
&format!("if `{}` is a struct, use braces as delimiters", name),
|
err.multipart_suggestion(
|
||||||
vec![(open_paren, " { ".to_string()), (close_paren, " }".to_string())],
|
&format!("if `{}` is a struct, use braces as delimiters", name),
|
||||||
Applicability::MaybeIncorrect,
|
vec![
|
||||||
)
|
(open_paren, " { ".to_string()),
|
||||||
.multipart_suggestion(
|
(close_paren, " }".to_string()),
|
||||||
&format!("if `{}` is a function, use the arguments directly", name),
|
],
|
||||||
fields
|
Applicability::MaybeIncorrect,
|
||||||
.into_iter()
|
);
|
||||||
.map(|field| (field.span.until(field.expr.span), String::new()))
|
err.multipart_suggestion(
|
||||||
.collect(),
|
&format!("if `{}` is a function, use the arguments directly", name),
|
||||||
Applicability::MaybeIncorrect,
|
fields
|
||||||
)
|
.into_iter()
|
||||||
.emit();
|
.map(|field| (field.span.until(field.expr.span), String::new()))
|
||||||
|
.collect(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
err.emit();
|
||||||
|
} else {
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
return Some(self.mk_expr_err(span));
|
return Some(self.mk_expr_err(span));
|
||||||
}
|
}
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
|
|
|
@ -439,6 +439,7 @@ symbols! {
|
||||||
compiler_builtins,
|
compiler_builtins,
|
||||||
compiler_fence,
|
compiler_fence,
|
||||||
concat,
|
concat,
|
||||||
|
concat_bytes,
|
||||||
concat_idents,
|
concat_idents,
|
||||||
conservative_impl_trait,
|
conservative_impl_trait,
|
||||||
console,
|
console,
|
||||||
|
@ -1058,7 +1059,6 @@ symbols! {
|
||||||
reg_nonzero,
|
reg_nonzero,
|
||||||
reg_pair,
|
reg_pair,
|
||||||
reg_ptr,
|
reg_ptr,
|
||||||
reg_thumb,
|
|
||||||
reg_upper,
|
reg_upper,
|
||||||
register_attr,
|
register_attr,
|
||||||
register_tool,
|
register_tool,
|
||||||
|
|
|
@ -6,7 +6,6 @@ use std::fmt;
|
||||||
def_reg_class! {
|
def_reg_class! {
|
||||||
Arm ArmInlineAsmRegClass {
|
Arm ArmInlineAsmRegClass {
|
||||||
reg,
|
reg,
|
||||||
reg_thumb,
|
|
||||||
sreg,
|
sreg,
|
||||||
sreg_low16,
|
sreg_low16,
|
||||||
dreg,
|
dreg,
|
||||||
|
@ -47,7 +46,7 @@ impl ArmInlineAsmRegClass {
|
||||||
_arch: InlineAsmArch,
|
_arch: InlineAsmArch,
|
||||||
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
) -> &'static [(InlineAsmType, Option<&'static str>)] {
|
||||||
match self {
|
match self {
|
||||||
Self::reg | Self::reg_thumb => types! { _: I8, I16, I32, F32; },
|
Self::reg => types! { _: I8, I16, I32, F32; },
|
||||||
Self::sreg | Self::sreg_low16 => types! { "vfp2": I32, F32; },
|
Self::sreg | Self::sreg_low16 => types! { "vfp2": I32, F32; },
|
||||||
Self::dreg | Self::dreg_low16 | Self::dreg_low8 => types! {
|
Self::dreg | Self::dreg_low16 | Self::dreg_low8 => types! {
|
||||||
"vfp2": I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
|
"vfp2": I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
|
||||||
|
@ -88,20 +87,32 @@ fn frame_pointer_r7(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn not_thumb1(
|
||||||
|
_arch: InlineAsmArch,
|
||||||
|
mut has_feature: impl FnMut(&str) -> bool,
|
||||||
|
_target: &Target,
|
||||||
|
) -> Result<(), &'static str> {
|
||||||
|
if has_feature("thumb-mode") && !has_feature("thumb2") {
|
||||||
|
Err("high registers (r8+) cannot be used in Thumb-1 code")
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def_regs! {
|
def_regs! {
|
||||||
Arm ArmInlineAsmReg ArmInlineAsmRegClass {
|
Arm ArmInlineAsmReg ArmInlineAsmRegClass {
|
||||||
r0: reg, reg_thumb = ["r0", "a1"],
|
r0: reg = ["r0", "a1"],
|
||||||
r1: reg, reg_thumb = ["r1", "a2"],
|
r1: reg = ["r1", "a2"],
|
||||||
r2: reg, reg_thumb = ["r2", "a3"],
|
r2: reg = ["r2", "a3"],
|
||||||
r3: reg, reg_thumb = ["r3", "a4"],
|
r3: reg = ["r3", "a4"],
|
||||||
r4: reg, reg_thumb = ["r4", "v1"],
|
r4: reg = ["r4", "v1"],
|
||||||
r5: reg, reg_thumb = ["r5", "v2"],
|
r5: reg = ["r5", "v2"],
|
||||||
r7: reg, reg_thumb = ["r7", "v4"] % frame_pointer_r7,
|
r7: reg = ["r7", "v4"] % frame_pointer_r7,
|
||||||
r8: reg = ["r8", "v5"],
|
r8: reg = ["r8", "v5"] % not_thumb1,
|
||||||
r10: reg = ["r10", "sl"],
|
r10: reg = ["r10", "sl"] % not_thumb1,
|
||||||
r11: reg = ["r11", "fp"] % frame_pointer_r11,
|
r11: reg = ["r11", "fp"] % frame_pointer_r11,
|
||||||
r12: reg = ["r12", "ip"],
|
r12: reg = ["r12", "ip"] % not_thumb1,
|
||||||
r14: reg = ["r14", "lr"],
|
r14: reg = ["r14", "lr"] % not_thumb1,
|
||||||
s0: sreg, sreg_low16 = ["s0"],
|
s0: sreg, sreg_low16 = ["s0"],
|
||||||
s1: sreg, sreg_low16 = ["s1"],
|
s1: sreg, sreg_low16 = ["s1"],
|
||||||
s2: sreg, sreg_low16 = ["s2"],
|
s2: sreg, sreg_low16 = ["s2"],
|
||||||
|
|
|
@ -967,6 +967,34 @@ pub(crate) mod builtin {
|
||||||
($($e:ident),+ $(,)?) => {{ /* compiler built-in */ }};
|
($($e:ident),+ $(,)?) => {{ /* compiler built-in */ }};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Concatenates literals into a byte slice.
|
||||||
|
///
|
||||||
|
/// This macro takes any number of comma-separated literals, and concatenates them all into
|
||||||
|
/// one, yielding an expression of type `&[u8, _]`, which represents all of the literals
|
||||||
|
/// concatenated left-to-right. The literals passed can be any combination of:
|
||||||
|
///
|
||||||
|
/// - byte literals (`b'r'`)
|
||||||
|
/// - byte strings (`b"Rust"`)
|
||||||
|
/// - arrays of bytes/numbers (`[b'A', 66, b'C']`)
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(concat_bytes)]
|
||||||
|
///
|
||||||
|
/// # fn main() {
|
||||||
|
/// let s: &[u8; 6] = concat_bytes!(b'A', b"BC", [68, b'E', 70]);
|
||||||
|
/// assert_eq!(s, b"ABCDEF");
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
#[unstable(feature = "concat_bytes", issue = "87555")]
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! concat_bytes {
|
||||||
|
($($e:literal),+ $(,)?) => {{ /* compiler built-in */ }};
|
||||||
|
}
|
||||||
|
|
||||||
/// Concatenates literals into a static string slice.
|
/// Concatenates literals into a static string slice.
|
||||||
///
|
///
|
||||||
/// This macro takes any number of comma-separated literals, yielding an
|
/// This macro takes any number of comma-separated literals, yielding an
|
||||||
|
|
|
@ -60,6 +60,15 @@ pub use crate::{
|
||||||
option_env, stringify, trace_macros,
|
option_env, stringify, trace_macros,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[unstable(
|
||||||
|
feature = "concat_bytes",
|
||||||
|
issue = "87555",
|
||||||
|
reason = "`concat_bytes` is not stable enough for use and is subject to change"
|
||||||
|
)]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
#[doc(no_inline)]
|
||||||
|
pub use crate::concat_bytes;
|
||||||
|
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "asm",
|
feature = "asm",
|
||||||
issue = "72016",
|
issue = "72016",
|
||||||
|
|
|
@ -583,28 +583,25 @@ pub fn home_dir() -> Option<PathBuf> {
|
||||||
/// may result in "insecure temporary file" security vulnerabilities. Consider
|
/// may result in "insecure temporary file" security vulnerabilities. Consider
|
||||||
/// using a crate that securely creates temporary files or directories.
|
/// using a crate that securely creates temporary files or directories.
|
||||||
///
|
///
|
||||||
/// # Unix
|
/// # Platform-specific behavior
|
||||||
///
|
///
|
||||||
/// Returns the value of the `TMPDIR` environment variable if it is
|
/// On Unix, returns the value of the `TMPDIR` environment variable if it is
|
||||||
/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
|
/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
|
||||||
/// is no global temporary folder (it is usually allocated per-app), it returns
|
/// is no global temporary folder (it is usually allocated per-app), it returns
|
||||||
/// `/data/local/tmp`.
|
/// `/data/local/tmp`.
|
||||||
|
/// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] /
|
||||||
|
/// [`GetTempPath`][GetTempPath], which this function uses internally.
|
||||||
|
/// Note that, this [may change in the future][changes].
|
||||||
///
|
///
|
||||||
/// # Windows
|
/// [changes]: io#platform-specific-behavior
|
||||||
///
|
/// [GetTempPath2]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
|
||||||
/// Returns the value of, in order, the `TMP`, `TEMP`,
|
/// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
|
||||||
/// `USERPROFILE` environment variable if any are set and not the empty
|
|
||||||
/// string. Otherwise, `temp_dir` returns the path of the Windows directory.
|
|
||||||
/// This behavior is identical to that of [`GetTempPath`][msdn], which this
|
|
||||||
/// function uses internally.
|
|
||||||
///
|
|
||||||
/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
|
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::env;
|
/// use std::env;
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let mut dir = env::temp_dir();
|
/// let dir = env::temp_dir();
|
||||||
/// println!("Temporary directory: {}", dir.display());
|
/// println!("Temporary directory: {}", dir.display());
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -250,6 +250,7 @@
|
||||||
#![feature(cfg_target_thread_local)]
|
#![feature(cfg_target_thread_local)]
|
||||||
#![feature(char_error_internals)]
|
#![feature(char_error_internals)]
|
||||||
#![feature(char_internals)]
|
#![feature(char_internals)]
|
||||||
|
#![cfg_attr(not(bootstrap), feature(concat_bytes))]
|
||||||
#![feature(concat_idents)]
|
#![feature(concat_idents)]
|
||||||
#![feature(const_cstr_unchecked)]
|
#![feature(const_cstr_unchecked)]
|
||||||
#![feature(const_fn_floating_point_arithmetic)]
|
#![feature(const_fn_floating_point_arithmetic)]
|
||||||
|
@ -576,6 +577,14 @@ pub use core::{
|
||||||
log_syntax, module_path, option_env, stringify, trace_macros,
|
log_syntax, module_path, option_env, stringify, trace_macros,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[unstable(
|
||||||
|
feature = "concat_bytes",
|
||||||
|
issue = "87555",
|
||||||
|
reason = "`concat_bytes` is not stable enough for use and is subject to change"
|
||||||
|
)]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
pub use core::concat_bytes;
|
||||||
|
|
||||||
#[stable(feature = "core_primitive", since = "1.43.0")]
|
#[stable(feature = "core_primitive", since = "1.43.0")]
|
||||||
pub use core::primitive;
|
pub use core::primitive;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,15 @@ pub use core::prelude::v1::{
|
||||||
PartialOrd,
|
PartialOrd,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[unstable(
|
||||||
|
feature = "concat_bytes",
|
||||||
|
issue = "87555",
|
||||||
|
reason = "`concat_bytes` is not stable enough for use and is subject to change"
|
||||||
|
)]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
#[doc(no_inline)]
|
||||||
|
pub use core::prelude::v1::concat_bytes;
|
||||||
|
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "asm",
|
feature = "asm",
|
||||||
issue = "72016",
|
issue = "72016",
|
||||||
|
|
|
@ -1110,6 +1110,12 @@ compat_fn! {
|
||||||
-> () {
|
-> () {
|
||||||
GetSystemTimeAsFileTime(lpSystemTimeAsFileTime)
|
GetSystemTimeAsFileTime(lpSystemTimeAsFileTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// >= Win11 / Server 2022
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
|
||||||
|
pub fn GetTempPath2W(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD {
|
||||||
|
GetTempPathW(nBufferLength, lpBuffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compat_fn! {
|
compat_fn! {
|
||||||
|
|
|
@ -275,7 +275,7 @@ pub fn unsetenv(n: &OsStr) -> io::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn temp_dir() -> PathBuf {
|
pub fn temp_dir() -> PathBuf {
|
||||||
super::fill_utf16_buf(|buf, sz| unsafe { c::GetTempPathW(sz, buf) }, super::os2path).unwrap()
|
super::fill_utf16_buf(|buf, sz| unsafe { c::GetTempPath2W(sz, buf) }, super::os2path).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_vendor = "uwp"))]
|
#[cfg(not(target_vendor = "uwp"))]
|
||||||
|
|
|
@ -28,6 +28,7 @@ use crate::dist;
|
||||||
use crate::native;
|
use crate::native;
|
||||||
use crate::tool::SourceType;
|
use crate::tool::SourceType;
|
||||||
use crate::util::{exe, is_debug_info, is_dylib, symlink_dir};
|
use crate::util::{exe, is_debug_info, is_dylib, symlink_dir};
|
||||||
|
use crate::LLVM_TOOLS;
|
||||||
use crate::{Compiler, DependencyType, GitRepo, Mode};
|
use crate::{Compiler, DependencyType, GitRepo, Mode};
|
||||||
|
|
||||||
#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -1164,6 +1165,16 @@ impl Step for Assemble {
|
||||||
let llvm_bin_dir = output(Command::new(llvm_config_bin).arg("--bindir"));
|
let llvm_bin_dir = output(Command::new(llvm_config_bin).arg("--bindir"));
|
||||||
let llvm_bin_dir = Path::new(llvm_bin_dir.trim());
|
let llvm_bin_dir = Path::new(llvm_bin_dir.trim());
|
||||||
builder.copy(&llvm_bin_dir.join(&src_exe), &libdir_bin.join(&dst_exe));
|
builder.copy(&llvm_bin_dir.join(&src_exe), &libdir_bin.join(&dst_exe));
|
||||||
|
|
||||||
|
// Since we've already built the LLVM tools, install them to the sysroot.
|
||||||
|
// This is the equivalent of installing the `llvm-tools-preview` component via
|
||||||
|
// rustup, and lets developers use a locally built toolchain to
|
||||||
|
// build projects that expect llvm tools to be present in the sysroot
|
||||||
|
// (e.g. the `bootimage` crate).
|
||||||
|
for tool in LLVM_TOOLS {
|
||||||
|
let tool_exe = exe(tool, target_compiler.host);
|
||||||
|
builder.copy(&llvm_bin_dir.join(&tool_exe), &libdir_bin.join(&tool_exe));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -564,12 +564,8 @@ Here is the list of currently supported register classes:
|
||||||
| AArch64 | `vreg` | `v[0-31]` | `w` |
|
| AArch64 | `vreg` | `v[0-31]` | `w` |
|
||||||
| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
|
| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
|
||||||
| AArch64 | `preg` | `p[0-15]`, `ffr` | Only clobbers |
|
| AArch64 | `preg` | `p[0-15]`, `ffr` | Only clobbers |
|
||||||
| ARM (ARM) | `reg` | `r[0-12]`, `r14` | `r` |
|
| ARM (ARM/Thumb2) | `reg` | `r[0-12]`, `r14` | `r` |
|
||||||
| ARM (Thumb2) | `reg` | `r[0-12]`, `r14` | `r` |
|
|
||||||
| ARM (Thumb1) | `reg` | `r[0-7]` | `r` |
|
| ARM (Thumb1) | `reg` | `r[0-7]` | `r` |
|
||||||
| ARM (ARM) | `reg_thumb` | `r[0-r12]`, `r14` | `l` |
|
|
||||||
| ARM (Thumb2) | `reg_thumb` | `r[0-7]` | `l` |
|
|
||||||
| ARM (Thumb1) | `reg_thumb` | `r[0-7]` | `l` |
|
|
||||||
| ARM | `sreg` | `s[0-31]` | `t` |
|
| ARM | `sreg` | `s[0-31]` | `t` |
|
||||||
| ARM | `sreg_low16` | `s[0-15]` | `x` |
|
| ARM | `sreg_low16` | `s[0-15]` | `x` |
|
||||||
| ARM | `dreg` | `d[0-31]` | `w` |
|
| ARM | `dreg` | `d[0-31]` | `w` |
|
||||||
|
|
|
@ -59,12 +59,6 @@ macro_rules! check {
|
||||||
// CHECK: @NO_APP
|
// CHECK: @NO_APP
|
||||||
check!(reg "" reg i32 "mov");
|
check!(reg "" reg i32 "mov");
|
||||||
|
|
||||||
// CHECK-LABEL: reg_thumb:
|
|
||||||
// CHECK: @APP
|
|
||||||
// CHECK: mov r0, r0
|
|
||||||
// CHECK: @NO_APP
|
|
||||||
check!(reg_thumb "" reg_thumb i32 "mov");
|
|
||||||
|
|
||||||
// CHECK-LABEL: sreg:
|
// CHECK-LABEL: sreg:
|
||||||
// CHECK: @APP
|
// CHECK: @APP
|
||||||
// CHECK: vmov.f32 s0, s0
|
// CHECK: vmov.f32 s0, s0
|
||||||
|
|
|
@ -163,36 +163,6 @@ check!(reg_f32 f32 reg "mov");
|
||||||
// CHECK: @NO_APP
|
// CHECK: @NO_APP
|
||||||
check!(reg_ptr ptr reg "mov");
|
check!(reg_ptr ptr reg "mov");
|
||||||
|
|
||||||
// CHECK-LABEL: reg_thumb_i8:
|
|
||||||
// CHECK: @APP
|
|
||||||
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
|
|
||||||
// CHECK: @NO_APP
|
|
||||||
check!(reg_thumb_i8 i8 reg_thumb "mov");
|
|
||||||
|
|
||||||
// CHECK-LABEL: reg_thumb_i16:
|
|
||||||
// CHECK: @APP
|
|
||||||
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
|
|
||||||
// CHECK: @NO_APP
|
|
||||||
check!(reg_thumb_i16 i16 reg_thumb "mov");
|
|
||||||
|
|
||||||
// CHECK-LABEL: reg_thumb_i32:
|
|
||||||
// CHECK: @APP
|
|
||||||
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
|
|
||||||
// CHECK: @NO_APP
|
|
||||||
check!(reg_thumb_i32 i32 reg_thumb "mov");
|
|
||||||
|
|
||||||
// CHECK-LABEL: reg_thumb_f32:
|
|
||||||
// CHECK: @APP
|
|
||||||
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
|
|
||||||
// CHECK: @NO_APP
|
|
||||||
check!(reg_thumb_f32 f32 reg_thumb "mov");
|
|
||||||
|
|
||||||
// CHECK-LABEL: reg_thumb_ptr:
|
|
||||||
// CHECK: @APP
|
|
||||||
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
|
|
||||||
// CHECK: @NO_APP
|
|
||||||
check!(reg_thumb_ptr ptr reg_thumb "mov");
|
|
||||||
|
|
||||||
// CHECK-LABEL: sreg_i32:
|
// CHECK-LABEL: sreg_i32:
|
||||||
// CHECK: @APP
|
// CHECK: @APP
|
||||||
// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
|
// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
|
||||||
|
|
4
src/test/ui/feature-gates/feature-gate-concat_bytes.rs
Normal file
4
src/test/ui/feature-gates/feature-gate-concat_bytes.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
let a = concat_bytes!(b'A', b"BC"); //~ ERROR use of unstable library feature 'concat_bytes'
|
||||||
|
assert_eq!(a, &[65, 66, 67]);
|
||||||
|
}
|
12
src/test/ui/feature-gates/feature-gate-concat_bytes.stderr
Normal file
12
src/test/ui/feature-gates/feature-gate-concat_bytes.stderr
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0658]: use of unstable library feature 'concat_bytes'
|
||||||
|
--> $DIR/feature-gate-concat_bytes.rs:2:13
|
||||||
|
|
|
||||||
|
LL | let a = concat_bytes!(b'A', b"BC");
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #87555 <https://github.com/rust-lang/rust/issues/87555> for more information
|
||||||
|
= help: add `#![feature(concat_bytes)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
42
src/test/ui/macros/concat-bytes-error.rs
Normal file
42
src/test/ui/macros/concat-bytes-error.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#![feature(concat_bytes)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
concat_bytes!(pie); //~ ERROR expected a byte literal
|
||||||
|
concat_bytes!(pie, pie); //~ ERROR expected a byte literal
|
||||||
|
concat_bytes!("tnrsi", "tnri"); //~ ERROR cannot concatenate string literals
|
||||||
|
concat_bytes!(2.8); //~ ERROR cannot concatenate float literals
|
||||||
|
concat_bytes!(300); //~ ERROR cannot concatenate numeric literals
|
||||||
|
concat_bytes!('a'); //~ ERROR cannot concatenate character literals
|
||||||
|
concat_bytes!(true, false); //~ ERROR cannot concatenate boolean literals
|
||||||
|
concat_bytes!(42, b"va", b'l'); //~ ERROR cannot concatenate numeric literals
|
||||||
|
concat_bytes!(42, b"va", b'l', [1, 2]); //~ ERROR cannot concatenate numeric literals
|
||||||
|
concat_bytes!([
|
||||||
|
"hi", //~ ERROR cannot concatenate string literals
|
||||||
|
]);
|
||||||
|
concat_bytes!([
|
||||||
|
'a', //~ ERROR cannot concatenate character literals
|
||||||
|
]);
|
||||||
|
concat_bytes!([
|
||||||
|
true, //~ ERROR cannot concatenate boolean literals
|
||||||
|
]);
|
||||||
|
concat_bytes!([
|
||||||
|
false, //~ ERROR cannot concatenate boolean literals
|
||||||
|
]);
|
||||||
|
concat_bytes!([
|
||||||
|
2.6, //~ ERROR cannot concatenate float literals
|
||||||
|
]);
|
||||||
|
concat_bytes!([
|
||||||
|
265, //~ ERROR numeric literal is out of bounds
|
||||||
|
]);
|
||||||
|
concat_bytes!([
|
||||||
|
-33, //~ ERROR expected a byte literal
|
||||||
|
]);
|
||||||
|
concat_bytes!([
|
||||||
|
b"hi!", //~ ERROR cannot concatenate doubly nested array
|
||||||
|
]);
|
||||||
|
concat_bytes!([
|
||||||
|
[5, 6, 7], //~ ERROR cannot concatenate doubly nested array
|
||||||
|
]);
|
||||||
|
concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals
|
||||||
|
concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8`
|
||||||
|
}
|
131
src/test/ui/macros/concat-bytes-error.stderr
Normal file
131
src/test/ui/macros/concat-bytes-error.stderr
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
error: expected a byte literal
|
||||||
|
--> $DIR/concat-bytes-error.rs:4:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!(pie);
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: only byte literals (like `b"foo"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`
|
||||||
|
|
||||||
|
error: expected a byte literal
|
||||||
|
--> $DIR/concat-bytes-error.rs:5:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!(pie, pie);
|
||||||
|
| ^^^ ^^^
|
||||||
|
|
|
||||||
|
= note: only byte literals (like `b"foo"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`
|
||||||
|
|
||||||
|
error: cannot concatenate string literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:6:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!("tnrsi", "tnri");
|
||||||
|
| ^^^^^^^ help: try using a byte string: `b"tnrsi"`
|
||||||
|
|
||||||
|
error: cannot concatenate float literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:7:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!(2.8);
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: cannot concatenate numeric literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:8:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!(300);
|
||||||
|
| ^^^ help: try wrapping the number in an array: `[300]`
|
||||||
|
|
||||||
|
error: cannot concatenate character literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:9:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!('a');
|
||||||
|
| ^^^ help: try using a byte character: `b'a'`
|
||||||
|
|
||||||
|
error: cannot concatenate boolean literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:10:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!(true, false);
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: cannot concatenate numeric literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:11:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!(42, b"va", b'l');
|
||||||
|
| ^^ help: try wrapping the number in an array: `[42]`
|
||||||
|
|
||||||
|
error: cannot concatenate numeric literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:12:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!(42, b"va", b'l', [1, 2]);
|
||||||
|
| ^^ help: try wrapping the number in an array: `[42]`
|
||||||
|
|
||||||
|
error: cannot concatenate string literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:14:9
|
||||||
|
|
|
||||||
|
LL | "hi",
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: cannot concatenate character literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:17:9
|
||||||
|
|
|
||||||
|
LL | 'a',
|
||||||
|
| ^^^ help: try using a byte character: `b'a'`
|
||||||
|
|
||||||
|
error: cannot concatenate boolean literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:20:9
|
||||||
|
|
|
||||||
|
LL | true,
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: cannot concatenate boolean literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:23:9
|
||||||
|
|
|
||||||
|
LL | false,
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: cannot concatenate float literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:26:9
|
||||||
|
|
|
||||||
|
LL | 2.6,
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: numeric literal is out of bounds
|
||||||
|
--> $DIR/concat-bytes-error.rs:29:9
|
||||||
|
|
|
||||||
|
LL | 265,
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: expected a byte literal
|
||||||
|
--> $DIR/concat-bytes-error.rs:32:9
|
||||||
|
|
|
||||||
|
LL | -33,
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: only byte literals (like `b"foo"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`
|
||||||
|
|
||||||
|
error: cannot concatenate doubly nested array
|
||||||
|
--> $DIR/concat-bytes-error.rs:35:9
|
||||||
|
|
|
||||||
|
LL | b"hi!",
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: byte strings are treated as arrays of bytes
|
||||||
|
= help: try flattening the array
|
||||||
|
|
||||||
|
error: cannot concatenate doubly nested array
|
||||||
|
--> $DIR/concat-bytes-error.rs:38:9
|
||||||
|
|
|
||||||
|
LL | [5, 6, 7],
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: cannot concatenate numeric literals
|
||||||
|
--> $DIR/concat-bytes-error.rs:40:19
|
||||||
|
|
|
||||||
|
LL | concat_bytes!(5u16);
|
||||||
|
| ^^^^ help: try wrapping the number in an array: `[5u16]`
|
||||||
|
|
||||||
|
error: numeric literal is not a `u8`
|
||||||
|
--> $DIR/concat-bytes-error.rs:41:20
|
||||||
|
|
|
||||||
|
LL | concat_bytes!([5u16]);
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: aborting due to 20 previous errors
|
||||||
|
|
7
src/test/ui/macros/concat-bytes.rs
Normal file
7
src/test/ui/macros/concat-bytes.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// run-pass
|
||||||
|
#![feature(concat_bytes)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(concat_bytes!(), &[]);
|
||||||
|
assert_eq!(concat_bytes!(b'A', b"BC", [68, b'E', 70]), b"ABCDEF");
|
||||||
|
}
|
6
src/test/ui/parser/issues/issue-91461.rs
Normal file
6
src/test/ui/parser/issues/issue-91461.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn main() {
|
||||||
|
a(_:b:,)
|
||||||
|
//~^ ERROR: expected identifier, found reserved identifier `_`
|
||||||
|
//~| ERROR: expected type, found `,`
|
||||||
|
//~| ERROR: expected type, found `,`
|
||||||
|
}
|
31
src/test/ui/parser/issues/issue-91461.stderr
Normal file
31
src/test/ui/parser/issues/issue-91461.stderr
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
error: expected identifier, found reserved identifier `_`
|
||||||
|
--> $DIR/issue-91461.rs:2:7
|
||||||
|
|
|
||||||
|
LL | a(_:b:,)
|
||||||
|
| ^ expected identifier, found reserved identifier
|
||||||
|
|
||||||
|
error: expected type, found `,`
|
||||||
|
--> $DIR/issue-91461.rs:2:11
|
||||||
|
|
|
||||||
|
LL | a(_:b:,)
|
||||||
|
| - -^ expected type
|
||||||
|
| | |
|
||||||
|
| | tried to parse a type due to this type ascription
|
||||||
|
| while parsing this struct
|
||||||
|
|
|
||||||
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
|
= note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
|
||||||
|
|
||||||
|
error: expected type, found `,`
|
||||||
|
--> $DIR/issue-91461.rs:2:11
|
||||||
|
|
|
||||||
|
LL | a(_:b:,)
|
||||||
|
| -^ expected type
|
||||||
|
| |
|
||||||
|
| tried to parse a type due to this type ascription
|
||||||
|
|
|
||||||
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
|
= note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue