From b6f2700ffa449a5312f9e57516f2c775f2dd277b Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Thu, 14 Oct 2021 03:23:09 -0400 Subject: [PATCH 01/13] Add support for specifying multiple clobber_abi in `asm!` Allow multiple clobber_abi in asm Update docs Fix aarch64 test Combine abis Emit duplicate ABI error, empty ABI list error multiple clobber_abi --- compiler/rustc_ast/src/ast.rs | 4 +- compiler/rustc_ast_lowering/src/asm.rs | 47 ++++++-- compiler/rustc_ast_pretty/src/pprust/state.rs | 4 +- compiler/rustc_builtin_macros/src/asm.rs | 92 ++++++++++------ .../unstable-book/src/library-features/asm.md | 8 +- src/test/ui/asm/aarch64/parse-error.rs | 3 +- src/test/ui/asm/aarch64/parse-error.stderr | 100 ++++++++---------- src/test/ui/asm/x86_64/bad-clobber-abi.rs | 32 ++++++ src/test/ui/asm/x86_64/bad-clobber-abi.stderr | 88 +++++++++++++++ src/test/ui/asm/x86_64/bad-options.rs | 3 + src/test/ui/asm/x86_64/bad-options.stderr | 31 ++++-- .../ui/asm/x86_64/multiple-clobber-abi.rs | 33 ++++++ src/test/ui/asm/x86_64/parse-error.rs | 14 +-- src/test/ui/asm/x86_64/parse-error.stderr | 54 +++++----- 14 files changed, 368 insertions(+), 145 deletions(-) create mode 100644 src/test/ui/asm/x86_64/bad-clobber-abi.rs create mode 100644 src/test/ui/asm/x86_64/bad-clobber-abi.stderr create mode 100644 src/test/ui/asm/x86_64/multiple-clobber-abi.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e2424e7d7ad90..169e0ef571516 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2058,7 +2058,7 @@ pub struct InlineAsm { pub template: Vec, pub template_strs: Box<[(Symbol, Option, Span)]>, pub operands: Vec<(InlineAsmOperand, Span)>, - pub clobber_abi: Option<(Symbol, Span)>, + pub clobber_abis: Vec<(Symbol, Span)>, pub options: InlineAsmOptions, pub line_spans: Vec, } @@ -2707,7 +2707,7 @@ pub enum ItemKind { /// E.g., `extern {}` or `extern "C" {}`. ForeignMod(ForeignMod), /// Module-level inline assembly (from `global_asm!()`). - GlobalAsm(InlineAsm), + GlobalAsm(Box), /// A type alias (`type`). /// /// E.g., `type Foo = Bar;`. diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 957b14f348729..198e4fa99ea3a 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -2,6 +2,7 @@ use super::LoweringContext; use rustc_ast::*; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_set::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_span::{Span, Symbol}; @@ -27,22 +28,47 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .emit(); } - let mut clobber_abi = None; + let mut clobber_abis = FxHashMap::default(); if let Some(asm_arch) = asm_arch { - if let Some((abi_name, abi_span)) = asm.clobber_abi { - match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, abi_name) { - Ok(abi) => clobber_abi = Some((abi, abi_span)), + for (abi_name, abi_span) in &asm.clobber_abis { + match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, *abi_name) { + Ok(abi) => { + // If the abi was already in the list, emit an error + match clobber_abis.get(&abi) { + Some((prev_name, prev_sp)) => { + let mut err = self.sess.struct_span_err( + *abi_span, + &format!("`{}` ABI specified multiple times", prev_name), + ); + err.span_label(*prev_sp, "previously specified here"); + + // Multiple different abi names may actually be the same ABI + // If the specified ABIs are not the same name, alert the user that they resolve to the same ABI + let source_map = self.sess.source_map(); + if source_map.span_to_snippet(*prev_sp) + != source_map.span_to_snippet(*abi_span) + { + err.note("these ABIs are equivalent on the current target"); + } + + err.emit(); + } + None => { + clobber_abis.insert(abi, (abi_name, *abi_span)); + } + } + } Err(&[]) => { self.sess .struct_span_err( - abi_span, + *abi_span, "`clobber_abi` is not supported on this target", ) .emit(); } Err(supported_abis) => { let mut err = - self.sess.struct_span_err(abi_span, "invalid ABI for `clobber_abi`"); + self.sess.struct_span_err(*abi_span, "invalid ABI for `clobber_abi`"); let mut abis = format!("`{}`", supported_abis[0]); for m in &supported_abis[1..] { let _ = write!(abis, ", `{}`", m); @@ -308,8 +334,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // If a clobber_abi is specified, add the necessary clobbers to the // operands list. - if let Some((abi, abi_span)) = clobber_abi { + let mut clobbered = FxHashSet::default(); + for (abi, (_, abi_span)) in clobber_abis { for &clobber in abi.clobbered_regs() { + // Don't emit a clobber for a register already clobbered + if clobbered.contains(&clobber) { + continue; + } + let mut output_used = false; clobber.overlapping_regs(|reg| { if used_output_regs.contains_key(®) { @@ -326,6 +358,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }, self.lower_span(abi_span), )); + clobbered.insert(clobber); } } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 6d0589b7ba1af..3b4d2fb746ab8 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -2199,8 +2199,8 @@ impl<'a> State<'a> { let mut args = vec![AsmArg::Template(InlineAsmTemplatePiece::to_string(&asm.template))]; args.extend(asm.operands.iter().map(|(o, _)| AsmArg::Operand(o))); - if let Some((abi, _)) = asm.clobber_abi { - args.push(AsmArg::ClobberAbi(abi)); + for (abi, _) in &asm.clobber_abis { + args.push(AsmArg::ClobberAbi(*abi)); } if !asm.options.is_empty() { args.push(AsmArg::Options(asm.options)); diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 198287f608e39..dc1aa2934b828 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -19,7 +19,7 @@ struct AsmArgs { operands: Vec<(ast::InlineAsmOperand, Span)>, named_args: FxHashMap, reg_args: FxHashSet, - clobber_abi: Option<(Symbol, Span)>, + clobber_abis: Vec<(Symbol, Span)>, options: ast::InlineAsmOptions, options_spans: Vec, } @@ -64,7 +64,7 @@ fn parse_args<'a>( operands: vec![], named_args: FxHashMap::default(), reg_args: FxHashSet::default(), - clobber_abi: None, + clobber_abis: Vec::new(), options: ast::InlineAsmOptions::empty(), options_spans: vec![], }; @@ -210,9 +210,9 @@ fn parse_args<'a>( .span_labels(args.options_spans.clone(), "previous options") .span_label(span, "argument") .emit(); - } else if let Some((_, abi_span)) = args.clobber_abi { + } else if let Some((_, abi_span)) = args.clobber_abis.last() { ecx.struct_span_err(span, "arguments are not allowed after clobber_abi") - .span_label(abi_span, "clobber_abi") + .span_label(*abi_span, "clobber_abi") .span_label(span, "argument") .emit(); } @@ -322,10 +322,13 @@ fn parse_args<'a>( // Bail out now since this is likely to confuse MIR return Err(err); } - if let Some((_, abi_span)) = args.clobber_abi { + + if args.clobber_abis.len() > 0 { if is_global_asm { - let err = - ecx.struct_span_err(abi_span, "`clobber_abi` cannot be used with `global_asm!`"); + let err = ecx.struct_span_err( + args.clobber_abis.iter().map(|(_, span)| *span).collect::>(), + "`clobber_abi` cannot be used with `global_asm!`", + ); // Bail out now since this is likely to confuse later stages return Err(err); @@ -335,7 +338,10 @@ fn parse_args<'a>( regclass_outputs.clone(), "asm with `clobber_abi` must specify explicit registers for outputs", ) - .span_label(abi_span, "clobber_abi") + .span_labels( + args.clobber_abis.iter().map(|(_, span)| *span).collect::>(), + "clobber_abi", + ) .span_labels(regclass_outputs, "generic outputs") .emit(); } @@ -439,37 +445,61 @@ fn parse_clobber_abi<'a>( p.expect(&token::OpenDelim(token::DelimToken::Paren))?; - let clobber_abi = match p.parse_str_lit() { - Ok(str_lit) => str_lit.symbol_unescaped, - Err(opt_lit) => { - let span = opt_lit.map_or(p.token.span, |lit| lit.span); - let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal"); - err.span_label(span, "not a string literal"); - return Err(err); - } - }; + if p.eat(&token::CloseDelim(token::DelimToken::Paren)) { + let err = p.sess.span_diagnostic.struct_span_err( + p.token.span, + "at least one abi must be provided as an argument to `clobber_abi`", + ); + return Err(err); + } - p.expect(&token::CloseDelim(token::DelimToken::Paren))?; + let mut new_abis = Vec::new(); + loop { + match p.parse_str_lit() { + Ok(str_lit) => { + new_abis.push((str_lit.symbol_unescaped, str_lit.span)); + } + Err(opt_lit) => { + // If the non-string literal is a closing paren then it's the end of the list and is fine + if p.eat(&token::CloseDelim(token::DelimToken::Paren)) { + break; + } + let span = opt_lit.map_or(p.token.span, |lit| lit.span); + let mut err = + p.sess.span_diagnostic.struct_span_err(span, "expected string literal"); + err.span_label(span, "not a string literal"); + return Err(err); + } + }; - let new_span = span_start.to(p.prev_token.span); + // Allow trailing commas + if p.eat(&token::CloseDelim(token::DelimToken::Paren)) { + break; + } + p.expect(&token::Comma)?; + } - if let Some((_, prev_span)) = args.clobber_abi { - let mut err = p - .sess - .span_diagnostic - .struct_span_err(new_span, "clobber_abi specified multiple times"); - err.span_label(prev_span, "clobber_abi previously specified here"); - return Err(err); - } else if !args.options_spans.is_empty() { + let full_span = span_start.to(p.prev_token.span); + + if !args.options_spans.is_empty() { let mut err = p .sess .span_diagnostic - .struct_span_err(new_span, "clobber_abi is not allowed after options"); + .struct_span_err(full_span, "clobber_abi is not allowed after options"); err.span_labels(args.options_spans.clone(), "options"); return Err(err); } - args.clobber_abi = Some((clobber_abi, new_span)); + match &new_abis[..] { + // should have errored above during parsing + [] => unreachable!(), + [(abi, _span)] => args.clobber_abis.push((*abi, full_span)), + [abis @ ..] => { + for (abi, span) in abis { + args.clobber_abis.push((*abi, *span)); + } + } + } Ok(()) } @@ -770,7 +800,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option( ident: Ident::empty(), attrs: Vec::new(), id: ast::DUMMY_NODE_ID, - kind: ast::ItemKind::GlobalAsm(inline_asm), + kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)), vis: ast::Visibility { span: sp.shrink_to_lo(), kind: ast::VisibilityKind::Inherited, diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 5a2cef24870be..dcf3e65a71667 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -319,7 +319,7 @@ fn call_foo(arg: i32) -> i32 { Note that the `fn` or `static` item does not need to be public or `#[no_mangle]`: the compiler will automatically insert the appropriate mangled symbol name into the assembly code. -By default, `asm!` assumes that any register not specified as an output will have its contents preserved by the assembly code. The [`clobber_abi`](#abi-clobbers) argument to `asm!` tells the compiler to automatically insert the necessary clobber operands according to the given calling convention ABI: any register which is not fully preserved in that ABI will be treated as clobbered. +By default, `asm!` assumes that any register not specified as an output will have its contents preserved by the assembly code. The [`clobber_abi`](#abi-clobbers) argument to `asm!` tells the compiler to automatically insert the necessary clobber operands according to the given calling convention ABI: any register which is not fully preserved in that ABI will be treated as clobbered. Multiple `clobber_abi` arguments may be provided and all clobbers from all specified ABIs will be inserted. ## Register template modifiers @@ -453,10 +453,10 @@ reg_spec := / "" operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_" reg_operand := dir_spec "(" reg_spec ")" operand_expr operand := reg_operand / "const" const_expr / "sym" path -clobber_abi := "clobber_abi(" ")" +clobber_abi := "clobber_abi(" *["," ] [","] ")" option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw" options := "options(" option *["," option] [","] ")" -asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," clobber_abi] *("," options) [","] ")" +asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) *("," clobber_abi) *("," options) [","] ")" ``` Inline assembly is currently supported on the following architectures: @@ -799,6 +799,8 @@ As stated in the previous section, passing an input value smaller than the regis The `clobber_abi` keyword can be used to apply a default set of clobbers to an `asm` block. This will automatically insert the necessary clobber constraints as needed for calling a function with a particular calling convention: if the calling convention does not fully preserve the value of a register across a call then a `lateout("reg") _` is implicitly added to the operands list. +`clobber_abi` may be specified any number of times. It will insert a clobber for all unique registers in the union of all specified calling conventions. + Generic register class outputs are disallowed by the compiler when `clobber_abi` is used: all outputs must specify an explicit register. Explicit register outputs have precedence over the implicit clobbers inserted by `clobber_abi`: a clobber will only be inserted for a register if that register is not used as an output. The following ABIs can be used with `clobber_abi`: diff --git a/src/test/ui/asm/aarch64/parse-error.rs b/src/test/ui/asm/aarch64/parse-error.rs index faa5e37b781ec..48016f2a6cf54 100644 --- a/src/test/ui/asm/aarch64/parse-error.rs +++ b/src/test/ui/asm/aarch64/parse-error.rs @@ -51,7 +51,6 @@ fn main() { asm!("{}", options(), clobber_abi("C"), const foo); //~^ ERROR clobber_abi is not allowed after options asm!("", clobber_abi("C"), clobber_abi("C")); - //~^ ERROR clobber_abi specified multiple times asm!("{a}", a = const foo, a = const bar); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used @@ -121,7 +120,7 @@ global_asm!("", options(), clobber_abi("C")); global_asm!("{}", options(), clobber_abi("C"), const FOO); //~^ ERROR clobber_abi is not allowed after options global_asm!("", clobber_abi("C"), clobber_abi("C")); -//~^ ERROR clobber_abi specified multiple times +//~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("{a}", a = const FOO, a = const BAR); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used diff --git a/src/test/ui/asm/aarch64/parse-error.stderr b/src/test/ui/asm/aarch64/parse-error.stderr index 6f318c9b9c2a1..0472f36fe6d2f 100644 --- a/src/test/ui/asm/aarch64/parse-error.stderr +++ b/src/test/ui/asm/aarch64/parse-error.stderr @@ -132,16 +132,8 @@ LL | asm!("{}", options(), clobber_abi("C"), const foo); | | | options -error: clobber_abi specified multiple times - --> $DIR/parse-error.rs:53:36 - | -LL | asm!("", clobber_abi("C"), clobber_abi("C")); - | ---------------- ^^^^^^^^^^^^^^^^ - | | - | clobber_abi previously specified here - error: duplicate argument named `a` - --> $DIR/parse-error.rs:55:36 + --> $DIR/parse-error.rs:54:36 | LL | asm!("{a}", a = const foo, a = const bar); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -149,7 +141,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | previously here error: argument never used - --> $DIR/parse-error.rs:55:36 + --> $DIR/parse-error.rs:54:36 | LL | asm!("{a}", a = const foo, a = const bar); | ^^^^^^^^^^^^^ argument never used @@ -157,13 +149,13 @@ LL | asm!("{a}", a = const foo, a = const bar); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: explicit register arguments cannot have names - --> $DIR/parse-error.rs:60:18 + --> $DIR/parse-error.rs:59:18 | LL | asm!("", a = in("x0") foo); | ^^^^^^^^^^^^^^^^ error: named arguments cannot follow explicit register arguments - --> $DIR/parse-error.rs:62:35 + --> $DIR/parse-error.rs:61:35 | LL | asm!("{a}", in("x0") foo, a = const bar); | ------------ ^^^^^^^^^^^^^ named argument @@ -171,7 +163,7 @@ LL | asm!("{a}", in("x0") foo, a = const bar); | explicit register argument error: named arguments cannot follow explicit register arguments - --> $DIR/parse-error.rs:65:35 + --> $DIR/parse-error.rs:64:35 | LL | asm!("{a}", in("x0") foo, a = const bar); | ------------ ^^^^^^^^^^^^^ named argument @@ -179,7 +171,7 @@ LL | asm!("{a}", in("x0") foo, a = const bar); | explicit register argument error: positional arguments cannot follow named arguments or explicit register arguments - --> $DIR/parse-error.rs:68:35 + --> $DIR/parse-error.rs:67:35 | LL | asm!("{1}", in("x0") foo, const bar); | ------------ ^^^^^^^^^ positional argument @@ -187,19 +179,19 @@ LL | asm!("{1}", in("x0") foo, const bar); | explicit register argument error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""` - --> $DIR/parse-error.rs:71:29 + --> $DIR/parse-error.rs:70:29 | LL | asm!("", options(), ""); | ^^ expected one of 9 possible tokens error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"` - --> $DIR/parse-error.rs:73:33 + --> $DIR/parse-error.rs:72:33 | LL | asm!("{}", in(reg) foo, "{}", out(reg) foo); | ^^^^ expected one of 9 possible tokens error: asm template must be a string literal - --> $DIR/parse-error.rs:75:14 + --> $DIR/parse-error.rs:74:14 | LL | asm!(format!("{{{}}}", 0), in(reg) foo); | ^^^^^^^^^^^^^^^^^^^^ @@ -207,7 +199,7 @@ LL | asm!(format!("{{{}}}", 0), in(reg) foo); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:77:21 + --> $DIR/parse-error.rs:76:21 | LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); | ^^^^^^^^^^^^^^^^^^^^ @@ -215,79 +207,79 @@ LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: _ cannot be used for input operands - --> $DIR/parse-error.rs:79:28 + --> $DIR/parse-error.rs:78:28 | LL | asm!("{}", in(reg) _); | ^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:81:31 + --> $DIR/parse-error.rs:80:31 | LL | asm!("{}", inout(reg) _); | ^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:83:35 + --> $DIR/parse-error.rs:82:35 | LL | asm!("{}", inlateout(reg) _); | ^ error: requires at least a template string argument - --> $DIR/parse-error.rs:90:1 + --> $DIR/parse-error.rs:89:1 | LL | global_asm!(); | ^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:92:13 + --> $DIR/parse-error.rs:91:13 | LL | global_asm!(FOO); | ^^^ error: expected token: `,` - --> $DIR/parse-error.rs:94:18 + --> $DIR/parse-error.rs:93:18 | LL | global_asm!("{}" FOO); | ^^^ expected `,` error: expected operand, options, or additional template string - --> $DIR/parse-error.rs:96:19 + --> $DIR/parse-error.rs:95:19 | LL | global_asm!("{}", FOO); | ^^^ expected operand, options, or additional template string error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:98:24 + --> $DIR/parse-error.rs:97:24 | LL | global_asm!("{}", const); | ^ expected expression error: expected one of `,`, `.`, `?`, or an operator, found `FOO` - --> $DIR/parse-error.rs:100:30 + --> $DIR/parse-error.rs:99:30 | LL | global_asm!("{}", const(reg) FOO); | ^^^ expected one of `,`, `.`, `?`, or an operator error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` - --> $DIR/parse-error.rs:102:25 + --> $DIR/parse-error.rs:101:25 | LL | global_asm!("", options(FOO)); | ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:104:25 + --> $DIR/parse-error.rs:103:25 | LL | global_asm!("", options(nomem FOO)); | ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:106:25 + --> $DIR/parse-error.rs:105:25 | LL | global_asm!("", options(nomem, FOO)); | ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: arguments are not allowed after options - --> $DIR/parse-error.rs:108:30 + --> $DIR/parse-error.rs:107:30 | LL | global_asm!("{}", options(), const FOO); | --------- ^^^^^^^^^ argument @@ -295,25 +287,25 @@ LL | global_asm!("{}", options(), const FOO); | previous options error: expected string literal - --> $DIR/parse-error.rs:110:29 + --> $DIR/parse-error.rs:109:29 | LL | global_asm!("", clobber_abi(FOO)); | ^^^ not a string literal error: expected `)`, found `FOO` - --> $DIR/parse-error.rs:112:33 + --> $DIR/parse-error.rs:111:33 | LL | global_asm!("", clobber_abi("C" FOO)); | ^^^ expected `)` error: expected `)`, found `,` - --> $DIR/parse-error.rs:114:32 + --> $DIR/parse-error.rs:113:32 | LL | global_asm!("", clobber_abi("C", FOO)); | ^ expected `)` error: arguments are not allowed after clobber_abi - --> $DIR/parse-error.rs:116:37 + --> $DIR/parse-error.rs:115:37 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ---------------- ^^^^^^^^^ argument @@ -321,13 +313,13 @@ LL | global_asm!("{}", clobber_abi("C"), const FOO); | clobber_abi error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:116:19 + --> $DIR/parse-error.rs:115:19 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:119:28 + --> $DIR/parse-error.rs:118:28 | LL | global_asm!("", options(), clobber_abi("C")); | --------- ^^^^^^^^^^^^^^^^ @@ -335,23 +327,21 @@ LL | global_asm!("", options(), clobber_abi("C")); | options error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:121:30 + --> $DIR/parse-error.rs:120:30 | LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | --------- ^^^^^^^^^^^^^^^^ | | | options -error: clobber_abi specified multiple times - --> $DIR/parse-error.rs:123:35 +error: `clobber_abi` cannot be used with `global_asm!` + --> $DIR/parse-error.rs:122:35 | LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); - | ---------------- ^^^^^^^^^^^^^^^^ - | | - | clobber_abi previously specified here + | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ error: duplicate argument named `a` - --> $DIR/parse-error.rs:125:35 + --> $DIR/parse-error.rs:124:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -359,7 +349,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | previously here error: argument never used - --> $DIR/parse-error.rs:125:35 + --> $DIR/parse-error.rs:124:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ^^^^^^^^^^^^^ argument never used @@ -367,19 +357,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `clobber_abi`, `const`, or `options`, found `""` - --> $DIR/parse-error.rs:128:28 + --> $DIR/parse-error.rs:127:28 | LL | global_asm!("", options(), ""); | ^^ expected one of `clobber_abi`, `const`, or `options` error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"` - --> $DIR/parse-error.rs:130:30 + --> $DIR/parse-error.rs:129:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); | ^^^^ expected one of `clobber_abi`, `const`, or `options` error: asm template must be a string literal - --> $DIR/parse-error.rs:132:13 + --> $DIR/parse-error.rs:131:13 | LL | global_asm!(format!("{{{}}}", 0), const FOO); | ^^^^^^^^^^^^^^^^^^^^ @@ -387,7 +377,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:134:20 + --> $DIR/parse-error.rs:133:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); | ^^^^^^^^^^^^^^^^^^^^ @@ -413,7 +403,7 @@ LL | asm!("{}", clobber_abi("C"), const foo); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:55:31 + --> $DIR/parse-error.rs:54:31 | LL | let mut foo = 0; | ---------- help: consider using `const` instead of `let`: `const foo` @@ -422,7 +412,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:55:46 + --> $DIR/parse-error.rs:54:46 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -431,7 +421,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:62:45 + --> $DIR/parse-error.rs:61:45 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -440,7 +430,7 @@ LL | asm!("{a}", in("x0") foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:65:45 + --> $DIR/parse-error.rs:64:45 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -449,7 +439,7 @@ LL | asm!("{a}", in("x0") foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:68:41 + --> $DIR/parse-error.rs:67:41 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -457,6 +447,6 @@ LL | let mut bar = 0; LL | asm!("{1}", in("x0") foo, const bar); | ^^^ non-constant value -error: aborting due to 66 previous errors +error: aborting due to 65 previous errors For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/asm/x86_64/bad-clobber-abi.rs b/src/test/ui/asm/x86_64/bad-clobber-abi.rs new file mode 100644 index 0000000000000..f4ca033048d71 --- /dev/null +++ b/src/test/ui/asm/x86_64/bad-clobber-abi.rs @@ -0,0 +1,32 @@ +// needs-asm-support +// only-x86_64 + +// checks various modes of failure for the `clobber_abi` argument (after parsing) + +#![feature(asm)] + +fn main() { + unsafe { + asm!("", clobber_abi("C")); + asm!("", clobber_abi("foo")); + //~^ ERROR invalid ABI for `clobber_abi` + asm!("", clobber_abi("C", "foo")); + //~^ ERROR invalid ABI for `clobber_abi` + asm!("", clobber_abi("C", "C")); + //~^ ERROR `C` ABI specified multiple times + asm!("", clobber_abi("win64", "sysv64")); + asm!("", clobber_abi("win64", "efiapi")); + //~^ ERROR `win64` ABI specified multiple times + asm!("", clobber_abi("C", "foo", "C")); + //~^ ERROR invalid ABI for `clobber_abi` + //~| ERROR `C` ABI specified multiple times + asm!("", clobber_abi("win64", "foo", "efiapi")); + //~^ ERROR invalid ABI for `clobber_abi` + //~| ERROR `win64` ABI specified multiple times + asm!("", clobber_abi("C"), clobber_abi("C")); + //~^ ERROR `C` ABI specified multiple times + asm!("", clobber_abi("win64"), clobber_abi("sysv64")); + asm!("", clobber_abi("win64"), clobber_abi("efiapi")); + //~^ ERROR `win64` ABI specified multiple times + } +} diff --git a/src/test/ui/asm/x86_64/bad-clobber-abi.stderr b/src/test/ui/asm/x86_64/bad-clobber-abi.stderr new file mode 100644 index 0000000000000..46e91a3951fb5 --- /dev/null +++ b/src/test/ui/asm/x86_64/bad-clobber-abi.stderr @@ -0,0 +1,88 @@ +error: invalid ABI for `clobber_abi` + --> $DIR/bad-clobber-abi.rs:11:18 + | +LL | asm!("", clobber_abi("foo")); + | ^^^^^^^^^^^^^^^^^^ + | + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + +error: invalid ABI for `clobber_abi` + --> $DIR/bad-clobber-abi.rs:13:35 + | +LL | asm!("", clobber_abi("C", "foo")); + | ^^^^^ + | + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + +error: `C` ABI specified multiple times + --> $DIR/bad-clobber-abi.rs:15:35 + | +LL | asm!("", clobber_abi("C", "C")); + | --- ^^^ + | | + | previously specified here + +error: `win64` ABI specified multiple times + --> $DIR/bad-clobber-abi.rs:18:39 + | +LL | asm!("", clobber_abi("win64", "efiapi")); + | ------- ^^^^^^^^ + | | + | previously specified here + | + = note: these ABIs are equivalent on the current target + +error: invalid ABI for `clobber_abi` + --> $DIR/bad-clobber-abi.rs:20:35 + | +LL | asm!("", clobber_abi("C", "foo", "C")); + | ^^^^^ + | + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + +error: `C` ABI specified multiple times + --> $DIR/bad-clobber-abi.rs:20:42 + | +LL | asm!("", clobber_abi("C", "foo", "C")); + | --- ^^^ + | | + | previously specified here + +error: invalid ABI for `clobber_abi` + --> $DIR/bad-clobber-abi.rs:23:39 + | +LL | asm!("", clobber_abi("win64", "foo", "efiapi")); + | ^^^^^ + | + = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` + +error: `win64` ABI specified multiple times + --> $DIR/bad-clobber-abi.rs:23:46 + | +LL | asm!("", clobber_abi("win64", "foo", "efiapi")); + | ------- ^^^^^^^^ + | | + | previously specified here + | + = note: these ABIs are equivalent on the current target + +error: `C` ABI specified multiple times + --> $DIR/bad-clobber-abi.rs:26:36 + | +LL | asm!("", clobber_abi("C"), clobber_abi("C")); + | ---------------- ^^^^^^^^^^^^^^^^ + | | + | previously specified here + +error: `win64` ABI specified multiple times + --> $DIR/bad-clobber-abi.rs:29:40 + | +LL | asm!("", clobber_abi("win64"), clobber_abi("efiapi")); + | -------------------- ^^^^^^^^^^^^^^^^^^^^^ + | | + | previously specified here + | + = note: these ABIs are equivalent on the current target + +error: aborting due to 10 previous errors + diff --git a/src/test/ui/asm/x86_64/bad-options.rs b/src/test/ui/asm/x86_64/bad-options.rs index dc61d1612e8d6..3facc87641569 100644 --- a/src/test/ui/asm/x86_64/bad-options.rs +++ b/src/test/ui/asm/x86_64/bad-options.rs @@ -21,6 +21,9 @@ fn main() { //~^ ERROR invalid ABI for `clobber_abi` asm!("{}", out(reg) foo, clobber_abi("C")); //~^ ERROR asm with `clobber_abi` must specify explicit registers for outputs + asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C")); + //~^ ERROR asm with `clobber_abi` must specify explicit registers for outputs + //~| ERROR `C` ABI specified multiple times asm!("", out("eax") foo, clobber_abi("C")); } } diff --git a/src/test/ui/asm/x86_64/bad-options.stderr b/src/test/ui/asm/x86_64/bad-options.stderr index 8cfd450ab02a5..e2351840eef21 100644 --- a/src/test/ui/asm/x86_64/bad-options.stderr +++ b/src/test/ui/asm/x86_64/bad-options.stderr @@ -36,38 +36,47 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C")); | | | generic outputs +error: asm with `clobber_abi` must specify explicit registers for outputs + --> $DIR/bad-options.rs:24:20 + | +LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C")); + | ^^^^^^^^^^^^ ---------------- ---------------- clobber_abi + | | | + | | clobber_abi + | generic outputs + error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` - --> $DIR/bad-options.rs:28:25 + --> $DIR/bad-options.rs:31:25 | LL | global_asm!("", options(nomem)); | ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `readonly` - --> $DIR/bad-options.rs:30:25 + --> $DIR/bad-options.rs:33:25 | LL | global_asm!("", options(readonly)); | ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn` - --> $DIR/bad-options.rs:32:25 + --> $DIR/bad-options.rs:35:25 | LL | global_asm!("", options(noreturn)); | ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `pure` - --> $DIR/bad-options.rs:34:25 + --> $DIR/bad-options.rs:37:25 | LL | global_asm!("", options(pure)); | ^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nostack` - --> $DIR/bad-options.rs:36:25 + --> $DIR/bad-options.rs:39:25 | LL | global_asm!("", options(nostack)); | ^^^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags` - --> $DIR/bad-options.rs:38:25 + --> $DIR/bad-options.rs:41:25 | LL | global_asm!("", options(preserves_flags)); | ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` @@ -80,5 +89,13 @@ LL | asm!("", clobber_abi("foo")); | = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64` -error: aborting due to 13 previous errors +error: `C` ABI specified multiple times + --> $DIR/bad-options.rs:24:52 + | +LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C")); + | ---------------- ^^^^^^^^^^^^^^^^ + | | + | previously specified here + +error: aborting due to 15 previous errors diff --git a/src/test/ui/asm/x86_64/multiple-clobber-abi.rs b/src/test/ui/asm/x86_64/multiple-clobber-abi.rs new file mode 100644 index 0000000000000..10aa004d431bd --- /dev/null +++ b/src/test/ui/asm/x86_64/multiple-clobber-abi.rs @@ -0,0 +1,33 @@ +// run-pass +// needs-asm-support +// only-x86_64 + +// Checks that multiple clobber_abi options can be used + +#![feature(asm)] + +extern "sysv64" fn foo(x: i32) -> i32 { + x + 16 +} + +extern "win64" fn bar(x: i32) -> i32 { + x / 2 +} + +fn main() { + let x = 8; + let y: i32; + // call `foo` with `x` as the input, and then `bar` with the output of `foo` + // and output that to `y` + unsafe { + asm!( + "call {}; mov rcx, rax; call {}", + sym foo, + sym bar, + in("rdi") x, + out("rax") y, + clobber_abi("sysv64", "win64"), + ); + } + assert_eq!((x, y), (8, 12)); +} diff --git a/src/test/ui/asm/x86_64/parse-error.rs b/src/test/ui/asm/x86_64/parse-error.rs index fa14c52cf0ad7..fdf3e40c7d375 100644 --- a/src/test/ui/asm/x86_64/parse-error.rs +++ b/src/test/ui/asm/x86_64/parse-error.rs @@ -37,12 +37,14 @@ fn main() { asm!("{}", options(), const foo); //~^ ERROR arguments are not allowed after options //~^^ ERROR attempt to use a non-constant value in a constant + asm!("", clobber_abi()); + //~^ ERROR at least one abi must be provided asm!("", clobber_abi(foo)); //~^ ERROR expected string literal asm!("", clobber_abi("C" foo)); - //~^ ERROR expected `)`, found `foo` + //~^ ERROR expected one of `)` or `,`, found `foo` asm!("", clobber_abi("C", foo)); - //~^ ERROR expected `)`, found `,` + //~^ ERROR expected string literal asm!("{}", clobber_abi("C"), const foo); //~^ ERROR arguments are not allowed after clobber_abi //~^^ ERROR attempt to use a non-constant value in a constant @@ -50,8 +52,6 @@ fn main() { //~^ ERROR clobber_abi is not allowed after options asm!("{}", options(), clobber_abi("C"), const foo); //~^ ERROR clobber_abi is not allowed after options - asm!("", clobber_abi("C"), clobber_abi("C")); - //~^ ERROR clobber_abi specified multiple times asm!("{a}", a = const foo, a = const bar); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used @@ -110,9 +110,9 @@ global_asm!("{}", options(), const FOO); global_asm!("", clobber_abi(FOO)); //~^ ERROR expected string literal global_asm!("", clobber_abi("C" FOO)); -//~^ ERROR expected `)`, found `FOO` +//~^ ERROR expected one of `)` or `,`, found `FOO` global_asm!("", clobber_abi("C", FOO)); -//~^ ERROR expected `)`, found `,` +//~^ ERROR expected string literal global_asm!("{}", clobber_abi("C"), const FOO); //~^ ERROR arguments are not allowed after clobber_abi //~^^ ERROR `clobber_abi` cannot be used with `global_asm!` @@ -121,7 +121,7 @@ global_asm!("", options(), clobber_abi("C")); global_asm!("{}", options(), clobber_abi("C"), const FOO); //~^ ERROR clobber_abi is not allowed after options global_asm!("", clobber_abi("C"), clobber_abi("C")); -//~^ ERROR clobber_abi specified multiple times +//~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("{a}", a = const FOO, a = const BAR); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used diff --git a/src/test/ui/asm/x86_64/parse-error.stderr b/src/test/ui/asm/x86_64/parse-error.stderr index 91a6baa4afb29..018df9826c6ee 100644 --- a/src/test/ui/asm/x86_64/parse-error.stderr +++ b/src/test/ui/asm/x86_64/parse-error.stderr @@ -90,26 +90,32 @@ LL | asm!("{}", options(), const foo); | | | previous options -error: expected string literal +error: at least one abi must be provided as an argument to `clobber_abi` --> $DIR/parse-error.rs:40:30 | +LL | asm!("", clobber_abi()); + | ^ + +error: expected string literal + --> $DIR/parse-error.rs:42:30 + | LL | asm!("", clobber_abi(foo)); | ^^^ not a string literal -error: expected `)`, found `foo` - --> $DIR/parse-error.rs:42:34 +error: expected one of `)` or `,`, found `foo` + --> $DIR/parse-error.rs:44:34 | LL | asm!("", clobber_abi("C" foo)); - | ^^^ expected `)` + | ^^^ expected one of `)` or `,` -error: expected `)`, found `,` - --> $DIR/parse-error.rs:44:33 +error: expected string literal + --> $DIR/parse-error.rs:46:35 | LL | asm!("", clobber_abi("C", foo)); - | ^ expected `)` + | ^^^ not a string literal error: arguments are not allowed after clobber_abi - --> $DIR/parse-error.rs:46:38 + --> $DIR/parse-error.rs:48:38 | LL | asm!("{}", clobber_abi("C"), const foo); | ---------------- ^^^^^^^^^ argument @@ -117,7 +123,7 @@ LL | asm!("{}", clobber_abi("C"), const foo); | clobber_abi error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:49:29 + --> $DIR/parse-error.rs:51:29 | LL | asm!("", options(), clobber_abi("C")); | --------- ^^^^^^^^^^^^^^^^ @@ -125,21 +131,13 @@ LL | asm!("", options(), clobber_abi("C")); | options error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:51:31 + --> $DIR/parse-error.rs:53:31 | LL | asm!("{}", options(), clobber_abi("C"), const foo); | --------- ^^^^^^^^^^^^^^^^ | | | options -error: clobber_abi specified multiple times - --> $DIR/parse-error.rs:53:36 - | -LL | asm!("", clobber_abi("C"), clobber_abi("C")); - | ---------------- ^^^^^^^^^^^^^^^^ - | | - | clobber_abi previously specified here - error: duplicate argument named `a` --> $DIR/parse-error.rs:55:36 | @@ -300,17 +298,17 @@ error: expected string literal LL | global_asm!("", clobber_abi(FOO)); | ^^^ not a string literal -error: expected `)`, found `FOO` +error: expected one of `)` or `,`, found `FOO` --> $DIR/parse-error.rs:112:33 | LL | global_asm!("", clobber_abi("C" FOO)); - | ^^^ expected `)` + | ^^^ expected one of `)` or `,` -error: expected `)`, found `,` - --> $DIR/parse-error.rs:114:32 +error: expected string literal + --> $DIR/parse-error.rs:114:34 | LL | global_asm!("", clobber_abi("C", FOO)); - | ^ expected `)` + | ^^^ not a string literal error: arguments are not allowed after clobber_abi --> $DIR/parse-error.rs:116:37 @@ -342,13 +340,11 @@ LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | | | options -error: clobber_abi specified multiple times - --> $DIR/parse-error.rs:123:35 +error: `clobber_abi` cannot be used with `global_asm!` + --> $DIR/parse-error.rs:123:17 | LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); - | ---------------- ^^^^^^^^^^^^^^^^ - | | - | clobber_abi previously specified here + | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ error: duplicate argument named `a` --> $DIR/parse-error.rs:125:35 @@ -404,7 +400,7 @@ LL | asm!("{}", options(), const foo); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:46:44 + --> $DIR/parse-error.rs:48:44 | LL | let mut foo = 0; | ---------- help: consider using `const` instead of `let`: `const foo` From c77cd0ab387e6757641df24c2b619c324b4f30ba Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Sun, 17 Oct 2021 03:30:24 -0400 Subject: [PATCH 02/13] Fix aarch tests --- src/test/ui/asm/aarch64/parse-error.rs | 3 - src/test/ui/asm/aarch64/parse-error.stderr | 108 ++++++++++----------- 2 files changed, 51 insertions(+), 60 deletions(-) diff --git a/src/test/ui/asm/aarch64/parse-error.rs b/src/test/ui/asm/aarch64/parse-error.rs index 48016f2a6cf54..92edb4c6ce681 100644 --- a/src/test/ui/asm/aarch64/parse-error.rs +++ b/src/test/ui/asm/aarch64/parse-error.rs @@ -50,7 +50,6 @@ fn main() { //~^ ERROR clobber_abi is not allowed after options asm!("{}", options(), clobber_abi("C"), const foo); //~^ ERROR clobber_abi is not allowed after options - asm!("", clobber_abi("C"), clobber_abi("C")); asm!("{a}", a = const foo, a = const bar); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used @@ -119,8 +118,6 @@ global_asm!("", options(), clobber_abi("C")); //~^ ERROR clobber_abi is not allowed after options global_asm!("{}", options(), clobber_abi("C"), const FOO); //~^ ERROR clobber_abi is not allowed after options -global_asm!("", clobber_abi("C"), clobber_abi("C")); -//~^ ERROR `clobber_abi` cannot be used with `global_asm!` global_asm!("{a}", a = const FOO, a = const BAR); //~^ ERROR duplicate argument named `a` //~^^ ERROR argument never used diff --git a/src/test/ui/asm/aarch64/parse-error.stderr b/src/test/ui/asm/aarch64/parse-error.stderr index 0472f36fe6d2f..3d88cef5c7d71 100644 --- a/src/test/ui/asm/aarch64/parse-error.stderr +++ b/src/test/ui/asm/aarch64/parse-error.stderr @@ -96,17 +96,17 @@ error: expected string literal LL | asm!("", clobber_abi(foo)); | ^^^ not a string literal -error: expected `)`, found `foo` +error: expected one of `)` or `,`, found `foo` --> $DIR/parse-error.rs:42:34 | LL | asm!("", clobber_abi("C" foo)); - | ^^^ expected `)` + | ^^^ expected one of `)` or `,` -error: expected `)`, found `,` - --> $DIR/parse-error.rs:44:33 +error: expected string literal + --> $DIR/parse-error.rs:44:35 | LL | asm!("", clobber_abi("C", foo)); - | ^ expected `)` + | ^^^ not a string literal error: arguments are not allowed after clobber_abi --> $DIR/parse-error.rs:46:38 @@ -133,7 +133,7 @@ LL | asm!("{}", options(), clobber_abi("C"), const foo); | options error: duplicate argument named `a` - --> $DIR/parse-error.rs:54:36 + --> $DIR/parse-error.rs:53:36 | LL | asm!("{a}", a = const foo, a = const bar); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -141,7 +141,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | previously here error: argument never used - --> $DIR/parse-error.rs:54:36 + --> $DIR/parse-error.rs:53:36 | LL | asm!("{a}", a = const foo, a = const bar); | ^^^^^^^^^^^^^ argument never used @@ -149,13 +149,13 @@ LL | asm!("{a}", a = const foo, a = const bar); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: explicit register arguments cannot have names - --> $DIR/parse-error.rs:59:18 + --> $DIR/parse-error.rs:58:18 | LL | asm!("", a = in("x0") foo); | ^^^^^^^^^^^^^^^^ error: named arguments cannot follow explicit register arguments - --> $DIR/parse-error.rs:61:35 + --> $DIR/parse-error.rs:60:35 | LL | asm!("{a}", in("x0") foo, a = const bar); | ------------ ^^^^^^^^^^^^^ named argument @@ -163,7 +163,7 @@ LL | asm!("{a}", in("x0") foo, a = const bar); | explicit register argument error: named arguments cannot follow explicit register arguments - --> $DIR/parse-error.rs:64:35 + --> $DIR/parse-error.rs:63:35 | LL | asm!("{a}", in("x0") foo, a = const bar); | ------------ ^^^^^^^^^^^^^ named argument @@ -171,7 +171,7 @@ LL | asm!("{a}", in("x0") foo, a = const bar); | explicit register argument error: positional arguments cannot follow named arguments or explicit register arguments - --> $DIR/parse-error.rs:67:35 + --> $DIR/parse-error.rs:66:35 | LL | asm!("{1}", in("x0") foo, const bar); | ------------ ^^^^^^^^^ positional argument @@ -179,19 +179,19 @@ LL | asm!("{1}", in("x0") foo, const bar); | explicit register argument error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""` - --> $DIR/parse-error.rs:70:29 + --> $DIR/parse-error.rs:69:29 | LL | asm!("", options(), ""); | ^^ expected one of 9 possible tokens error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"` - --> $DIR/parse-error.rs:72:33 + --> $DIR/parse-error.rs:71:33 | LL | asm!("{}", in(reg) foo, "{}", out(reg) foo); | ^^^^ expected one of 9 possible tokens error: asm template must be a string literal - --> $DIR/parse-error.rs:74:14 + --> $DIR/parse-error.rs:73:14 | LL | asm!(format!("{{{}}}", 0), in(reg) foo); | ^^^^^^^^^^^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | asm!(format!("{{{}}}", 0), in(reg) foo); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:76:21 + --> $DIR/parse-error.rs:75:21 | LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); | ^^^^^^^^^^^^^^^^^^^^ @@ -207,79 +207,79 @@ LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: _ cannot be used for input operands - --> $DIR/parse-error.rs:78:28 + --> $DIR/parse-error.rs:77:28 | LL | asm!("{}", in(reg) _); | ^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:80:31 + --> $DIR/parse-error.rs:79:31 | LL | asm!("{}", inout(reg) _); | ^ error: _ cannot be used for input operands - --> $DIR/parse-error.rs:82:35 + --> $DIR/parse-error.rs:81:35 | LL | asm!("{}", inlateout(reg) _); | ^ error: requires at least a template string argument - --> $DIR/parse-error.rs:89:1 + --> $DIR/parse-error.rs:88:1 | LL | global_asm!(); | ^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:91:13 + --> $DIR/parse-error.rs:90:13 | LL | global_asm!(FOO); | ^^^ error: expected token: `,` - --> $DIR/parse-error.rs:93:18 + --> $DIR/parse-error.rs:92:18 | LL | global_asm!("{}" FOO); | ^^^ expected `,` error: expected operand, options, or additional template string - --> $DIR/parse-error.rs:95:19 + --> $DIR/parse-error.rs:94:19 | LL | global_asm!("{}", FOO); | ^^^ expected operand, options, or additional template string error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:97:24 + --> $DIR/parse-error.rs:96:24 | LL | global_asm!("{}", const); | ^ expected expression error: expected one of `,`, `.`, `?`, or an operator, found `FOO` - --> $DIR/parse-error.rs:99:30 + --> $DIR/parse-error.rs:98:30 | LL | global_asm!("{}", const(reg) FOO); | ^^^ expected one of `,`, `.`, `?`, or an operator error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` - --> $DIR/parse-error.rs:101:25 + --> $DIR/parse-error.rs:100:25 | LL | global_asm!("", options(FOO)); | ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:103:25 + --> $DIR/parse-error.rs:102:25 | LL | global_asm!("", options(nomem FOO)); | ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:105:25 + --> $DIR/parse-error.rs:104:25 | LL | global_asm!("", options(nomem, FOO)); | ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: arguments are not allowed after options - --> $DIR/parse-error.rs:107:30 + --> $DIR/parse-error.rs:106:30 | LL | global_asm!("{}", options(), const FOO); | --------- ^^^^^^^^^ argument @@ -287,25 +287,25 @@ LL | global_asm!("{}", options(), const FOO); | previous options error: expected string literal - --> $DIR/parse-error.rs:109:29 + --> $DIR/parse-error.rs:108:29 | LL | global_asm!("", clobber_abi(FOO)); | ^^^ not a string literal -error: expected `)`, found `FOO` - --> $DIR/parse-error.rs:111:33 +error: expected one of `)` or `,`, found `FOO` + --> $DIR/parse-error.rs:110:33 | LL | global_asm!("", clobber_abi("C" FOO)); - | ^^^ expected `)` + | ^^^ expected one of `)` or `,` -error: expected `)`, found `,` - --> $DIR/parse-error.rs:113:32 +error: expected string literal + --> $DIR/parse-error.rs:112:34 | LL | global_asm!("", clobber_abi("C", FOO)); - | ^ expected `)` + | ^^^ not a string literal error: arguments are not allowed after clobber_abi - --> $DIR/parse-error.rs:115:37 + --> $DIR/parse-error.rs:114:37 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ---------------- ^^^^^^^^^ argument @@ -313,13 +313,13 @@ LL | global_asm!("{}", clobber_abi("C"), const FOO); | clobber_abi error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:115:19 + --> $DIR/parse-error.rs:114:19 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:118:28 + --> $DIR/parse-error.rs:117:28 | LL | global_asm!("", options(), clobber_abi("C")); | --------- ^^^^^^^^^^^^^^^^ @@ -327,21 +327,15 @@ LL | global_asm!("", options(), clobber_abi("C")); | options error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:120:30 + --> $DIR/parse-error.rs:119:30 | LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | --------- ^^^^^^^^^^^^^^^^ | | | options -error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:122:35 - | -LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); - | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ - error: duplicate argument named `a` - --> $DIR/parse-error.rs:124:35 + --> $DIR/parse-error.rs:121:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -349,7 +343,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | previously here error: argument never used - --> $DIR/parse-error.rs:124:35 + --> $DIR/parse-error.rs:121:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ^^^^^^^^^^^^^ argument never used @@ -357,19 +351,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `clobber_abi`, `const`, or `options`, found `""` - --> $DIR/parse-error.rs:127:28 + --> $DIR/parse-error.rs:124:28 | LL | global_asm!("", options(), ""); | ^^ expected one of `clobber_abi`, `const`, or `options` error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"` - --> $DIR/parse-error.rs:129:30 + --> $DIR/parse-error.rs:126:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); | ^^^^ expected one of `clobber_abi`, `const`, or `options` error: asm template must be a string literal - --> $DIR/parse-error.rs:131:13 + --> $DIR/parse-error.rs:128:13 | LL | global_asm!(format!("{{{}}}", 0), const FOO); | ^^^^^^^^^^^^^^^^^^^^ @@ -377,7 +371,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:133:20 + --> $DIR/parse-error.rs:130:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); | ^^^^^^^^^^^^^^^^^^^^ @@ -403,7 +397,7 @@ LL | asm!("{}", clobber_abi("C"), const foo); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:54:31 + --> $DIR/parse-error.rs:53:31 | LL | let mut foo = 0; | ---------- help: consider using `const` instead of `let`: `const foo` @@ -412,7 +406,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:54:46 + --> $DIR/parse-error.rs:53:46 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -421,7 +415,7 @@ LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:61:45 + --> $DIR/parse-error.rs:60:45 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -430,7 +424,7 @@ LL | asm!("{a}", in("x0") foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:64:45 + --> $DIR/parse-error.rs:63:45 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -439,7 +433,7 @@ LL | asm!("{a}", in("x0") foo, a = const bar); | ^^^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/parse-error.rs:67:41 + --> $DIR/parse-error.rs:66:41 | LL | let mut bar = 0; | ---------- help: consider using `const` instead of `let`: `const bar` @@ -447,6 +441,6 @@ LL | let mut bar = 0; LL | asm!("{1}", in("x0") foo, const bar); | ^^^ non-constant value -error: aborting due to 65 previous errors +error: aborting due to 64 previous errors For more information about this error, try `rustc --explain E0435`. From 5d1e09f44ab0bd3ca29acf44d92e884ec140d00a Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Tue, 2 Nov 2021 22:41:34 +0100 Subject: [PATCH 03/13] Added the --temps-dir option. --- compiler/rustc_driver/src/lib.rs | 12 +++++++++++- compiler/rustc_interface/src/interface.rs | 15 ++++++++++++++- compiler/rustc_interface/src/passes.rs | 7 +++++++ compiler/rustc_interface/src/util.rs | 3 +++ compiler/rustc_session/src/config.rs | 14 ++++++++++++-- src/librustdoc/core.rs | 1 + src/librustdoc/doctest.rs | 1 + 7 files changed, 49 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 9a57ec991444a..6b3c65dd52722 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -215,6 +215,7 @@ fn run_compiler( let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg")); let (odir, ofile) = make_output(&matches); + let temps_dir = make_temps_dir(&matches); let mut config = interface::Config { opts: sopts, crate_cfg: cfg, @@ -222,6 +223,7 @@ fn run_compiler( input_path: None, output_file: ofile, output_dir: odir, + temps_dir, file_loader, diagnostic_output, stderr: None, @@ -267,6 +269,7 @@ fn run_compiler( None, compiler.output_dir(), compiler.output_file(), + compiler.temps_dir(), ); if should_stop == Compilation::Stop { @@ -295,6 +298,7 @@ fn run_compiler( Some(compiler.input()), compiler.output_dir(), compiler.output_file(), + compiler.temps_dir(), ) .and_then(|| { RustcDefaultCalls::list_metadata( @@ -454,6 +458,11 @@ fn make_output(matches: &getopts::Matches) -> (Option, Option) (odir, ofile) } +// Extract temporary directory from matches. +fn make_temps_dir(matches: &getopts::Matches) -> Option { + matches.opt_str("temps-dir").map(|o| PathBuf::from(&o)) +} + // Extract input (string or file and optional path) from matches. fn make_input( error_format: ErrorOutputType, @@ -647,6 +656,7 @@ impl RustcDefaultCalls { input: Option<&Input>, odir: &Option, ofile: &Option, + temps_dir: &Option, ) -> Compilation { use rustc_session::config::PrintRequest::*; // PrintRequest::NativeStaticLibs is special - printed during linking @@ -685,7 +695,7 @@ impl RustcDefaultCalls { }); let attrs = attrs.as_ref().unwrap(); let t_outputs = rustc_interface::util::build_output_filenames( - input, odir, ofile, attrs, sess, + input, odir, ofile, temps_dir, attrs, sess, ); let id = rustc_session::output::find_crate_name(sess, attrs, input); if *req == PrintRequest::CrateName { diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 7a6a643e3d0bb..7b235be48b34f 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -36,6 +36,7 @@ pub struct Compiler { pub(crate) input_path: Option, pub(crate) output_dir: Option, pub(crate) output_file: Option, + pub(crate) temps_dir: Option, pub(crate) register_lints: Option>, pub(crate) override_queries: Option, @@ -57,6 +58,9 @@ impl Compiler { pub fn output_file(&self) -> &Option { &self.output_file } + pub fn temps_dir(&self) -> &Option { + &self.temps_dir + } pub fn register_lints(&self) -> &Option> { &self.register_lints } @@ -65,7 +69,14 @@ impl Compiler { sess: &Session, attrs: &[ast::Attribute], ) -> OutputFilenames { - util::build_output_filenames(&self.input, &self.output_dir, &self.output_file, attrs, sess) + util::build_output_filenames( + &self.input, + &self.output_dir, + &self.output_file, + &self.temps_dir, + attrs, + sess, + ) } } @@ -132,6 +143,7 @@ pub struct Config { pub input_path: Option, pub output_dir: Option, pub output_file: Option, + pub temps_dir: Option, pub file_loader: Option>, pub diagnostic_output: DiagnosticOutput, @@ -193,6 +205,7 @@ pub fn create_compiler_and_run(config: Config, f: impl FnOnce(&Compiler) -> R input_path: config.input_path, output_dir: config.output_dir, output_file: config.output_file, + temps_dir: config.temps_dir, register_lints: config.register_lints, override_queries: config.override_queries, }; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 62f5f09aa4827..b14b1c4f1e659 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -692,6 +692,7 @@ pub fn prepare_outputs( &compiler.input, &compiler.output_dir, &compiler.output_file, + &compiler.temps_dir, &krate.attrs, sess, ); @@ -734,6 +735,12 @@ pub fn prepare_outputs( return Err(ErrorReported); } } + if let Some(ref dir) = compiler.temps_dir { + if fs::create_dir_all(dir).is_err() { + sess.err("failed to find or create the directory specified by `--temps-dir`"); + return Err(ErrorReported); + } + } } Ok(outputs) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index cffb087af187f..b446422f62f31 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -604,6 +604,7 @@ pub fn build_output_filenames( input: &Input, odir: &Option, ofile: &Option, + temps_dir: &Option, attrs: &[ast::Attribute], sess: &Session, ) -> OutputFilenames { @@ -626,6 +627,7 @@ pub fn build_output_filenames( dirpath, stem, None, + temps_dir.clone(), sess.opts.cg.extra_filename.clone(), sess.opts.output_types.clone(), ) @@ -654,6 +656,7 @@ pub fn build_output_filenames( out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(), ofile, + temps_dir.clone(), sess.opts.cg.extra_filename.clone(), sess.opts.output_types.clone(), ) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 299dfed9d5dce..52cd8638b0083 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -578,6 +578,7 @@ pub struct OutputFilenames { pub out_directory: PathBuf, filestem: String, pub single_output_file: Option, + pub temps_directory: Option, pub outputs: OutputTypes, } @@ -592,12 +593,14 @@ impl OutputFilenames { out_directory: PathBuf, out_filestem: String, single_output_file: Option, + temps_directory: Option, extra: String, outputs: OutputTypes, ) -> Self { OutputFilenames { out_directory, single_output_file, + temps_directory, outputs, filestem: format!("{}{}", out_filestem, extra), } @@ -643,11 +646,17 @@ impl OutputFilenames { extension.push_str(ext); } - self.with_extension(&extension) + let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory); + + self.with_directory_and_extension(&temps_directory, &extension) } pub fn with_extension(&self, extension: &str) -> PathBuf { - let mut path = self.out_directory.join(&self.filestem); + self.with_directory_and_extension(&self.out_directory, extension) + } + + fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf { + let mut path = directory.join(&self.filestem); path.set_extension(extension); path } @@ -1094,6 +1103,7 @@ pub fn rustc_short_optgroups() -> Vec { in ", "DIR", ), + opt::opt_s("", "temps-dir", "Write temporary output files to ", "DIR"), opt::opt_s( "", "explain", diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b7251e8f57151..063c0bc20c684 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -259,6 +259,7 @@ crate fn create_config( input_path: cpath, output_file: None, output_dir: None, + temps_dir: None, file_loader: None, diagnostic_output: DiagnosticOutput::Default, stderr: None, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 9b32ad979e385..63eaded03207a 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -94,6 +94,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { input_path: None, output_file: None, output_dir: None, + temps_dir: None, file_loader: None, diagnostic_output: DiagnosticOutput::Default, stderr: None, From bde794dadabd294b8a8a8a9157dbc52d0d469c15 Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Sun, 4 Apr 2021 13:33:33 +0200 Subject: [PATCH 04/13] Create temps_dir before it's needed. --- compiler/rustc_interface/src/passes.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index b14b1c4f1e659..e0b0a2195f50d 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -723,6 +723,13 @@ pub fn prepare_outputs( } } + if let Some(ref dir) = compiler.temps_dir { + if fs::create_dir_all(dir).is_err() { + sess.err("failed to find or create the directory specified by `--temps-dir`"); + return Err(ErrorReported); + } + } + write_out_deps(sess, boxed_resolver, &outputs, &output_paths); let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo) @@ -735,12 +742,6 @@ pub fn prepare_outputs( return Err(ErrorReported); } } - if let Some(ref dir) = compiler.temps_dir { - if fs::create_dir_all(dir).is_err() { - sess.err("failed to find or create the directory specified by `--temps-dir`"); - return Err(ErrorReported); - } - } } Ok(outputs) From 0132adc176c193fe9a1319a2a754306f2d438500 Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Sun, 4 Apr 2021 13:35:04 +0200 Subject: [PATCH 05/13] Emitted files go to the output dir. --- compiler/rustc_session/src/config.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 52cd8638b0083..034aebe42c1fa 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -611,7 +611,14 @@ impl OutputFilenames { .get(&flavor) .and_then(|p| p.to_owned()) .or_else(|| self.single_output_file.clone()) - .unwrap_or_else(|| self.temp_path(flavor, None)) + .unwrap_or_else(|| self.output_path(flavor)) + } + + /// Gets the output path where a compilation artifact of the given type + /// should be placed on disk. + pub fn output_path(&self, flavor: OutputType) -> PathBuf { + let extension = flavor.extension(); + self.with_directory_and_extension(&self.out_directory, &extension) } /// Gets the path where a compilation artifact of the given type for the From ac4f04bd82f019778b6b2c678f300f62a36024c3 Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Sun, 4 Apr 2021 14:48:07 +0200 Subject: [PATCH 06/13] Documentation. --- src/doc/rustc/src/command-line-arguments.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 7f482f0f2b1a0..2d8aa3a4933cc 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -194,6 +194,15 @@ This flag controls the output filename. The outputted crate will be written to this directory. This flag is ignored if the [`-o` flag](#option-o-output) is used. + +## `--temps-dir`: directory to write the intermediate files in + +Intermediate files will be written to this directory. If not set, the output +directory is used. This option is useful if you are running more than one +instance of `rustc` (e.g. with different `--crate-type` settings), and you +need to make sure they are not overwriting each other's intermediate files. +No files are kept unless `-C save-temps=yes` is also set. + ## `--explain`: provide a detailed explanation of an error message From 0b378f008b9dd75ecadeede1ea0c963549f2933a Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Sun, 4 Apr 2021 15:24:17 +0200 Subject: [PATCH 07/13] Fix test. --- src/test/run-make-fulldeps/issue-19371/foo.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index 4acabbb70ede2..626f74a342e37 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -53,6 +53,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { input_path: None, output_file: Some(output), output_dir: None, + temps_dir: None, file_loader: None, diagnostic_output: DiagnosticOutput::Default, stderr: None, From d4bcee9638cf8fdf7e9297438e70e20b212c6535 Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Sun, 4 Apr 2021 15:54:21 +0200 Subject: [PATCH 08/13] Added a regression test. --- src/test/run-make/issue-10971-temps-dir/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/test/run-make/issue-10971-temps-dir/Makefile diff --git a/src/test/run-make/issue-10971-temps-dir/Makefile b/src/test/run-make/issue-10971-temps-dir/Makefile new file mode 100644 index 0000000000000..d6b35cbfafd6a --- /dev/null +++ b/src/test/run-make/issue-10971-temps-dir/Makefile @@ -0,0 +1,10 @@ +include ../../run-make-fulldeps/tools.mk + +# Regression test for issue #10971 +# Running two invocations in parallel would overwrite each other's temp files. + +all: + touch $(TMPDIR)/lib.rs + + $(RUSTC) --crate-type=lib --temps-dir=$(TMPDIR)/temp1 $(TMPDIR)/lib.rs & \ + $(RUSTC) --crate-type=cdylib --temps-dir=$(TMPDIR)/temp2 $(TMPDIR)/lib.rs From f06a71149bdeeac0c88dba6e1ad0774487b5d3de Mon Sep 17 00:00:00 2001 From: Ken Matsui <26405363+ken-matsui@users.noreply.github.com> Date: Sun, 7 Nov 2021 10:25:04 +0900 Subject: [PATCH 09/13] Support early stopping too old pre-installed `tidy` command for macOS in the HTML checker --- src/tools/html-checker/main.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/tools/html-checker/main.rs b/src/tools/html-checker/main.rs index 7bdf527d8842b..f52fbdfe2d7dc 100644 --- a/src/tools/html-checker/main.rs +++ b/src/tools/html-checker/main.rs @@ -79,11 +79,34 @@ fn find_all_html_files(dir: &Path) -> (usize, usize) { (files_read, errors) } +/// Default `tidy` command for macOS is too old that it does not have `mute-id` and `mute` options. +/// `tidy` on macOS Monterey was released on 31 October 2006, and the same date can be seen seven +/// years ago at . Accordingly, +/// the macOS environment using pre-installed `tidy` should immediately suspend HTML checker process +/// and show a hint to install a newer one. +#[cfg(target_os = "macos")] +fn check_tidy_version() -> Result<(), String> { + let output = Command::new("tidy").arg("-v").output().expect("failed to run tidy command"); + let version = String::from_utf8(output.stdout).expect("failed to read version of tidy command"); + if version.contains("HTML Tidy for Mac OS X released on 31 October 2006") { + eprintln!("The pre-installed HTML Tidy for macOS is not supported."); + eprintln!("Consider installing a newer one and re-running."); + eprintln!("If you're using Homebrew, you can install it by the following command:"); + eprintln!(" brew install tidy-html5"); + eprintln!(); + Err("HTML check failed: 1 error".to_string()) + } else { + Ok(()) + } +} + fn main() -> Result<(), String> { let args = env::args().collect::>(); if args.len() != 2 { return Err(format!("Usage: {} ", args[0])); } + #[cfg(target_os = "macos")] + check_tidy_version()?; println!("Running HTML checker..."); From ede76c40d1f1d32e6e1536b1e08122debc52ab00 Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Sun, 7 Nov 2021 00:14:54 +0100 Subject: [PATCH 10/13] Made temps-dir an unstable option. --- compiler/rustc_driver/src/lib.rs | 7 ------- compiler/rustc_interface/src/interface.rs | 5 +++-- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/src/config.rs | 1 - compiler/rustc_session/src/options.rs | 2 ++ src/doc/rustc/src/command-line-arguments.md | 9 --------- src/doc/unstable-book/src/compiler-flags/temps-dir.md | 10 ++++++++++ src/librustdoc/core.rs | 1 - src/librustdoc/doctest.rs | 1 - src/test/run-make-fulldeps/issue-19371/foo.rs | 1 - src/test/run-make/issue-10971-temps-dir/Makefile | 4 ++-- 11 files changed, 18 insertions(+), 24 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/temps-dir.md diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 6b3c65dd52722..09fe3a552a0a6 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -215,7 +215,6 @@ fn run_compiler( let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg")); let (odir, ofile) = make_output(&matches); - let temps_dir = make_temps_dir(&matches); let mut config = interface::Config { opts: sopts, crate_cfg: cfg, @@ -223,7 +222,6 @@ fn run_compiler( input_path: None, output_file: ofile, output_dir: odir, - temps_dir, file_loader, diagnostic_output, stderr: None, @@ -458,11 +456,6 @@ fn make_output(matches: &getopts::Matches) -> (Option, Option) (odir, ofile) } -// Extract temporary directory from matches. -fn make_temps_dir(matches: &getopts::Matches) -> Option { - matches.opt_str("temps-dir").map(|o| PathBuf::from(&o)) -} - // Extract input (string or file and optional path) from matches. fn make_input( error_format: ErrorOutputType, diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 7b235be48b34f..2904b3f5b7071 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -143,7 +143,6 @@ pub struct Config { pub input_path: Option, pub output_dir: Option, pub output_file: Option, - pub temps_dir: Option, pub file_loader: Option>, pub diagnostic_output: DiagnosticOutput, @@ -198,6 +197,8 @@ pub fn create_compiler_and_run(config: Config, f: impl FnOnce(&Compiler) -> R ); } + let temps_dir = sess.opts.debugging_opts.temps_dir.as_ref().map(|o| PathBuf::from(&o)); + let compiler = Compiler { sess, codegen_backend, @@ -205,7 +206,7 @@ pub fn create_compiler_and_run(config: Config, f: impl FnOnce(&Compiler) -> R input_path: config.input_path, output_dir: config.output_dir, output_file: config.output_file, - temps_dir: config.temps_dir, + temps_dir, register_lints: config.register_lints, override_queries: config.override_queries, }; diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2d3cb52f5fd47..eed2e07e890e7 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -685,6 +685,7 @@ fn test_debugging_options_tracking_hash() { untracked!(span_debug, true); untracked!(span_free_formats, true); untracked!(strip, Strip::Debuginfo); + untracked!(temps_dir, Some(String::from("abc"))); untracked!(terminal_width, Some(80)); untracked!(threads, 99); untracked!(time, true); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 034aebe42c1fa..fe8a26a700e53 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1110,7 +1110,6 @@ pub fn rustc_short_optgroups() -> Vec { in ", "DIR", ), - opt::opt_s("", "temps-dir", "Write temporary output files to ", "DIR"), opt::opt_s( "", "explain", diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index e894e46a30142..77a993a28ca79 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1331,6 +1331,8 @@ options! { "which mangling version to use for symbol names ('legacy' (default) or 'v0')"), teach: bool = (false, parse_bool, [TRACKED], "show extended diagnostic help (default: no)"), + temps_dir: Option = (None, parse_opt_string, [UNTRACKED], + "the directory the intermediate files are written to"), terminal_width: Option = (None, parse_opt_number, [UNTRACKED], "set the current terminal width"), tune_cpu: Option = (None, parse_opt_string, [TRACKED], diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 2d8aa3a4933cc..7f482f0f2b1a0 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -194,15 +194,6 @@ This flag controls the output filename. The outputted crate will be written to this directory. This flag is ignored if the [`-o` flag](#option-o-output) is used. - -## `--temps-dir`: directory to write the intermediate files in - -Intermediate files will be written to this directory. If not set, the output -directory is used. This option is useful if you are running more than one -instance of `rustc` (e.g. with different `--crate-type` settings), and you -need to make sure they are not overwriting each other's intermediate files. -No files are kept unless `-C save-temps=yes` is also set. - ## `--explain`: provide a detailed explanation of an error message diff --git a/src/doc/unstable-book/src/compiler-flags/temps-dir.md b/src/doc/unstable-book/src/compiler-flags/temps-dir.md new file mode 100644 index 0000000000000..e25011f71197b --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/temps-dir.md @@ -0,0 +1,10 @@ +# `temps-dir` + +-------------------- + +The `-Ztemps-dir` compiler flag specifies the directory to write the +intermediate files in. If not set, the output directory is used. This option is +useful if you are running more than one instance of `rustc` (e.g. with different +`--crate-type` settings), and you need to make sure they are not overwriting +each other's intermediate files. No files are kept unless `-C save-temps=yes` is +also set. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 063c0bc20c684..b7251e8f57151 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -259,7 +259,6 @@ crate fn create_config( input_path: cpath, output_file: None, output_dir: None, - temps_dir: None, file_loader: None, diagnostic_output: DiagnosticOutput::Default, stderr: None, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 63eaded03207a..9b32ad979e385 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -94,7 +94,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { input_path: None, output_file: None, output_dir: None, - temps_dir: None, file_loader: None, diagnostic_output: DiagnosticOutput::Default, stderr: None, diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index 626f74a342e37..4acabbb70ede2 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -53,7 +53,6 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { input_path: None, output_file: Some(output), output_dir: None, - temps_dir: None, file_loader: None, diagnostic_output: DiagnosticOutput::Default, stderr: None, diff --git a/src/test/run-make/issue-10971-temps-dir/Makefile b/src/test/run-make/issue-10971-temps-dir/Makefile index d6b35cbfafd6a..28aa188c3926a 100644 --- a/src/test/run-make/issue-10971-temps-dir/Makefile +++ b/src/test/run-make/issue-10971-temps-dir/Makefile @@ -6,5 +6,5 @@ include ../../run-make-fulldeps/tools.mk all: touch $(TMPDIR)/lib.rs - $(RUSTC) --crate-type=lib --temps-dir=$(TMPDIR)/temp1 $(TMPDIR)/lib.rs & \ - $(RUSTC) --crate-type=cdylib --temps-dir=$(TMPDIR)/temp2 $(TMPDIR)/lib.rs + $(RUSTC) --crate-type=lib -Z temps-dir=$(TMPDIR)/temp1 $(TMPDIR)/lib.rs & \ + $(RUSTC) --crate-type=cdylib -Z temps-dir=$(TMPDIR)/temp2 $(TMPDIR)/lib.rs From 27464fa5016bf5cfcc7e6cab3801003b1c7d21d4 Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Sun, 7 Nov 2021 20:06:22 +0100 Subject: [PATCH 11/13] Almost all the other tests use '-include', so we'll do too. --- src/test/run-make/issue-10971-temps-dir/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make/issue-10971-temps-dir/Makefile b/src/test/run-make/issue-10971-temps-dir/Makefile index 28aa188c3926a..18d8729ab0c36 100644 --- a/src/test/run-make/issue-10971-temps-dir/Makefile +++ b/src/test/run-make/issue-10971-temps-dir/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +-include ../../run-make-fulldeps/tools.mk # Regression test for issue #10971 # Running two invocations in parallel would overwrite each other's temp files. From 13dbdc6ad30a6584f02c723ce3f7447237c97b17 Mon Sep 17 00:00:00 2001 From: Tor Hovland Date: Sun, 7 Nov 2021 20:08:42 +0100 Subject: [PATCH 12/13] There is a -Clinker='arm-none-eabi-gcc' that seems to be causing trouble. --- src/test/run-make/issue-10971-temps-dir/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/run-make/issue-10971-temps-dir/Makefile b/src/test/run-make/issue-10971-temps-dir/Makefile index 18d8729ab0c36..f062e652a04ec 100644 --- a/src/test/run-make/issue-10971-temps-dir/Makefile +++ b/src/test/run-make/issue-10971-temps-dir/Makefile @@ -3,6 +3,9 @@ # Regression test for issue #10971 # Running two invocations in parallel would overwrite each other's temp files. +## clean up unused env variables which might cause harm. +unexport RUSTC_LINKER + all: touch $(TMPDIR)/lib.rs From 72ae5a33244641d995c050f5e973d59e8773bf56 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 7 Nov 2021 17:28:04 -0800 Subject: [PATCH 13/13] Update libc to 0.2.107 Changelog: https://github.com/rust-lang/libc/releases/tag/0.2.107 Primarily intended to pull in fd331f65f214ea75b6210b415b5fd8650be15c73 This should help with https://github.com/rust-lang/rust/pull/90044 --- Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f95dae42a4ab..007db14e3e1f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1900,9 +1900,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.106" +version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673" +checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" dependencies = [ "rustc-std-workspace-core", ] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 248ecdf4befce..abb17ceffcb32 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -15,7 +15,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } -libc = { version = "0.2.106", default-features = false, features = ['rustc-dep-of-std'] } +libc = { version = "0.2.107", default-features = false, features = ['rustc-dep-of-std'] } compiler_builtins = { version = "0.1.44" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" }