Skip to content

Commit df038df

Browse files
committed
very cool commit
1 parent ead49f0 commit df038df

File tree

66 files changed

+777
-235
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+777
-235
lines changed

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ const NOTE_ON_UNDEFINED_BEHAVIOR_ERROR: &str = "The rules on what exactly is und
2424
repository if you believe it should not be considered undefined behavior.";
2525

2626
// Returns a pointer to where the result lives
27+
#[instrument(level = "debug", skip(ecx, body), fields(?param_env=ecx.param_env()), ret)]
2728
fn eval_body_using_ecx<'mir, 'tcx>(
2829
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
2930
cid: GlobalId<'tcx>,
3031
body: &'mir mir::Body<'tcx>,
3132
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
32-
debug!("eval_body_using_ecx: {:?}, {:?}", cid, ecx.param_env);
3333
let tcx = *ecx.tcx;
3434
assert!(
3535
cid.promoted.is_some()
@@ -78,7 +78,6 @@ fn eval_body_using_ecx<'mir, 'tcx>(
7878
intern_const_alloc_recursive(ecx, intern_kind, &ret)?;
7979
// we leave alignment checks off, since this `ecx` will not be used for further evaluation anyway
8080

81-
debug!("eval_body_using_ecx done: {:?}", *ret);
8281
Ok(ret)
8382
}
8483

compiler/rustc_const_eval/src/const_eval/valtrees.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ fn create_mplace_from_layout<'tcx>(
162162
ty: Ty<'tcx>,
163163
) -> MPlaceTy<'tcx> {
164164
let tcx = ecx.tcx;
165-
let param_env = ecx.param_env;
165+
let param_env = ecx.param_env();
166166
let layout = tcx.layout_of(param_env.and(ty)).unwrap();
167167
debug!(?layout);
168168

compiler/rustc_const_eval/src/interpret/cast.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
6464

6565
let instance = ty::Instance::resolve_for_fn_ptr(
6666
*self.tcx,
67-
self.param_env,
67+
self.param_env(),
6868
def_id,
6969
substs,
7070
)
@@ -301,14 +301,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
301301
) -> InterpResult<'tcx> {
302302
// A<Struct> -> A<Trait> conversion
303303
let (src_pointee_ty, dest_pointee_ty) =
304-
self.tcx.struct_lockstep_tails_erasing_lifetimes(source_ty, cast_ty, self.param_env);
304+
self.tcx.struct_lockstep_tails_erasing_lifetimes(source_ty, cast_ty, self.param_env());
305305

306306
match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) {
307307
(&ty::Array(_, length), &ty::Slice(_)) => {
308308
let ptr = self.read_scalar(src)?;
309309
// u64 cast is from usize to u64, which is always good
310310
let val =
311-
Immediate::new_slice(ptr, length.eval_usize(*self.tcx, self.param_env), self);
311+
Immediate::new_slice(ptr, length.eval_usize(*self.tcx, self.param_env()), self);
312312
self.write_immediate(val, dest)
313313
}
314314
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {

compiler/rustc_const_eval/src/interpret/eval_context.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
3737
pub tcx: TyCtxtAt<'tcx>,
3838

3939
/// Bounds in scope for polymorphic evaluations.
40-
pub(crate) param_env: ty::ParamEnv<'tcx>,
40+
///
41+
/// This has to be mutable as we may only lazily reveal opaque types.
42+
pub(crate) param_env: Cell<ty::ParamEnv<'tcx>>,
4143

4244
/// The virtual memory system.
4345
pub memory: Memory<'mir, 'tcx, M>,
@@ -298,7 +300,7 @@ where
298300
M: Machine<'mir, 'tcx>,
299301
{
300302
fn param_env(&self) -> ty::ParamEnv<'tcx> {
301-
self.param_env
303+
self.param_env.get()
302304
}
303305
}
304306

@@ -405,7 +407,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
405407
InterpCx {
406408
machine,
407409
tcx: tcx.at(root_span),
408-
param_env,
410+
param_env: Cell::new(param_env),
409411
memory: Memory::new(),
410412
recursion_limit: tcx.recursion_limit(),
411413
}
@@ -418,6 +420,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
418420
self.stack().last().map_or(self.tcx.span, |f| f.current_span())
419421
}
420422

423+
#[inline(always)]
424+
pub fn param_env(&self) -> ParamEnv<'tcx> {
425+
self.param_env.get()
426+
}
427+
421428
#[inline(always)]
422429
pub(crate) fn stack(&self) -> &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>] {
423430
M::stack(self)
@@ -465,7 +472,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
465472

466473
#[inline]
467474
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
468-
ty.is_freeze(self.tcx, self.param_env)
475+
ty.is_freeze(self.tcx, self.param_env())
476+
}
477+
478+
pub fn reveal_opaque_types_in_value<T: TypeFoldable<'tcx>>(&self, value: T) -> T {
479+
let (param_env, value) = self.tcx.reveal_opaque_types_in_value(self.param_env.get(), value);
480+
self.param_env.set(param_env);
481+
value
469482
}
470483

