Skip to content

Commit

Permalink
Make param-env optional in drop elaboration
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Aug 4, 2024
1 parent ab1527f commit 56d99ac
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 31 deletions.
36 changes: 24 additions & 12 deletions compiler/rustc_mir_dataflow/src/elaborate_drops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug {
fn patch(&mut self) -> &mut MirPatch<'tcx>;
fn body(&self) -> &'a Body<'tcx>;
fn tcx(&self) -> TyCtxt<'tcx>;
fn param_env(&self) -> ty::ParamEnv<'tcx>;

// A param-env that can be used to compute drop queries (such as `Ty::needs_drop`).
// If this is `None`, then the elaborator must handle the type as if it were unknown,
// i.e. emitting full drops.
fn param_env(&self) -> Option<ty::ParamEnv<'tcx>>;

// Drop logic

Expand Down Expand Up @@ -276,9 +280,11 @@ where
let subpath = self.elaborator.field_subpath(variant_path, field);
let tcx = self.tcx();

assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
let field_ty =
tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, args));
let mut field_ty = f.ty(tcx, args);
if let Some(param_env) = self.elaborator.param_env() {
assert_eq!(param_env.reveal(), Reveal::All);
field_ty = tcx.normalize_erasing_regions(param_env, field_ty);
}

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

let mut fields = fields;
fields.retain(|&(place, _)| {
self.place_ty(place).needs_drop(self.tcx(), self.elaborator.param_env())
});
if let Some(param_env) = self.elaborator.param_env() {
fields.retain(|&(place, _)| self.place_ty(place).needs_drop(self.tcx(), param_env));
}

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

Expand Down Expand Up @@ -548,10 +554,13 @@ where
have_otherwise = true;

let param_env = self.elaborator.param_env();
let have_field_with_drop_glue = variant
.fields
.iter()
.any(|field| field.ty(tcx, args).needs_drop(tcx, param_env));

let have_field_with_drop_glue = param_env.is_none_or(|param_env| {
variant
.fields
.iter()
.any(|field| field.ty(tcx, args).needs_drop(tcx, param_env))
});
if have_field_with_drop_glue {
have_otherwise_with_drop_glue = true;
}
Expand Down Expand Up @@ -869,7 +878,10 @@ where
ty::Adt(def, args) => self.open_drop_for_adt(*def, args),
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
ty::Array(ety, size) => {
let size = size.try_eval_target_usize(self.tcx(), self.elaborator.param_env());
let size = self
.elaborator
.param_env()
.and_then(|param_env| size.try_eval_target_usize(self.tcx(), param_env));
self.open_drop_for_array(*ety, size)
}
ty::Slice(ety) => self.drop_loop_pair(*ety),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_dataflow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(exact_size_is_empty)]
#![feature(is_none_or)]
#![feature(let_chains)]
#![feature(try_blocks)]
// tidy-alphabetical-end
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_mir_transform/src/coroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,8 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let def_id = body.source.def_id();
let param_env = tcx.param_env(def_id);

let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env };
let mut elaborator =
DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env: Some(param_env) };

for (block, block_data) in body.basic_blocks.iter_enumerated() {
let (target, unwind, source_info) = match block_data.terminator() {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/elaborate_drops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
self.ctxt.tcx
}

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

#[instrument(level = "debug", skip(self), ret)]
Expand Down
13 changes: 1 addition & 12 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::{
self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt, TypeFlags, TypeVisitableExt,
};
use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
use rustc_session::config::{DebugInfo, OptLevel};
use rustc_span::source_map::Spanned;
use rustc_span::sym;
Expand Down Expand Up @@ -323,15 +321,6 @@ impl<'tcx> Inliner<'tcx> {
return Err("instance without MIR (intrinsic / virtual)");
}

// FIXME(#127030): `ConstParamHasTy` has bad interactions with
// the drop shim builder, which does not evaluate predicates in
// the correct param-env for types being dropped. Stall resolving
// the MIR for this instance until all of its const params are
// substituted.
InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => {
return Err("still needs substitution");
}

// This cannot result in an immediate cycle since the callee MIR is a shim, which does
// not get any optimizations run on it. Any subsequent inlining may cause cycles, but we
// do not need to catch this here, we can wait until the inliner decides to continue
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_mir_transform/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_middle::mir::patch::MirPatch;
use rustc_middle::mir::*;
use rustc_middle::query::Providers;
use rustc_middle::ty::{
self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt,
self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeVisitableExt,
};
use rustc_middle::{bug, span_bug};
use rustc_mir_dataflow::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle};
Expand Down Expand Up @@ -276,7 +276,8 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)

if ty.is_some() {
let patch = {
let param_env = tcx.param_env_reveal_all_normalized(def_id);
let param_env =
if ty.has_non_region_param() { None } else { Some(ty::ParamEnv::reveal_all()) };
let mut elaborator =
DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, param_env };
let dropee = tcx.mk_place_deref(dropee_ptr);
Expand Down Expand Up @@ -336,7 +337,7 @@ pub struct DropShimElaborator<'a, 'tcx> {
pub body: &'a Body<'tcx>,
pub patch: MirPatch<'tcx>,
pub tcx: TyCtxt<'tcx>,
pub param_env: ty::ParamEnv<'tcx>,
pub param_env: Option<ty::ParamEnv<'tcx>>,
}

impl fmt::Debug for DropShimElaborator<'_, '_> {
Expand All @@ -357,7 +358,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn param_env(&self) -> ty::ParamEnv<'tcx> {
fn param_env(&self) -> Option<ty::ParamEnv<'tcx>> {
self.param_env
}

Expand Down

0 comments on commit 56d99ac

Please sign in to comment.