diff options
| author | bors <bors@rust-lang.org> | 2019-01-05 14:58:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-01-05 14:58:57 +0000 |
| commit | 8c2d0f4a1da300cb34d77fbcdd9f7209cc556582 (patch) | |
| tree | 0401cf1c7bb2474333a26b2d22c5b28fe52d3dae /src/librustc_codegen_ssa | |
| parent | 68614265d312fc2cbe8a696f7dabb9416eb6f221 (diff) | |
| parent | c118b17953a8e29b850b8ed8fe0d3aaf2917a9da (diff) | |
| download | rust-8c2d0f4a1da300cb34d77fbcdd9f7209cc556582.tar.gz rust-8c2d0f4a1da300cb34d77fbcdd9f7209cc556582.zip | |
Auto merge of #57145 - RalfJung:panic-if-uninhabited, r=alexcrichton
panic when calling MaybeUninhabited::into_inner on uninhabited type I do this by adding an internal-only intrinsic `panic_if_uninhabited`. I have no idea what I am doing here, just mindlessly copying code around, so please review carefully!
Diffstat (limited to 'src/librustc_codegen_ssa')
| -rw-r--r-- | src/librustc_codegen_ssa/mir/block.rs | 96 |
1 files changed, 50 insertions, 46 deletions
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 7397c722df6..aa82c853257 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -500,53 +500,57 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bx.new_fn_type(sig, &extra_args) }; - // emit a panic instead of instantiating an uninhabited type - if (intrinsic == Some("init") || intrinsic == Some("uninit")) && - fn_ty.ret.layout.abi.is_uninhabited() - { - let loc = bx.sess().source_map().lookup_char_pos(span.lo()); - let filename = Symbol::intern(&loc.file.name.to_string()).as_str(); - let filename = bx.const_str_slice(filename); - let line = bx.const_u32(loc.line as u32); - let col = bx.const_u32(loc.col.to_usize() as u32 + 1); - let align = tcx.data_layout.aggregate_align.abi - .max(tcx.data_layout.i32_align.abi) - .max(tcx.data_layout.pointer_align.abi); - - let str = format!( - "Attempted to instantiate uninhabited type {} using mem::{}", - sig.output(), - if intrinsic == Some("init") { "zeroed" } else { "uninitialized" } - ); - let msg_str = Symbol::intern(&str).as_str(); - let msg_str = bx.const_str_slice(msg_str); - let msg_file_line_col = bx.const_struct( - &[msg_str, filename, line, col], - false, - ); - let msg_file_line_col = bx.static_addr_of( - msg_file_line_col, - align, - Some("panic_loc"), - ); + // emit a panic or a NOP for `panic_if_uninhabited` + if intrinsic == Some("panic_if_uninhabited") { + let ty = instance.unwrap().substs.type_at(0); + let layout = bx.layout_of(ty); + if layout.abi.is_uninhabited() { + let loc = bx.sess().source_map().lookup_char_pos(span.lo()); + let filename = Symbol::intern(&loc.file.name.to_string()).as_str(); + let filename = bx.const_str_slice(filename); + let line = bx.const_u32(loc.line as u32); + let col = bx.const_u32(loc.col.to_usize() as u32 + 1); + let align = tcx.data_layout.aggregate_align.abi + .max(tcx.data_layout.i32_align.abi) + .max(tcx.data_layout.pointer_align.abi); + + let str = format!( + "Attempted to instantiate uninhabited type {}", + ty + ); + let msg_str = Symbol::intern(&str).as_str(); + let msg_str = bx.const_str_slice(msg_str); + let msg_file_line_col = bx.const_struct( + &[msg_str, filename, line, col], + false, + ); + let msg_file_line_col = bx.static_addr_of( + msg_file_line_col, + align, + Some("panic_loc"), + ); - // Obtain the panic entry point. - let def_id = - common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem); - let instance = ty::Instance::mono(bx.tcx(), def_id); - let fn_ty = bx.fn_type_of_instance(&instance); - let llfn = bx.get_fn(instance); - - // Codegen the actual panic invoke/call. - do_call( - self, - &mut bx, - fn_ty, - llfn, - &[msg_file_line_col], - destination.as_ref().map(|(_, bb)| (ReturnDest::Nothing, *bb)), - cleanup, - ); + // Obtain the panic entry point. + let def_id = + common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem); + let instance = ty::Instance::mono(bx.tcx(), def_id); + let fn_ty = bx.fn_type_of_instance(&instance); + let llfn = bx.get_fn(instance); + + // Codegen the actual panic invoke/call. + do_call( + self, + &mut bx, + fn_ty, + llfn, + &[msg_file_line_col], + destination.as_ref().map(|(_, bb)| (ReturnDest::Nothing, *bb)), + cleanup, + ); + } else { + // a NOP + funclet_br(self, &mut bx, destination.as_ref().unwrap().1); + } return; } |