471484
pub fn load_mir(
@@ -505,7 +518,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
505518
) -> Result<T, InterpError<'tcx>> {
506519
frame
507520
.instance
508-
.try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value)
521+
.try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env(), value)
522+
.map(|value| {
523+
let (param_env, value) =
524+
self.tcx.reveal_opaque_types_in_value(self.param_env.get(), value);
525+
self.param_env.set(param_env);
526+
value
527+
})
509528
.map_err(|e| {
510529
self.tcx.sess.delay_span_bug(
511530
self.cur_span(),
@@ -517,15 +536,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
517536
}
518537

519538
/// The `substs` are assumed to already be in our interpreter "universe" (param_env).
539+
#[instrument(level = "trace", skip(self), fields(param_env = ?self.param_env), ret)]
520540
pub(super) fn resolve(
521541
&self,
522542
def: ty::WithOptConstParam<DefId>,
523543
substs: SubstsRef<'tcx>,
524544
) -> InterpResult<'tcx, ty::Instance<'tcx>> {
525-
trace!("resolve: {:?}, {:#?}", def, substs);
526-
trace!("param_env: {:#?}", self.param_env);
527-
trace!("substs: {:#?}", substs);
528-
match ty::Instance::resolve_opt_const_arg(*self.tcx, self.param_env, def, substs) {
545+
match ty::Instance::resolve_opt_const_arg(*self.tcx, self.param_env(), def, substs) {
529546
Ok(Some(instance)) => Ok(instance),
530547
Ok(None) => throw_inval!(TooGeneric),
531548

@@ -545,7 +562,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
545562
// have to support that case (mostly by skipping all caching).
546563
match frame.locals.get(local).and_then(|state| state.layout.get()) {
547564
None => {
548-
let layout = from_known_layout(self.tcx, self.param_env, layout, || {
565+
let layout = from_known_layout(self.tcx, self.param_env(), layout, || {
549566
let local_ty = frame.body.local_decls[local].ty;
550567
let local_ty =
551568
self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
@@ -914,7 +931,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
914931
let param_env = if self.tcx.is_static(gid.instance.def_id()) {
915932
ty::ParamEnv::reveal_all()
916933
} else {
917-
self.param_env
934+
self.param_env()
918935
};
919936
let param_env = param_env.with_const();
920937
// Use a precise span for better cycle errors.

compiler/rustc_const_eval/src/interpret/intern.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
114114
if let InternMode::Static(mutability) = mode {
115115
// For this, we need to take into account `UnsafeCell`. When `ty` is `None`, we assume
116116
// no interior mutability.
117-
let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx, ecx.param_env));
117+
let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx, ecx.param_env.get()));
118118
// For statics, allocation mutability is the combination of place mutability and
119119
// type mutability.
120120
// The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
@@ -243,7 +243,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
243243
assert_eq!(mplace.layout.ty, referenced_ty);
244244
// Handle trait object vtables.
245245
if let ty::Dynamic(..) =
246-
tcx.struct_tail_erasing_lifetimes(referenced_ty, self.ecx.param_env).kind()
246+
tcx.struct_tail_erasing_lifetimes(referenced_ty, self.ecx.param_env()).kind()
247247
{
248248
let ptr = mplace.meta.unwrap_meta().to_pointer(&tcx)?;
249249
if let Some(alloc_id) = ptr.provenance {

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
170170
_ => bug!(),
171171
};
172172
let val =
173-
self.tcx.const_eval_global_id(self.param_env, gid, Some(self.tcx.span))?;
173+
self.tcx.const_eval_global_id(self.param_env(), gid, Some(self.tcx.span))?;
174174
let val = self.const_val_to_op(val, ty, Some(dest.layout))?;
175175
self.copy_op(&val, dest, /*allow_transmute*/ false)?;
176176
}

compiler/rustc_const_eval/src/interpret/operand.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
499499
debug_assert!(
500500
mir_assign_valid_types(
501501
*self.tcx,
502-
self.param_env,
502+
self.param_env(),
503503
self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions(
504504
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty
505505
)?)?,
@@ -570,7 +570,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
570570
let cid = GlobalId { instance, promoted: None };
571571
let _valtree = self
572572
.tcx
573-
.eval_to_valtree(self.param_env.and(cid))?
573+
.eval_to_valtree(self.param_env().and(cid))?
574574
.unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}"));
575575

576576
Ok(self.eval_to_allocation(cid)?.into())
@@ -606,7 +606,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
606606
Scalar::Int(int) => Scalar::Int(int),
607607
})
608608
};
609-
let layout = from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty))?;
609+
let layout = from_known_layout(self.tcx, self.param_env(), layout, || self.layout_of(ty))?;
610610
let op = match val_val {
611611
ConstValue::ByRef { alloc, offset } => {
612612
let id = self.tcx.create_memory_alloc(alloc);

compiler/rustc_const_eval/src/interpret/place.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ where
426426
debug_assert!(
427427
mir_assign_valid_types(
428428
*self.tcx,
429-
self.param_env,
429+
self.param_env(),
430430
self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions(
431431
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty
432432
)?)?,
@@ -626,7 +626,7 @@ where
626626
// We do NOT compare the types for equality, because well-typed code can
627627
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
628628
let layout_compat =
629-
mir_assign_valid_types(*self.tcx, self.param_env, src.layout, dest.layout);
629+
mir_assign_valid_types(*self.tcx, self.param_env(), src.layout, dest.layout);
630630
if !allow_transmute && !layout_compat {
631631
span_bug!(
632632
self.cur_span(),

compiler/rustc_const_eval/src/interpret/terminator.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
7373

7474
let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx);
7575
let fn_sig =
76-
self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder);
76+
self.tcx.normalize_erasing_late_bound_regions(self.param_env(), fn_sig_binder);
7777
let extra_args = &args[fn_sig.inputs().len()..];
7878
let extra_args = self.tcx.mk_type_list(extra_args.iter().map(|arg| arg.layout.ty));
7979

@@ -86,6 +86,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
8686
ty::FnDef(def_id, substs) => {
8787
let instance =
8888
self.resolve(ty::WithOptConstParam::unknown(def_id), substs)?;
89+
let instance = self.reveal_opaque_types_in_value(instance);
8990
(
9091
FnVal::Instance(instance),
9192
self.fn_abi_of_instance(instance, extra_args)?,
@@ -563,7 +564,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
563564
// Obtain the underlying trait we are working on.
564565
let receiver_tail = self
565566
.tcx
566-
.struct_tail_erasing_lifetimes(receiver_place.layout.ty, self.param_env);
567+
.struct_tail_erasing_lifetimes(receiver_place.layout.ty, self.param_env());
567568
let ty::Dynamic(data, ..) = receiver_tail.kind() else {
568569
span_bug!(self.cur_span(), "dynamic call on non-`dyn` type {}", receiver_tail)
569570
};
@@ -599,7 +600,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
599600

600601
let concrete_method = Instance::resolve_for_vtable(
601602
tcx,
602-
self.param_env,
603+
self.param_env(),
603604
def_id,
604605
instance.substs.rebase_onto(tcx, trait_def_id, concrete_trait_ref.substs),
605606
)

compiler/rustc_const_eval/src/interpret/util.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ where
1313
T: TypeVisitable<'tcx>,
1414
{
1515
debug!("ensure_monomorphic_enough: ty={:?}", ty);
16-
if !ty.needs_subst() {
16+
if !(ty.needs_subst() || ty.has_opaque_types()) {
1717
return Ok(());
1818
}
1919

@@ -31,7 +31,7 @@ where
3131
}
3232

3333
match *ty.kind() {
34-
ty::Param(_) => ControlFlow::Break(FoundParam),
34+
ty::Param(_) | ty::Opaque(..) => ControlFlow::Break(FoundParam),
3535
ty::Closure(def_id, substs)
3636
| ty::Generator(def_id, substs, ..)
3737
| ty::FnDef(def_id, substs) => {

compiler/rustc_const_eval/src/interpret/validity.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
333333
meta: MemPlaceMeta<M::Provenance>,
334334
pointee: TyAndLayout<'tcx>,
335335
) -> InterpResult<'tcx> {
336-
let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
336+
let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env());
337337
match tail.kind() {
338338
ty::Dynamic(..) => {
339339
let vtable = meta.unwrap_meta().to_pointer(self.ecx)?;
@@ -726,7 +726,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
726726
) -> InterpResult<'tcx> {
727727
// Special check preventing `UnsafeCell` inside unions in the inner part of constants.
728728
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. })) {
729-
if !op.layout.ty.is_freeze(self.ecx.tcx.at(DUMMY_SP), self.ecx.param_env) {
729+
if !op.layout.ty.is_freeze(self.ecx.tcx.at(DUMMY_SP), self.ecx.param_env()) {
730730
throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });
731731
}
732732
}

0 commit comments

Comments
 (0)