diff --git a/Cargo.lock b/Cargo.lock index f0c6e371c38be..716f4d7501467 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,7 +221,6 @@ dependencies = [ "getopts", "ignore", "libc", - "num_cpus", "once_cell", "opener", "pretty_assertions", @@ -249,7 +248,6 @@ dependencies = [ "anyhow", "flate2", "hex 0.4.2", - "num_cpus", "rayon", "serde", "serde_json", @@ -4241,7 +4239,6 @@ name = "rustc_session" version = "0.0.0" dependencies = [ "getopts", - "num_cpus", "rustc_ast", "rustc_data_structures", "rustc_errors", diff --git a/RELEASES.md b/RELEASES.md index 971a63b240f3e..08040f4815836 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1060,7 +1060,7 @@ Version 1.52.1 (2021-05-10) This release disables incremental compilation, unless the user has explicitly opted in via the newly added RUSTC_FORCE_INCREMENTAL=1 environment variable. -This is due to the widespread, and frequently occuring, breakage encountered by +This is due to the widespread, and frequently occurring, breakage encountered by Rust users due to newly enabled incremental verification in 1.52.0. Notably, Rust users **should** upgrade to 1.52.0 or 1.52.1: the bugs that are detected by newly added incremental verification are still present in past stable versions, diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 974e59b65ec91..be3f6a12706f8 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1064,7 +1064,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let val_type = value.get_type(); match (type_is_pointer(val_type), type_is_pointer(dest_ty)) { (false, true) => { - // NOTE: Projecting a field of a pointer type will attemp a cast from a signed char to + // NOTE: Projecting a field of a pointer type will attempt a cast from a signed char to // a pointer, which is not supported by gccjit. return self.cx.context.new_cast(None, self.inttoptr(value, val_type.make_pointer()), dest_ty); }, diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index f8f6956c47e4d..b14a4f28c756c 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -561,8 +561,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { if self.conv == Conv::CCmseNonSecureCall { // This will probably get ignored on all targets but those supporting the TrustZone-M // extension (thumbv8m targets). - let cmse_nonsecure_call = - llvm::CreateAttrString(bx.cx.llcx, cstr::cstr!("cmse_nonsecure_call")); + let cmse_nonsecure_call = llvm::CreateAttrString(bx.cx.llcx, "cmse_nonsecure_call"); attributes::apply_to_callsite( callsite, llvm::AttributePlace::Function, diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index e382af8880b8d..6fd836946ffb4 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,10 +1,6 @@ //! Set and unset common attributes on LLVM values. -use std::ffi::CString; - -use cstr::cstr; use rustc_codegen_ssa::traits::*; -use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::{self, TyCtxt}; @@ -103,11 +99,11 @@ pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attr fp = FramePointer::Always; } let attr_value = match fp { - FramePointer::Always => cstr!("all"), - FramePointer::NonLeaf => cstr!("non-leaf"), + FramePointer::Always => "all", + FramePointer::NonLeaf => "non-leaf", FramePointer::MayOmit => return None, }; - Some(llvm::CreateAttrStringValue(cx.llcx, cstr!("frame-pointer"), attr_value)) + Some(llvm::CreateAttrStringValue(cx.llcx, "frame-pointer", attr_value)) } /// Tell LLVM what instrument function to insert. @@ -119,11 +115,11 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribu // The function name varies on platforms. // See test/CodeGen/mcount.c in clang. - let mcount_name = CString::new(cx.sess().target.mcount.as_str().as_bytes()).unwrap(); + let mcount_name = cx.sess().target.mcount.as_str(); Some(llvm::CreateAttrStringValue( cx.llcx, - cstr!("instrument-function-entry-inlined"), + "instrument-function-entry-inlined", &mcount_name, )) } else { @@ -159,20 +155,20 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { StackProbeType::None => return None, // Request LLVM to generate the probes inline. If the given LLVM version does not support // this, no probe is generated at all (even if the attribute is specified). - StackProbeType::Inline => cstr!("inline-asm"), + StackProbeType::Inline => "inline-asm", // Flag our internal `__rust_probestack` function as the stack probe symbol. // This is defined in the `compiler-builtins` crate for each architecture. - StackProbeType::Call => cstr!("__rust_probestack"), + StackProbeType::Call => "__rust_probestack", // Pick from the two above based on the LLVM version. StackProbeType::InlineOrCall { min_llvm_version_for_inline } => { if llvm_util::get_version() < min_llvm_version_for_inline { - cstr!("__rust_probestack") + "__rust_probestack" } else { - cstr!("inline-asm") + "inline-asm" } } }; - Some(llvm::CreateAttrStringValue(cx.llcx, cstr!("probe-stack"), attr_value)) + Some(llvm::CreateAttrStringValue(cx.llcx, "probe-stack", attr_value)) } fn stackprotector_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { @@ -187,15 +183,13 @@ fn stackprotector_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { } pub fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute { - let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess)); - llvm::CreateAttrStringValue(cx.llcx, cstr!("target-cpu"), target_cpu.as_c_str()) + let target_cpu = llvm_util::target_cpu(cx.tcx.sess); + llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu) } pub fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { - llvm_util::tune_cpu(cx.tcx.sess).map(|tune| { - let tune_cpu = SmallCStr::new(tune); - llvm::CreateAttrStringValue(cx.llcx, cstr!("tune-cpu"), tune_cpu.as_c_str()) - }) + llvm_util::tune_cpu(cx.tcx.sess) + .map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu)) } /// Get the `NonLazyBind` LLVM attribute, @@ -280,7 +274,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( } if cx.sess().opts.debugging_opts.profile_sample_use.is_some() { - to_add.push(llvm::CreateAttrString(cx.llcx, cstr!("use-sample-profile"))); + to_add.push(llvm::CreateAttrString(cx.llcx, "use-sample-profile")); } // FIXME: none of these three functions interact with source level attributes. @@ -310,7 +304,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]); } if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) { - to_add.push(llvm::CreateAttrString(cx.llcx, cstr!("cmse_nonsecure_entry"))); + to_add.push(llvm::CreateAttrString(cx.llcx, "cmse_nonsecure_entry")); } if let Some(align) = codegen_fn_attrs.alignment { llvm::set_alignment(llfn, align as usize); @@ -363,12 +357,12 @@ pub fn from_fn_attrs<'ll, 'tcx>( // If this function is an import from the environment but the wasm // import has a specific module/name, apply them here. if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) { - to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("wasm-import-module"), &module)); + to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-module", &module)); let name = codegen_fn_attrs.link_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id())); - let name = CString::new(name.as_str()).unwrap(); - to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("wasm-import-name"), &name)); + let name = name.as_str(); + to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-name", name)); } // The `"wasm"` abi on wasm targets automatically enables the @@ -388,13 +382,13 @@ pub fn from_fn_attrs<'ll, 'tcx>( let val = global_features .chain(function_features.iter().map(|s| &s[..])) .intersperse(",") - .collect::(); - to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("target-features"), &val)); + .collect::(); + to_add.push(llvm::CreateAttrStringValue(cx.llcx, "target-features", &val)); } attributes::apply_to_llfn(llfn, Function, &to_add); } -fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option { - tcx.wasm_import_module_map(id.krate).get(&id).map(|s| CString::new(&s[..]).unwrap()) +fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<&String> { + tcx.wasm_import_module_map(id.krate).get(&id) } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 6e9e0332faf60..a7dd4cea04e1b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1175,11 +1175,12 @@ extern "C" { // Operations on attributes pub fn LLVMRustCreateAttrNoValue(C: &Context, attr: AttributeKind) -> &Attribute; - pub fn LLVMRustCreateAttrString(C: &Context, Name: *const c_char) -> &Attribute; - pub fn LLVMRustCreateAttrStringValue( + pub fn LLVMCreateStringAttribute( C: &Context, Name: *const c_char, + NameLen: c_uint, Value: *const c_char, + ValueLen: c_uint, ) -> &Attribute; pub fn LLVMRustCreateAlignmentAttr(C: &Context, bytes: u64) -> &Attribute; pub fn LLVMRustCreateDereferenceableAttr(C: &Context, bytes: u64) -> &Attribute; diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 4892b8d4a84c6..48fbc1de8ee44 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -47,12 +47,28 @@ pub fn AddCallSiteAttributes<'ll>( } } -pub fn CreateAttrStringValue<'ll>(llcx: &'ll Context, attr: &CStr, value: &CStr) -> &'ll Attribute { - unsafe { LLVMRustCreateAttrStringValue(llcx, attr.as_ptr(), value.as_ptr()) } +pub fn CreateAttrStringValue<'ll>(llcx: &'ll Context, attr: &str, value: &str) -> &'ll Attribute { + unsafe { + LLVMCreateStringAttribute( + llcx, + attr.as_ptr().cast(), + attr.len().try_into().unwrap(), + value.as_ptr().cast(), + value.len().try_into().unwrap(), + ) + } } -pub fn CreateAttrString<'ll>(llcx: &'ll Context, attr: &CStr) -> &'ll Attribute { - unsafe { LLVMRustCreateAttrStringValue(llcx, attr.as_ptr(), std::ptr::null()) } +pub fn CreateAttrString<'ll>(llcx: &'ll Context, attr: &str) -> &'ll Attribute { + unsafe { + LLVMCreateStringAttribute( + llcx, + attr.as_ptr().cast(), + attr.len().try_into().unwrap(), + std::ptr::null(), + 0, + ) + } } pub fn CreateAlignmentAttr(llcx: &Context, bytes: u64) -> &Attribute { diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 3b06587061d9d..e9d13a4ebaf8c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -369,12 +369,12 @@ pub fn target_cpu(sess: &Session) -> &str { /// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`, /// `--target` and similar). pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec { - // Features that come earlier are overriden by conflicting features later in the string. + // Features that come earlier are overridden by conflicting features later in the string. // Typically we'll want more explicit settings to override the implicit ones, so: // - // * Features from -Ctarget-cpu=*; are overriden by [^1] - // * Features implied by --target; are overriden by - // * Features from -Ctarget-feature; are overriden by + // * Features from -Ctarget-cpu=*; are overridden by [^1] + // * Features implied by --target; are overridden by + // * Features from -Ctarget-feature; are overridden by // * function specific features. // // [^1]: target-cpu=native is handled here, other target-cpu values are handled implicitly @@ -383,7 +383,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec)] = &[ // #[target_feature]. ("thumb-mode", Some(sym::arm_target_feature)), ("thumb2", Some(sym::arm_target_feature)), + ("d32", Some(sym::arm_target_feature)), ]; const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 716c01ba78ceb..16870489176d7 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -535,7 +535,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal)?; // This can still fail: - // * During ConstProp, with `TooGeneric` or since the `requried_consts` were not all + // * During ConstProp, with `TooGeneric` or since the `required_consts` were not all // checked yet. // * During CTFE, since promoteds in `const`/`static` initializer bodies can fail. diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index b36ce63dda756..43c9e9296b90a 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1228,7 +1228,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { /// /// A custom rustc driver can skip calling this to set up a custom ICE hook. pub fn install_ice_hook() { - // If the user has not explicitly overriden "RUST_BACKTRACE", then produce + // If the user has not explicitly overridden "RUST_BACKTRACE", then produce // full backtraces. When a compiler ICE happens, we want to gather // as much information as possible to present in the issue opened // by the user. Compiler developers and other rustc users can diff --git a/compiler/rustc_error_codes/src/error_codes/E0772.md b/compiler/rustc_error_codes/src/error_codes/E0772.md index 262e52351ef01..3b73abaf776c2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0772.md +++ b/compiler/rustc_error_codes/src/error_codes/E0772.md @@ -45,7 +45,7 @@ trait object's internal data to be accessed safely from any trait methods. This rule also goes for any lifetime any struct made into a trait object may have. In the implementation for `dyn Person`, the `'2` lifetime representing the -internal data was ommitted, meaning that the compiler inferred the lifetime +internal data was omitted, meaning that the compiler inferred the lifetime `'static`. As a result, the implementation's `is_cool` is inferred by the compiler to look like this: diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 1b97618050939..4af376b983c94 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1841,7 +1841,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { self.flat_map_node(node) } - fn flat_map_stmt(&mut self, mut node: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { + fn flat_map_stmt(&mut self, node: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { // FIXME: invocations in semicolon-less expressions positions are expanded as expressions, // changing that requires some compatibility measures. if node.is_expr() { @@ -1863,7 +1863,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { self.cx.current_expansion.is_trailing_mac = false; res } - _ => assign_id!(self, &mut node.id, || noop_flat_map_stmt(node, self)), + _ => noop_flat_map_stmt(node, self), }; } diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index a419612e315df..bb36dfd793d4a 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -154,7 +154,7 @@ type NamedMatchVec = SmallVec<[NamedMatch; 4]>; /// lifetime. By separating `'tt` from `'root`, we can show that. #[derive(Clone)] struct MatcherPos<'root, 'tt> { - /// The token or sequence of tokens that make up the matcher + /// The token or sequence of tokens that make up the matcher. `elts` is short for "elements". top_elts: TokenTreeOrTokenTreeSlice<'tt>, /// The position of the "dot" in this matcher @@ -184,17 +184,8 @@ struct MatcherPos<'root, 'tt> { /// in this matcher. match_hi: usize, - // The following fields are used if we are matching a repetition. If we aren't, they should be - // `None`. - /// The KleeneOp of this sequence if we are in a repetition. - seq_op: Option, - - /// The separator if we are in a repetition. - sep: Option, - - /// The "parent" matcher position if we are in a repetition. That is, the matcher position just - /// before we enter the sequence. - up: Option>, + /// This field is only used if we are matching a repetition. + repetition: Option>, /// Specifically used to "unzip" token trees. By "unzip", we mean to unwrap the delimiters from /// a delimited token tree (e.g., something wrapped in `(` `)`) or to get the contents of a doc @@ -207,7 +198,38 @@ struct MatcherPos<'root, 'tt> { stack: SmallVec<[MatcherTtFrame<'tt>; 1]>, } +// This type is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +rustc_data_structures::static_assert_size!(MatcherPos<'_, '_>, 192); + impl<'root, 'tt> MatcherPos<'root, 'tt> { + /// Generates the top-level matcher position in which the "dot" is before the first token of + /// the matcher `ms`. + fn new(ms: &'tt [TokenTree]) -> Self { + let match_idx_hi = count_names(ms); + MatcherPos { + // Start with the top level matcher given to us. + top_elts: TtSeq(ms), + + // The "dot" is before the first token of the matcher. + idx: 0, + + // Initialize `matches` to a bunch of empty `Vec`s -- one for each metavar in + // `top_elts`. `match_lo` for `top_elts` is 0 and `match_hi` is `match_idx_hi`. + // `match_cur` is 0 since we haven't actually matched anything yet. + matches: create_matches(match_idx_hi), + match_lo: 0, + match_cur: 0, + match_hi: match_idx_hi, + + // Haven't descended into any delimiters, so this is empty. + stack: smallvec![], + + // Haven't descended into any sequences, so this is `None`. + repetition: None, + } + } + /// Adds `m` as a named match for the `idx`-th metavar. fn push_match(&mut self, idx: usize, m: NamedMatch) { let matches = Lrc::make_mut(&mut self.matches[idx]); @@ -215,6 +237,19 @@ impl<'root, 'tt> MatcherPos<'root, 'tt> { } } +#[derive(Clone)] +struct MatcherPosRepetition<'root, 'tt> { + /// The KleeneOp of this sequence. + seq_op: mbe::KleeneOp, + + /// The separator. + sep: Option, + + /// The "parent" matcher position. That is, the matcher position just before we enter the + /// sequence. + up: MatcherPosHandle<'root, 'tt>, +} + // Lots of MatcherPos instances are created at runtime. Allocating them on the // heap is slow. Furthermore, using SmallVec to allocate them all // on the stack is also slow, because MatcherPos is quite a large type and @@ -258,6 +293,12 @@ impl<'root, 'tt> DerefMut for MatcherPosHandle<'root, 'tt> { } } +enum EofItems<'root, 'tt> { + None, + One(MatcherPosHandle<'root, 'tt>), + Multiple, +} + /// Represents the possible results of an attempted parse. crate enum ParseResult { /// Parsed successfully. @@ -300,35 +341,6 @@ fn create_matches(len: usize) -> Box<[Lrc]> { .into_boxed_slice() } -/// Generates the top-level matcher position in which the "dot" is before the first token of the -/// matcher `ms`. -fn initial_matcher_pos<'root, 'tt>(ms: &'tt [TokenTree]) -> MatcherPos<'root, 'tt> { - let match_idx_hi = count_names(ms); - let matches = create_matches(match_idx_hi); - MatcherPos { - // Start with the top level matcher given to us - top_elts: TtSeq(ms), // "elts" is an abbr. for "elements" - // The "dot" is before the first token of the matcher - idx: 0, - - // Initialize `matches` to a bunch of empty `Vec`s -- one for each metavar in `top_elts`. - // `match_lo` for `top_elts` is 0 and `match_hi` is `matches.len()`. `match_cur` is 0 since - // we haven't actually matched anything yet. - matches, - match_lo: 0, - match_cur: 0, - match_hi: match_idx_hi, - - // Haven't descended into any delimiters, so empty stack - stack: smallvec![], - - // Haven't descended into any sequences, so both of these are `None`. - seq_op: None, - sep: None, - up: None, - } -} - /// `NamedMatch` is a pattern-match result for a single `token::MATCH_NONTERMINAL`: /// so it is associated with a single ident in a parse, and all /// `MatchedNonterminal`s in the `NamedMatch` have the same non-terminal type @@ -475,10 +487,10 @@ fn inner_parse_loop<'root, 'tt>( sess: &ParseSess, cur_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>, next_items: &mut Vec>, - eof_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>, bb_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>, + eof_items: &mut EofItems<'root, 'tt>, token: &Token, -) -> ParseResult<()> { +) -> Result<(), (rustc_span::Span, String)> { // Pop items from `cur_items` until it is empty. while let Some(mut item) = cur_items.pop() { // When unzipped trees end, remove them. This corresponds to backtracking out of a @@ -504,7 +516,7 @@ fn inner_parse_loop<'root, 'tt>( // We are repeating iff there is a parent. If the matcher is inside of a repetition, // then we could be at the end of a sequence or at the beginning of the next // repetition. - if item.up.is_some() { + if let Some(repetition) = &item.repetition { // At this point, regardless of whether there is a separator, we should add all // matches from the complete repetition of the sequence to the shared, top-level // `matches` list (actually, `up.matches`, which could itself not be the top-level, @@ -515,7 +527,7 @@ fn inner_parse_loop<'root, 'tt>( // NOTE: removing the condition `idx == len` allows trailing separators. if idx == len { // Get the `up` matcher - let mut new_pos = item.up.clone().unwrap(); + let mut new_pos = repetition.up.clone(); // Add matches from this repetition to the `matches` of `up` for idx in item.match_lo..item.match_hi { @@ -530,32 +542,33 @@ fn inner_parse_loop<'root, 'tt>( } // Check if we need a separator. - if idx == len && item.sep.is_some() { + if idx == len && repetition.sep.is_some() { // We have a separator, and it is the current token. We can advance past the // separator token. - if item.sep.as_ref().map_or(false, |sep| token_name_eq(token, sep)) { + if repetition.sep.as_ref().map_or(false, |sep| token_name_eq(token, sep)) { item.idx += 1; next_items.push(item); } - } - // We don't need a separator. Move the "dot" back to the beginning of the matcher - // and try to match again UNLESS we are only allowed to have _one_ repetition. - else if item.seq_op != Some(mbe::KleeneOp::ZeroOrOne) { + } else if repetition.seq_op != mbe::KleeneOp::ZeroOrOne { + // We don't need a separator. Move the "dot" back to the beginning of the + // matcher and try to match again UNLESS we are only allowed to have _one_ + // repetition. item.match_cur = item.match_lo; item.idx = 0; cur_items.push(item); } + } else { + // If we are not in a repetition, then being at the end of a matcher means that we + // have reached the potential end of the input. + *eof_items = match eof_items { + EofItems::None => EofItems::One(item), + EofItems::One(_) | EofItems::Multiple => EofItems::Multiple, + } } - // If we are not in a repetition, then being at the end of a matcher means that we have - // reached the potential end of the input. - else { - eof_items.push(item); - } - } - // We are in the middle of a matcher. - else { - // Look at what token in the matcher we are trying to match the current token (`token`) - // against. Depending on that, we may generate new items. + } else { + // We are in the middle of a matcher. Look at what token in the matcher we are trying + // to match the current token (`token`) against. Depending on that, we may generate new + // items. match item.top_elts.get_tt(idx) { // Need to descend into a sequence TokenTree::Sequence(sp, seq) => { @@ -578,14 +591,16 @@ fn inner_parse_loop<'root, 'tt>( let matches = create_matches(item.matches.len()); cur_items.push(MatcherPosHandle::Box(Box::new(MatcherPos { stack: smallvec![], - sep: seq.separator.clone(), - seq_op: Some(seq.kleene.op), idx: 0, matches, match_lo: item.match_cur, match_cur: item.match_cur, match_hi: item.match_cur + seq.num_captures, - up: Some(item), + repetition: Some(MatcherPosRepetition { + up: item, + sep: seq.separator.clone(), + seq_op: seq.kleene.op, + }), top_elts: Tt(TokenTree::Sequence(sp, seq)), }))); } @@ -593,7 +608,7 @@ fn inner_parse_loop<'root, 'tt>( // We need to match a metavar (but the identifier is invalid)... this is an error TokenTree::MetaVarDecl(span, _, None) => { if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { - return Error(span, "missing fragment specifier".to_string()); + return Err((span, "missing fragment specifier".to_string())); } } @@ -641,7 +656,7 @@ fn inner_parse_loop<'root, 'tt>( } // Yay a successful parse (so far)! - Success(()) + Ok(()) } /// Use the given sequence of token trees (`ms`) as a matcher. Match the token @@ -659,17 +674,18 @@ pub(super) fn parse_tt( // // This MatcherPos instance is allocated on the stack. All others -- and // there are frequently *no* others! -- are allocated on the heap. - let mut initial = initial_matcher_pos(ms); + let mut initial = MatcherPos::new(ms); let mut cur_items = smallvec![MatcherPosHandle::Ref(&mut initial)]; let mut next_items = Vec::new(); loop { + assert!(next_items.is_empty()); + // Matcher positions black-box parsed by parser.rs (`parser`) let mut bb_items = SmallVec::new(); // Matcher positions that would be valid if the macro invocation was over now - let mut eof_items = SmallVec::new(); - assert!(next_items.is_empty()); + let mut eof_items = EofItems::None; // Process `cur_items` until either we have finished the input or we need to get some // parsing from the black-box parser done. The result is that `next_items` will contain a @@ -678,37 +694,34 @@ pub(super) fn parse_tt( parser.sess, &mut cur_items, &mut next_items, - &mut eof_items, &mut bb_items, + &mut eof_items, &parser.token, ) { - Success(_) => {} - Failure(token, msg) => return Failure(token, msg), - Error(sp, msg) => return Error(sp, msg), - ErrorReported => return ErrorReported, + Ok(()) => {} + Err((sp, msg)) => return Error(sp, msg), } // inner parse loop handled all cur_items, so it's empty assert!(cur_items.is_empty()); - // We need to do some post processing after the `inner_parser_loop`. + // We need to do some post processing after the `inner_parse_loop`. // // Error messages here could be improved with links to original rules. // If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise, // either the parse is ambiguous (which should never happen) or there is a syntax error. if parser.token == token::Eof { - if eof_items.len() == 1 { - let matches = - eof_items[0].matches.iter_mut().map(|dv| Lrc::make_mut(dv).pop().unwrap()); - return nameize(parser.sess, ms, matches); - } else if eof_items.len() > 1 { - return Error( - parser.token.span, - "ambiguity: multiple successful parses".to_string(), - ); - } else { - return Failure( + return match eof_items { + EofItems::One(mut eof_item) => { + let matches = + eof_item.matches.iter_mut().map(|dv| Lrc::make_mut(dv).pop().unwrap()); + nameize(parser.sess, ms, matches) + } + EofItems::Multiple => { + Error(parser.token.span, "ambiguity: multiple successful parses".to_string()) + } + EofItems::None => Failure( Token::new( token::Eof, if parser.token.span.is_dummy() { @@ -718,12 +731,12 @@ pub(super) fn parse_tt( }, ), "missing tokens in macro arguments", - ); - } + ), + }; } - // Performance hack: eof_items may share matchers via Rc with other things that we want - // to modify. Dropping eof_items now may drop these refcounts to 1, preventing an - // unnecessary implicit clone later in Rc::make_mut. + // Performance hack: `eof_items` may share matchers via `Rc` with other things that we want + // to modify. Dropping `eof_items` now may drop these refcounts to 1, preventing an + // unnecessary implicit clone later in `Rc::make_mut`. drop(eof_items); // If there are no possible next positions AND we aren't waiting for the black-box parser, @@ -731,9 +744,10 @@ pub(super) fn parse_tt( if bb_items.is_empty() && next_items.is_empty() { return Failure(parser.token.clone(), "no rules expected this token in macro call"); } - // Another possibility is that we need to call out to parse some rust nonterminal - // (black-box) parser. However, if there is not EXACTLY ONE of these, something is wrong. - else if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 { + + if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 { + // We need to call out to parse some rust nonterminal (black-box) parser. But something + // is wrong, because there is not EXACTLY ONE of these. let nts = bb_items .iter() .map(|item| match item.top_elts.get_tt(item.idx) { @@ -755,15 +769,15 @@ pub(super) fn parse_tt( ), ); } - // Dump all possible `next_items` into `cur_items` for the next iteration. - else if !next_items.is_empty() { - // Now process the next token + + if !next_items.is_empty() { + // Dump all possible `next_items` into `cur_items` for the next iteration. Then process + // the next token. cur_items.extend(next_items.drain(..)); parser.to_mut().bump(); - } - // Finally, we have the case where we need to call the black-box parser to get some - // nonterminal. - else { + } else { + // Finally, we have the case where we need to call the black-box parser to get some + // nonterminal. assert_eq!(bb_items.len(), 1); let mut item = bb_items.pop().unwrap(); diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 54000527c15b9..760dea77f9c2b 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -233,7 +233,7 @@ pub(super) fn transcribe<'a>( } else { // Other variables are emitted into the output stream as groups with // `Delimiter::None` to maintain parsing priorities. - // `Interpolated` is currenty used for such groups in rustc parser. + // `Interpolated` is currently used for such groups in rustc parser. marker.visit_span(&mut sp); TokenTree::token(token::Interpolated(nt.clone()), sp) }; diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 869cada400f0f..0aef5982cff50 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -847,7 +847,7 @@ impl server::Span for Rustc<'_, '_> { /// the `quote` proc-macro. This will save the span of /// "hello" into the metadata of `my_proc_macro`. As a result, /// the body of `my_proc_macro` (after expansion) will end - /// up containg a call that looks like this: + /// up containing a call that looks like this: /// `proc_macro::Ident::new("hello", proc_macro::Span::recover_proc_macro_span(0))` /// /// where `0` is the id returned by this function. diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 870c3f8068245..908a936142475 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -27,7 +27,7 @@ pub enum LoadResult { }, /// The file either didn't exist or was produced by an incompatible compiler version. DataOutOfDate, - /// An error occured. + /// An error occurred. Error { #[allow(missing_docs)] message: String, diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 3bc30f0220d40..16f7504cbbe58 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -928,7 +928,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// performing that replacement, we'll turn all remaining infer type params to use their name from /// their definition, and replace all the `[type error]`s back to being infer so they display in /// the output as `_`. If we didn't go through `[type error]`, we would either show all type params -/// by their name *or* `_`, neither of which is desireable: we want to show all types that we could +/// by their name *or* `_`, neither of which is desirable: we want to show all types that we could /// infer as `_` to reduce verbosity and avoid telling the user about unnecessary type annotations. struct ResolvedTypeParamEraser<'tcx> { tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index e0420291aa3f5..4710eae6189a5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { bug!("Node not an impl."); }; - // Next, let's figure out the set of trait objects with implict static bounds + // Next, let's figure out the set of trait objects with implicit static bounds let ty = self.tcx().type_of(*impl_def_id); let mut v = super::static_impl_trait::TraitObjectVisitor(FxHashSet::default()); v.visit_ty(ty); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 919fe7cac5ce3..ef6c9ef6627d5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -267,12 +267,6 @@ extern "C" LLVMAttributeRef LLVMRustCreateAttrNoValue(LLVMContextRef C, return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr))); } -extern "C" LLVMAttributeRef LLVMRustCreateAttrStringValue(LLVMContextRef C, - const char *Name, - const char *Value) { - return wrap(Attribute::get(*unwrap(C), StringRef(Name), StringRef(Value))); -} - extern "C" LLVMAttributeRef LLVMRustCreateAlignmentAttr(LLVMContextRef C, uint64_t Bytes) { return wrap(Attribute::getWithAlignment(*unwrap(C), llvm::Align(Bytes))); diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 37cfc4a0dc3c2..6b1eaa4d399d9 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -15,6 +15,5 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_span = { path = "../rustc_span" } rustc_fs_util = { path = "../rustc_fs_util" } -num_cpus = "1.0" rustc_ast = { path = "../rustc_ast" } rustc_lint_defs = { path = "../rustc_lint_defs" } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c2b13346cd6c9..43123d30ad5c6 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -551,7 +551,7 @@ mod parse { crate fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool { match v.and_then(|s| s.parse().ok()) { Some(0) => { - *slot = ::num_cpus::get(); + *slot = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get); true } Some(i) => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6767593bbc51a..9d452131fa6ac 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -539,6 +539,7 @@ symbols! { custom_inner_attributes, custom_test_frameworks, d, + d32, dbg_macro, dead_code, dealloc, diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 88f2d3f80d2c3..aaa632333db38 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -50,9 +50,12 @@ impl ArmInlineAsmRegClass { match self { Self::reg => types! { _: I8, I16, I32, F32; }, Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F32; }, - Self::dreg | Self::dreg_low16 | Self::dreg_low8 => types! { + Self::dreg_low16 | Self::dreg_low8 => types! { vfp2: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2); }, + Self::dreg => types! { + d32: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2); + }, Self::qreg | Self::qreg_low8 | Self::qreg_low4 => types! { neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4); }, diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index b2ed82508dd29..d2077a63e150a 100644 --- a/library/core/src/iter/adapters/map.rs +++ b/library/core/src/iter/adapters/map.rs @@ -38,7 +38,7 @@ use crate::ops::Try; /// } /// ``` /// -/// This will print "('a', 1), ('b', 2), ('c', 3)". +/// This will print `('a', 1), ('b', 2), ('c', 3)`. /// /// Now consider this twist where we add a call to `rev`. This version will /// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed, diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index cf8cf5ad49f73..ff01ce2733329 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -279,10 +279,15 @@ pub fn available_parallelism() -> io::Result { ))] { #[cfg(any(target_os = "android", target_os = "linux"))] { + let quota = cgroup2_quota().max(1); let mut set: libc::cpu_set_t = unsafe { mem::zeroed() }; - if unsafe { libc::sched_getaffinity(0, mem::size_of::(), &mut set) } == 0 { - let count = unsafe { libc::CPU_COUNT(&set) }; - return Ok(unsafe { NonZeroUsize::new_unchecked(count as usize) }); + unsafe { + if libc::sched_getaffinity(0, mem::size_of::(), &mut set) == 0 { + let count = libc::CPU_COUNT(&set) as usize; + let count = count.min(quota); + // SAFETY: affinity mask can't be empty and the quota gets clamped to a minimum of 1 + return Ok(NonZeroUsize::new_unchecked(count)); + } } } match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { @@ -368,6 +373,80 @@ pub fn available_parallelism() -> io::Result { } } +/// Returns cgroup CPU quota in core-equivalents, rounded down, or usize::MAX if the quota cannot +/// be determined or is not set. +#[cfg(any(target_os = "android", target_os = "linux"))] +fn cgroup2_quota() -> usize { + use crate::ffi::OsString; + use crate::fs::{try_exists, File}; + use crate::io::Read; + use crate::os::unix::ffi::OsStringExt; + use crate::path::PathBuf; + + let mut quota = usize::MAX; + + let _: Option<()> = try { + let mut buf = Vec::with_capacity(128); + // find our place in the cgroup hierarchy + File::open("/proc/self/cgroup").ok()?.read_to_end(&mut buf).ok()?; + let cgroup_path = buf + .split(|&c| c == b'\n') + .filter_map(|line| { + let mut fields = line.splitn(3, |&c| c == b':'); + // expect cgroupv2 which has an empty 2nd field + if fields.nth(1) != Some(b"") { + return None; + } + let path = fields.last()?; + // skip leading slash + Some(path[1..].to_owned()) + }) + .next()?; + let cgroup_path = PathBuf::from(OsString::from_vec(cgroup_path)); + + let mut path = PathBuf::with_capacity(128); + let mut read_buf = String::with_capacity(20); + + let cgroup_mount = "/sys/fs/cgroup"; + + path.push(cgroup_mount); + path.push(&cgroup_path); + + path.push("cgroup.controllers"); + + // skip if we're not looking at cgroup2 + if matches!(try_exists(&path), Err(_) | Ok(false)) { + return usize::MAX; + }; + + path.pop(); + + while path.starts_with(cgroup_mount) { + path.push("cpu.max"); + + read_buf.clear(); + + if File::open(&path).and_then(|mut f| f.read_to_string(&mut read_buf)).is_ok() { + let raw_quota = read_buf.lines().next()?; + let mut raw_quota = raw_quota.split(' '); + let limit = raw_quota.next()?; + let period = raw_quota.next()?; + match (limit.parse::(), period.parse::()) { + (Ok(limit), Ok(period)) => { + quota = quota.min(limit / period); + } + _ => {} + } + } + + path.pop(); // pop filename + path.pop(); // pop dir + } + }; + + quota +} + #[cfg(all( not(target_os = "linux"), not(target_os = "freebsd"), diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index beb606099341e..09d1e714ab6dd 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1524,7 +1524,10 @@ fn _assert_sync_and_send() { /// /// On Linux: /// - It may overcount the amount of parallelism available when limited by a -/// process-wide affinity mask, or when affected by cgroup limits. +/// process-wide affinity mask or cgroup quotas and cgroup2 fs or `sched_getaffinity()` can't be +/// queried, e.g. due to sandboxing. +/// - It may undercount the amount of parallelism if the current thread's affinity mask +/// does not reflect the process' cpuset, e.g. due to pinned threads. /// /// On all targets: /// - It may overcount the amount of parallelism available when running in a VM diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 592a137e379de..02efc08cc791f 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -37,7 +37,6 @@ test = false build_helper = { path = "../build_helper" } cmake = "0.1.38" filetime = "0.2" -num_cpus = "1.0" getopts = "0.2.19" cc = "1.0.69" libc = "0.2" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d6f77fe6cd6d0..ce76ccd57551d 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1187,7 +1187,7 @@ fn set(field: &mut T, val: Option) { fn threads_from_config(v: u32) -> u32 { match v { - 0 => num_cpus::get() as u32, + 0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32, n => n, } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 9180c5f03af68..74528f2752f5f 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -208,7 +208,7 @@ To learn more about a subcommand, run `./x.py -h`", let j_msg = format!( "number of jobs to run in parallel; \ defaults to {} (this host's logical CPU count)", - num_cpus::get() + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) ); opts.optopt("j", "jobs", &j_msg, "JOBS"); opts.optflag("h", "help", "print this help message"); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 86339c8d7f88d..6a58de40181c2 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -917,7 +917,9 @@ impl Build { /// Returns the number of parallel jobs that have been configured for this /// build. fn jobs(&self) -> u32 { - self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32) + self.config.jobs.unwrap_or_else(|| { + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32 + }) } fn debuginfo_map_to(&self, which: GitRepo) -> Option { diff --git a/src/test/debuginfo/basic-types-globals-metadata.rs b/src/test/debuginfo/basic-types-globals-metadata.rs index 3934d3c7a685e..30e4b882076af 100644 --- a/src/test/debuginfo/basic-types-globals-metadata.rs +++ b/src/test/debuginfo/basic-types-globals-metadata.rs @@ -1,5 +1,4 @@ // min-lldb-version: 310 -// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // compile-flags:-g // gdb-command:run @@ -11,7 +10,7 @@ // gdb-check:type = isize // gdbg-command:whatis 'basic_types_globals_metadata::C' // gdbr-command:whatis basic_types_globals_metadata::C -// gdb-check:type = char +// gdb-check:type = char32_t // gdbg-command:whatis 'basic_types_globals_metadata::I8' // gdbr-command:whatis basic_types_globals_metadata::I8 // gdb-check:type = i8 diff --git a/src/test/debuginfo/c-style-enum.rs b/src/test/debuginfo/c-style-enum.rs index dce34fc0dcf5e..86079e45b2727 100644 --- a/src/test/debuginfo/c-style-enum.rs +++ b/src/test/debuginfo/c-style-enum.rs @@ -1,5 +1,4 @@ // ignore-aarch64 -// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/cross-crate-spans.rs b/src/test/debuginfo/cross-crate-spans.rs index 7c58e1db23f35..57077f4aa802f 100644 --- a/src/test/debuginfo/cross-crate-spans.rs +++ b/src/test/debuginfo/cross-crate-spans.rs @@ -5,7 +5,6 @@ // This fails on lldb 6.0.1 on x86-64 Fedora 28; so mark it macOS-only // for now. -// only-macos // aux-build:cross_crate_spans.rs extern crate cross_crate_spans; diff --git a/src/test/debuginfo/destructured-for-loop-variable.rs b/src/test/debuginfo/destructured-for-loop-variable.rs index 15cb88ef25d5b..eb821a580564a 100644 --- a/src/test/debuginfo/destructured-for-loop-variable.rs +++ b/src/test/debuginfo/destructured-for-loop-variable.rs @@ -1,9 +1,5 @@ // min-lldb-version: 310 -// This fails on lldb 6.0.1 on x86-64 Fedora 28; so mark it macOS-only -// for now. -// only-macos - // compile-flags:-g // === GDB TESTS =================================================================================== diff --git a/src/test/debuginfo/function-arg-initialization.rs b/src/test/debuginfo/function-arg-initialization.rs index dea1339517b46..ad432d2e7d370 100644 --- a/src/test/debuginfo/function-arg-initialization.rs +++ b/src/test/debuginfo/function-arg-initialization.rs @@ -1,4 +1,4 @@ -// ignore-test // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 +// ignore-lldb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // min-lldb-version: 310 // This test case checks if function arguments already have the correct value diff --git a/src/test/debuginfo/lexical-scopes-in-block-expression.rs b/src/test/debuginfo/lexical-scopes-in-block-expression.rs index 72621ffc74267..fee4ac7bd2f6d 100644 --- a/src/test/debuginfo/lexical-scopes-in-block-expression.rs +++ b/src/test/debuginfo/lexical-scopes-in-block-expression.rs @@ -1,5 +1,4 @@ // min-lldb-version: 310 -// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // compile-flags:-g diff --git a/src/test/debuginfo/limited-debuginfo.rs b/src/test/debuginfo/limited-debuginfo.rs index bd381cd0e22d3..bf03ac3dd29e9 100644 --- a/src/test/debuginfo/limited-debuginfo.rs +++ b/src/test/debuginfo/limited-debuginfo.rs @@ -1,5 +1,4 @@ // ignore-lldb -// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // compile-flags:-C debuginfo=1 diff --git a/src/test/debuginfo/method-on-enum.rs b/src/test/debuginfo/method-on-enum.rs index aaa9bd9d6f97a..e746895797820 100644 --- a/src/test/debuginfo/method-on-enum.rs +++ b/src/test/debuginfo/method-on-enum.rs @@ -1,5 +1,5 @@ // min-lldb-version: 310 -// ignore-test // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 +// ignore-lldb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // compile-flags:-g diff --git a/src/test/debuginfo/simple-struct.rs b/src/test/debuginfo/simple-struct.rs index aa3cf023a718d..fc2b1f64221d1 100644 --- a/src/test/debuginfo/simple-struct.rs +++ b/src/test/debuginfo/simple-struct.rs @@ -1,5 +1,4 @@ // min-lldb-version: 310 -// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // compile-flags:-g diff --git a/src/test/debuginfo/simple-tuple.rs b/src/test/debuginfo/simple-tuple.rs index 0807cfedce01d..b89a51437b3ba 100644 --- a/src/test/debuginfo/simple-tuple.rs +++ b/src/test/debuginfo/simple-tuple.rs @@ -1,5 +1,4 @@ // min-lldb-version: 310 -// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // compile-flags:-g diff --git a/src/test/debuginfo/union-smoke.rs b/src/test/debuginfo/union-smoke.rs index 4d4b6cc96fb57..5d1cd03ad3e8c 100644 --- a/src/test/debuginfo/union-smoke.rs +++ b/src/test/debuginfo/union-smoke.rs @@ -1,5 +1,4 @@ // min-lldb-version: 310 -// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // ignore-gdb-version: 7.11.90 - 7.12.9 diff --git a/src/test/debuginfo/vec.rs b/src/test/debuginfo/vec.rs index 895661816b864..9bead21fe5f88 100644 --- a/src/test/debuginfo/vec.rs +++ b/src/test/debuginfo/vec.rs @@ -1,5 +1,4 @@ // min-lldb-version: 310 -// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // compile-flags:-g diff --git a/src/test/ui/check-cfg/stmt-no-ice.rs b/src/test/ui/check-cfg/stmt-no-ice.rs new file mode 100644 index 0000000000000..cf76487ed46fb --- /dev/null +++ b/src/test/ui/check-cfg/stmt-no-ice.rs @@ -0,0 +1,10 @@ +// This test checks that there is no ICE with this code +// +// check-pass +// compile-flags:--check-cfg=names() -Z unstable-options + +fn main() { + #[cfg(crossbeam_loom)] + //~^ WARNING unexpected `cfg` condition name + {} +} diff --git a/src/test/ui/check-cfg/stmt-no-ice.stderr b/src/test/ui/check-cfg/stmt-no-ice.stderr new file mode 100644 index 0000000000000..da65b596911d2 --- /dev/null +++ b/src/test/ui/check-cfg/stmt-no-ice.stderr @@ -0,0 +1,10 @@ +warning: unexpected `cfg` condition name + --> $DIR/stmt-no-ice.rs:7:11 + | +LL | #[cfg(crossbeam_loom)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index c022d3aa0acd7..c437bde5ae69a 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -13,4 +13,3 @@ tar = "0.4.29" sha2 = "0.10.1" rayon = "1.5.1" hex = "0.4.2" -num_cpus = "1.13.0" diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8a62146abfc4e..378efeb644375 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -208,7 +208,7 @@ fn main() { let num_threads = if let Some(num) = env::var_os("BUILD_MANIFEST_NUM_THREADS") { num.to_str().unwrap().parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS") } else { - num_cpus::get() + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) }; rayon::ThreadPoolBuilder::new() .num_threads(num_threads)