Skip to content

Commit 56d99ac

Browse files
Make param-env optional in drop elaboration
1 parent ab1527f commit 56d99ac

File tree

6 files changed

+35
-31
lines changed

6 files changed

+35
-31
lines changed

compiler/rustc_mir_dataflow/src/elaborate_drops.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,11 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug {
111111
fn patch(&mut self) -> &mut MirPatch<'tcx>;
112112
fn body(&self) -> &'a Body<'tcx>;
113113
fn tcx(&self) -> TyCtxt<'tcx>;
114-
fn param_env(&self) -> ty::ParamEnv<'tcx>;
114+
115+
// A param-env that can be used to compute drop queries (such as `Ty::needs_drop`).
116+
// If this is `None`, then the elaborator must handle the type as if it were unknown,
117+
// i.e. emitting full drops.
118+
fn param_env(&self) -> Option<ty::ParamEnv<'tcx>>;
115119

116120
// Drop logic
117121

@@ -276,9 +280,11 @@ where
276280
let subpath = self.elaborator.field_subpath(variant_path, field);
277281
let tcx = self.tcx();
278282

279-
assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
280-
let field_ty =
281-
tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, args));
283+
let mut field_ty = f.ty(tcx, args);
284+
if let Some(param_env) = self.elaborator.param_env() {
285+
assert_eq!(param_env.reveal(), Reveal::All);
286+
field_ty = tcx.normalize_erasing_regions(param_env, field_ty);
287+
}
282288

283289
(tcx.mk_place_field(base_place, field, field_ty), subpath)
284290
})
@@ -374,9 +380,9 @@ where
374380
debug!("drop_ladder({:?}, {:?})", self, fields);
375381

376382
let mut fields = fields;
377-
fields.retain(|&(place, _)| {
378-
self.place_ty(place).needs_drop(self.tcx(), self.elaborator.param_env())
379-
});
383+
if let Some(param_env) = self.elaborator.param_env() {
384+
fields.retain(|&(place, _)| self.place_ty(place).needs_drop(self.tcx(), param_env));
385+
}
380386

381387
debug!("drop_ladder - fields needing drop: {:?}", fields);
382388

@@ -548,10 +554,13 @@ where
548554
have_otherwise = true;
549555

550556
let param_env = self.elaborator.param_env();
551-
let have_field_with_drop_glue = variant
552-
.fields
553-
.iter()
554-
.any(|field| field.ty(tcx, args).needs_drop(tcx, param_env));
557+
558+
let have_field_with_drop_glue = param_env.is_none_or(|param_env| {
559+
variant
560+
.fields
561+
.iter()
562+
.any(|field| field.ty(tcx, args).needs_drop(tcx, param_env))
563+
});
555564
if have_field_with_drop_glue {
556565
have_otherwise_with_drop_glue = true;
557566
}
@@ -869,7 +878,10 @@ where
869878
ty::Adt(def, args) => self.open_drop_for_adt(*def, args),
870879
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
871880
ty::Array(ety, size) => {
872-
let size = size.try_eval_target_usize(self.tcx(), self.elaborator.param_env());
881+
let size = self
882+
.elaborator
883+
.param_env()
884+
.and_then(|param_env| size.try_eval_target_usize(self.tcx(), param_env));
873885
self.open_drop_for_array(*ety, size)
874886
}
875887
ty::Slice(ety) => self.drop_loop_pair(*ety),

compiler/rustc_mir_dataflow/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![feature(associated_type_defaults)]
33
#![feature(box_patterns)]
44
#![feature(exact_size_is_empty)]
5+
#![feature(is_none_or)]
56
#![feature(let_chains)]
67
#![feature(try_blocks)]
78
// tidy-alphabetical-end

compiler/rustc_mir_transform/src/coroutine.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,8 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
11741174
let def_id = body.source.def_id();
11751175
let param_env = tcx.param_env(def_id);
11761176

1177-
let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env };
1177+
let mut elaborator =
1178+
DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env: Some(param_env) };
11781179

11791180
for (block, block_data) in body.basic_blocks.iter_enumerated() {
11801181
let (target, unwind, source_info) = match block_data.terminator() {

compiler/rustc_mir_transform/src/elaborate_drops.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
161161
self.ctxt.tcx
162162
}
163163

164-
fn param_env(&self) -> ty::ParamEnv<'tcx> {
165-
self.ctxt.param_env()
164+
fn param_env(&self) -> Option<ty::ParamEnv<'tcx>> {
165+
Some(self.ctxt.param_env())
166166
}
167167

168168
#[instrument(level = "debug", skip(self), ret)]

compiler/rustc_mir_transform/src/inline.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ use rustc_middle::bug;
1212
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
1313
use rustc_middle::mir::visit::*;
1414
use rustc_middle::mir::*;
15-
use rustc_middle::ty::{
16-
self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt, TypeFlags, TypeVisitableExt,
17-
};
15+
use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
1816
use rustc_session::config::{DebugInfo, OptLevel};
1917
use rustc_span::source_map::Spanned;
2018
use rustc_span::sym;
@@ -323,15 +321,6 @@ impl<'tcx> Inliner<'tcx> {
323321
return Err("instance without MIR (intrinsic / virtual)");
324322
}
325323

326-
// FIXME(#127030): `ConstParamHasTy` has bad interactions with
327-
// the drop shim builder, which does not evaluate predicates in
328-
// the correct param-env for types being dropped. Stall resolving
329-
// the MIR for this instance until all of its const params are
330-
// substituted.
331-
InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => {
332-
return Err("still needs substitution");
333-
}
334-
335324
// This cannot result in an immediate cycle since the callee MIR is a shim, which does
336325
// not get any optimizations run on it. Any subsequent inlining may cause cycles, but we
337326
// do not need to catch this here, we can wait until the inliner decides to continue

compiler/rustc_mir_transform/src/shim.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::mir::patch::MirPatch;
99
use rustc_middle::mir::*;
1010
use rustc_middle::query::Providers;
1111
use rustc_middle::ty::{
12-
self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt,
12+
self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeVisitableExt,
1313
};
1414
use rustc_middle::{bug, span_bug};
1515
use rustc_mir_dataflow::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle};
@@ -276,7 +276,8 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
276276

277277
if ty.is_some() {
278278
let patch = {
279-
let param_env = tcx.param_env_reveal_all_normalized(def_id);
279+
let param_env =
280+
if ty.has_non_region_param() { None } else { Some(ty::ParamEnv::reveal_all()) };
280281
let mut elaborator =
281282
DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, param_env };
282283
let dropee = tcx.mk_place_deref(dropee_ptr);
@@ -336,7 +337,7 @@ pub struct DropShimElaborator<'a, 'tcx> {
336337
pub body: &'a Body<'tcx>,
337338
pub patch: MirPatch<'tcx>,
338339
pub tcx: TyCtxt<'tcx>,
339-
pub param_env: ty::ParamEnv<'tcx>,
340+
pub param_env: Option<ty::ParamEnv<'tcx>>,
340341
}
341342

342343
impl fmt::Debug for DropShimElaborator<'_, '_> {
@@ -357,7 +358,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
357358
fn tcx(&self) -> TyCtxt<'tcx> {
358359
self.tcx
359360
}
360-
fn param_env(&self) -> ty::ParamEnv<'tcx> {
361+
fn param_env(&self) -> Option<ty::ParamEnv<'tcx>> {
361362
self.param_env
362363
}
363364

0 commit comments

Comments
 (0)