diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 5759eb2991a81..1557630fc7afd 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -16,7 +16,9 @@ use crate::ModuleLlvm; use log::debug; use rustc::bug; use rustc::ty::TyCtxt; -use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, EmbedBitcode, ModuleConfig}; +use rustc_codegen_ssa::back::write::{ + run_assembler, BitcodeSection, CodegenContext, EmitObj, ModuleConfig, +}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION}; use rustc_data_structures::small_c_str::SmallCStr; @@ -651,7 +653,7 @@ pub(crate) unsafe fn codegen( let thin = ThinBuffer::new(llmod); let data = thin.data(); - if config.emit_bc || config.obj_is_bitcode { + if config.emit_bc || config.emit_obj == EmitObj::Bitcode { let _timer = cgcx.prof.generic_activity_with_arg( "LLVM_module_codegen_emit_bitcode", &module.name[..], @@ -662,7 +664,7 @@ pub(crate) unsafe fn codegen( } } - if config.embed_bitcode == EmbedBitcode::Full { + if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { let _timer = cgcx.prof.generic_activity_with_arg( "LLVM_module_codegen_embed_bitcode", &module.name[..], @@ -682,7 +684,7 @@ pub(crate) unsafe fn codegen( diag_handler.err(&msg); } } - } else if config.embed_bitcode == EmbedBitcode::Marker { + } else if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Marker) { embed_bitcode(cgcx, llcx, llmod, None); } @@ -732,9 +734,9 @@ pub(crate) unsafe fn codegen( })?; } - let config_emit_normal_obj = config.emit_obj && !config.obj_is_bitcode; + let config_emit_object_code = matches!(config.emit_obj, EmitObj::ObjectCode(_)); - if config.emit_asm || (config_emit_normal_obj && config.no_integrated_as) { + if config.emit_asm || (config_emit_object_code && config.no_integrated_as) { let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]); @@ -743,60 +745,65 @@ pub(crate) unsafe fn codegen( // We can't use the same module for asm and binary output, because that triggers // various errors like invalid IR or broken binaries, so we might have to clone the // module to produce the asm output - let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod }; + let llmod = if config_emit_object_code { llvm::LLVMCloneModule(llmod) } else { llmod }; with_codegen(tm, llmod, config.no_builtins, |cpm| { write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile) })?; } - if config_emit_normal_obj { - if !config.no_integrated_as { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); - with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file( - diag_handler, - tm, - cpm, - llmod, - &obj_out, - llvm::FileType::ObjectFile, - ) - })?; - } else { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]); - let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - run_assembler(cgcx, diag_handler, &assembly, &obj_out); - - if !config.emit_asm && !cgcx.save_temps { - drop(fs::remove_file(&assembly)); + match config.emit_obj { + EmitObj::ObjectCode(_) => { + if !config.no_integrated_as { + let _timer = cgcx.prof.generic_activity_with_arg( + "LLVM_module_codegen_emit_obj", + &module.name[..], + ); + with_codegen(tm, llmod, config.no_builtins, |cpm| { + write_output_file( + diag_handler, + tm, + cpm, + llmod, + &obj_out, + llvm::FileType::ObjectFile, + ) + })?; + } else { + let _timer = cgcx.prof.generic_activity_with_arg( + "LLVM_module_codegen_asm_to_obj", + &module.name[..], + ); + let assembly = + cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); + run_assembler(cgcx, diag_handler, &assembly, &obj_out); + + if !config.emit_asm && !cgcx.save_temps { + drop(fs::remove_file(&assembly)); + } } } - } - if config.obj_is_bitcode { - if config.emit_obj { + EmitObj::Bitcode => { debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out); if let Err(e) = link_or_copy(&bc_out, &obj_out) { diag_handler.err(&format!("failed to copy bitcode to object file: {}", e)); } - } - if !config.emit_bc { - debug!("removing_bitcode {:?}", bc_out); - if let Err(e) = fs::remove_file(&bc_out) { - diag_handler.err(&format!("failed to remove bitcode: {}", e)); + if !config.emit_bc { + debug!("removing_bitcode {:?}", bc_out); + if let Err(e) = fs::remove_file(&bc_out) { + diag_handler.err(&format!("failed to remove bitcode: {}", e)); + } } } + + EmitObj::None => {} } drop(handlers); } Ok(module.into_compiled_module( - config.emit_obj, + config.emit_obj != EmitObj::None, config.emit_bc, config.emit_bc_compressed, &cgcx.output_filenames, diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index a4b5acdcd18a2..e9b3bf026b2ba 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -51,11 +51,31 @@ use std::thread; const PRE_LTO_BC_EXT: &str = "pre-lto.bc"; -/// The kind of bitcode to embed in object files. -#[derive(PartialEq)] -pub enum EmbedBitcode { +/// What kind of object file to emit. +#[derive(Clone, Copy, PartialEq)] +pub enum EmitObj { + // No object file. None, + + // Just uncompressed llvm bitcode. Provides easy compatibility with + // emscripten's ecc compiler, when used as the linker. + Bitcode, + + // Object code, possibly augmented with a bitcode section. + ObjectCode(BitcodeSection), +} + +/// What kind of llvm bitcode section to embed in an object file. +#[derive(Clone, Copy, PartialEq)] +pub enum BitcodeSection { + // No bitcode section. + None, + + // An empty bitcode section (to placate tools such as the iOS linker that + // require this section even if they don't use it). Marker, + + // A full, uncompressed bitcode section. Full, } @@ -84,7 +104,7 @@ pub struct ModuleConfig { pub emit_bc_compressed: bool, pub emit_ir: bool, pub emit_asm: bool, - pub emit_obj: bool, + pub emit_obj: EmitObj, // Miscellaneous flags. These are mostly copied from command-line // options. pub verify_llvm_ir: bool, @@ -96,12 +116,7 @@ pub struct ModuleConfig { pub merge_functions: bool, pub inline_threshold: Option, pub new_llvm_pass_manager: Option, - // Instead of creating an object file by doing LLVM codegen, just - // make the object file bitcode. Provides easy compatibility with - // emscripten's ecc compiler, when used as the linker. - pub obj_is_bitcode: bool, pub no_integrated_as: bool, - pub embed_bitcode: EmbedBitcode, } impl ModuleConfig { @@ -124,9 +139,7 @@ impl ModuleConfig { emit_bc_compressed: false, emit_ir: false, emit_asm: false, - emit_obj: false, - obj_is_bitcode: false, - embed_bitcode: EmbedBitcode::None, + emit_obj: EmitObj::None, no_integrated_as: false, verify_llvm_ir: false, @@ -147,17 +160,6 @@ impl ModuleConfig { self.no_builtins = no_builtins || sess.target.target.options.no_builtins; self.inline_threshold = sess.opts.cg.inline_threshold; self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager; - self.obj_is_bitcode = - sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled(); - self.embed_bitcode = - if sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode { - match sess.opts.optimize { - config::OptLevel::No | config::OptLevel::Less => EmbedBitcode::Marker, - _ => EmbedBitcode::Full, - } - } else { - EmbedBitcode::None - }; // Copy what clang does by turning on loop vectorization at O2 and // slp vectorization at O3. Otherwise configure other optimization aspects @@ -194,9 +196,9 @@ impl ModuleConfig { pub fn bitcode_needed(&self) -> bool { self.emit_bc - || self.obj_is_bitcode || self.emit_bc_compressed - || self.embed_bitcode == EmbedBitcode::Full + || self.emit_obj == EmitObj::Bitcode + || self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) } } @@ -397,6 +399,20 @@ pub fn start_async_codegen( allocator_config.emit_bc_compressed = true; } + let emit_obj = + if sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() { + EmitObj::Bitcode + } else if sess.opts.debugging_opts.embed_bitcode { + match sess.opts.optimize { + config::OptLevel::No | config::OptLevel::Less => { + EmitObj::ObjectCode(BitcodeSection::Marker) + } + _ => EmitObj::ObjectCode(BitcodeSection::Full), + } + } else { + EmitObj::ObjectCode(BitcodeSection::None) + }; + modules_config.emit_pre_lto_bc = need_pre_lto_bitcode_for_incr_comp(sess); modules_config.no_integrated_as = @@ -416,20 +432,20 @@ pub fn start_async_codegen( // could be invoked specially with output_type_assembly, so // in this case we still want the metadata object file. if !sess.opts.output_types.contains_key(&OutputType::Assembly) { - metadata_config.emit_obj = true; - allocator_config.emit_obj = true; + metadata_config.emit_obj = emit_obj; + allocator_config.emit_obj = emit_obj; } } OutputType::Object => { - modules_config.emit_obj = true; + modules_config.emit_obj = emit_obj; } OutputType::Metadata => { - metadata_config.emit_obj = true; + metadata_config.emit_obj = emit_obj; } OutputType::Exe => { - modules_config.emit_obj = true; - metadata_config.emit_obj = true; - allocator_config.emit_obj = true; + modules_config.emit_obj = emit_obj; + metadata_config.emit_obj = emit_obj; + allocator_config.emit_obj = emit_obj; } OutputType::Mir => {} OutputType::DepInfo => {} @@ -880,7 +896,7 @@ fn execute_copy_from_cache_work_item( } } - assert_eq!(object.is_some(), module_config.emit_obj); + assert_eq!(object.is_some(), module_config.emit_obj != EmitObj::None); assert_eq!(bytecode.is_some(), module_config.emit_bc); assert_eq!(bytecode_compressed.is_some(), module_config.emit_bc_compressed); diff --git a/src/librustc_error_codes/error_codes/E0459.md b/src/librustc_error_codes/error_codes/E0459.md index 580cbf1e1c6ed..6f75f2a99a563 100644 --- a/src/librustc_error_codes/error_codes/E0459.md +++ b/src/librustc_error_codes/error_codes/E0459.md @@ -1,4 +1,6 @@ -A link was used without a name parameter. Erroneous code example: +A link was used without a name parameter. + +Erroneous code example: ```compile_fail,E0459 #[link(kind = "dylib")] extern {} diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index f7327825ca4b7..24176427ba526 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -229,6 +229,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // float -> uint Uint(t) => { let width = t.bit_width().unwrap_or_else(|| self.pointer_size().bits()); + // `to_u128` is a saturating cast, which is what we need + // (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r). let v = f.to_u128(usize::try_from(width).unwrap()).value; // This should already fit the bit width Ok(Scalar::from_uint(v, Size::from_bits(width))) @@ -236,6 +238,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // float -> int Int(t) => { let width = t.bit_width().unwrap_or_else(|| self.pointer_size().bits()); + // `to_i128` is a saturating cast, which is what we need + // (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r). let v = f.to_i128(usize::try_from(width).unwrap()).value; Ok(Scalar::from_int(v, Size::from_bits(width))) } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 8437399752e29..7b6de4b0726c1 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -833,17 +833,57 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ptr: Scalar, src: impl IntoIterator, ) -> InterpResult<'tcx> { - let src = src.into_iter(); + let mut src = src.into_iter(); let size = Size::from_bytes(src.size_hint().0); // `write_bytes` checks that this lower bound `size` matches the upper bound and reality. let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? { Some(ptr) => ptr, - None => return Ok(()), // zero-sized access + None => { + // zero-sized access + src.next().expect_none("iterator said it was empty but returned an element"); + return Ok(()); + } }; let tcx = self.tcx.tcx; self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src) } + /// Writes the given stream of u16s into memory. + /// + /// Performs appropriate bounds checks. + pub fn write_u16s( + &mut self, + ptr: Scalar, + src: impl IntoIterator, + ) -> InterpResult<'tcx> { + let mut src = src.into_iter(); + let (lower, upper) = src.size_hint(); + let len = upper.expect("can only write bounded iterators"); + assert_eq!(lower, len, "can only write iterators with a precise length"); + + let size = Size::from_bytes(lower); + let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(2).unwrap())? { + Some(ptr) => ptr, + None => { + // zero-sized access + src.next().expect_none("iterator said it was empty but returned an element"); + return Ok(()); + } + }; + let tcx = self.tcx.tcx; + let allocation = self.get_raw_mut(ptr.alloc_id)?; + + for idx in 0..len { + let val = Scalar::from_u16( + src.next().expect("iterator was shorter than it said it would be"), + ); + let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication + allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?; + } + src.next().expect_none("iterator was longer than it said it would be"); + Ok(()) + } + /// Expects the caller to have checked bounds and alignment. pub fn copy( &mut self, diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 7d3aba3ff034e..85e44adc30b86 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust. #![feature(range_is_empty)] #![feature(stmt_expr_attributes)] #![feature(trait_alias)] +#![feature(option_expect_none)] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs index 76fcbf326fa78..5c69cea8b9169 100644 --- a/src/librustc_mir_build/hair/pattern/_match.rs +++ b/src/librustc_mir_build/hair/pattern/_match.rs @@ -1619,12 +1619,17 @@ impl<'tcx> fmt::Debug for MissingConstructors<'tcx> { /// relation to preceding patterns, it is not reachable) and exhaustiveness /// checking (if a wildcard pattern is useful in relation to a matrix, the /// matrix isn't exhaustive). +/// +/// `is_under_guard` is used to inform if the pattern has a guard. If it +/// has one it must not be inserted into the matrix. This shouldn't be +/// relied on for soundness. crate fn is_useful<'p, 'tcx>( cx: &mut MatchCheckCtxt<'p, 'tcx>, matrix: &Matrix<'p, 'tcx>, v: &PatStack<'p, 'tcx>, witness_preference: WitnessPreference, hir_id: HirId, + is_under_guard: bool, is_top_level: bool, ) -> Usefulness<'tcx, 'p> { let &Matrix(ref rows) = matrix; @@ -1653,7 +1658,7 @@ crate fn is_useful<'p, 'tcx>( let mut unreachable_pats = Vec::new(); let mut any_is_useful = false; for v in vs { - let res = is_useful(cx, &matrix, &v, witness_preference, hir_id, false); + let res = is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false); match res { Useful(pats) => { any_is_useful = true; @@ -1664,7 +1669,10 @@ crate fn is_useful<'p, 'tcx>( bug!("Encountered or-pat in `v` during exhaustiveness checking") } } - matrix.push(v); + // If pattern has a guard don't add it to the matrix + if !is_under_guard { + matrix.push(v); + } } return if any_is_useful { Useful(unreachable_pats) } else { NotUseful }; } @@ -1712,7 +1720,18 @@ crate fn is_useful<'p, 'tcx>( Some(hir_id), ) .into_iter() - .map(|c| is_useful_specialized(cx, matrix, v, c, pcx.ty, witness_preference, hir_id)) + .map(|c| { + is_useful_specialized( + cx, + matrix, + v, + c, + pcx.ty, + witness_preference, + hir_id, + is_under_guard, + ) + }) .find(|result| result.is_useful()) .unwrap_or(NotUseful) } else { @@ -1746,14 +1765,24 @@ crate fn is_useful<'p, 'tcx>( split_grouped_constructors(cx.tcx, cx.param_env, pcx, all_ctors, matrix, DUMMY_SP, None) .into_iter() .map(|c| { - is_useful_specialized(cx, matrix, v, c, pcx.ty, witness_preference, hir_id) + is_useful_specialized( + cx, + matrix, + v, + c, + pcx.ty, + witness_preference, + hir_id, + is_under_guard, + ) }) .find(|result| result.is_useful()) .unwrap_or(NotUseful) } else { let matrix = matrix.specialize_wildcard(); let v = v.to_tail(); - let usefulness = is_useful(cx, &matrix, &v, witness_preference, hir_id, false); + let usefulness = + is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false); // In this case, there's at least one "free" // constructor that is only matched against by @@ -1810,6 +1839,7 @@ fn is_useful_specialized<'p, 'tcx>( lty: Ty<'tcx>, witness_preference: WitnessPreference, hir_id: HirId, + is_under_guard: bool, ) -> Usefulness<'tcx, 'p> { debug!("is_useful_specialized({:#?}, {:#?}, {:?})", v, ctor, lty); @@ -1817,7 +1847,7 @@ fn is_useful_specialized<'p, 'tcx>( cx.pattern_arena.alloc_from_iter(ctor.wildcard_subpatterns(cx, lty)); let matrix = matrix.specialize_constructor(cx, &ctor, ctor_wild_subpatterns); v.specialize_constructor(cx, &ctor, ctor_wild_subpatterns) - .map(|v| is_useful(cx, &matrix, &v, witness_preference, hir_id, false)) + .map(|v| is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false)) .map(|u| u.apply_constructor(cx, &ctor, lty)) .unwrap_or(NotUseful) } diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index 9c86669cf9d92..c2eeac60b8b3b 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -360,7 +360,7 @@ fn check_arms<'p, 'tcx>( let mut catchall = None; for (arm_index, (pat, id, has_guard)) in arms.iter().copied().enumerate() { let v = PatStack::from_pattern(pat); - match is_useful(cx, &seen, &v, LeaveOutWitness, id, true) { + match is_useful(cx, &seen, &v, LeaveOutWitness, id, has_guard, true) { NotUseful => { match source { hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar => bug!(), @@ -410,7 +410,10 @@ fn check_not_useful<'p, 'tcx>( ) -> Result<(), Vec>> { let wild_pattern = cx.pattern_arena.alloc(super::Pat::wildcard_from_ty(ty)); let v = PatStack::from_pattern(wild_pattern); - match is_useful(cx, matrix, &v, ConstructWitness, hir_id, true) { + + // false is given for `is_under_guard` argument due to the wildcard + // pattern not having a guard + match is_useful(cx, matrix, &v, ConstructWitness, hir_id, false, true) { NotUseful => Ok(()), // This is good, wildcard pattern isn't reachable. UsefulWithWitness(pats) => Err(if pats.is_empty() { bug!("Exhaustiveness check returned no witnesses") diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index cc88464d774e8..6b7a9ec658dff 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -908,8 +908,10 @@ impl<'a> Parser<'a> { fn error_bad_item_kind(&self, span: Span, kind: &ItemKind, ctx: &str) -> Option { let span = self.sess.source_map().guess_head_span(span); - let msg = format!("{} is not supported in {}", kind.descr(), ctx); - self.struct_span_err(span, &msg).emit(); + let descr = kind.descr(); + self.struct_span_err(span, &format!("{} is not supported in {}", descr, ctx)) + .help(&format!("consider moving the {} out to a nearby module scope", descr)) + .emit(); None } diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 6e5111bd7018a..6d688c12977e3 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -771,9 +771,6 @@ pub struct TargetOptions { /// rather than "default" pub default_hidden_visibility: bool, - /// Whether or not bitcode is embedded in object files - pub embed_bitcode: bool, - /// Whether a .debug_gdb_scripts section will be added to the output object file pub emit_debug_gdb_scripts: bool, @@ -893,7 +890,6 @@ impl Default for TargetOptions { no_builtins: false, codegen_backend: "llvm".to_string(), default_hidden_visibility: false, - embed_bitcode: false, emit_debug_gdb_scripts: true, requires_uwtable: false, simd_types_indirect: true, @@ -1208,7 +1204,6 @@ impl Target { key!(no_builtins, bool); key!(codegen_backend); key!(default_hidden_visibility, bool); - key!(embed_bitcode, bool); key!(emit_debug_gdb_scripts, bool); key!(requires_uwtable, bool); key!(simd_types_indirect, bool); @@ -1437,7 +1432,6 @@ impl ToJson for Target { target_option_val!(no_builtins); target_option_val!(codegen_backend); target_option_val!(default_hidden_visibility); - target_option_val!(embed_bitcode); target_option_val!(emit_debug_gdb_scripts); target_option_val!(requires_uwtable); target_option_val!(simd_types_indirect); diff --git a/src/test/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs b/src/test/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs new file mode 100644 index 0000000000000..eb6706e50006f --- /dev/null +++ b/src/test/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs @@ -0,0 +1,22 @@ +// check-pass + +#![deny(unreachable_patterns)] + +#![feature(or_patterns)] +fn main() { + match (3,42) { + (a,_) | (_,a) if a > 10 => {println!("{}", a)} + _ => () + } + + match Some((3,42)) { + Some((a, _)) | Some((_, a)) if a > 10 => {println!("{}", a)} + _ => () + + } + + match Some((3,42)) { + Some((a, _) | (_, a)) if a > 10 => {println!("{}", a)} + _ => () + } +} diff --git a/src/test/ui/parser/default-on-wrong-item-kind.stderr b/src/test/ui/parser/default-on-wrong-item-kind.stderr index 9788bd64725b8..af513f7617b09 100644 --- a/src/test/ui/parser/default-on-wrong-item-kind.stderr +++ b/src/test/ui/parser/default-on-wrong-item-kind.stderr @@ -123,6 +123,8 @@ error: extern crate is not supported in `extern` blocks | LL | default extern crate foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern crate out to a nearby module scope error: a `use` import cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:35:5 @@ -137,6 +139,8 @@ error: `use` import is not supported in `extern` blocks | LL | default use foo; | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the `use` import out to a nearby module scope error: a static item cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:37:5 @@ -169,6 +173,8 @@ error: module is not supported in `extern` blocks | LL | default mod foo {} | ^^^^^^^^^^^^^^^ + | + = help: consider moving the module out to a nearby module scope error: an extern block cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:43:5 @@ -183,6 +189,8 @@ error: extern block is not supported in `extern` blocks | LL | default extern "C" {} | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern block out to a nearby module scope error: an enum cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:46:5 @@ -197,6 +205,8 @@ error: enum is not supported in `extern` blocks | LL | default enum foo {} | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the enum out to a nearby module scope error: a struct cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:48:5 @@ -211,6 +221,8 @@ error: struct is not supported in `extern` blocks | LL | default struct foo {} | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope error: a union cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:50:5 @@ -225,6 +237,8 @@ error: union is not supported in `extern` blocks | LL | default union foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the union out to a nearby module scope error: a trait cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:52:5 @@ -239,6 +253,8 @@ error: trait is not supported in `extern` blocks | LL | default trait foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait out to a nearby module scope error: a trait alias cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:54:5 @@ -253,12 +269,16 @@ error: trait alias is not supported in `extern` blocks | LL | default trait foo = Ord; | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait alias out to a nearby module scope error: implementation is not supported in `extern` blocks --> $DIR/default-on-wrong-item-kind.rs:56:5 | LL | default impl foo {} | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope error: an item macro invocation cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:60:5 @@ -289,6 +309,8 @@ error: macro definition is not supported in `extern` blocks | LL | default macro foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope error: a macro definition cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:64:5 @@ -303,6 +325,8 @@ error: macro definition is not supported in `extern` blocks | LL | default macro_rules! foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope error: an extern crate cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:70:5 @@ -317,6 +341,8 @@ error: extern crate is not supported in `trait`s or `impl`s | LL | default extern crate foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern crate out to a nearby module scope error: a `use` import cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:72:5 @@ -331,6 +357,8 @@ error: `use` import is not supported in `trait`s or `impl`s | LL | default use foo; | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the `use` import out to a nearby module scope error: a static item cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:74:5 @@ -359,6 +387,8 @@ error: module is not supported in `trait`s or `impl`s | LL | default mod foo {} | ^^^^^^^^^^^^^^^ + | + = help: consider moving the module out to a nearby module scope error: an extern block cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:80:5 @@ -373,6 +403,8 @@ error: extern block is not supported in `trait`s or `impl`s | LL | default extern "C" {} | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern block out to a nearby module scope error: an enum cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:83:5 @@ -387,6 +419,8 @@ error: enum is not supported in `trait`s or `impl`s | LL | default enum foo {} | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the enum out to a nearby module scope error: a struct cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:85:5 @@ -401,6 +435,8 @@ error: struct is not supported in `trait`s or `impl`s | LL | default struct foo {} | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope error: a union cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:87:5 @@ -415,6 +451,8 @@ error: union is not supported in `trait`s or `impl`s | LL | default union foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the union out to a nearby module scope error: a trait cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:89:5 @@ -429,6 +467,8 @@ error: trait is not supported in `trait`s or `impl`s | LL | default trait foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait out to a nearby module scope error: a trait alias cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:91:5 @@ -443,12 +483,16 @@ error: trait alias is not supported in `trait`s or `impl`s | LL | default trait foo = Ord; | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait alias out to a nearby module scope error: implementation is not supported in `trait`s or `impl`s --> $DIR/default-on-wrong-item-kind.rs:93:5 | LL | default impl foo {} | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope error: an item macro invocation cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:97:5 @@ -479,6 +523,8 @@ error: macro definition is not supported in `trait`s or `impl`s | LL | default macro foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope error: a macro definition cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:101:5 @@ -493,6 +539,8 @@ error: macro definition is not supported in `trait`s or `impl`s | LL | default macro_rules! foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope error: an extern crate cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:107:5 @@ -507,6 +555,8 @@ error: extern crate is not supported in `trait`s or `impl`s | LL | default extern crate foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern crate out to a nearby module scope error: a `use` import cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:109:5 @@ -521,6 +571,8 @@ error: `use` import is not supported in `trait`s or `impl`s | LL | default use foo; | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the `use` import out to a nearby module scope error: a static item cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:111:5 @@ -549,6 +601,8 @@ error: module is not supported in `trait`s or `impl`s | LL | default mod foo {} | ^^^^^^^^^^^^^^^ + | + = help: consider moving the module out to a nearby module scope error: an extern block cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:117:5 @@ -563,6 +617,8 @@ error: extern block is not supported in `trait`s or `impl`s | LL | default extern "C" {} | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the extern block out to a nearby module scope error: an enum cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:120:5 @@ -577,6 +633,8 @@ error: enum is not supported in `trait`s or `impl`s | LL | default enum foo {} | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the enum out to a nearby module scope error: a struct cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:122:5 @@ -591,6 +649,8 @@ error: struct is not supported in `trait`s or `impl`s | LL | default struct foo {} | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope error: a union cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:124:5 @@ -605,6 +665,8 @@ error: union is not supported in `trait`s or `impl`s | LL | default union foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the union out to a nearby module scope error: a trait cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:126:5 @@ -619,6 +681,8 @@ error: trait is not supported in `trait`s or `impl`s | LL | default trait foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait out to a nearby module scope error: a trait alias cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:128:5 @@ -633,12 +697,16 @@ error: trait alias is not supported in `trait`s or `impl`s | LL | default trait foo = Ord; | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the trait alias out to a nearby module scope error: implementation is not supported in `trait`s or `impl`s --> $DIR/default-on-wrong-item-kind.rs:130:5 | LL | default impl foo {} | ^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope error: an item macro invocation cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:134:5 @@ -669,6 +737,8 @@ error: macro definition is not supported in `trait`s or `impl`s | LL | default macro foo {} | ^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope error: a macro definition cannot be `default` --> $DIR/default-on-wrong-item-kind.rs:138:5 @@ -683,6 +753,8 @@ error: macro definition is not supported in `trait`s or `impl`s | LL | default macro_rules! foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the macro definition out to a nearby module scope error: aborting due to 95 previous errors diff --git a/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr b/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr index bfd27a1a41e13..c83205aadd672 100644 --- a/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr +++ b/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr @@ -3,6 +3,8 @@ error: struct is not supported in `trait`s or `impl`s | LL | struct BadS; | ^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope error: enum is not supported in `trait`s or `impl`s --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 @@ -13,6 +15,7 @@ LL | enum BadE {} LL | expand_to_enum!(); | ------------------ in this macro invocation | + = help: consider moving the enum out to a nearby module scope = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: struct is not supported in `trait`s or `impl`s @@ -20,6 +23,8 @@ error: struct is not supported in `trait`s or `impl`s | LL | struct BadS; | ^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope error: enum is not supported in `trait`s or `impl`s --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 @@ -30,6 +35,7 @@ LL | enum BadE {} LL | expand_to_enum!(); | ------------------ in this macro invocation | + = help: consider moving the enum out to a nearby module scope = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: struct is not supported in `extern` blocks @@ -37,6 +43,8 @@ error: struct is not supported in `extern` blocks | LL | struct BadS; | ^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope error: enum is not supported in `extern` blocks --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 @@ -47,6 +55,7 @@ LL | enum BadE {} LL | expand_to_enum!(); | ------------------ in this macro invocation | + = help: consider moving the enum out to a nearby module scope = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr index 1655a96839569..cc7cc0c55d5ff 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr @@ -12,12 +12,16 @@ error: trait is not supported in `trait`s or `impl`s | LL | trait T { | ^^^^^^^ + | + = help: consider moving the trait out to a nearby module scope error: struct is not supported in `trait`s or `impl`s --> $DIR/missing-close-brace-in-impl-trait.rs:11:1 | LL | pub(crate) struct Bar(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope error[E0405]: cannot find trait `T` in this scope --> $DIR/missing-close-brace-in-impl-trait.rs:3:6 diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr index 43a3883357a75..7c6254356e077 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr @@ -12,12 +12,16 @@ error: struct is not supported in `trait`s or `impl`s | LL | pub(crate) struct Bar(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the struct out to a nearby module scope error: implementation is not supported in `trait`s or `impl`s --> $DIR/missing-close-brace-in-trait.rs:7:1 | LL | impl T for Bar { | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope error: aborting due to 3 previous errors