Skip to content

Commit 600820d

Browse files
committed
Auto merge of rust-lang#91692 - matthiaskrgr:rollup-u7dvh0n, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#87599 (Implement concat_bytes!) - rust-lang#89999 (Update std::env::temp_dir to use GetTempPath2 on Windows when available.) - rust-lang#90796 (Remove the reg_thumb register class for asm! on ARM) - rust-lang#91042 (Use Vec extend instead of repeated pushes on several places) - rust-lang#91634 (Do not attempt to suggest help for overly malformed struct/function call) - rust-lang#91685 (Install llvm tools to sysroot when assembling local toolchain) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents e250777 + ab92eca commit 600820d

File tree

26 files changed

+542
-98
lines changed

26 files changed

+542
-98
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
use rustc_ast as ast;
2+
use rustc_ast::{ptr::P, tokenstream::TokenStream};
3+
use rustc_data_structures::sync::Lrc;
4+
use rustc_errors::Applicability;
5+
use rustc_expand::base::{self, DummyResult};
6+
7+
/// Emits errors for literal expressions that are invalid inside and outside of an array.
8+
fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_nested: bool) {
9+
let lit = if let ast::ExprKind::Lit(lit) = &expr.kind {
10+
lit
11+
} else {
12+
unreachable!();
13+
};
14+
match lit.kind {
15+
ast::LitKind::Char(_) => {
16+
let mut err = cx.struct_span_err(expr.span, "cannot concatenate character literals");
17+
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
18+
err.span_suggestion(
19+
expr.span,
20+
"try using a byte character",
21+
format!("b{}", snippet),
22+
Applicability::MachineApplicable,
23+
)
24+
.emit();
25+
}
26+
}
27+
ast::LitKind::Str(_, _) => {
28+
let mut err = cx.struct_span_err(expr.span, "cannot concatenate string literals");
29+
// suggestion would be invalid if we are nested
30+
if !is_nested {
31+
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
32+
err.span_suggestion(
33+
expr.span,
34+
"try using a byte string",
35+
format!("b{}", snippet),
36+
Applicability::MachineApplicable,
37+
);
38+
}
39+
}
40+
err.emit();
41+
}
42+
ast::LitKind::Float(_, _) => {
43+
cx.span_err(expr.span, "cannot concatenate float literals");
44+
}
45+
ast::LitKind::Bool(_) => {
46+
cx.span_err(expr.span, "cannot concatenate boolean literals");
47+
}
48+
ast::LitKind::Err(_) => {}
49+
ast::LitKind::Int(_, _) if !is_nested => {
50+
let mut err = cx.struct_span_err(expr.span, "cannot concatenate numeric literals");
51+
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
52+
err.span_suggestion(
53+
expr.span,
54+
"try wrapping the number in an array",
55+
format!("[{}]", snippet),
56+
Applicability::MachineApplicable,
57+
);
58+
}
59+
err.emit();
60+
}
61+
ast::LitKind::Int(
62+
val,
63+
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
64+
) => {
65+
assert!(val > u8::MAX.into()); // must be an error
66+
cx.span_err(expr.span, "numeric literal is out of bounds");
67+
}
68+
ast::LitKind::Int(_, _) => {
69+
cx.span_err(expr.span, "numeric literal is not a `u8`");
70+
}
71+
_ => unreachable!(),
72+
}
73+
}
74+
75+
pub fn expand_concat_bytes(
76+
cx: &mut base::ExtCtxt<'_>,
77+
sp: rustc_span::Span,
78+
tts: TokenStream,
79+
) -> Box<dyn base::MacResult + 'static> {
80+
let es = match base::get_exprs_from_tts(cx, sp, tts) {
81+
Some(e) => e,
82+
None => return DummyResult::any(sp),
83+
};
84+
let mut accumulator = Vec::new();
85+
let mut missing_literals = vec![];
86+
let mut has_errors = false;
87+
for e in es {
88+
match e.kind {
89+
ast::ExprKind::Array(ref exprs) => {
90+
for expr in exprs {
91+
match expr.kind {
92+
ast::ExprKind::Array(_) => {
93+
if !has_errors {
94+
cx.span_err(expr.span, "cannot concatenate doubly nested array");
95+
}
96+
has_errors = true;
97+
}
98+
ast::ExprKind::Lit(ref lit) => match lit.kind {
99+
ast::LitKind::Int(
100+
val,
101+
ast::LitIntType::Unsuffixed
102+
| ast::LitIntType::Unsigned(ast::UintTy::U8),
103+
) if val <= u8::MAX.into() => {
104+
accumulator.push(val as u8);
105+
}
106+
107+
ast::LitKind::Byte(val) => {
108+
accumulator.push(val);
109+
}
110+
ast::LitKind::ByteStr(_) => {
111+
if !has_errors {
112+
cx.struct_span_err(
113+
expr.span,
114+
"cannot concatenate doubly nested array",
115+
)
116+
.note("byte strings are treated as arrays of bytes")
117+
.help("try flattening the array")
118+
.emit();
119+
}
120+
has_errors = true;
121+
}
122+
_ => {
123+
if !has_errors {
124+
invalid_type_err(cx, expr, true);
125+
}
126+
has_errors = true;
127+
}
128+
},
129+
_ => {
130+
missing_literals.push(expr.span);
131+
}
132+
}
133+
}
134+
}
135+
ast::ExprKind::Lit(ref lit) => match lit.kind {
136+
ast::LitKind::Byte(val) => {
137+
accumulator.push(val);
138+
}
139+
ast::LitKind::ByteStr(ref bytes) => {
140+
accumulator.extend_from_slice(&bytes);
141+
}
142+
_ => {
143+
if !has_errors {
144+
invalid_type_err(cx, &e, false);
145+
}
146+
has_errors = true;
147+
}
148+
},
149+
ast::ExprKind::Err => {
150+
has_errors = true;
151+
}
152+
_ => {
153+
missing_literals.push(e.span);
154+
}
155+
}
156+
}
157+
if !missing_literals.is_empty() {
158+
let mut err = cx.struct_span_err(missing_literals.clone(), "expected a byte literal");
159+
err.note("only byte literals (like `b\"foo\"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`");
160+
err.emit();
161+
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
162+
} else if has_errors {
163+
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
164+
}
165+
let sp = cx.with_def_site_ctxt(sp);
166+
base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(accumulator))))
167+
}

