Rollup merge of #110297 - kylematsuda:earlybinder_tcx_subst, r=BoxyUwU
Make `(try_)subst_and_normalize_erasing_regions` take `EarlyBinder` Changes `subst_and_normalize_erasing_regions` and `try_subst_and_normalize_erasing_regions` to take `EarlyBinder<T>` instead of `T`. (related to #105779) This was suggested by `@BoxyUwU` in https://github.com/rust-lang/rust/pull/107753#discussion_r1105828139. After changing `type_of` to return `EarlyBinder`, there were several places where the binder was immediately skipped to call `tcx.subst_and_normalize_erasing_regions`, only for the binder to be reconstructed inside of that method. r? `@BoxyUwU`
This commit is contained in:
commit
71a1ac2c9a
14 changed files with 44 additions and 29 deletions
|
@ -361,7 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||||
self.instance.subst_mir_and_normalize_erasing_regions(
|
self.instance.subst_mir_and_normalize_erasing_regions(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
value,
|
ty::EarlyBinder(value),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||||
let callee = cx.tcx.subst_and_normalize_erasing_regions(
|
let callee = cx.tcx.subst_and_normalize_erasing_regions(
|
||||||
instance.substs,
|
instance.substs,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
callee,
|
ty::EarlyBinder(callee),
|
||||||
);
|
);
|
||||||
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
|
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
|
||||||
cx.dbg_scope_fn(callee, callee_fn_abi, None)
|
cx.dbg_scope_fn(callee, callee_fn_abi, None)
|
||||||
|
|
|
@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
|
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
|
||||||
instance.substs,
|
instance.substs,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
cx.tcx.type_of(impl_def_id).skip_binder(),
|
cx.tcx.type_of(impl_def_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Only "class" methods are generally understood by LLVM,
|
// Only "class" methods are generally understood by LLVM,
|
||||||
|
|
|
@ -111,7 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
self.instance.subst_mir_and_normalize_erasing_regions(
|
self.instance.subst_mir_and_normalize_erasing_regions(
|
||||||
self.cx.tcx(),
|
self.cx.tcx(),
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
value,
|
ty::EarlyBinder(value),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,7 +495,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
) -> Result<T, InterpError<'tcx>> {
|
) -> Result<T, InterpError<'tcx>> {
|
||||||
frame
|
frame
|
||||||
.instance
|
.instance
|
||||||
.try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value)
|
.try_subst_mir_and_normalize_erasing_regions(
|
||||||
|
*self.tcx,
|
||||||
|
self.param_env,
|
||||||
|
ty::EarlyBinder(value),
|
||||||
|
)
|
||||||
.map_err(|_| err_inval!(TooGeneric))
|
.map_err(|_| err_inval!(TooGeneric))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl<'tcx> Instance<'tcx> {
|
||||||
/// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
|
/// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
|
||||||
pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
|
pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
|
||||||
let ty = tcx.type_of(self.def.def_id());
|
let ty = tcx.type_of(self.def.def_id());
|
||||||
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty.skip_binder())
|
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds a crate that contains a monomorphization of this instance that
|
/// Finds a crate that contains a monomorphization of this instance that
|
||||||
|
@ -578,14 +578,15 @@ impl<'tcx> Instance<'tcx> {
|
||||||
self.def.has_polymorphic_mir_body().then_some(self.substs)
|
self.def.has_polymorphic_mir_body().then_some(self.substs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T
|
pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
|
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
|
||||||
{
|
{
|
||||||
|
let v = v.map_bound(|v| *v);
|
||||||
if let Some(substs) = self.substs_for_mir_body() {
|
if let Some(substs) = self.substs_for_mir_body() {
|
||||||
EarlyBinder(*v).subst(tcx, substs)
|
v.subst(tcx, substs)
|
||||||
} else {
|
} else {
|
||||||
*v
|
v.skip_binder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,7 +595,7 @@ impl<'tcx> Instance<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
v: T,
|
v: EarlyBinder<T>,
|
||||||
) -> T
|
) -> T
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
|
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
|
||||||
|
@ -602,7 +603,7 @@ impl<'tcx> Instance<'tcx> {
|
||||||
if let Some(substs) = self.substs_for_mir_body() {
|
if let Some(substs) = self.substs_for_mir_body() {
|
||||||
tcx.subst_and_normalize_erasing_regions(substs, param_env, v)
|
tcx.subst_and_normalize_erasing_regions(substs, param_env, v)
|
||||||
} else {
|
} else {
|
||||||
tcx.normalize_erasing_regions(param_env, v)
|
tcx.normalize_erasing_regions(param_env, v.skip_binder())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +612,7 @@ impl<'tcx> Instance<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
v: T,
|
v: EarlyBinder<T>,
|
||||||
) -> Result<T, NormalizationError<'tcx>>
|
) -> Result<T, NormalizationError<'tcx>>
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
|
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
|
||||||
|
@ -619,7 +620,7 @@ impl<'tcx> Instance<'tcx> {
|
||||||
if let Some(substs) = self.substs_for_mir_body() {
|
if let Some(substs) = self.substs_for_mir_body() {
|
||||||
tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v)
|
tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v)
|
||||||
} else {
|
} else {
|
||||||
tcx.try_normalize_erasing_regions(param_env, v)
|
tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self,
|
self,
|
||||||
param_substs: SubstsRef<'tcx>,
|
param_substs: SubstsRef<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
value: T,
|
value: EarlyBinder<T>,
|
||||||
) -> T
|
) -> T
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
|
@ -151,7 +151,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
param_env={:?})",
|
param_env={:?})",
|
||||||
param_substs, value, param_env,
|
param_substs, value, param_env,
|
||||||
);
|
);
|
||||||
let substituted = EarlyBinder(value).subst(self, param_substs);
|
let substituted = value.subst(self, param_substs);
|
||||||
self.normalize_erasing_regions(param_env, substituted)
|
self.normalize_erasing_regions(param_env, substituted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self,
|
self,
|
||||||
param_substs: SubstsRef<'tcx>,
|
param_substs: SubstsRef<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
value: T,
|
value: EarlyBinder<T>,
|
||||||
) -> Result<T, NormalizationError<'tcx>>
|
) -> Result<T, NormalizationError<'tcx>>
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
|
@ -175,7 +175,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
param_env={:?})",
|
param_env={:?})",
|
||||||
param_substs, value, param_env,
|
param_substs, value, param_env,
|
||||||
);
|
);
|
||||||
let substituted = EarlyBinder(value).subst(self, param_substs);
|
let substituted = value.subst(self, param_substs);
|
||||||
self.try_normalize_erasing_regions(param_env, substituted)
|
self.try_normalize_erasing_regions(param_env, substituted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions(
|
let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
callee_body.clone(),
|
ty::EarlyBinder(callee_body.clone()),
|
||||||
) else {
|
) else {
|
||||||
return Err("failed to normalize callee body");
|
return Err("failed to normalize callee body");
|
||||||
};
|
};
|
||||||
|
@ -444,7 +444,9 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
work_list.push(target);
|
work_list.push(target);
|
||||||
|
|
||||||
// If the place doesn't actually need dropping, treat it like a regular goto.
|
// If the place doesn't actually need dropping, treat it like a regular goto.
|
||||||
let ty = callsite.callee.subst_mir(self.tcx, &place.ty(callee_body, tcx).ty);
|
let ty = callsite
|
||||||
|
.callee
|
||||||
|
.subst_mir(self.tcx, ty::EarlyBinder(&place.ty(callee_body, tcx).ty));
|
||||||
if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind {
|
if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind {
|
||||||
work_list.push(unwind);
|
work_list.push(unwind);
|
||||||
}
|
}
|
||||||
|
@ -788,7 +790,9 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
|
||||||
match terminator.kind {
|
match terminator.kind {
|
||||||
TerminatorKind::Drop { ref place, unwind, .. } => {
|
TerminatorKind::Drop { ref place, unwind, .. } => {
|
||||||
// If the place doesn't actually need dropping, treat it like a regular goto.
|
// If the place doesn't actually need dropping, treat it like a regular goto.
|
||||||
let ty = self.instance.subst_mir(tcx, &place.ty(self.callee_body, tcx).ty);
|
let ty = self
|
||||||
|
.instance
|
||||||
|
.subst_mir(tcx, ty::EarlyBinder(&place.ty(self.callee_body, tcx).ty));
|
||||||
if ty.needs_drop(tcx, self.param_env) {
|
if ty.needs_drop(tcx, self.param_env) {
|
||||||
self.cost += CALL_PENALTY;
|
self.cost += CALL_PENALTY;
|
||||||
if let UnwindAction::Cleanup(_) = unwind {
|
if let UnwindAction::Cleanup(_) = unwind {
|
||||||
|
@ -799,7 +803,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
|
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
|
||||||
let fn_ty = self.instance.subst_mir(tcx, &f.literal.ty());
|
let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder(&f.literal.ty()));
|
||||||
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
|
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
|
||||||
// Don't give intrinsics the extra penalty for calls
|
// Don't give intrinsics the extra penalty for calls
|
||||||
INSTR_COST
|
INSTR_COST
|
||||||
|
|
|
@ -44,7 +44,11 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
|
||||||
) -> bool {
|
) -> bool {
|
||||||
trace!(%caller);
|
trace!(%caller);
|
||||||
for &(callee, substs) in tcx.mir_inliner_callees(caller.def) {
|
for &(callee, substs) in tcx.mir_inliner_callees(caller.def) {
|
||||||
let Ok(substs) = caller.try_subst_mir_and_normalize_erasing_regions(tcx, param_env, substs) else {
|
let Ok(substs) = caller.try_subst_mir_and_normalize_erasing_regions(
|
||||||
|
tcx,
|
||||||
|
param_env,
|
||||||
|
ty::EarlyBinder(substs),
|
||||||
|
) else {
|
||||||
trace!(?caller, ?param_env, ?substs, "cannot normalize, skipping");
|
trace!(?caller, ?param_env, ?substs, "cannot normalize, skipping");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
|
@ -677,7 +677,7 @@ impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> {
|
||||||
self.instance.subst_mir_and_normalize_erasing_regions(
|
self.instance.subst_mir_and_normalize_erasing_regions(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
value,
|
ty::EarlyBinder(value),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,7 +310,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
|
||||||
let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
|
let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
|
||||||
instance.substs,
|
instance.substs,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
tcx.type_of(impl_def_id).skip_binder(),
|
tcx.type_of(impl_def_id),
|
||||||
);
|
);
|
||||||
if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) {
|
if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) {
|
||||||
return Some(def_id);
|
return Some(def_id);
|
||||||
|
|
|
@ -29,12 +29,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In
|
||||||
let before_feature_tys = tcx.subst_and_normalize_erasing_regions(
|
let before_feature_tys = tcx.subst_and_normalize_erasing_regions(
|
||||||
closure_instance.substs,
|
closure_instance.substs,
|
||||||
param_env,
|
param_env,
|
||||||
before_feature_tys,
|
ty::EarlyBinder(before_feature_tys),
|
||||||
);
|
);
|
||||||
let after_feature_tys = tcx.subst_and_normalize_erasing_regions(
|
let after_feature_tys = tcx.subst_and_normalize_erasing_regions(
|
||||||
closure_instance.substs,
|
closure_instance.substs,
|
||||||
param_env,
|
param_env,
|
||||||
after_feature_tys,
|
ty::EarlyBinder(after_feature_tys),
|
||||||
);
|
);
|
||||||
|
|
||||||
let new_size = tcx
|
let new_size = tcx
|
||||||
|
|
|
@ -27,8 +27,7 @@ fn resolve_instance<'tcx>(
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let ty = tcx.type_of(def);
|
let ty = tcx.type_of(def);
|
||||||
let item_type =
|
let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty);
|
||||||
tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder());
|
|
||||||
|
|
||||||
let def = match *item_type.kind() {
|
let def = match *item_type.kind() {
|
||||||
ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => {
|
ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => {
|
||||||
|
|
|
@ -385,6 +385,9 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
||||||
Node::Expr(parent_expr) => {
|
Node::Expr(parent_expr) => {
|
||||||
if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
|
if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
|
||||||
{
|
{
|
||||||
|
// FIXME: the `subst_identity()` below seems incorrect, since we eventually
|
||||||
|
// call `tcx.try_subst_and_normalize_erasing_regions` further down
|
||||||
|
// (i.e., we are explicitly not in the identity context).
|
||||||
let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder();
|
let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder();
|
||||||
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
|
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
|
||||||
&& let Some(param_ty) = fn_sig.inputs().get(arg_index)
|
&& let Some(param_ty) = fn_sig.inputs().get(arg_index)
|
||||||
|
@ -435,7 +438,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
||||||
let output_ty = fn_sig.output();
|
let output_ty = fn_sig.output();
|
||||||
if output_ty.contains(*param_ty) {
|
if output_ty.contains(*param_ty) {
|
||||||
if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions(
|
if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions(
|
||||||
new_subst, cx.param_env, output_ty) {
|
new_subst, cx.param_env, EarlyBinder(output_ty)) {
|
||||||
expr = parent_expr;
|
expr = parent_expr;
|
||||||
ty = new_ty;
|
ty = new_ty;
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue