Skip to content

Commit b586701

Browse files
committed
Auto merge of rust-lang#128707 - matthiaskrgr:rollup-63klywk, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#122049 (Promote riscv64gc-unknown-linux-musl to tier 2) - rust-lang#128580 (Use `ParamEnv::reveal_all` in CFI) - rust-lang#128688 (custom MIR: add support for tail calls) - rust-lang#128694 (Normalize when equating `dyn` tails in MIR borrowck) - rust-lang#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

Lines changed: 6 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 36 additions & 1 deletion
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

Lines changed: 8 additions & 35 deletions
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

Lines changed: 22 additions & 0 deletions
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

Lines changed: 3 additions & 2 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 8 additions & 0 deletions
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()

0 commit comments

Comments
 (0)