compiler/rustc_builtin_macros/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ mod cfg_accessible;
2727
mod cfg_eval;
2828
mod compile_error;
2929
mod concat;
30+
mod concat_bytes;
3031
mod concat_idents;
3132
mod derive;
3233
mod deriving;
@@ -65,6 +66,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
6566
cfg: cfg::expand_cfg,
6667
column: source_util::expand_column,
6768
compile_error: compile_error::expand_compile_error,
69+
concat_bytes: concat_bytes::expand_concat_bytes,
6870
concat_idents: concat_idents::expand_concat_idents,
6971
concat: concat::expand_concat,
7072
env: env::expand_env,

compiler/rustc_codegen_gcc/src/asm.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,6 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
568568
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => unimplemented!(),
569569
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => unimplemented!(),
570570
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => unimplemented!(),
571-
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => unimplemented!(),
572571
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
573572
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
574573
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => unimplemented!(),
@@ -628,8 +627,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
628627
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
629628
unimplemented!()
630629
}
631-
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)
632-
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => cx.type_i32(),
630+
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)=> cx.type_i32(),
633631
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
634632
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
635633
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
@@ -737,8 +735,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
737735
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
738736
unimplemented!()
739737
}
740-
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)
741-
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => unimplemented!(),
738+
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => unimplemented!(),
742739
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
743740
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => unimplemented!(),
744741
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)

compiler/rustc_codegen_llvm/src/asm.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,6 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
632632
unreachable!("clobber-only")
633633
}
634634
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r",
635-
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => "l",
636635
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
637636
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
638637
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => "t",
@@ -703,8 +702,7 @@ fn modifier_to_llvm(
703702
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
704703
unreachable!("clobber-only")
705704
}
706-
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)
707-
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => None,
705+
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => None,
708706
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
709707
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => None,
710708
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
@@ -785,8 +783,7 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
785783
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
786784
unreachable!("clobber-only")
787785
}
788-
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)
789-
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => cx.type_i32(),
786+
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
790787
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
791788
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
792789
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)

compiler/rustc_codegen_ssa/src/target_features.rs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
3535
// since it should be enabled per-function using #[instruction_set], not
3636
// #[target_feature].
3737
("thumb-mode", Some(sym::arm_target_feature)),
38+
("thumb2", Some(sym::arm_target_feature)),
3839
];
3940

