diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 3ddc7fce1b770..e8fca6f04ba5b 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1366,7 +1366,7 @@ impl<'hir> LoweringContext<'_, 'hir> { generics: &Generics, itctx: ImplTraitContext<'_, 'hir>, ) -> GenericsCtor<'hir> { - // Error if `?Trait` bounds in where clauses don't refer directly to type paramters. + // Error if `?Trait` bounds in where clauses don't refer directly to type parameters. // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering // these into hir when we lower thee where clauses), but this makes it quite difficult to // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 68b536da9f70f..846abce9d6a6e 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -1,8 +1,7 @@ //! Parsing and validation of builtin attributes use rustc_ast as ast; -use rustc_ast::node_id::CRATE_NODE_ID; -use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem}; +use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem, NodeId}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; @@ -436,7 +435,12 @@ pub fn find_crate_name(sess: &Session, attrs: &[Attribute]) -> Option { } /// Tests if a cfg-pattern matches the cfg set -pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool { +pub fn cfg_matches( + cfg: &ast::MetaItem, + sess: &ParseSess, + lint_node_id: NodeId, + features: Option<&Features>, +) -> bool { eval_condition(cfg, sess, features, &mut |cfg| { try_gate_cfg(cfg, sess, features); let error = |span, msg| { @@ -470,7 +474,7 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat sess.buffer_lint_with_diagnostic( UNEXPECTED_CFGS, cfg.span, - CRATE_NODE_ID, + lint_node_id, "unexpected `cfg` condition name", BuiltinLintDiagnostics::UnexpectedCfg(ident.span, name, None), ); @@ -482,7 +486,7 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat sess.buffer_lint_with_diagnostic( UNEXPECTED_CFGS, cfg.span, - CRATE_NODE_ID, + lint_node_id, "unexpected `cfg` condition value", BuiltinLintDiagnostics::UnexpectedCfg( cfg.name_value_literal_span().unwrap(), diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 3f0ce7dea00fb..fa9fe905256f5 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1992,7 +1992,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { .find_map(|constraint| { if let ConstraintCategory::Predicate(predicate_span) = constraint.category { // We currentl'y doesn't store the `DefId` in the `ConstraintCategory` - // for perforamnce reasons. The error reporting code used by NLL only + // for performances reasons. The error reporting code used by NLL only // uses the span, so this doesn't cause any problems at the moment. Some(ObligationCauseCode::BindingObligation( CRATE_DEF_ID.to_def_id(), diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 1e1cf917c6093..f5ef4765df64f 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -19,7 +19,12 @@ pub fn expand_cfg( match parse_cfg(cx, sp, tts) { Ok(cfg) => { - let matches_cfg = attr::cfg_matches(&cfg, &cx.sess.parse_sess, cx.ecfg.features); + let matches_cfg = attr::cfg_matches( + &cfg, + &cx.sess.parse_sess, + cx.current_expansion.lint_node_id, + cx.ecfg.features, + ); MacEager::expr(cx.expr_bool(sp, matches_cfg)) } Err(mut err) => { diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 31086a2acf8cc..3c8f8f1854bf2 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -5,6 +5,7 @@ use rustc_ast::mut_visit::MutVisitor; use rustc_ast::ptr::P; use rustc_ast::tokenstream::CanSynthesizeMissingTokens; use rustc_ast::visit::Visitor; +use rustc_ast::NodeId; use rustc_ast::{mut_visit, visit}; use rustc_ast::{AstLike, Attribute}; use rustc_expand::base::{Annotatable, ExtCtxt}; @@ -26,15 +27,16 @@ crate fn expand( ) -> Vec { check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval); warn_on_duplicate_attribute(&ecx, &annotatable, sym::cfg_eval); - vec![cfg_eval(ecx.sess, ecx.ecfg.features, annotatable)] + vec![cfg_eval(ecx.sess, ecx.ecfg.features, annotatable, ecx.current_expansion.lint_node_id)] } crate fn cfg_eval( sess: &Session, features: Option<&Features>, annotatable: Annotatable, + lint_node_id: NodeId, ) -> Annotatable { - CfgEval { cfg: &mut StripUnconfigured { sess, features, config_tokens: true } } + CfgEval { cfg: &mut StripUnconfigured { sess, features, config_tokens: true, lint_node_id } } .configure_annotatable(annotatable) // Since the item itself has already been configured by the `InvocationCollector`, // we know that fold result vector will contain exactly one element. @@ -201,7 +203,7 @@ impl CfgEval<'_, '_> { // Re-parse the tokens, setting the `capture_cfg` flag to save extra information // to the captured `AttrAnnotatedTokenStream` (specifically, we capture - // `AttrAnnotatedTokenTree::AttributesData` for all occurences of `#[cfg]` and `#[cfg_attr]`) + // `AttrAnnotatedTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`) let mut parser = rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None); parser.capture_cfg = true; diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 47d7b6c259e33..61681ec66a48d 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -64,7 +64,12 @@ impl MultiItemModifier for Expander { match &mut resolutions[..] { [] => {} [(_, first_item, _), others @ ..] => { - *first_item = cfg_eval(sess, features, item.clone()); + *first_item = cfg_eval( + sess, + features, + item.clone(), + ecx.current_expansion.lint_node_id, + ); for (_, item, _) in others { *item = first_item.clone(); } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 587453fd8e8d6..a00c6af80cac8 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1,4 +1,5 @@ use rustc_arena::TypedArena; +use rustc_ast::CRATE_NODE_ID; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; @@ -989,7 +990,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( // ... and otherwise we're processing a `*.dwp` packed dwarf file. // - // We cannot rely on the .o paths in the exectuable because they may have been + // We cannot rely on the .o paths in the executable because they may have been // remapped by --remap-path-prefix and therefore invalid, so we need to provide // the .o/.dwo paths explicitly. SplitDebuginfo::Packed => link_dwarf_object(sess, codegen_results, out_filename), @@ -2434,7 +2435,7 @@ fn add_upstream_native_libraries( fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => rustc_attr::cfg_matches(cfg, &sess.parse_sess, None), + Some(ref cfg) => rustc_attr::cfg_matches(cfg, &sess.parse_sess, CRATE_NODE_ID, None), None => true, } } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 3fb56f42b8cca..a838787381d3f 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1338,7 +1338,7 @@ impl<'a> Linker for WasmLd<'a> { } // LLD will hide these otherwise-internal symbols since it only exports - // symbols explicity passed via the `--export` flags above and hides all + // symbols explicitly passed via the `--export` flags above and hides all // others. Various bits and pieces of tooling use this, so be sure these // symbols make their way out of the linker as well. self.cmd.arg("--export=__heap_base"); diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 77166c89735e4..14045ad7ff524 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -36,6 +36,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ // #[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_data_structures/src/sso/either_iter.rs b/compiler/rustc_data_structures/src/sso/either_iter.rs index af8ffcf4c13a5..131eeef4582de 100644 --- a/compiler/rustc_data_structures/src/sso/either_iter.rs +++ b/compiler/rustc_data_structures/src/sso/either_iter.rs @@ -7,7 +7,7 @@ use std::iter::Iterator; /// one of two specific implementations. /// /// Note: For most methods providing custom -/// implementation may margianlly +/// implementation may marginally /// improve performance by avoiding /// doing Left/Right match on every step /// and doing it only once instead. diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index c0d7bc359bf44..d43c6fec7d5ad 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -5,6 +5,7 @@ use rustc_ast::token::{DelimToken, Token, TokenKind}; use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree}; use rustc_ast::tokenstream::{DelimSpan, Spacing}; use rustc_ast::tokenstream::{LazyTokenStream, TokenTree}; +use rustc_ast::NodeId; use rustc_ast::{self as ast, AstLike, AttrStyle, Attribute, MetaItem}; use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; @@ -29,6 +30,7 @@ pub struct StripUnconfigured<'a> { /// This is only used for the input to derive macros, /// which needs eager expansion of `cfg` and `cfg_attr` pub config_tokens: bool, + pub lint_node_id: NodeId, } fn get_features( @@ -196,8 +198,13 @@ fn get_features( } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(sess: &Session, mut krate: ast::Crate) -> (ast::Crate, Features) { - let mut strip_unconfigured = StripUnconfigured { sess, features: None, config_tokens: false }; +pub fn features( + sess: &Session, + mut krate: ast::Crate, + lint_node_id: NodeId, +) -> (ast::Crate, Features) { + let mut strip_unconfigured = + StripUnconfigured { sess, features: None, config_tokens: false, lint_node_id }; let unconfigured_attrs = krate.attrs.clone(); let diag = &sess.parse_sess.span_diagnostic; @@ -353,7 +360,12 @@ impl<'a> StripUnconfigured<'a> { ); } - if !attr::cfg_matches(&cfg_predicate, &self.sess.parse_sess, self.features) { + if !attr::cfg_matches( + &cfg_predicate, + &self.sess.parse_sess, + self.lint_node_id, + self.features, + ) { return vec![]; } @@ -445,7 +457,7 @@ impl<'a> StripUnconfigured<'a> { } }; parse_cfg(&meta_item, &self.sess).map_or(true, |meta_item| { - attr::cfg_matches(&meta_item, &self.sess.parse_sess, self.features) + attr::cfg_matches(&meta_item, &self.sess.parse_sess, self.lint_node_id, self.features) }) } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index ab3951d768301..1b97618050939 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -551,11 +551,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // attribute is expanded. Therefore, we don't need to configure the tokens // Derive macros *can* see the results of cfg-expansion - they are handled // specially in `fully_expand_fragment` - cfg: StripUnconfigured { - sess: &self.cx.sess, - features: self.cx.ecfg.features, - config_tokens: false, - }, cx: self.cx, invocations: Vec::new(), monotonic: self.monotonic, @@ -1538,12 +1533,20 @@ impl InvocationCollectorNode for AstLikeWrapper, OptExprTag> { struct InvocationCollector<'a, 'b> { cx: &'a mut ExtCtxt<'b>, - cfg: StripUnconfigured<'a>, invocations: Vec<(Invocation, Option>)>, monotonic: bool, } impl<'a, 'b> InvocationCollector<'a, 'b> { + fn cfg(&self) -> StripUnconfigured<'_> { + StripUnconfigured { + sess: &self.cx.sess, + features: self.cx.ecfg.features, + config_tokens: false, + lint_node_id: self.cx.current_expansion.lint_node_id, + } + } + fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment { let expn_id = LocalExpnId::fresh_empty(); let vis = kind.placeholder_visibility(); @@ -1683,7 +1686,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { attr: ast::Attribute, pos: usize, ) -> bool { - let res = self.cfg.cfg_true(&attr); + let res = self.cfg().cfg_true(&attr); if res { // FIXME: `cfg(TRUE)` attributes do not currently remove themselves during expansion, // and some tools like rustdoc and clippy rely on that. Find a way to remove them @@ -1696,7 +1699,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn expand_cfg_attr(&self, node: &mut impl AstLike, attr: ast::Attribute, pos: usize) { node.visit_attrs(|attrs| { - attrs.splice(pos..pos, self.cfg.expand_cfg_attr(attr, false)); + attrs.splice(pos..pos, self.cfg().expand_cfg_attr(attr, false)); }); } @@ -1718,7 +1721,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { continue; } _ => { - Node::pre_flat_map_node_collect_attr(&self.cfg, &attr); + Node::pre_flat_map_node_collect_attr(&self.cfg(), &attr); self.collect_attr((attr, pos, derives), node.to_annotatable(), Node::KIND) .make_ast::() } @@ -1882,7 +1885,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { fn visit_expr(&mut self, node: &mut P) { // FIXME: Feature gating is performed inconsistently between `Expr` and `OptExpr`. if let Some(attr) = node.attrs.first() { - self.cfg.maybe_emit_expr_attr_err(attr); + self.cfg().maybe_emit_expr_attr_err(attr); } self.visit_node(node) } diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index d655f12f5e1d1..4c93d661fd2fd 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -50,7 +50,7 @@ impl DefPathTable { // Continuing with colliding DefPathHashes can lead to correctness // issues. We must abort compilation. // - // The likelyhood of such a collision is very small, so actually + // The likelihood of such a collision is very small, so actually // running into one could be indicative of a poor hash function // being used. // diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c0552fd200be8..951ae0ce2a4c7 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -2,6 +2,7 @@ use crate::interface::{Compiler, Result}; use crate::proc_macro_decls; use crate::util; +use ast::CRATE_NODE_ID; use rustc_ast::mut_visit::MutVisitor; use rustc_ast::{self as ast, visit}; use rustc_borrowck as mir_borrowck; @@ -188,7 +189,7 @@ pub fn register_plugins<'a>( ) }); - let (krate, features) = rustc_expand::config::features(sess, krate); + let (krate, features) = rustc_expand::config::features(sess, krate, CRATE_NODE_ID); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index dce1b35c6b889..7cdcb6a4ab302 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -1,3 +1,4 @@ +use rustc_ast::CRATE_NODE_ID; use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; @@ -21,7 +22,7 @@ crate fn collect(tcx: TyCtxt<'_>) -> Vec { crate fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None), + Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, CRATE_NODE_ID, None), None => true, } } diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs index 839d94167fecd..ef4b27a15d8b8 100644 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ b/compiler/rustc_mir_transform/src/const_debuginfo.rs @@ -55,10 +55,8 @@ fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Consta let mut locals_to_debuginfo = BitSet::new_empty(body.local_decls.len()); for debuginfo in &body.var_debug_info { - if let VarDebugInfoContents::Place(p) = debuginfo.value { - if let Some(l) = p.as_local() { - locals_to_debuginfo.insert(l); - } + if let VarDebugInfoContents::Place(p) = debuginfo.value && let Some(l) = p.as_local() { + locals_to_debuginfo.insert(l); } } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 6075f572a651c..c5ef1e101460f 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -633,24 +633,22 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn propagate_operand(&mut self, operand: &mut Operand<'tcx>) { match *operand { Operand::Copy(l) | Operand::Move(l) => { - if let Some(value) = self.get_const(l) { - if self.should_const_prop(&value) { - // FIXME(felix91gr): this code only handles `Scalar` cases. - // For now, we're not handling `ScalarPair` cases because - // doing so here would require a lot of code duplication. - // We should hopefully generalize `Operand` handling into a fn, - // and use it to do const-prop here and everywhere else - // where it makes sense. - if let interpret::Operand::Immediate(interpret::Immediate::Scalar( - ScalarMaybeUninit::Scalar(scalar), - )) = *value - { - *operand = self.operand_from_scalar( - scalar, - value.layout.ty, - self.source_info.unwrap().span, - ); - } + if let Some(value) = self.get_const(l) && self.should_const_prop(&value) { + // FIXME(felix91gr): this code only handles `Scalar` cases. + // For now, we're not handling `ScalarPair` cases because + // doing so here would require a lot of code duplication. + // We should hopefully generalize `Operand` handling into a fn, + // and use it to do const-prop here and everywhere else + // where it makes sense. + if let interpret::Operand::Immediate(interpret::Immediate::Scalar( + ScalarMaybeUninit::Scalar(scalar), + )) = *value + { + *operand = self.operand_from_scalar( + scalar, + value.layout.ty, + self.source_info.unwrap().span, + ); } } } @@ -1086,15 +1084,13 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> { // This will return None if the above `const_prop` invocation only "wrote" a // type whose creation requires no write. E.g. a generator whose initial state // consists solely of uninitialized memory (so it doesn't capture any locals). - if let Some(ref value) = self.get_const(place) { - if self.should_const_prop(value) { - trace!("replacing {:?} with {:?}", rval, value); - self.replace_with_const(rval, value, source_info); - if can_const_prop == ConstPropMode::FullConstProp - || can_const_prop == ConstPropMode::OnlyInsideOwnBlock - { - trace!("propagated into {:?}", place); - } + if let Some(ref value) = self.get_const(place) && self.should_const_prop(value) { + trace!("replacing {:?} with {:?}", rval, value); + self.replace_with_const(rval, value, source_info); + if can_const_prop == ConstPropMode::FullConstProp + || can_const_prop == ConstPropMode::OnlyInsideOwnBlock + { + trace!("propagated into {:?}", place); } } match can_const_prop { diff --git a/compiler/rustc_mir_transform/src/coverage/debug.rs b/compiler/rustc_mir_transform/src/coverage/debug.rs index 62e060c8e0c6c..8e28ed2426bbb 100644 --- a/compiler/rustc_mir_transform/src/coverage/debug.rs +++ b/compiler/rustc_mir_transform/src/coverage/debug.rs @@ -357,14 +357,12 @@ impl DebugCounters { if let Some(counters) = &self.some_counters { if let Some(DebugCounter { counter_kind, some_block_label }) = counters.get(&operand) { if let CoverageKind::Expression { .. } = counter_kind { - if let Some(block_label) = some_block_label { - if debug_options().counter_format.block { - return format!( - "{}:({})", - block_label, - self.format_counter_kind(counter_kind) - ); - } + if let Some(label) = some_block_label && debug_options().counter_format.block { + return format!( + "{}:({})", + label, + self.format_counter_kind(counter_kind) + ); } return format!("({})", self.format_counter_kind(counter_kind)); } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 27b9b6c2fa3e7..a36ba9300e4ff 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -191,16 +191,13 @@ impl CoverageSpan { /// If the span is part of a macro, and the macro is visible (expands directly to the given /// body_span), returns the macro name symbol. pub fn visible_macro(&self, body_span: Span) -> Option { - if let Some(current_macro) = self.current_macro() { - if self - .expn_span - .parent_callsite() - .unwrap_or_else(|| bug!("macro must have a parent")) - .ctxt() - == body_span.ctxt() - { - return Some(current_macro); - } + if let Some(current_macro) = self.current_macro() && self + .expn_span + .parent_callsite() + .unwrap_or_else(|| bug!("macro must have a parent")) + .ctxt() == body_span.ctxt() + { + return Some(current_macro); } None } @@ -584,21 +581,19 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { /// In either case, no more spans will match the span of `pending_dups`, so /// add the `pending_dups` if they don't overlap `curr`, and clear the list. fn check_pending_dups(&mut self) { - if let Some(dup) = self.pending_dups.last() { - if dup.span != self.prev().span { - debug!( - " SAME spans, but pending_dups are NOT THE SAME, so BCBs matched on \ - previous iteration, or prev started a new disjoint span" - ); - if dup.span.hi() <= self.curr().span.lo() { - let pending_dups = self.pending_dups.split_off(0); - for dup in pending_dups.into_iter() { - debug!(" ...adding at least one pending={:?}", dup); - self.push_refined_span(dup); - } - } else { - self.pending_dups.clear(); + if let Some(dup) = self.pending_dups.last() && dup.span != self.prev().span { + debug!( + " SAME spans, but pending_dups are NOT THE SAME, so BCBs matched on \ + previous iteration, or prev started a new disjoint span" + ); + if dup.span.hi() <= self.curr().span.lo() { + let pending_dups = self.pending_dups.split_off(0); + for dup in pending_dups.into_iter() { + debug!(" ...adding at least one pending={:?}", dup); + self.push_refined_span(dup); } + } else { + self.pending_dups.clear(); } } } diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 7878d6eaab123..5d0b58e9c5360 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -549,14 +549,15 @@ impl<'a> Conflicts<'a> { target: _, unwind: _, } => { - if let Some(place) = value.place() { - if !place.is_indirect() && !dropped_place.is_indirect() { - self.record_local_conflict( - place.local, - dropped_place.local, - "DropAndReplace operand overlap", - ); - } + if let Some(place) = value.place() + && !place.is_indirect() + && !dropped_place.is_indirect() + { + self.record_local_conflict( + place.local, + dropped_place.local, + "DropAndReplace operand overlap", + ); } } TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => { @@ -614,14 +615,15 @@ impl<'a> Conflicts<'a> { for op in operands { match op { InlineAsmOperand::In { reg: _, value } => { - if let Some(p) = value.place() { - if !p.is_indirect() && !dest_place.is_indirect() { - self.record_local_conflict( - p.local, - dest_place.local, - "asm! operand overlap", - ); - } + if let Some(p) = value.place() + && !p.is_indirect() + && !dest_place.is_indirect() + { + self.record_local_conflict( + p.local, + dest_place.local, + "asm! operand overlap", + ); } } InlineAsmOperand::Out { @@ -643,24 +645,26 @@ impl<'a> Conflicts<'a> { in_value, out_place, } => { - if let Some(place) = in_value.place() { - if !place.is_indirect() && !dest_place.is_indirect() { - self.record_local_conflict( - place.local, - dest_place.local, - "asm! operand overlap", - ); - } + if let Some(place) = in_value.place() + && !place.is_indirect() + && !dest_place.is_indirect() + { + self.record_local_conflict( + place.local, + dest_place.local, + "asm! operand overlap", + ); } - if let Some(place) = out_place { - if !place.is_indirect() && !dest_place.is_indirect() { - self.record_local_conflict( - place.local, - dest_place.local, - "asm! operand overlap", - ); - } + if let Some(place) = out_place + && !place.is_indirect() + && !dest_place.is_indirect() + { + self.record_local_conflict( + place.local, + dest_place.local, + "asm! operand overlap", + ); } } InlineAsmOperand::Out { reg: _, late: _, place: None } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index cbd7c7964d7f7..23e5f0b4f30c3 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -724,12 +724,11 @@ impl<'tcx> Inliner<'tcx> { caller_body: &mut Body<'tcx>, ) -> Local { // Reuse the operand if it is a moved temporary. - if let Operand::Move(place) = &arg { - if let Some(local) = place.as_local() { - if caller_body.local_kind(local) == LocalKind::Temp { - return local; - } - } + if let Operand::Move(place) = &arg + && let Some(local) = place.as_local() + && caller_body.local_kind(local) == LocalKind::Temp + { + return local; } // Otherwise, create a temporary for the argument. diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index 792ac68671efb..385fcc43496e3 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -77,10 +77,8 @@ impl<'tcx> InstCombineContext<'tcx, '_> { _ => None, }; - if let Some(new) = new { - if self.should_combine(source_info, rvalue) { - *rvalue = new; - } + if let Some(new) = new && self.should_combine(source_info, rvalue) { + *rvalue = new; } } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index c0c66daffa8e0..3b2332a6e3142 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,16 +1,17 @@ +#![allow(rustc::potential_query_instability)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] +#![feature(let_chains)] #![feature(let_else)] #![feature(map_try_insert)] #![feature(min_specialization)] -#![feature(option_get_or_insert_default)] -#![feature(once_cell)] #![feature(never_type)] +#![feature(once_cell)] +#![feature(option_get_or_insert_default)] #![feature(trusted_step)] #![feature(try_blocks)] #![recursion_limit = "256"] -#![allow(rustc::potential_query_instability)] #[macro_use] extern crate tracing; diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs index 1c48efd8b42cb..b87220a3aa4f3 100644 --- a/compiler/rustc_mir_transform/src/required_consts.rs +++ b/compiler/rustc_mir_transform/src/required_consts.rs @@ -14,10 +14,9 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) { - if let Some(ct) = constant.literal.const_for_ty() { - if let ConstKind::Unevaluated(_) = ct.val() { - self.required_consts.push(*constant); - } + let literal = constant.literal; + if let Some(ct) = literal.const_for_ty() && let ConstKind::Unevaluated(_) = ct.val() { + self.required_consts.push(*constant); } } } 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/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 855f900430c4a..d95bc9b15c9c4 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -149,6 +149,11 @@ pub trait CommandExt: Sealed { fn arg0(&mut self, arg: S) -> &mut process::Command where S: AsRef; + + /// Sets the process group ID of the child process. Translates to a `setpgid` call in the child + /// process. + #[unstable(feature = "process_set_process_group", issue = "93857")] + fn process_group(&mut self, pgroup: i32) -> &mut process::Command; } #[stable(feature = "rust1", since = "1.0.0")] @@ -201,6 +206,11 @@ impl CommandExt for process::Command { self.as_inner_mut().set_arg_0(arg.as_ref()); self } + + fn process_group(&mut self, pgroup: i32) -> &mut process::Command { + self.as_inner_mut().pgroup(pgroup); + self + } } /// Unix-specific extensions to [`process::ExitStatus`] and diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 97985ddd3316b..27bee714f5b43 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -18,7 +18,7 @@ use crate::sys_common::IntoInner; #[cfg(not(target_os = "fuchsia"))] use crate::sys::fs::OpenOptions; -use libc::{c_char, c_int, gid_t, uid_t, EXIT_FAILURE, EXIT_SUCCESS}; +use libc::{c_char, c_int, gid_t, pid_t, uid_t, EXIT_FAILURE, EXIT_SUCCESS}; cfg_if::cfg_if! { if #[cfg(target_os = "fuchsia")] { @@ -82,6 +82,7 @@ pub struct Command { stderr: Option, #[cfg(target_os = "linux")] create_pidfd: bool, + pgroup: Option, } // Create a new type for argv, so that we can make it `Send` and `Sync` @@ -145,6 +146,7 @@ impl Command { stdin: None, stdout: None, stderr: None, + pgroup: None, } } @@ -167,6 +169,7 @@ impl Command { stdout: None, stderr: None, create_pidfd: false, + pgroup: None, } } @@ -202,6 +205,9 @@ impl Command { pub fn groups(&mut self, groups: &[gid_t]) { self.groups = Some(Box::from(groups)); } + pub fn pgroup(&mut self, pgroup: pid_t) { + self.pgroup = Some(pgroup); + } #[cfg(target_os = "linux")] pub fn create_pidfd(&mut self, val: bool) { @@ -265,6 +271,10 @@ impl Command { pub fn get_groups(&self) -> Option<&[gid_t]> { self.groups.as_deref() } + #[allow(dead_code)] + pub fn get_pgroup(&self) -> Option { + self.pgroup + } pub fn get_closures(&mut self) -> &mut Vec io::Result<()> + Send + Sync>> { &mut self.closures diff --git a/library/std/src/sys/unix/process/process_common/tests.rs b/library/std/src/sys/unix/process/process_common/tests.rs index 10aa34e9443b7..73e9b2f9d75a9 100644 --- a/library/std/src/sys/unix/process/process_common/tests.rs +++ b/library/std/src/sys/unix/process/process_common/tests.rs @@ -67,3 +67,38 @@ fn test_process_mask() { t!(cat.wait()); } } + +#[test] +fn test_process_group_posix_spawn() { + unsafe { + // Spawn a cat subprocess that's just going to hang since there is no I/O. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.pgroup(0); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Check that we can kill its process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + +#[test] +fn test_process_group_no_posix_spawn() { + unsafe { + // Same as above, create hang-y cat. This time, force using the non-posix_spawnp path. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.pgroup(0); + cmd.pre_exec(Box::new(|| Ok(()))); // pre_exec forces fork + exec + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Check that we can kill its process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 9fc2d9fce4dc4..ebd16b2cc02ae 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -317,6 +317,10 @@ impl Command { cvt(libc::chdir(cwd.as_ptr()))?; } + if let Some(pgroup) = self.get_pgroup() { + cvt(libc::setpgid(0, pgroup))?; + } + // emscripten has no signal support. #[cfg(not(target_os = "emscripten"))] { @@ -456,6 +460,8 @@ impl Command { None => None, }; + let pgroup = self.get_pgroup(); + // Safety: -1 indicates we don't have a pidfd. let mut p = unsafe { Process::new(0, -1) }; @@ -484,6 +490,8 @@ impl Command { cvt_nz(libc::posix_spawnattr_init(attrs.as_mut_ptr()))?; let attrs = PosixSpawnattr(&mut attrs); + let mut flags = 0; + let mut file_actions = MaybeUninit::uninit(); cvt_nz(libc::posix_spawn_file_actions_init(file_actions.as_mut_ptr()))?; let file_actions = PosixSpawnFileActions(&mut file_actions); @@ -513,13 +521,18 @@ impl Command { cvt_nz(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?; } + if let Some(pgroup) = pgroup { + flags |= libc::POSIX_SPAWN_SETPGROUP; + cvt_nz(libc::posix_spawnattr_setpgroup(attrs.0.as_mut_ptr(), pgroup))?; + } + let mut set = MaybeUninit::::uninit(); cvt(sigemptyset(set.as_mut_ptr()))?; cvt_nz(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), set.as_ptr()))?; cvt(sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?; cvt_nz(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), set.as_ptr()))?; - let flags = libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK; + flags |= libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK; cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource diff --git a/src/test/ui/check-cfg/allow-macro-cfg.rs b/src/test/ui/check-cfg/allow-macro-cfg.rs new file mode 100644 index 0000000000000..8016a4d190cc3 --- /dev/null +++ b/src/test/ui/check-cfg/allow-macro-cfg.rs @@ -0,0 +1,14 @@ +// This test check that local #[allow(unexpected_cfgs)] works +// +// check-pass +// compile-flags:--check-cfg=names() -Z unstable-options + +#[allow(unexpected_cfgs)] +fn foo() { + if cfg!(FALSE) {} +} + +fn main() { + #[allow(unexpected_cfgs)] + if cfg!(FALSE) {} +} diff --git a/src/test/ui/check-cfg/allow-same-level.rs b/src/test/ui/check-cfg/allow-same-level.rs new file mode 100644 index 0000000000000..6c869dc420235 --- /dev/null +++ b/src/test/ui/check-cfg/allow-same-level.rs @@ -0,0 +1,11 @@ +// This test check that #[allow(unexpected_cfgs)] doesn't work if put on the same level +// +// check-pass +// compile-flags:--check-cfg=names() -Z unstable-options + +#[allow(unexpected_cfgs)] +#[cfg(FALSE)] +//~^ WARNING unexpected `cfg` condition name +fn bar() {} + +fn main() {} diff --git a/src/test/ui/check-cfg/allow-same-level.stderr b/src/test/ui/check-cfg/allow-same-level.stderr new file mode 100644 index 0000000000000..7797de584b9e1 --- /dev/null +++ b/src/test/ui/check-cfg/allow-same-level.stderr @@ -0,0 +1,10 @@ +warning: unexpected `cfg` condition name + --> $DIR/allow-same-level.rs:7:7 + | +LL | #[cfg(FALSE)] + | ^^^^^ + | + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/src/test/ui/check-cfg/allow-top-level.rs b/src/test/ui/check-cfg/allow-top-level.rs new file mode 100644 index 0000000000000..d14b0eae5ccdd --- /dev/null +++ b/src/test/ui/check-cfg/allow-top-level.rs @@ -0,0 +1,15 @@ +// This test check that a top-level #![allow(unexpected_cfgs)] works +// +// check-pass +// compile-flags:--check-cfg=names() -Z unstable-options + +#![allow(unexpected_cfgs)] + +#[cfg(FALSE)] +fn bar() {} + +fn foo() { + if cfg!(FALSE) {} +} + +fn main() {} diff --git a/src/test/ui/check-cfg/allow-upper-level.rs b/src/test/ui/check-cfg/allow-upper-level.rs new file mode 100644 index 0000000000000..04340694d9c1e --- /dev/null +++ b/src/test/ui/check-cfg/allow-upper-level.rs @@ -0,0 +1,12 @@ +// This test check that #[allow(unexpected_cfgs)] work if put on an upper level +// +// check-pass +// compile-flags:--check-cfg=names() -Z unstable-options + +#[allow(unexpected_cfgs)] +mod aa { + #[cfg(FALSE)] + fn bar() {} +} + +fn main() {}