summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorb-naber <b_naber@gmx.de>2023-05-04 21:03:57 +0000
committerb-naber <b_naber@gmx.de>2023-05-10 16:03:52 +0000
commite7a2f52ba163a47e751b6e6d666b52c2acdd0949 (patch)
tree2305971c67a1883c2b80fa6ea276adf72ae92dd4
parent7871bec7aaad47e8bfaca4fc06c5cb96c466917f (diff)
downloadrust-e7a2f52ba163a47e751b6e6d666b52c2acdd0949.tar.gz
don't inline polymorphic adt instances whose fields contain projections
in DropGlue.
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs11
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs27
2 files changed, 29 insertions, 9 deletions
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index e2f538e22b7..18895072c3b 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -272,15 +272,10 @@ where
let field = FieldIdx::new(i);
let subpath = self.elaborator.field_subpath(variant_path, field);
let tcx = self.tcx();
- assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
- let fty = f.ty(tcx, substs);
- let field_ty = match tcx
- .try_normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs))
- {
- Ok(f_ty) => f_ty,
- Err(_) => fty,
- };
+ assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
+ let field_ty =
+ tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs));
(tcx.mk_place_field(base_place, field, field_ty), subpath)
})
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 71bdfd5aae1..092bbcea0ca 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -7,6 +7,7 @@ use rustc_index::Idx;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
+use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_session::config::OptLevel;
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
@@ -168,7 +169,7 @@ impl<'tcx> Inliner<'tcx> {
let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id());
self.check_codegen_attributes(callsite, callee_attrs)?;
self.check_mir_is_available(caller_body, &callsite.callee)?;
- let callee_body = self.tcx.instance_mir(callsite.callee.def);
+ let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?;
self.check_mir_body(callsite, callee_body, callee_attrs)?;
if !self.tcx.consider_optimizing(|| {
@@ -1124,3 +1125,27 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
}
}
}
+
+#[instrument(skip(tcx), level = "debug")]
+fn try_instance_mir<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ instance: InstanceDef<'tcx>,
+) -> Result<&'tcx Body<'tcx>, &'static str> {
+ match instance {
+ ty::InstanceDef::DropGlue(_, Some(ty)) => match ty.kind() {
+ ty::Adt(def, substs) => {
+ let fields = def.all_fields();
+ for field in fields {
+ let field_ty = field.ty(tcx, substs);
+ if field_ty.has_param() && field_ty.has_projections() {
+ return Err("cannot build drop shim for polymorphic type");
+ }
+ }
+
+ Ok(tcx.instance_mir(instance))
+ }
+ _ => Ok(tcx.instance_mir(instance)),
+ },
+ _ => Ok(tcx.instance_mir(instance)),
+ }
+}