4041
const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[

compiler/rustc_parse/src/parser/expr.rs

+27-20
Original file line numberDiff line numberDiff line change
@@ -1100,30 +1100,37 @@ impl<'a> Parser<'a> {
11001100
snapshot.bump(); // `(`
11011101
match snapshot.parse_struct_fields(path, false, token::Paren) {
11021102
Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => {
1103-
// We have are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
1103+
// We are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
11041104
// `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`.
11051105
*self = snapshot;
11061106
let close_paren = self.prev_token.span;
11071107
let span = lo.to(self.prev_token.span);
1108-
err.cancel();
1109-
self.struct_span_err(
1110-
span,
1111-
"invalid `struct` delimiters or `fn` call arguments",
1112-
)
1113-
.multipart_suggestion(
1114-
&format!("if `{}` is a struct, use braces as delimiters", name),
1115-
vec![(open_paren, " { ".to_string()), (close_paren, " }".to_string())],
1116-
Applicability::MaybeIncorrect,
1117-
)
1118-
.multipart_suggestion(
1119-
&format!("if `{}` is a function, use the arguments directly", name),
1120-
fields
1121-
.into_iter()
1122-
.map(|field| (field.span.until(field.expr.span), String::new()))
1123-
.collect(),
1124-
Applicability::MaybeIncorrect,
1125-
)
1126-
.emit();
1108+
if !fields.is_empty() {
1109+
err.cancel();
1110+
let mut err = self.struct_span_err(
1111+
span,
1112+
"invalid `struct` delimiters or `fn` call arguments",
1113+
);
1114+
err.multipart_suggestion(
1115+
&format!("if `{}` is a struct, use braces as delimiters", name),
1116+
vec![
1117+
(open_paren, " { ".to_string()),
1118+
(close_paren, " }".to_string()),
1119+
],
1120+
Applicability::MaybeIncorrect,
1121+
);
1122+
err.multipart_suggestion(
1123+
&format!("if `{}` is a function, use the arguments directly", name),
1124+
fields
1125+
.into_iter()
1126+
.map(|field| (field.span.until(field.expr.span), String::new()))
1127+
.collect(),
1128+
Applicability::MaybeIncorrect,
1129+
);
1130+
err.emit();
1131+
} else {
1132+
err.emit();
1133+
}
11271134
return Some(self.mk_expr_err(span));
11281135
}
11291136
Ok(_) => {}

compiler/rustc_span/src/symbol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ symbols! {
439439
compiler_builtins,
440440
compiler_fence,
441441
concat,
442+
concat_bytes,
442443
concat_idents,
443444
conservative_impl_trait,
444445
console,
@@ -1058,7 +1059,6 @@ symbols! {
10581059
reg_nonzero,
10591060
reg_pair,
10601061
reg_ptr,
1061-
reg_thumb,
10621062
reg_upper,
10631063
register_attr,
10641064
register_tool,

compiler/rustc_target/src/asm/arm.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::fmt;
66
def_reg_class! {
77
Arm ArmInlineAsmRegClass {
88
reg,
9-
reg_thumb,
109
sreg,
1110
sreg_low16,
1211
dreg,
@@ -47,7 +46,7 @@ impl ArmInlineAsmRegClass {
4746
_arch: InlineAsmArch,
4847
) -> &'static [(InlineAsmType, Option<&'static str>)] {
4948
match self {
50-
Self::reg | Self::reg_thumb => types! { _: I8, I16, I32, F32; },
49+
Self::reg => types! { _: I8, I16, I32, F32; },
5150
Self::sreg | Self::sreg_low16 => types! { "vfp2": I32, F32; },
5251
Self::dreg | Self::dreg_low16 | Self::dreg_low8 => types! {
5352
"vfp2": I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
@@ -88,20 +87,32 @@ fn frame_pointer_r7(
8887
}
8988
}
9089

90+
fn not_thumb1(
91+
_arch: InlineAsmArch,
92+
mut has_feature: impl FnMut(&str) -> bool,
93+
_target: &Target,
94+
) -> Result<(), &'static str> {
95+
if has_feature("thumb-mode") && !has_feature("thumb2") {
96+
Err("high registers (r8+) cannot be used in Thumb-1 code")
97+
} else {
98+
Ok(())
99+
}
100+
}
101+
91102
def_regs! {
92103
Arm ArmInlineAsmReg ArmInlineAsmRegClass {
93-
r0: reg, reg_thumb = ["r0", "a1"],
94-
r1: reg, reg_thumb = ["r1", "a2"],
95-
r2: reg, reg_thumb = ["r2", "a3"],
96-
r3: reg, reg_thumb = ["r3", "a4"],
97-
r4: reg, reg_thumb = ["r4", "v1"],
98-
r5: reg, reg_thumb = ["r5", "v2"],
99-
r7: reg, reg_thumb = ["r7", "v4"] % frame_pointer_r7,
100-
r8: reg = ["r8", "v5"],
101-
r10: reg = ["r10", "sl"],
104+
r0: reg = ["r0", "a1"],
105+
r1: reg = ["r1", "a2"],
106+
r2: reg = ["r2", "a3"],
107+
r3: reg = ["r3", "a4"],
108+
r4: reg = ["r4", "v1"],
109+
r5: reg = ["r5", "v2"],
110+
r7: reg = ["r7", "v4"] % frame_pointer_r7,
111+
r8: reg = ["r8", "v5"] % not_thumb1,
112+
r10: reg = ["r10", "sl"] % not_thumb1,
102113
r11: reg = ["r11", "fp"] % frame_pointer_r11,
103-
r12: reg = ["r12", "ip"],
104-
r14: reg = ["r14", "lr"],
114+
r12: reg = ["r12", "ip"] % not_thumb1,
115+
r14: reg = ["r14", "lr"] % not_thumb1,
105116
s0: sreg, sreg_low16 = ["s0"],
106117
s1: sreg, sreg_low16 = ["s1"],
107118
s2: sreg, sreg_low16 = ["s2"],

0 commit comments

Comments
 (0)