diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index bbb5daccfd639..b13773ffe1460 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2330,10 +2330,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { match (cast_ty_from, cast_ty_to) { (Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => { let mut normalize = |t| self.normalize(t, location); + + // N.B. `struct_tail_with_normalize` only "structurally resolves" + // the type. It is not fully normalized, so we have to normalize it + // afterwards. let src_tail = tcx.struct_tail_with_normalize(src.ty, &mut normalize, || ()); + let src_tail = normalize(src_tail); let dst_tail = tcx.struct_tail_with_normalize(dst.ty, &mut normalize, || ()); + let dst_tail = normalize(dst_tail); // This checks (lifetime part of) vtable validity for pointer casts, // which is irrelevant when there are aren't principal traits on both sides (aka only auto traits). diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 901149825bfd6..79e8e2127765a 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -458,7 +458,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { _unwind: mir::UnwindAction, ) -> InterpResult<'tcx, Option>> { // Shared intrinsics. - if ecx.emulate_intrinsic(instance, args, dest, target)? { + if ecx.eval_intrinsic(instance, args, dest, target)? { return Ok(None); } let intrinsic_name = ecx.tcx.item_name(instance.def_id()); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 16a0a76a316e6..9210ec4e16fd0 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -97,7 +97,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Returns `true` if emulation happened. /// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own /// intrinsic handling. - pub fn emulate_intrinsic( + pub fn eval_intrinsic( &mut self, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, M::Provenance>], @@ -447,7 +447,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok(true) } - pub(super) fn emulate_nondiverging_intrinsic( + pub(super) fn eval_nondiverging_intrinsic( &mut self, intrinsic: &NonDivergingIntrinsic<'tcx>, ) -> InterpResult<'tcx> { diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index fe5869ad7fa7a..2f860f9f942b2 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -1,8 +1,9 @@ use either::Either; use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::interpret::{InterpResult, Scalar}; +use rustc_middle::mir::NullOp; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; -use rustc_middle::ty::{self, FloatTy, ScalarInt}; +use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::symbol::sym; use tracing::trace; @@ -480,4 +481,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } } + + pub fn nullary_op( + &self, + null_op: NullOp<'tcx>, + arg_ty: Ty<'tcx>, + ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> { + use rustc_middle::mir::NullOp::*; + + let layout = self.layout_of(arg_ty)?; + let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap(); + + Ok(match null_op { + SizeOf => { + if !layout.abi.is_sized() { + span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`"); + } + let val = layout.size.bytes(); + ImmTy::from_uint(val, usize_layout()) + } + AlignOf => { + if !layout.abi.is_sized() { + span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`"); + } + let val = layout.align.abi.bytes(); + ImmTy::from_uint(val, usize_layout()) + } + OffsetOf(fields) => { + let val = + self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes(); + ImmTy::from_uint(val, usize_layout()) + } + UbChecks => ImmTy::from_bool(self.tcx.sess.ub_checks(), *self.tcx), + }) + } } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 211a7b2300222..28cf1068f4081 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -4,8 +4,7 @@ use either::Either; use rustc_index::IndexSlice; -use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::{bug, mir, span_bug}; +use rustc_middle::{bug, mir}; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use tracing::{info, instrument, trace}; @@ -94,7 +93,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { M::retag_place_contents(self, *kind, &dest)?; } - Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?, + Intrinsic(box intrinsic) => self.eval_nondiverging_intrinsic(intrinsic)?, // Evaluate the place expression, without reading from it. PlaceMention(box place) => { @@ -179,6 +178,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_immediate(*result, &dest)?; } + NullaryOp(null_op, ty) => { + let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?; + let val = self.nullary_op(null_op, ty)?; + self.write_immediate(*val, &dest)?; + } + Aggregate(box ref kind, ref operands) => { self.write_aggregate(kind, operands, &dest)?; } @@ -230,38 +235,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_immediate(*val, &dest)?; } - NullaryOp(ref null_op, ty) => { - let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?; - let layout = self.layout_of(ty)?; - if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op - && layout.is_unsized() - { - span_bug!( - self.frame().current_span(), - "{null_op:?} MIR operator called for unsized type {ty}", - ); - } - let val = match null_op { - mir::NullOp::SizeOf => { - let val = layout.size.bytes(); - Scalar::from_target_usize(val, self) - } - mir::NullOp::AlignOf => { - let val = layout.align.abi.bytes(); - Scalar::from_target_usize(val, self) - } - mir::NullOp::OffsetOf(fields) => { - let val = self - .tcx - .offset_of_subfield(self.param_env, layout, fields.iter()) - .bytes(); - Scalar::from_target_usize(val, self) - } - mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()), - }; - self.write_scalar(val, &dest)?; - } - ShallowInitBox(ref operand, _) => { let src = self.eval_operand(operand, None)?; let v = self.read_immediate(&src)?; diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 3d4b706aa652b..56896d945e5f3 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -75,6 +75,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { @call(mir_call, args) => { self.parse_call(args) }, + @call(mir_tail_call, args) => { + self.parse_tail_call(args) + }, ExprKind::Match { scrutinee, arms, .. } => { let discr = self.parse_operand(*scrutinee)?; self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t }) @@ -187,6 +190,25 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ) } + fn parse_tail_call(&self, args: &[ExprId]) -> PResult> { + parse_by_kind!(self, args[0], _, "tail call", + ExprKind::Call { fun, args, fn_span, .. } => { + let fun = self.parse_operand(*fun)?; + let args = args + .iter() + .map(|arg| + Ok(Spanned { node: self.parse_operand(*arg)?, span: self.thir.exprs[*arg].span } ) + ) + .collect::>>()?; + Ok(TerminatorKind::TailCall { + func: fun, + args, + fn_span: *fn_span, + }) + }, + ) + } + fn parse_rvalue(&self, expr_id: ExprId) -> PResult> { parse_by_kind!(self, expr_id, expr, "rvalue", @call(mir_discriminant, args) => self.parse_place(args[0]).map(Rvalue::Discriminant), diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs index ac664c53f4454..cb15c67b895b8 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_middle::bug; -use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_target::abi::call::{Conv, FnAbi, PassMode}; use tracing::instrument; @@ -112,11 +112,12 @@ pub fn typeid_for_instance<'tcx>( instance: Instance<'tcx>, options: TypeIdOptions, ) -> String { + assert!(!instance.has_non_region_param(), "{instance:#?} must be fully monomorphic"); let transform_ty_options = TransformTyOptions::from_bits(options.bits()) .unwrap_or_else(|| bug!("typeid_for_instance: invalid option(s) `{:?}`", options.bits())); let instance = transform_instance(tcx, instance, transform_ty_options); let fn_abi = tcx - .fn_abi_of_instance(tcx.param_env(instance.def_id()).and((instance, ty::List::empty()))) + .fn_abi_of_instance(ty::ParamEnv::reveal_all().and((instance, ty::List::empty()))) .unwrap_or_else(|error| { bug!("typeid_for_instance: couldn't get fn_abi of instance {instance:?}: {error:?}") }); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9977fa7425a3e..94cf21da4efb8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1216,6 +1216,7 @@ symbols! { mir_static_mut, mir_storage_dead, mir_storage_live, + mir_tail_call, mir_unreachable, mir_unwind_cleanup, mir_unwind_continue, diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs index 3e575fdd528de..8b40132986867 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs @@ -21,6 +21,7 @@ pub fn target() -> Target { llvm_abiname: "lp64d".into(), max_atomic_width: Some(64), supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), + crt_static_default: false, ..base::linux_musl::opts() }, } diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index fd49a96eaa049..c7cec396e1f2e 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -247,6 +247,8 @@ //! otherwise branch. //! - [`Call`] has an associated function as well, with special syntax: //! `Call(ret_val = function(arg1, arg2, ...), ReturnTo(next_block), UnwindContinue())`. +//! - [`TailCall`] does not have a return destination or next block, so its syntax is just +//! `TailCall(function(arg1, arg2, ...))`. #![unstable( feature = "custom_mir", @@ -350,6 +352,12 @@ define!("mir_call", /// - [`UnwindCleanup`] fn Call(call: (), goto: ReturnToArg, unwind_action: UnwindActionArg) ); +define!("mir_tail_call", + /// Call a function. + /// + /// The argument must be of the form `fun(arg1, arg2, ...)`. + fn TailCall(call: T) +); define!("mir_unwind_resume", /// A terminator that resumes the unwinding. fn UnwindResume() diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 2621e9a603185..1b98d54169338 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -24,7 +24,8 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no # Needed for apt-key to work: dirmngr \ gpg-agent \ - g++-9-arm-linux-gnueabi + g++-9-arm-linux-gnueabi \ + g++-11-riscv64-linux-gnu RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486 RUN add-apt-repository -y 'deb https://apt.dilos.org/dilos dilos2 main' @@ -73,6 +74,10 @@ RUN env \ CC=arm-linux-gnueabi-gcc-9 CFLAGS="-march=armv7-a" \ CXX=arm-linux-gnueabi-g++-9 CXXFLAGS="-march=armv7-a" \ bash musl.sh armv7 && \ + env \ + CC=riscv64-linux-gnu-gcc-11 \ + CXX=riscv64-linux-gnu-g++-11 \ + bash musl.sh riscv64gc && \ rm -rf /build/* WORKDIR /tmp @@ -125,6 +130,7 @@ ENV TARGETS=$TARGETS,x86_64-unknown-none ENV TARGETS=$TARGETS,aarch64-unknown-uefi ENV TARGETS=$TARGETS,i686-unknown-uefi ENV TARGETS=$TARGETS,x86_64-unknown-uefi +ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-musl # As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211 # we need asm in the search path for gcc-9 (for gnux32) but not in the search path of the @@ -132,7 +138,11 @@ ENV TARGETS=$TARGETS,x86_64-unknown-uefi # Luckily one of the folders is /usr/local/include so symlink /usr/include/x86_64-linux-gnu/asm there RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm +# musl-gcc can't find libgcc_s.so.1 since it doesn't use the standard search paths. +RUN ln -s /usr/riscv64-linux-gnu/lib/libgcc_s.so.1 /usr/lib/gcc-cross/riscv64-linux-gnu/11/ + ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \ - --musl-root-armv7=/musl-armv7 + --musl-root-armv7=/musl-armv7 \ + --musl-root-riscv64gc=/musl-riscv64gc ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index d5141591b97e4..467fd6f43e48f 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -66,6 +66,7 @@ - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) - [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) - [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md) + - [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md) - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index f3b49a65aad28..7fd1808a1f026 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -98,6 +98,7 @@ target | notes `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17) `powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17) [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29) +[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3) `s390x-unknown-linux-gnu` | S390x Linux (kernel 3.2, glibc 2.17) `x86_64-unknown-freebsd` | 64-bit FreeBSD `x86_64-unknown-illumos` | illumos @@ -354,7 +355,6 @@ target | std | host | notes [`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit `riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD `riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia -`riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.3) [`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 [`riscv64-linux-android`](platform-support/android.md) | | | RISC-V 64-bit Android diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md new file mode 100644 index 0000000000000..5b3dc68303803 --- /dev/null +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md @@ -0,0 +1,47 @@ +# riscv64gc-unknown-linux-musl + +**Tier: 2** + +Target for RISC-V Linux programs using musl libc. + +## Target maintainers + +- [@Amanieu](https://github.com/Amanieu) +- [@kraj](https://github.com/kraj) + +## Requirements + +Building the target itself requires a RISC-V compiler that is supported by `cc-rs`. + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["riscv64gc-unknown-linux-musl"] +``` + +Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`: + +```toml +[target.riscv64gc-unknown-linux-musl] +cc = "riscv64-linux-gnu-gcc" +cxx = "riscv64-linux-gnu-g++" +ar = "riscv64-linux-gnu-ar" +linker = "riscv64-linux-gnu-gcc" +``` + +## Building Rust programs + +This target are distributed through `rustup`, and otherwise require no +special configuration. + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +This target can be tested as normal with `x.py` on a RISC-V host or via QEMU +emulation. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index ff475b9571b87..2b263f848e89e 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -141,6 +141,7 @@ static TARGETS: &[&str] = &[ "riscv64gc-unknown-hermit", "riscv64gc-unknown-none-elf", "riscv64gc-unknown-linux-gnu", + "riscv64gc-unknown-linux-musl", "s390x-unknown-linux-gnu", "sparc64-unknown-linux-gnu", "sparcv9-sun-solaris", diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index d60119e75f16d..18b22827bdb15 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); // See if the core engine can handle this intrinsic. - if this.emulate_intrinsic(instance, args, dest, ret)? { + if this.eval_intrinsic(instance, args, dest, ret)? { return Ok(None); } let intrinsic_name = this.tcx.item_name(instance.def_id()); diff --git a/tests/crashes/128621-2.rs b/tests/crashes/128621-2.rs deleted file mode 100644 index b1cdaf94984a8..0000000000000 --- a/tests/crashes/128621-2.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: rust-lang/rust#128621 - -#![feature(ptr_metadata)] -use std::{ops::FnMut, ptr::Pointee}; - -pub type EmplacerFn<'a, T> = dyn for<'b> FnMut(::Metadata) + 'a; - -pub struct Emplacer<'a, T>(EmplacerFn<'a, T>); - -impl<'a, T> Emplacer<'a, T> { - pub unsafe fn from_fn<'b>(emplacer_fn: &'b mut EmplacerFn<'a, T>) -> &'b mut Self { - unsafe { &mut *((emplacer_fn as *mut EmplacerFn<'a, T>) as *mut Self) } - } -} - -pub fn main() {} diff --git a/tests/mir-opt/building/custom/terminators.rs b/tests/mir-opt/building/custom/terminators.rs index a8e0b4b35bf47..ed08040a2a58c 100644 --- a/tests/mir-opt/building/custom/terminators.rs +++ b/tests/mir-opt/building/custom/terminators.rs @@ -22,6 +22,18 @@ fn direct_call(x: i32) -> i32 { } } +// EMIT_MIR terminators.tail_call.built.after.mir +#[custom_mir(dialect = "built")] +fn tail_call(x: i32) -> i32 { + mir! { + let y; + { + y = x + 42; + TailCall(ident(y)) + } + } +} + // EMIT_MIR terminators.indirect_call.built.after.mir #[custom_mir(dialect = "built")] fn indirect_call(x: i32, f: fn(i32) -> i32) -> i32 { diff --git a/tests/mir-opt/building/custom/terminators.tail_call.built.after.mir b/tests/mir-opt/building/custom/terminators.tail_call.built.after.mir new file mode 100644 index 0000000000000..4cf6e459aa820 --- /dev/null +++ b/tests/mir-opt/building/custom/terminators.tail_call.built.after.mir @@ -0,0 +1,11 @@ +// MIR for `tail_call` after built + +fn tail_call(_1: i32) -> i32 { + let mut _0: i32; + let mut _2: i32; + + bb0: { + _2 = Add(_1, const 42_i32); + tailcall ident::(Spanned { node: _2, span: $DIR/terminators.rs:32:28: 32:29 (#0) }); + } +} diff --git a/tests/crashes/128621.rs b/tests/ui/cast/dyn-tails-need-normalization.rs similarity index 87% rename from tests/crashes/128621.rs rename to tests/ui/cast/dyn-tails-need-normalization.rs index 0a02352236dbb..719e0e892430d 100644 --- a/tests/crashes/128621.rs +++ b/tests/ui/cast/dyn-tails-need-normalization.rs @@ -1,4 +1,4 @@ -//@ known-bug: rust-lang/rust#128621 +//@ check-pass trait Trait { type Associated; @@ -17,3 +17,5 @@ struct Wrap(TraitObject); fn cast(x: *mut TraitObject) { x as *mut Wrap; } + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index 8d59235e2f448..01529599d37d0 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -1,4 +1,4 @@ -error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug +error: internal compiler error: compiler/rustc_const_eval/src/interpret/operator.rs:LL:CC: unsized type for `NullaryOp::SizeOf` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL Box diff --git a/tests/ui/sanitizer/cfi-can-reveal-opaques.rs b/tests/ui/sanitizer/cfi-can-reveal-opaques.rs new file mode 100644 index 0000000000000..55988a62a8cdf --- /dev/null +++ b/tests/ui/sanitizer/cfi-can-reveal-opaques.rs @@ -0,0 +1,44 @@ +//@ needs-sanitizer-cfi +//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi +//@ no-prefer-dynamic +//@ only-x86_64-unknown-linux-gnu +//@ build-pass + +// See comment below for why this test exists. + +trait Tr { + type Projection; +} + +impl Tr for F +where + F: Fn() -> U +{ + type Projection = U; +} + +fn test, U>(b: B) -> B::Projection +{ + todo!() +} + +fn main() { + fn rpit_fn() -> impl Sized {} + + // When CFI runs, it tries to compute the signature of the call. This + // ends up giving us a signature of: + // `fn test::() -> >::Projection`, + // where `rpit_fn` is the ZST FnDef for the function. However, we were + // previously using a Reveal::UserFacing param-env. This means that the + // `>::Projection` return type is impossible to normalize, + // since it would require proving `rpit_fn: Fn() -> ()`, but we cannot + // prove that the `impl Sized` opaque is `()` with a user-facing param-env. + // This leads to a normalization error, and then an ICE. + // + // Side-note: + // So why is the second generic of `test` "`()`", and not the + // `impl Sized` since we inferred it from the return type of `rpit_fn` + // during typeck? Well, that's because we're using the generics from the + // terminator of the MIR, which has had the RevealAll pass performed on it. + let _ = test(rpit_fn); +}