Skip to content

Commit b586701

Browse files
committed
Auto merge of #128707 - matthiaskrgr:rollup-63klywk, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #122049 (Promote riscv64gc-unknown-linux-musl to tier 2) - #128580 (Use `ParamEnv::reveal_all` in CFI) - #128688 (custom MIR: add support for tail calls) - #128694 (Normalize when equating `dyn` tails in MIR borrowck) - #128697 (interpret: move nullary-op evaluation into operator.rs) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e57f309 + c53698b commit b586701

File tree

22 files changed

+222
-63
lines changed

22 files changed

+222
-63
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2330,10 +2330,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23302330
match (cast_ty_from, cast_ty_to) {
23312331
(Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => {
23322332
let mut normalize = |t| self.normalize(t, location);
2333+
2334+
// N.B. `struct_tail_with_normalize` only "structurally resolves"
2335+
// the type. It is not fully normalized, so we have to normalize it
2336+
// afterwards.
23332337
let src_tail =
23342338
tcx.struct_tail_with_normalize(src.ty, &mut normalize, || ());
2339+
let src_tail = normalize(src_tail);
23352340
let dst_tail =
23362341
tcx.struct_tail_with_normalize(dst.ty, &mut normalize, || ());
2342+
let dst_tail = normalize(dst_tail);
23372343

23382344
// This checks (lifetime part of) vtable validity for pointer casts,
23392345
// which is irrelevant when there are aren't principal traits on both sides (aka only auto traits).

compiler/rustc_const_eval/src/const_eval/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
458458
_unwind: mir::UnwindAction,
459459
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
460460
// Shared intrinsics.
461-
if ecx.emulate_intrinsic(instance, args, dest, target)? {
461+
if ecx.eval_intrinsic(instance, args, dest, target)? {
462462
return Ok(None);
463463
}
464464
let intrinsic_name = ecx.tcx.item_name(instance.def_id());

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
9797
/// Returns `true` if emulation happened.
9898
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
9999
/// intrinsic handling.
100-
pub fn emulate_intrinsic(
100+
pub fn eval_intrinsic(
101101
&mut self,
102102
instance: ty::Instance<'tcx>,
103103
args: &[OpTy<'tcx, M::Provenance>],
@@ -447,7 +447,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
447447
Ok(true)
448448
}
449449

450-
pub(super) fn emulate_nondiverging_intrinsic(
450+
pub(super) fn eval_nondiverging_intrinsic(
451451
&mut self,
452452
intrinsic: &NonDivergingIntrinsic<'tcx>,
453453
) -> InterpResult<'tcx> {

compiler/rustc_const_eval/src/interpret/operator.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use either::Either;
22
use rustc_apfloat::{Float, FloatConvert};
33
use rustc_middle::mir::interpret::{InterpResult, Scalar};
4+
use rustc_middle::mir::NullOp;
45
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
5-
use rustc_middle::ty::{self, FloatTy, ScalarInt};
6+
use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty};
67
use rustc_middle::{bug, mir, span_bug};
78
use rustc_span::symbol::sym;
89
use tracing::trace;
@@ -480,4 +481,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
480481
}
481482
}
482483
}
484+
485+
pub fn nullary_op(
486+
&self,
487+
null_op: NullOp<'tcx>,
488+
arg_ty: Ty<'tcx>,
489+
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
490+
use rustc_middle::mir::NullOp::*;
491+
492+
let layout = self.layout_of(arg_ty)?;
493+
let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap();
494+
495+
Ok(match null_op {
496+
SizeOf => {
497+
if !layout.abi.is_sized() {
498+
span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`");
499+
}
500+
let val = layout.size.bytes();
501+
ImmTy::from_uint(val, usize_layout())
502+
}
503+
AlignOf => {
504+
if !layout.abi.is_sized() {
505+
span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
506+
}
507+
let val = layout.align.abi.bytes();
508+
ImmTy::from_uint(val, usize_layout())
509+
}
510+
OffsetOf(fields) => {
511+
let val =
512+
self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
513+
ImmTy::from_uint(val, usize_layout())
514+
}
515+
UbChecks => ImmTy::from_bool(self.tcx.sess.ub_checks(), *self.tcx),
516+
})
517+
}
483518
}

compiler/rustc_const_eval/src/interpret/step.rs

+8-35
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
55
use either::Either;
66
use rustc_index::IndexSlice;
7-
use rustc_middle::ty::layout::LayoutOf;
8-
use rustc_middle::{bug, mir, span_bug};
7+
use rustc_middle::{bug, mir};
98
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
109
use tracing::{info, instrument, trace};
1110

@@ -94,7 +93,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
9493
M::retag_place_contents(self, *kind, &dest)?;
9594
}
9695

97-
Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
96+
Intrinsic(box intrinsic) => self.eval_nondiverging_intrinsic(intrinsic)?,
9897

9998
// Evaluate the place expression, without reading from it.
10099
PlaceMention(box place) => {
@@ -179,6 +178,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
179178
self.write_immediate(*result, &dest)?;
180179
}
181180

181+
NullaryOp(null_op, ty) => {
182+
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
183+
let val = self.nullary_op(null_op, ty)?;
184+
self.write_immediate(*val, &dest)?;
185+
}
186+
182187
Aggregate(box ref kind, ref operands) => {
183188
self.write_aggregate(kind, operands, &dest)?;
184189
}
@@ -230,38 +235,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
230235
self.write_immediate(*val, &dest)?;
231236
}
232237

233-
NullaryOp(ref null_op, ty) => {
234-
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
235-
let layout = self.layout_of(ty)?;
236-
if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op
237-
&& layout.is_unsized()
238-
{
239-
span_bug!(
240-
self.frame().current_span(),
241-
"{null_op:?} MIR operator called for unsized type {ty}",
242-
);
243-
}
244-
let val = match null_op {
245-
mir::NullOp::SizeOf => {
246-
let val = layout.size.bytes();
247-
Scalar::from_target_usize(val, self)
248-
}
249-
mir::NullOp::AlignOf => {
250-
let val = layout.align.abi.bytes();
251-
Scalar::from_target_usize(val, self)
252-
}
253-
mir::NullOp::OffsetOf(fields) => {
254-
let val = self
255-
.tcx
256-
.offset_of_subfield(self.param_env, layout, fields.iter())
257-
.bytes();
258-
Scalar::from_target_usize(val, self)
259-
}
260-
mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()),
261-
};
262-
self.write_scalar(val, &dest)?;
263-
}
264-
265238
ShallowInitBox(ref operand, _) => {
266239
let src = self.eval_operand(operand, None)?;
267240
let v = self.read_immediate(&src)?;

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+22
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
7575
@call(mir_call, args) => {
7676
self.parse_call(args)
7777
},
78+
@call(mir_tail_call, args) => {
79+
self.parse_tail_call(args)
80+
},
7881
ExprKind::Match { scrutinee, arms, .. } => {
7982
let discr = self.parse_operand(*scrutinee)?;
8083
self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t })
@@ -187,6 +190,25 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
187190
)
188191
}
189192

193+
fn parse_tail_call(&self, args: &[ExprId]) -> PResult<TerminatorKind<'tcx>> {
194+
parse_by_kind!(self, args[0], _, "tail call",
195+
ExprKind::Call { fun, args, fn_span, .. } => {
196+
let fun = self.parse_operand(*fun)?;
197+
let args = args
198+
.iter()
199+
.map(|arg|
200+
Ok(Spanned { node: self.parse_operand(*arg)?, span: self.thir.exprs[*arg].span } )
201+
)
202+
.collect::<PResult<Box<[_]>>>()?;
203+
Ok(TerminatorKind::TailCall {
204+
func: fun,
205+
args,
206+
fn_span: *fn_span,
207+
})
208+
},
209+
)
210+
}
211+
190212
fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
191213
parse_by_kind!(self, expr_id, expr, "rvalue",
192214
@call(mir_discriminant, args) => self.parse_place(args[0]).map(Rvalue::Discriminant),

compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use rustc_data_structures::fx::FxHashMap;
88
use rustc_middle::bug;
9-
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
9+
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
1010
use rustc_target::abi::call::{Conv, FnAbi, PassMode};
1111
use tracing::instrument;
1212

@@ -112,11 +112,12 @@ pub fn typeid_for_instance<'tcx>(
112112
instance: Instance<'tcx>,
113113
options: TypeIdOptions,
114114
) -> String {
115+
assert!(!instance.has_non_region_param(), "{instance:#?} must be fully monomorphic");
115116
let transform_ty_options = TransformTyOptions::from_bits(options.bits())
116117
.unwrap_or_else(|| bug!("typeid_for_instance: invalid option(s) `{:?}`", options.bits()));
117118
let instance = transform_instance(tcx, instance, transform_ty_options);
118119
let fn_abi = tcx
119-
.fn_abi_of_instance(tcx.param_env(instance.def_id()).and((instance, ty::List::empty())))
120+
.fn_abi_of_instance(ty::ParamEnv::reveal_all().and((instance, ty::List::empty())))
120121
.unwrap_or_else(|error| {
121122
bug!("typeid_for_instance: couldn't get fn_abi of instance {instance:?}: {error:?}")
122123
});

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,7 @@ symbols! {
12161216
mir_static_mut,
12171217
mir_storage_dead,
12181218
mir_storage_live,
1219+
mir_tail_call,
12191220
mir_unreachable,
12201221
mir_unwind_cleanup,
12211222
mir_unwind_continue,

compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub fn target() -> Target {
2121
llvm_abiname: "lp64d".into(),
2222
max_atomic_width: Some(64),
2323
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
24+
crt_static_default: false,
2425
..base::linux_musl::opts()
2526
},
2627
}

library/core/src/intrinsics/mir.rs

+8
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@
247247
//! otherwise branch.
248248
//! - [`Call`] has an associated function as well, with special syntax:
249249
//! `Call(ret_val = function(arg1, arg2, ...), ReturnTo(next_block), UnwindContinue())`.
250+
//! - [`TailCall`] does not have a return destination or next block, so its syntax is just
251+
//! `TailCall(function(arg1, arg2, ...))`.
250252
251253
#![unstable(
252254
feature = "custom_mir",
@@ -350,6 +352,12 @@ define!("mir_call",
350352
/// - [`UnwindCleanup`]
351353
fn Call(call: (), goto: ReturnToArg, unwind_action: UnwindActionArg)
352354
);
355+
define!("mir_tail_call",
356+
/// Call a function.
357+
///
358+
/// The argument must be of the form `fun(arg1, arg2, ...)`.
359+
fn TailCall<T>(call: T)
360+
);
353361
define!("mir_unwind_resume",
354362
/// A terminator that resumes the unwinding.
355363
fn UnwindResume()

src/ci/docker/host-x86_64/dist-various-2/Dockerfile

+12-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no
2424
# Needed for apt-key to work:
2525
dirmngr \
2626
gpg-agent \
27-
g++-9-arm-linux-gnueabi
27+
g++-9-arm-linux-gnueabi \
28+
g++-11-riscv64-linux-gnu
2829

2930
RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486
3031
RUN add-apt-repository -y 'deb https://apt.dilos.org/dilos dilos2 main'
@@ -73,6 +74,10 @@ RUN env \
7374
CC=arm-linux-gnueabi-gcc-9 CFLAGS="-march=armv7-a" \
7475
CXX=arm-linux-gnueabi-g++-9 CXXFLAGS="-march=armv7-a" \
7576
bash musl.sh armv7 && \
77+
env \
78+
CC=riscv64-linux-gnu-gcc-11 \
79+
CXX=riscv64-linux-gnu-g++-11 \
80+
bash musl.sh riscv64gc && \
7681
rm -rf /build/*
7782

7883
WORKDIR /tmp
@@ -125,14 +130,19 @@ ENV TARGETS=$TARGETS,x86_64-unknown-none
125130
ENV TARGETS=$TARGETS,aarch64-unknown-uefi
126131
ENV TARGETS=$TARGETS,i686-unknown-uefi
127132
ENV TARGETS=$TARGETS,x86_64-unknown-uefi
133+
ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-musl
128134

129135
# As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
130136
# we need asm in the search path for gcc-9 (for gnux32) but not in the search path of the
131137
# cross compilers.
132138
# Luckily one of the folders is /usr/local/include so symlink /usr/include/x86_64-linux-gnu/asm there
133139
RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm
134140

141+
# musl-gcc can't find libgcc_s.so.1 since it doesn't use the standard search paths.
142+
RUN ln -s /usr/riscv64-linux-gnu/lib/libgcc_s.so.1 /usr/lib/gcc-cross/riscv64-linux-gnu/11/
143+
135144
ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \
136-
--musl-root-armv7=/musl-armv7
145+
--musl-root-armv7=/musl-armv7 \
146+
--musl-root-riscv64gc=/musl-riscv64gc
137147

138148
ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS

src/doc/rustc/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
6767
- [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
6868
- [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md)
69+
- [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md)
6970
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
7071
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
7172
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)

src/doc/rustc/src/platform-support.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ target | notes
9898
`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
9999
`powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17)
100100
[`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29)
101+
[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3)
101102
`s390x-unknown-linux-gnu` | S390x Linux (kernel 3.2, glibc 2.17)
102103
`x86_64-unknown-freebsd` | 64-bit FreeBSD
103104
`x86_64-unknown-illumos` | illumos
@@ -354,7 +355,6 @@ target | std | host | notes
354355
[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit
355356
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD
356357
`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia
357-
`riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.3)
358358
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD
359359
[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
360360
[`riscv64-linux-android`](platform-support/android.md) | | | RISC-V 64-bit Android
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# riscv64gc-unknown-linux-musl
2+
3+
**Tier: 2**
4+
5+
Target for RISC-V Linux programs using musl libc.
6+
7+
## Target maintainers
8+
9+
- [@Amanieu](https://github.com/Amanieu)
10+
- [@kraj](https://github.com/kraj)
11+
12+
## Requirements
13+
14+
Building the target itself requires a RISC-V compiler that is supported by `cc-rs`.
15+
16+
## Building the target
17+
18+
The target can be built by enabling it for a `rustc` build.
19+
20+
```toml
21+
[build]
22+
target = ["riscv64gc-unknown-linux-musl"]
23+
```
24+
25+
Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`:
26+
27+
```toml
28+
[target.riscv64gc-unknown-linux-musl]
29+
cc = "riscv64-linux-gnu-gcc"
30+
cxx = "riscv64-linux-gnu-g++"
31+
ar = "riscv64-linux-gnu-ar"
32+
linker = "riscv64-linux-gnu-gcc"
33+
```
34+
35+
## Building Rust programs
36+
37+
This target are distributed through `rustup`, and otherwise require no
38+
special configuration.
39+
40+
## Cross-compilation
41+
42+
This target can be cross-compiled from any host.
43+
44+
## Testing
45+
46+
This target can be tested as normal with `x.py` on a RISC-V host or via QEMU
47+
emulation.

src/tools/build-manifest/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ static TARGETS: &[&str] = &[
141141
"riscv64gc-unknown-hermit",
142142
"riscv64gc-unknown-none-elf",
143143
"riscv64gc-unknown-linux-gnu",
144+
"riscv64gc-unknown-linux-musl",
144145
"s390x-unknown-linux-gnu",
145146
"sparc64-unknown-linux-gnu",
146147
"sparcv9-sun-solaris",

src/tools/miri/src/intrinsics/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
3333
let this = self.eval_context_mut();
3434

3535
// See if the core engine can handle this intrinsic.
36-
if this.emulate_intrinsic(instance, args, dest, ret)? {
36+
if this.eval_intrinsic(instance, args, dest, ret)? {
3737
return Ok(None);
3838
}
3939
let intrinsic_name = this.tcx.item_name(instance.def_id());

0 commit comments

Comments
 (0)