Skip to content

Commit 99836b5

Browse files
Make param-env optional in drop elaboration
1 parent cae4a84 commit 99836b5

File tree

6 files changed

+35
-29
lines changed

6 files changed

+35
-29
lines changed

compiler/rustc_mir_dataflow/src/elaborate_drops.rs

+24-12
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

+1
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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,8 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
11781178
let def_id = body.source.def_id();
11791179
let param_env = tcx.param_env(def_id);
11801180

1181-
let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env };
1181+
let mut elaborator =
1182+
DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env: Some(param_env) };
11821183

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

compiler/rustc_mir_transform/src/elaborate_drops.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
159159
self.ctxt.tcx
160160
}
161161

162-
fn param_env(&self) -> ty::ParamEnv<'tcx> {
163-
self.ctxt.param_env()
162+
fn param_env(&self) -> Option<ty::ParamEnv<'tcx>> {
163+
Some(self.ctxt.param_env())
164164
}
165165

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

compiler/rustc_mir_transform/src/inline.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}
1111
use rustc_middle::mir::visit::*;
1212
use rustc_middle::mir::*;
1313
use rustc_middle::ty::TypeVisitableExt;
14-
use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt, TypeFlags};
14+
use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt};
1515
use rustc_session::config::{DebugInfo, OptLevel};
1616
use rustc_span::source_map::Spanned;
1717
use rustc_span::sym;
@@ -321,15 +321,6 @@ impl<'tcx> Inliner<'tcx> {
321321
return Err("instance without MIR (intrinsic / virtual)");
322322
}
323323

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

compiler/rustc_mir_transform/src/shim.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use rustc_hir::lang_items::LangItem;
44
use rustc_index::{Idx, IndexVec};
55
use rustc_middle::mir::*;
66
use rustc_middle::query::Providers;
7-
use rustc_middle::ty::GenericArgs;
87
use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, Ty, TyCtxt};
8+
use rustc_middle::ty::{GenericArgs, TypeVisitableExt};
99
use rustc_middle::{bug, span_bug};
1010
use rustc_span::{source_map::Spanned, Span, DUMMY_SP};
1111
use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
@@ -274,7 +274,8 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
274274

275275
if ty.is_some() {
276276
let patch = {
277-
let param_env = tcx.param_env_reveal_all_normalized(def_id);
277+
let param_env =
278+
if ty.has_non_region_param() { None } else { Some(ty::ParamEnv::reveal_all()) };
278279
let mut elaborator =
279280
DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, param_env };
280281
let dropee = tcx.mk_place_deref(dropee_ptr);
@@ -331,7 +332,7 @@ pub struct DropShimElaborator<'a, 'tcx> {
331332
pub body: &'a Body<'tcx>,
332333
pub patch: MirPatch<'tcx>,
333334
pub tcx: TyCtxt<'tcx>,
334-
pub param_env: ty::ParamEnv<'tcx>,
335+
pub param_env: Option<ty::ParamEnv<'tcx>>,
335336
}
336337

337338
impl fmt::Debug for DropShimElaborator<'_, '_> {
@@ -352,7 +353,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
352353
fn tcx(&self) -> TyCtxt<'tcx> {
353354
self.tcx
354355
}
355-
fn param_env(&self) -> ty::ParamEnv<'tcx> {
356+
fn param_env(&self) -> Option<ty::ParamEnv<'tcx>> {
356357
self.param_env
357358
}
358359

0 commit comments

Comments
 (0)