diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index e9ace7088d8f0..8102208ec519d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -237,42 +237,39 @@ pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResu } EvalConfigResult::True } - CfgEntry::Any(subs, span) => { + CfgEntry::Any(subs, _) => { for sub in subs { let res = eval_config_entry(sess, sub); if res.as_bool() { return res; } } - EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } + EvalConfigResult::False { reason: cfg_entry.clone() } } - CfgEntry::Not(sub, span) => { + CfgEntry::Not(sub, _) => { if eval_config_entry(sess, sub).as_bool() { - EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } + EvalConfigResult::False { reason: cfg_entry.clone() } } else { EvalConfigResult::True } } - CfgEntry::Bool(b, span) => { + CfgEntry::Bool(b, _) => { if *b { EvalConfigResult::True } else { - EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } + EvalConfigResult::False { reason: cfg_entry.clone() } } } - CfgEntry::NameValue { name, value, span } => { + CfgEntry::NameValue { name, value, span: _ } => { if sess.config.contains(&(*name, *value)) { EvalConfigResult::True } else { - EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } + EvalConfigResult::False { reason: cfg_entry.clone() } } } - CfgEntry::Version(min_version, version_span) => { + CfgEntry::Version(min_version, _) => { let Some(min_version) = min_version else { - return EvalConfigResult::False { - reason: cfg_entry.clone(), - reason_span: *version_span, - }; + return EvalConfigResult::False { reason: cfg_entry.clone() }; }; // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details let min_version_ok = if sess.opts.unstable_opts.assume_incomplete_release { @@ -283,7 +280,7 @@ pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResu if min_version_ok { EvalConfigResult::True } else { - EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *version_span } + EvalConfigResult::False { reason: cfg_entry.clone() } } } } @@ -291,7 +288,7 @@ pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResu pub enum EvalConfigResult { True, - False { reason: CfgEntry, reason_span: Span }, + False { reason: CfgEntry }, } impl EvalConfigResult { diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs index 68de0a53e918b..4333559afb1c0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs @@ -15,7 +15,8 @@ use rustc_span::{ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::AttributeSafety; use crate::parser::{AllowExprMetavar, MetaItemOrLitParser}; use crate::{ - AttributeParser, AttributeTemplate, ParsedDescription, ShouldEmit, diagnostics, parse_cfg_entry, + AttributeParser, AttributeTemplate, EvalConfigResult, ParsedDescription, ShouldEmit, + diagnostics, parse_cfg_entry, }; #[derive(Clone)] @@ -49,11 +50,16 @@ impl CfgSelectBranches { /// or the wildcard if none of the reachable branches satisfied the predicate. pub fn pop_first_match(&mut self, predicate: F) -> Option<(CfgEntry, TokenStream, Span)> where - F: Fn(&CfgEntry) -> bool, + F: Fn(&CfgEntry) -> EvalConfigResult, { - for (index, (cfg, _, _)) in self.reachable.iter().enumerate() { - if predicate(cfg) { - return Some(self.reachable.remove(index)); + for (index, (cfg, _, _)) in self.reachable.iter_mut().enumerate() { + match predicate(cfg) { + EvalConfigResult::True => { + return Some(self.reachable.remove(index)); + } + EvalConfigResult::False { reason } => { + *cfg = reason; + } } } diff --git a/compiler/rustc_builtin_macros/src/cfg_select.rs b/compiler/rustc_builtin_macros/src/cfg_select.rs index 7202c56efed4e..69c3802ceafae 100644 --- a/compiler/rustc_builtin_macros/src/cfg_select.rs +++ b/compiler/rustc_builtin_macros/src/cfg_select.rs @@ -3,7 +3,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::{AttrKind, Expr, SyntheticAttr, ast}; use rustc_attr_ir::CfgEntry; use rustc_attr_parsing as attr; -use rustc_attr_parsing::{CfgSelectBranches, EvalConfigResult, parse_cfg_select}; +use rustc_attr_parsing::{CfgSelectBranches, parse_cfg_select}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacResult, MacroExpanderResult}; use rustc_expand::expand::DeclaredIdents; use rustc_span::{Ident, Span, sym}; @@ -129,9 +129,7 @@ pub(super) fn expand_cfg_select<'cx>( ) { Ok(mut branches) => { if let Some((cfg_entry, selected_tts, selected_span)) = - branches.pop_first_match(|cfg| { - matches!(attr::eval_config_entry(ecx.sess, cfg), EvalConfigResult::True) - }) + branches.pop_first_match(|cfg| attr::eval_config_entry(ecx.sess, cfg)) { let mac = CfgSelectResult { ecx, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 024ee2871b125..268011a50eb14 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2366,13 +2366,13 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { let res = self.expand_cfg_true(&mut node, attr, pos); match res { EvalConfigResult::True => continue, - EvalConfigResult::False { reason, reason_span } => { + EvalConfigResult::False { reason } => { for ident in node.declared_idents() { self.cx.resolver.append_stripped_cfg_item( self.cx.current_expansion.lint_node_id, ident, reason.clone(), - reason_span, + reason.span(), ) } } diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs deleted file mode 100644 index 1fdf827c14044..0000000000000 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ /dev/null @@ -1,226 +0,0 @@ -use rustc_abi::{HasDataLayout, Size, TagEncoding, Variants}; -use rustc_const_eval::interpret::{Scalar, alloc_range}; -use rustc_data_structures::fx::FxHashMap; -use rustc_middle::mir::interpret::AllocId; -use rustc_middle::mir::*; -use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; - -use crate::PassPolicy; -use crate::patch::MirPatch; - -/// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large -/// enough discrepancy between them. -/// -/// i.e. If there are two variants: -/// ``` -/// enum Example { -/// Small, -/// Large([u32; 1024]), -/// } -/// ``` -/// Instead of emitting moves of the large variant, perform a memcpy instead. -/// Based off of [this HackMD](https://hackmd.io/@ft4bxUsFT5CEUBmRKYHr7w/rJM8BBPzD). -/// -/// In summary, what this does is at runtime determine which enum variant is active, -/// and instead of copying all the bytes of the largest possible variant, -/// copy only the bytes for the currently active variant. The number of bytes to copy is determined -/// by a lookup table: a discriminant-indexed array indicating the size of each variant. -pub(super) struct EnumSizeOpt { - pub(crate) discrepancy: u64, -} - -impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { - fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy { - // There are some differences in behavior on wasm and ARM that are not properly - // understood, so we conservatively treat this optimization as unsound: - // https://github.com/rust-lang/rust/issues/154413 - PassPolicy::optional(ctx.mir_opt_level() >= 3 && ctx.opts.unstable_opts.unsound_mir_opts) - } - - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - // NOTE: This pass may produce different MIR based on the alignment of the target - // platform, but it will still be valid. - - let mut alloc_cache = FxHashMap::default(); - let typing_env = body.typing_env(tcx); - - let mut patch = MirPatch::new(body); - - for (block, data) in body.basic_blocks.as_mut().iter_enumerated_mut() { - for (statement_index, st) in data.statements.iter_mut().enumerate() { - let StatementKind::Assign(( - lhs, - Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs), _), - )) = &st.kind - else { - continue; - }; - - let location = Location { block, statement_index }; - - let ty = lhs.ty(&body.local_decls, tcx).ty; - - let Some((adt_def, num_variants, alloc_id)) = - self.candidate(tcx, typing_env, ty, &mut alloc_cache) - else { - continue; - }; - - let span = st.source_info.span; - - let tmp_ty = Ty::new_array(tcx, tcx.types.usize, num_variants as u64); - let size_array_local = patch.new_temp(tmp_ty, span); - - let store_live = StatementKind::StorageLive(size_array_local); - - let place = Place::from(size_array_local); - let constant_vals = ConstOperand { - span, - user_ty: None, - const_: Const::Val( - ConstValue::Indirect { alloc_id, offset: Size::ZERO }, - tmp_ty, - ), - }; - let rval = Rvalue::Use(Operand::Constant(Box::new(constant_vals)), WithRetag::No); - let const_assign = StatementKind::Assign(Box::new((place, rval))); - - let discr_place = - Place::from(patch.new_temp(adt_def.repr().discr_type().to_ty(tcx), span)); - let store_discr = - StatementKind::Assign(Box::new((discr_place, Rvalue::Discriminant(*rhs)))); - - let discr_cast_place = Place::from(patch.new_temp(tcx.types.usize, span)); - let cast_discr = StatementKind::Assign(Box::new(( - discr_cast_place, - Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr_place), tcx.types.usize), - ))); - - let size_place = Place::from(patch.new_temp(tcx.types.usize, span)); - let store_size = StatementKind::Assign(Box::new(( - size_place, - Rvalue::Use( - Operand::Copy(Place { - local: size_array_local, - projection: tcx - .mk_place_elems(&[PlaceElem::Index(discr_cast_place.local)]), - }), - WithRetag::No, - ), - ))); - - let dst = Place::from(patch.new_temp(Ty::new_mut_ptr(tcx, ty), span)); - let dst_ptr = - StatementKind::Assign(Box::new((dst, Rvalue::RawPtr(RawPtrKind::Mut, *lhs)))); - - let dst_cast_ty = Ty::new_mut_ptr(tcx, tcx.types.u8); - let dst_cast_place = Place::from(patch.new_temp(dst_cast_ty, span)); - let dst_cast = StatementKind::Assign(Box::new(( - dst_cast_place, - Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(dst), dst_cast_ty), - ))); - - let src = Place::from(patch.new_temp(Ty::new_imm_ptr(tcx, ty), span)); - let src_ptr = - StatementKind::Assign(Box::new((src, Rvalue::RawPtr(RawPtrKind::Const, *rhs)))); - - let src_cast_ty = Ty::new_imm_ptr(tcx, tcx.types.u8); - let src_cast_place = Place::from(patch.new_temp(src_cast_ty, span)); - let src_cast = StatementKind::Assign(Box::new(( - src_cast_place, - Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(src), src_cast_ty), - ))); - - let copy_bytes = StatementKind::Intrinsic(Box::new( - NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { - src: Operand::Copy(src_cast_place), - dst: Operand::Copy(dst_cast_place), - count: Operand::Copy(size_place), - }), - )); - - let store_dead = StatementKind::StorageDead(size_array_local); - - let stmts = [ - store_live, - const_assign, - store_discr, - cast_discr, - store_size, - dst_ptr, - dst_cast, - src_ptr, - src_cast, - copy_bytes, - store_dead, - ]; - for stmt in stmts { - patch.add_statement(location, stmt); - } - - st.make_nop(true); - } - } - - patch.apply(body); - } -} - -impl EnumSizeOpt { - fn candidate<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - ty: Ty<'tcx>, - alloc_cache: &mut FxHashMap, AllocId>, - ) -> Option<(AdtDef<'tcx>, usize, AllocId)> { - let adt_def = match ty.kind() { - ty::Adt(adt_def, _args) if adt_def.is_enum() => adt_def, - _ => return None, - }; - let layout = tcx.layout_of(typing_env.as_query_input(ty)).ok()?; - let variants = match &layout.variants { - Variants::Single { .. } | Variants::Empty => return None, - Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => return None, - - Variants::Multiple { variants, .. } if variants.len() <= 1 => return None, - Variants::Multiple { variants, .. } => variants, - }; - let min = variants.iter().map(|v| v.size).min().unwrap(); - let max = variants.iter().map(|v| v.size).max().unwrap(); - if max.bytes() - min.bytes() < self.discrepancy { - return None; - } - - let num_discrs = adt_def.discriminants(tcx).count(); - if variants.iter_enumerated().any(|(var_idx, _)| { - let discr_for_var = adt_def.discriminant_for_variant(tcx, var_idx).val; - (discr_for_var > usize::MAX as u128) || (discr_for_var as usize >= num_discrs) - }) { - return None; - } - if let Some(alloc_id) = alloc_cache.get(&ty) { - return Some((*adt_def, num_discrs, *alloc_id)); - } - - // Construct an in-memory array mapping discriminant idx to variant size. - let data_layout = tcx.data_layout(); - let ptr_size = data_layout.pointer_size(); - let mut alloc = interpret::Allocation::from_bytes( - vec![0; ptr_size.bytes_usize() * num_discrs], - tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, - Mutability::Mut, - (), - ); - for (var_idx, layout) in variants.iter_enumerated() { - let curr_idx = ptr_size * adt_def.discriminant_for_variant(tcx, var_idx).val as u64; - let val = Scalar::from_target_usize(layout.size.bytes(), &tcx); - alloc.write_scalar(&tcx, alloc_range(curr_idx, val.size()), val).unwrap(); - } - alloc.mutability = Mutability::Not; - let alloc = tcx.reserve_and_set_memory_alloc(tcx.mk_const_alloc(alloc)); - - Some((*adt_def, num_discrs, *alloc_cache.entry(ty).or_insert(alloc))) - } -} diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 6fdccad1505a5..283b963e732f9 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -159,7 +159,6 @@ declare_passes! { mod instsimplify : InstSimplify { BeforeInline, AfterSimplifyCfg }; mod jump_threading : JumpThreading; mod known_panics_lint : KnownPanicsLint; - mod large_enums : EnumSizeOpt; mod lint_and_remove_uninhabited : LintAndRemoveUninhabited; mod lower_intrinsics : LowerIntrinsics; mod lower_slice_len : LowerSliceLenCalls; @@ -763,7 +762,6 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<' &dest_prop::DestinationPropagation, &simplify::SimplifyLocals::Final, &multiple_return_terminators::MultipleReturnTerminators, - &large_enums::EnumSizeOpt { discrepancy: 128 }, // Some cleanup necessary at least for LLVM and potentially other codegen backends. &add_call_guards::CriticalCallEdges, // Cleanup for human readability, off by default. diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 8b770528a1736..d7354b8deccd8 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -135,11 +135,10 @@ //! entirely, but the Linux targets [use the kernel] to assist (which comes //! with a performance penalty). It's not until ARMv6K onwards that ARM CPUs //! have support for load/store and Compare and Swap (CAS) atomics in hardware. -//! * ARMv6-M and ARMv8-M baseline targets (`thumbv6m-*` and -//! `thumbv8m.base-*`) only provide `load` and `store` operations, and do +//! * ARMv6-M targets (`thumbv6m-*`) only provide `load` and `store` operations, and do //! not support Compare and Swap (CAS) operations, such as `swap`, //! `fetch_add`, etc. Full CAS support is available on ARMv7-M and ARMv8-M -//! Mainline (`thumbv7m-*`, `thumbv7em*` and `thumbv8m.main-*`). +//! (`thumbv7m-*`, `thumbv7em*`, `thumbv8m.base-*` and `thumbv8m.main-*`). //! //! [use the kernel]: https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt //! diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index 3761996f2069b..e371105ebdb01 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -328,7 +328,7 @@ fn calculate_jobs( } if jobs.len() > MAX_TRY_JOBS_COUNT && !nolimit { return Err(anyhow::anyhow!( - "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs expanded from {} pattern(s)", + "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs expanded from {} pattern(s). Use `@bors try jobs=... nolimit` to allow running an arbitrary number of try jobs.", jobs.len(), patterns.len() )); diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff deleted file mode 100644 index ea189cf2fb82d..0000000000000 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ /dev/null @@ -1,72 +0,0 @@ -- // MIR for `cand` before EnumSizeOpt -+ // MIR for `cand` after EnumSizeOpt - - fn cand() -> Candidate { - let mut _0: Candidate; - let mut _1: Candidate; - let mut _2: Candidate; - let mut _3: [u8; 8196]; -+ let mut _4: [usize; 2]; -+ let mut _5: isize; -+ let mut _6: usize; -+ let mut _7: usize; -+ let mut _8: *mut Candidate; -+ let mut _9: *mut u8; -+ let mut _10: *const Candidate; -+ let mut _11: *const u8; -+ let mut _12: [usize; 2]; -+ let mut _13: isize; -+ let mut _14: usize; -+ let mut _15: usize; -+ let mut _16: *mut Candidate; -+ let mut _17: *mut u8; -+ let mut _18: *const Candidate; -+ let mut _19: *const u8; - scope 1 { - debug a => _1; - } - - bb0: { - StorageLive(_1); - _1 = Candidate::Small(const 1_u8); - StorageLive(_2); - StorageLive(_3); - _3 = [const 1_u8; 8196]; - _2 = Candidate::Large(move _3); - StorageDead(_3); -- _1 = move _2; -+ StorageLive(_4); -+ _4 = no_retag const [2_usize, 8197_usize]; -+ _5 = discriminant(_2); -+ _6 = copy _5 as usize (IntToInt); -+ _7 = no_retag copy _4[_6]; -+ _8 = &raw mut _1; -+ _9 = copy _8 as *mut u8 (PtrToPtr); -+ _10 = &raw const _2; -+ _11 = copy _10 as *const u8 (PtrToPtr); -+ copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); -+ StorageDead(_4); -+ nop; - StorageDead(_2); -- _0 = move _1; -+ StorageLive(_12); -+ _12 = no_retag const [2_usize, 8197_usize]; -+ _13 = discriminant(_1); -+ _14 = copy _13 as usize (IntToInt); -+ _15 = no_retag copy _12[_14]; -+ _16 = &raw mut _0; -+ _17 = copy _16 as *mut u8 (PtrToPtr); -+ _18 = &raw const _1; -+ _19 = copy _18 as *const u8 (PtrToPtr); -+ copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); -+ StorageDead(_12); -+ nop; - StorageDead(_1); - return; - } -+ } -+ -+ ALLOC0 (size: 8, align: 4) { -+ 02 00 00 00 05 20 00 00 │ ..... .. - } - diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff deleted file mode 100644 index 6e46bdc8ed442..0000000000000 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ /dev/null @@ -1,72 +0,0 @@ -- // MIR for `cand` before EnumSizeOpt -+ // MIR for `cand` after EnumSizeOpt - - fn cand() -> Candidate { - let mut _0: Candidate; - let mut _1: Candidate; - let mut _2: Candidate; - let mut _3: [u8; 8196]; -+ let mut _4: [usize; 2]; -+ let mut _5: isize; -+ let mut _6: usize; -+ let mut _7: usize; -+ let mut _8: *mut Candidate; -+ let mut _9: *mut u8; -+ let mut _10: *const Candidate; -+ let mut _11: *const u8; -+ let mut _12: [usize; 2]; -+ let mut _13: isize; -+ let mut _14: usize; -+ let mut _15: usize; -+ let mut _16: *mut Candidate; -+ let mut _17: *mut u8; -+ let mut _18: *const Candidate; -+ let mut _19: *const u8; - scope 1 { - debug a => _1; - } - - bb0: { - StorageLive(_1); - _1 = Candidate::Small(const 1_u8); - StorageLive(_2); - StorageLive(_3); - _3 = [const 1_u8; 8196]; - _2 = Candidate::Large(move _3); - StorageDead(_3); -- _1 = move _2; -+ StorageLive(_4); -+ _4 = no_retag const [2_usize, 8197_usize]; -+ _5 = discriminant(_2); -+ _6 = copy _5 as usize (IntToInt); -+ _7 = no_retag copy _4[_6]; -+ _8 = &raw mut _1; -+ _9 = copy _8 as *mut u8 (PtrToPtr); -+ _10 = &raw const _2; -+ _11 = copy _10 as *const u8 (PtrToPtr); -+ copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); -+ StorageDead(_4); -+ nop; - StorageDead(_2); -- _0 = move _1; -+ StorageLive(_12); -+ _12 = no_retag const [2_usize, 8197_usize]; -+ _13 = discriminant(_1); -+ _14 = copy _13 as usize (IntToInt); -+ _15 = no_retag copy _12[_14]; -+ _16 = &raw mut _0; -+ _17 = copy _16 as *mut u8 (PtrToPtr); -+ _18 = &raw const _1; -+ _19 = copy _18 as *const u8 (PtrToPtr); -+ copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); -+ StorageDead(_12); -+ nop; - StorageDead(_1); - return; - } -+ } -+ -+ ALLOC0 (size: 16, align: 8) { -+ 02 00 00 00 00 00 00 00 05 20 00 00 00 00 00 00 │ ......... ...... - } - diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff deleted file mode 100644 index b627fd279071f..0000000000000 --- a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff +++ /dev/null @@ -1,28 +0,0 @@ -- // MIR for `invalid` before EnumSizeOpt -+ // MIR for `invalid` after EnumSizeOpt - - fn invalid() -> InvalidIdxs { - let mut _0: InvalidIdxs; - let mut _1: InvalidIdxs; - let mut _2: InvalidIdxs; - let mut _3: [u64; 1024]; - scope 1 { - debug a => _1; - } - - bb0: { - StorageLive(_1); - _1 = InvalidIdxs::A; - StorageLive(_2); - StorageLive(_3); - _3 = [const 0_u64; 1024]; - _2 = InvalidIdxs::Large(move _3); - StorageDead(_3); - _1 = move _2; - StorageDead(_2); - _0 = move _1; - StorageDead(_1); - return; - } - } - diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff deleted file mode 100644 index b627fd279071f..0000000000000 --- a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff +++ /dev/null @@ -1,28 +0,0 @@ -- // MIR for `invalid` before EnumSizeOpt -+ // MIR for `invalid` after EnumSizeOpt - - fn invalid() -> InvalidIdxs { - let mut _0: InvalidIdxs; - let mut _1: InvalidIdxs; - let mut _2: InvalidIdxs; - let mut _3: [u64; 1024]; - scope 1 { - debug a => _1; - } - - bb0: { - StorageLive(_1); - _1 = InvalidIdxs::A; - StorageLive(_2); - StorageLive(_3); - _3 = [const 0_u64; 1024]; - _2 = InvalidIdxs::Large(move _3); - StorageDead(_3); - _1 = move _2; - StorageDead(_2); - _0 = move _1; - StorageDead(_1); - return; - } - } - diff --git a/tests/mir-opt/enum_opt.rs b/tests/mir-opt/enum_opt.rs deleted file mode 100644 index 90697a71cdfc1..0000000000000 --- a/tests/mir-opt/enum_opt.rs +++ /dev/null @@ -1,86 +0,0 @@ -//@ skip-filecheck -//@ test-mir-pass: EnumSizeOpt -// EMIT_MIR_FOR_EACH_BIT_WIDTH -//@ compile-flags: -Zunsound-mir-opts -//@ ignore-endian-big - -// Tests that an enum with a variant with no data gets correctly transformed. -pub enum NoData { - Large([u8; 8196]), - None, -} - -// Tests that an enum with a variant with data that is a valid candidate gets transformed. -pub enum Candidate { - Small(u8), - Large([u8; 8196]), -} - -// Tests that an enum which has a discriminant much higher than the variant does not get -// tformed. -#[repr(u32)] -pub enum InvalidIdxs { - A = 302, - Large([u64; 1024]), -} - -// Tests that an enum with too high of a discriminant index (not in bounds of usize) does not -// get tformed. -#[repr(u128)] -pub enum NotTrunctable { - A = 0, - B([u8; 1024]) = 1, - C([u8; 4096]) = 0x10000000000000001, -} - -// Tests that an enum with discriminants in random order still gets tformed correctly. -#[repr(u32)] -pub enum RandOrderDiscr { - A = 13, - B([u8; 1024]) = 5, - C = 7, -} - -// EMIT_MIR enum_opt.unin.EnumSizeOpt.diff -pub fn unin() -> NoData { - let mut a = NoData::None; - a = NoData::Large([1; 8196]); - a -} - -// EMIT_MIR enum_opt.cand.EnumSizeOpt.diff -pub fn cand() -> Candidate { - let mut a = Candidate::Small(1); - a = Candidate::Large([1; 8196]); - a -} - -// EMIT_MIR enum_opt.invalid.EnumSizeOpt.diff -pub fn invalid() -> InvalidIdxs { - let mut a = InvalidIdxs::A; - a = InvalidIdxs::Large([0; 1024]); - a -} - -// EMIT_MIR enum_opt.trunc.EnumSizeOpt.diff -pub fn trunc() -> NotTrunctable { - let mut a = NotTrunctable::A; - a = NotTrunctable::B([0; 1024]); - a = NotTrunctable::C([0; 4096]); - a -} - -pub fn rand_order() -> RandOrderDiscr { - let mut a = RandOrderDiscr::A; - a = RandOrderDiscr::B([0; 1024]); - a = RandOrderDiscr::C; - a -} - -pub fn main() { - unin(); - cand(); - invalid(); - trunc(); - rand_order(); -} diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff deleted file mode 100644 index 100a73e56f22a..0000000000000 --- a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff +++ /dev/null @@ -1,37 +0,0 @@ -- // MIR for `trunc` before EnumSizeOpt -+ // MIR for `trunc` after EnumSizeOpt - - fn trunc() -> NotTrunctable { - let mut _0: NotTrunctable; - let mut _1: NotTrunctable; - let mut _2: NotTrunctable; - let mut _3: [u8; 1024]; - let mut _4: NotTrunctable; - let mut _5: [u8; 4096]; - scope 1 { - debug a => _1; - } - - bb0: { - StorageLive(_1); - _1 = NotTrunctable::A; - StorageLive(_2); - StorageLive(_3); - _3 = [const 0_u8; 1024]; - _2 = NotTrunctable::B(move _3); - StorageDead(_3); - _1 = move _2; - StorageDead(_2); - StorageLive(_4); - StorageLive(_5); - _5 = [const 0_u8; 4096]; - _4 = NotTrunctable::C(move _5); - StorageDead(_5); - _1 = move _4; - StorageDead(_4); - _0 = move _1; - StorageDead(_1); - return; - } - } - diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff deleted file mode 100644 index 100a73e56f22a..0000000000000 --- a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff +++ /dev/null @@ -1,37 +0,0 @@ -- // MIR for `trunc` before EnumSizeOpt -+ // MIR for `trunc` after EnumSizeOpt - - fn trunc() -> NotTrunctable { - let mut _0: NotTrunctable; - let mut _1: NotTrunctable; - let mut _2: NotTrunctable; - let mut _3: [u8; 1024]; - let mut _4: NotTrunctable; - let mut _5: [u8; 4096]; - scope 1 { - debug a => _1; - } - - bb0: { - StorageLive(_1); - _1 = NotTrunctable::A; - StorageLive(_2); - StorageLive(_3); - _3 = [const 0_u8; 1024]; - _2 = NotTrunctable::B(move _3); - StorageDead(_3); - _1 = move _2; - StorageDead(_2); - StorageLive(_4); - StorageLive(_5); - _5 = [const 0_u8; 4096]; - _4 = NotTrunctable::C(move _5); - StorageDead(_5); - _1 = move _4; - StorageDead(_4); - _0 = move _1; - StorageDead(_1); - return; - } - } - diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff deleted file mode 100644 index c8d615383c0c3..0000000000000 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ /dev/null @@ -1,72 +0,0 @@ -- // MIR for `unin` before EnumSizeOpt -+ // MIR for `unin` after EnumSizeOpt - - fn unin() -> NoData { - let mut _0: NoData; - let mut _1: NoData; - let mut _2: NoData; - let mut _3: [u8; 8196]; -+ let mut _4: [usize; 2]; -+ let mut _5: isize; -+ let mut _6: usize; -+ let mut _7: usize; -+ let mut _8: *mut NoData; -+ let mut _9: *mut u8; -+ let mut _10: *const NoData; -+ let mut _11: *const u8; -+ let mut _12: [usize; 2]; -+ let mut _13: isize; -+ let mut _14: usize; -+ let mut _15: usize; -+ let mut _16: *mut NoData; -+ let mut _17: *mut u8; -+ let mut _18: *const NoData; -+ let mut _19: *const u8; - scope 1 { - debug a => _1; - } - - bb0: { - StorageLive(_1); - _1 = NoData::None; - StorageLive(_2); - StorageLive(_3); - _3 = [const 1_u8; 8196]; - _2 = NoData::Large(move _3); - StorageDead(_3); -- _1 = move _2; -+ StorageLive(_4); -+ _4 = no_retag const [8197_usize, 1_usize]; -+ _5 = discriminant(_2); -+ _6 = copy _5 as usize (IntToInt); -+ _7 = no_retag copy _4[_6]; -+ _8 = &raw mut _1; -+ _9 = copy _8 as *mut u8 (PtrToPtr); -+ _10 = &raw const _2; -+ _11 = copy _10 as *const u8 (PtrToPtr); -+ copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); -+ StorageDead(_4); -+ nop; - StorageDead(_2); -- _0 = move _1; -+ StorageLive(_12); -+ _12 = no_retag const [8197_usize, 1_usize]; -+ _13 = discriminant(_1); -+ _14 = copy _13 as usize (IntToInt); -+ _15 = no_retag copy _12[_14]; -+ _16 = &raw mut _0; -+ _17 = copy _16 as *mut u8 (PtrToPtr); -+ _18 = &raw const _1; -+ _19 = copy _18 as *const u8 (PtrToPtr); -+ copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); -+ StorageDead(_12); -+ nop; - StorageDead(_1); - return; - } -+ } -+ -+ ALLOC0 (size: 8, align: 4) { -+ 05 20 00 00 01 00 00 00 │ . ...... - } - diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff deleted file mode 100644 index e25644d7a4383..0000000000000 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ /dev/null @@ -1,72 +0,0 @@ -- // MIR for `unin` before EnumSizeOpt -+ // MIR for `unin` after EnumSizeOpt - - fn unin() -> NoData { - let mut _0: NoData; - let mut _1: NoData; - let mut _2: NoData; - let mut _3: [u8; 8196]; -+ let mut _4: [usize; 2]; -+ let mut _5: isize; -+ let mut _6: usize; -+ let mut _7: usize; -+ let mut _8: *mut NoData; -+ let mut _9: *mut u8; -+ let mut _10: *const NoData; -+ let mut _11: *const u8; -+ let mut _12: [usize; 2]; -+ let mut _13: isize; -+ let mut _14: usize; -+ let mut _15: usize; -+ let mut _16: *mut NoData; -+ let mut _17: *mut u8; -+ let mut _18: *const NoData; -+ let mut _19: *const u8; - scope 1 { - debug a => _1; - } - - bb0: { - StorageLive(_1); - _1 = NoData::None; - StorageLive(_2); - StorageLive(_3); - _3 = [const 1_u8; 8196]; - _2 = NoData::Large(move _3); - StorageDead(_3); -- _1 = move _2; -+ StorageLive(_4); -+ _4 = no_retag const [8197_usize, 1_usize]; -+ _5 = discriminant(_2); -+ _6 = copy _5 as usize (IntToInt); -+ _7 = no_retag copy _4[_6]; -+ _8 = &raw mut _1; -+ _9 = copy _8 as *mut u8 (PtrToPtr); -+ _10 = &raw const _2; -+ _11 = copy _10 as *const u8 (PtrToPtr); -+ copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); -+ StorageDead(_4); -+ nop; - StorageDead(_2); -- _0 = move _1; -+ StorageLive(_12); -+ _12 = no_retag const [8197_usize, 1_usize]; -+ _13 = discriminant(_1); -+ _14 = copy _13 as usize (IntToInt); -+ _15 = no_retag copy _12[_14]; -+ _16 = &raw mut _0; -+ _17 = copy _16 as *mut u8 (PtrToPtr); -+ _18 = &raw const _1; -+ _19 = copy _18 as *const u8 (PtrToPtr); -+ copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); -+ StorageDead(_12); -+ nop; - StorageDead(_1); - return; - } -+ } -+ -+ ALLOC0 (size: 16, align: 8) { -+ 05 20 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ . .............. - } - diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 0f03a8a99c4fb..0d5fcec971550 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -1,3 +1,4 @@ +//@ compile-flags: --check-cfg 'cfg(feature, values("meow"))' #![crate_type = "lib"] #![warn(unreachable_cfg_select_predicates)] // Unused warnings are disabled by default in UI tests. @@ -251,3 +252,31 @@ cfg_select! { debug_assertions => {} _ => {} } + +cfg_select! { + all(true, false) => { + struct Thing1; + } + _ => {} +} + +cfg_select! { + feature = "meow" => { + struct Thing2; + } + _ => {} +} + +cfg_select! { + all(true, feature = "meow") => { + struct Thing2; + } + _ => {} +} + +fn usages() { + let t1: Thing1; + //~^ ERROR cannot find type `Thing1` in this scope [E0425] + let t2: Thing2; + //~^ ERROR cannot find type `Thing2` in this scope [E0425] +} diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 8e09aa4da93f3..9af74456367f2 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -1,5 +1,5 @@ error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:161:1 + --> $DIR/cfg_select.rs:162:1 | LL | / cfg_select! { LL | | @@ -8,73 +8,73 @@ LL | | } | |_^ error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:166:1 + --> $DIR/cfg_select.rs:167:1 | LL | cfg_select! {} | ^^^^^^^^^^^^^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `=>` - --> $DIR/cfg_select.rs:170:5 + --> $DIR/cfg_select.rs:171:5 | LL | => {} | ^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression - --> $DIR/cfg_select.rs:175:5 + --> $DIR/cfg_select.rs:176:5 | LL | () => {} | ^^ expressions are not allowed here error[E0565]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:180:5 + --> $DIR/cfg_select.rs:181:5 | LL | "str" => {} | ^^^^^ expected a valid identifier here error[E0565]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:185:5 + --> $DIR/cfg_select.rs:186:5 | LL | a::b => {} | ^^^^ expected a valid identifier here error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:190:5 + --> $DIR/cfg_select.rs:191:5 | LL | a() => {} | ^^^ valid arguments are `any`, `all`, `not` or `target` error: expected one of `(`, `::`, `=>`, or `=`, found `+` - --> $DIR/cfg_select.rs:195:7 + --> $DIR/cfg_select.rs:196:7 | LL | a + 1 => {} | ^ expected one of `(`, `::`, `=>`, or `=` error: expected one of `(`, `::`, `=>`, or `=`, found `!` - --> $DIR/cfg_select.rs:201:8 + --> $DIR/cfg_select.rs:202:8 | LL | cfg!() => {} | ^ expected one of `(`, `::`, `=>`, or `=` error: doc comments are not allowed on `cfg_select` branches - --> $DIR/cfg_select.rs:208:5 + --> $DIR/cfg_select.rs:209:5 | LL | /// doc comment | ^^^^^^^^^^^^^^^ error: doc comments are not allowed on `cfg_select` branches - --> $DIR/cfg_select.rs:211:5 + --> $DIR/cfg_select.rs:212:5 | LL | /// doc comment | ^^^^^^^^^^^^^^^ error: attributes are not allowed on `cfg_select` branches - --> $DIR/cfg_select.rs:217:5 + --> $DIR/cfg_select.rs:218:5 | LL | #[cfg(false)] | ^^^^^^^^^^^^^ error: an inner attribute is not permitted in this context - --> $DIR/cfg_select.rs:224:5 + --> $DIR/cfg_select.rs:225:5 | LL | #![cfg(false)] | ^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | #![cfg(false)] = note: outer attributes, like `#[test]`, annotate the item following them error[E0753]: expected outer doc comment - --> $DIR/cfg_select.rs:231:5 + --> $DIR/cfg_select.rs:232:5 | LL | //! inner doc comment | ^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL + // inner doc comment | error: doc comments are not allowed on `cfg_select` branches - --> $DIR/cfg_select.rs:239:5 + --> $DIR/cfg_select.rs:240:5 | LL | /// line1 | ^^^^^^^^^ @@ -105,7 +105,7 @@ LL | /// line3 | ^^^^^^^^^ error[E0753]: expected outer doc comment - --> $DIR/cfg_select.rs:249:5 + --> $DIR/cfg_select.rs:250:5 | LL | //! inner doc comment | ^^^^^^^^^^^^^^^^^^^^^ @@ -118,13 +118,48 @@ LL + // inner doc comment | error: doc comments are not allowed on `cfg_select` branches - --> $DIR/cfg_select.rs:247:5 + --> $DIR/cfg_select.rs:248:5 | LL | /// outer doc comment | ^^^^^^^^^^^^^^^^^^^^^ +error[E0425]: cannot find type `Thing1` in this scope + --> $DIR/cfg_select.rs:278:13 + | +LL | let t1: Thing1; + | ^^^^^^ not found in this scope + | +note: found an item that was configured out + --> $DIR/cfg_select.rs:258:16 + | +LL | all(true, false) => { + | ----- the item is gated here +LL | struct Thing1; + | ^^^^^^ + +error[E0425]: cannot find type `Thing2` in this scope + --> $DIR/cfg_select.rs:280:13 + | +LL | let t2: Thing2; + | ^^^^^^ not found in this scope + | +note: found an item that was configured out + --> $DIR/cfg_select.rs:265:16 + | +LL | feature = "meow" => { + | ---------------- the item is gated behind the `meow` feature +LL | struct Thing2; + | ^^^^^^ +note: found an item that was configured out + --> $DIR/cfg_select.rs:272:16 + | +LL | all(true, feature = "meow") => { + | ---------------- the item is gated behind the `meow` feature +LL | struct Thing2; + | ^^^^^^ + warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:136:5 + --> $DIR/cfg_select.rs:137:5 | LL | _ => {} | - always matches @@ -132,13 +167,13 @@ LL | true => {} | ^^^^ this configuration predicate is never reached | note: the lint level is defined here - --> $DIR/cfg_select.rs:2:9 + --> $DIR/cfg_select.rs:3:9 | LL | #![warn(unreachable_cfg_select_predicates)] // Unused warnings are disabled by default in UI tests. | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:142:5 + --> $DIR/cfg_select.rs:143:5 | LL | true => {} | ---- always matches @@ -146,36 +181,36 @@ LL | _ => {} | ^ this configuration predicate is never reached warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:149:5 + --> $DIR/cfg_select.rs:150:5 | LL | _ => {} | ^ this configuration predicate is never reached warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:155:5 + --> $DIR/cfg_select.rs:156:5 | LL | test => {} | ^^^^ this configuration predicate is never reached warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:157:5 + --> $DIR/cfg_select.rs:158:5 | LL | _ => {} | ^ this configuration predicate is never reached warning: unexpected `cfg` condition name: `a` - --> $DIR/cfg_select.rs:195:5 + --> $DIR/cfg_select.rs:196:5 | LL | a + 1 => {} | ^ help: found config with similar value: `target_feature = "a"` | - = help: expected names are: `FALSE` and `test` and 34 more + = help: expected names are: `FALSE`, `feature`, and `test` and 34 more = help: to expect this configuration use `--check-cfg=cfg(a)` = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `cfg` - --> $DIR/cfg_select.rs:201:5 + --> $DIR/cfg_select.rs:202:5 | LL | cfg!() => {} | ^^^ @@ -183,7 +218,7 @@ LL | cfg!() => {} = help: to expect this configuration use `--check-cfg=cfg(cfg)` = note: see for more information about checking conditional configuration -error: aborting due to 17 previous errors; 7 warnings emitted +error: aborting due to 19 previous errors; 7 warnings emitted -Some errors have detailed explanations: E0539, E0565, E0753. -For more information about an error, try `rustc --explain E0539`. +Some errors have detailed explanations: E0425, E0539, E0565, E0753. +For more information about an error, try `rustc --explain E0425`.