don't inline polymorphic adt instances whose fields contain projections

in DropGlue.
This commit is contained in:
b-naber 2023-05-04 21:03:57 +00:00
parent 7871bec7aa
commit e7a2f52ba1
2 changed files with 29 additions and 9 deletions

View File

@ -272,15 +272,10 @@ fn move_paths_for_fields(
let field = FieldIdx::new(i); let field = FieldIdx::new(i);
let subpath = self.elaborator.field_subpath(variant_path, field); let subpath = self.elaborator.field_subpath(variant_path, field);
let tcx = self.tcx(); let tcx = self.tcx();
assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
let fty = f.ty(tcx, substs); assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
let field_ty = match tcx let field_ty =
.try_normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)) tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs));
{
Ok(f_ty) => f_ty,
Err(_) => fty,
};
(tcx.mk_place_field(base_place, field, field_ty), subpath) (tcx.mk_place_field(base_place, field, field_ty), subpath)
}) })

View File

@ -7,6 +7,7 @@
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::visit::*; use rustc_middle::mir::visit::*;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_session::config::OptLevel; use rustc_session::config::OptLevel;
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
@ -168,7 +169,7 @@ fn try_inlining(
let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id()); let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id());
self.check_codegen_attributes(callsite, callee_attrs)?; self.check_codegen_attributes(callsite, callee_attrs)?;
self.check_mir_is_available(caller_body, &callsite.callee)?; 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)?; self.check_mir_body(callsite, callee_body, callee_attrs)?;
if !self.tcx.consider_optimizing(|| { if !self.tcx.consider_optimizing(|| {
@ -1124,3 +1125,27 @@ fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, loc: Location)
} }
} }
} }
#[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)),
}
}