Rollup merge of #150861 - folding-cleanups, r=lcnr
Folding/`ReErased` cleanups Various cleanups I found while reading this code closely, mostly involving folding and the use of `ReErased`. r? @lcnr
This commit is contained in:
commit
79445c315e
13 changed files with 25 additions and 74 deletions
|
|
@ -1520,7 +1520,6 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
|
|||
// Unwrap potential addrspacecast
|
||||
let vtable = find_vtable_behind_cast(vtable);
|
||||
let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty);
|
||||
let trait_ref_self = cx.tcx.erase_and_anonymize_regions(trait_ref_self);
|
||||
let trait_def_id = trait_ref_self.def_id;
|
||||
let trait_vis = cx.tcx.visibility(trait_def_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
|||
use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint};
|
||||
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug, ty};
|
||||
use rustc_span::{Symbol, sym};
|
||||
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
|
||||
|
|
@ -243,13 +243,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
ocx.register_obligations(preds.iter().map(|pred: PolyExistentialPredicate<'_>| {
|
||||
let pred = pred.with_self_ty(tcx, tp_ty);
|
||||
// Lifetimes can only be 'static because of the bound on T
|
||||
let pred = pred.fold_with(&mut ty::BottomUpFolder {
|
||||
tcx,
|
||||
ty_op: |ty| ty,
|
||||
lt_op: |lt| {
|
||||
if lt == tcx.lifetimes.re_erased { tcx.lifetimes.re_static } else { lt }
|
||||
},
|
||||
ct_op: |ct| ct,
|
||||
let pred = ty::fold_regions(tcx, pred, |r, _| {
|
||||
if r == tcx.lifetimes.re_erased { tcx.lifetimes.re_static } else { r }
|
||||
});
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, pred)
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -508,23 +508,18 @@ fn sanity_check_found_hidden_type<'tcx>(
|
|||
return Ok(());
|
||||
}
|
||||
}
|
||||
let strip_vars = |ty: Ty<'tcx>| {
|
||||
ty.fold_with(&mut BottomUpFolder {
|
||||
tcx,
|
||||
ty_op: |t| t,
|
||||
ct_op: |c| c,
|
||||
lt_op: |l| match l.kind() {
|
||||
RegionKind::ReVar(_) => tcx.lifetimes.re_erased,
|
||||
_ => l,
|
||||
},
|
||||
let erase_re_vars = |ty: Ty<'tcx>| {
|
||||
fold_regions(tcx, ty, |r, _| match r.kind() {
|
||||
RegionKind::ReVar(_) => tcx.lifetimes.re_erased,
|
||||
_ => r,
|
||||
})
|
||||
};
|
||||
// Closures frequently end up containing erased lifetimes in their final representation.
|
||||
// These correspond to lifetime variables that never got resolved, so we patch this up here.
|
||||
ty.ty = strip_vars(ty.ty);
|
||||
ty.ty = erase_re_vars(ty.ty);
|
||||
// Get the hidden type.
|
||||
let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args);
|
||||
let hidden_ty = strip_vars(hidden_ty);
|
||||
let hidden_ty = erase_re_vars(hidden_ty);
|
||||
|
||||
// If the hidden types differ, emit a type mismatch diagnostic.
|
||||
if hidden_ty == ty.ty {
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
|
|||
|
||||
fn is_transmutable(
|
||||
&self,
|
||||
dst: <Self::Interner as Interner>::Ty,
|
||||
src: <Self::Interner as Interner>::Ty,
|
||||
dst: <Self::Interner as Interner>::Ty,
|
||||
assume: <Self::Interner as Interner>::Const,
|
||||
) -> Result<Certainty, NoSolution>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1170,8 +1170,8 @@ where
|
|||
|
||||
pub(super) fn is_transmutable(
|
||||
&mut self,
|
||||
dst: I::Ty,
|
||||
src: I::Ty,
|
||||
dst: I::Ty,
|
||||
assume: I::Const,
|
||||
) -> Result<Certainty, NoSolution> {
|
||||
self.delegate.is_transmutable(dst, src, assume)
|
||||
|
|
|
|||
|
|
@ -2781,11 +2781,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
self.tcx.instantiate_bound_regions_with_erased(trait_pred),
|
||||
);
|
||||
|
||||
let src_and_dst = rustc_transmute::Types {
|
||||
dst: trait_pred.trait_ref.args.type_at(0),
|
||||
src: trait_pred.trait_ref.args.type_at(1),
|
||||
};
|
||||
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
let Ok(assume) = ocx.structurally_normalize_const(
|
||||
&obligation.cause,
|
||||
|
|
@ -2812,7 +2807,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`");
|
||||
|
||||
match rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx)
|
||||
.is_transmutable(src_and_dst, assume)
|
||||
.is_transmutable(src, dst, assume)
|
||||
{
|
||||
Answer::No(reason) => {
|
||||
let safe_transmute_explanation = match reason {
|
||||
|
|
|
|||
|
|
@ -294,8 +294,8 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
// register candidates. We probably need to register >1 since we may have an OR of ANDs.
|
||||
fn is_transmutable(
|
||||
&self,
|
||||
dst: Ty<'tcx>,
|
||||
src: Ty<'tcx>,
|
||||
dst: Ty<'tcx>,
|
||||
assume: ty::Const<'tcx>,
|
||||
) -> Result<Certainty, NoSolution> {
|
||||
// Erase regions because we compute layouts in `rustc_transmute`,
|
||||
|
|
@ -307,9 +307,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
};
|
||||
|
||||
// FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
|
||||
match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx)
|
||||
.is_transmutable(rustc_transmute::Types { src, dst }, assume)
|
||||
{
|
||||
match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx).is_transmutable(src, dst, assume) {
|
||||
rustc_transmute::Answer::Yes => Ok(Certainty::Yes),
|
||||
rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -365,8 +365,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
debug!(?src, ?dst);
|
||||
let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx);
|
||||
let maybe_transmutable =
|
||||
transmute_env.is_transmutable(rustc_transmute::Types { dst, src }, assume);
|
||||
let maybe_transmutable = transmute_env.is_transmutable(src, dst, assume);
|
||||
|
||||
let fully_flattened = match maybe_transmutable {
|
||||
Answer::No(_) => Err(SelectionError::Unimplemented)?,
|
||||
|
|
|
|||
|
|
@ -93,15 +93,6 @@ mod rustc {
|
|||
|
||||
use super::*;
|
||||
|
||||
/// The source and destination types of a transmutation.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Types<'tcx> {
|
||||
/// The source type.
|
||||
pub src: Ty<'tcx>,
|
||||
/// The destination type.
|
||||
pub dst: Ty<'tcx>,
|
||||
}
|
||||
|
||||
pub struct TransmuteTypeEnv<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
|
@ -113,13 +104,12 @@ mod rustc {
|
|||
|
||||
pub fn is_transmutable(
|
||||
&mut self,
|
||||
types: Types<'tcx>,
|
||||
src: Ty<'tcx>,
|
||||
dst: Ty<'tcx>,
|
||||
assume: crate::Assume,
|
||||
) -> crate::Answer<Region<'tcx>, Ty<'tcx>> {
|
||||
crate::maybe_transmutable::MaybeTransmutableQuery::new(
|
||||
types.src, types.dst, assume, self.tcx,
|
||||
)
|
||||
.answer()
|
||||
crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, self.tcx)
|
||||
.answer()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -222,8 +222,6 @@ fn resolve_associated_item<'tcx>(
|
|||
return Err(guar);
|
||||
}
|
||||
|
||||
let args = tcx.erase_and_anonymize_regions(args);
|
||||
|
||||
// We check that the impl item is compatible with the trait item
|
||||
// because otherwise we may ICE in const eval due to type mismatches,
|
||||
// signature incompatibilities, etc.
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ bitflags::bitflags! {
|
|||
/// Does this have `Projection`?
|
||||
const HAS_TY_PROJECTION = 1 << 10;
|
||||
/// Does this have `Free` aliases?
|
||||
const HAS_TY_FREE_ALIAS = 1 << 11;
|
||||
const HAS_TY_FREE_ALIAS = 1 << 11;
|
||||
/// Does this have `Opaque`?
|
||||
const HAS_TY_OPAQUE = 1 << 12;
|
||||
/// Does this have `Inherent`?
|
||||
|
|
@ -135,7 +135,7 @@ bitflags::bitflags! {
|
|||
const HAS_TY_CORO = 1 << 24;
|
||||
|
||||
/// Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`?
|
||||
const HAS_CANONICAL_BOUND = 1 << 25;
|
||||
const HAS_CANONICAL_BOUND = 1 << 25;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use rustc_errors::{Applicability, Diag};
|
|||
use rustc_hir::intravisit::{Visitor, walk_expr};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, MatchSource};
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
use rustc_middle::ty::{GenericArgKind, Region, RegionKind, Ty, TyCtxt, TypeVisitable, TypeVisitor};
|
||||
use rustc_middle::ty::{GenericArgKind, RegionKind, Ty, TypeVisitableExt};
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::SIGNIFICANT_DROP_IN_SCRUTINEE;
|
||||
|
|
@ -303,13 +303,13 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> {
|
|||
|
||||
if self.sig_drop_holder != SigDropHolder::None {
|
||||
let parent_ty = self.cx.typeck_results().expr_ty(parent_expr);
|
||||
if !ty_has_erased_regions(parent_ty) && !parent_expr.is_syntactic_place_expr() {
|
||||
if !parent_ty.has_erased_regions() && !parent_expr.is_syntactic_place_expr() {
|
||||
self.replace_current_sig_drop(parent_expr.span, parent_ty.is_unit(), 0);
|
||||
self.sig_drop_holder = SigDropHolder::Moved;
|
||||
}
|
||||
|
||||
let (peel_ref_ty, peel_ref_times) = ty_peel_refs(parent_ty);
|
||||
if !ty_has_erased_regions(peel_ref_ty) && is_copy(self.cx, peel_ref_ty) {
|
||||
if !peel_ref_ty.has_erased_regions() && is_copy(self.cx, peel_ref_ty) {
|
||||
self.replace_current_sig_drop(parent_expr.span, peel_ref_ty.is_unit(), peel_ref_times);
|
||||
self.sig_drop_holder = SigDropHolder::Moved;
|
||||
}
|
||||
|
|
@ -399,24 +399,6 @@ fn ty_peel_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) {
|
|||
(ty, n)
|
||||
}
|
||||
|
||||
fn ty_has_erased_regions(ty: Ty<'_>) -> bool {
|
||||
struct V;
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for V {
|
||||
type Result = ControlFlow<()>;
|
||||
|
||||
fn visit_region(&mut self, region: Region<'tcx>) -> Self::Result {
|
||||
if region.is_erased() {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty.visit_with(&mut V).is_break()
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for SigDropHelper<'_, 'tcx> {
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
|
||||
// We've emitted a lint on some neighborhood expression. That lint will suggest to move out the
|
||||
|
|
|
|||
|
|
@ -232,8 +232,8 @@ impl<'db> SolverDelegate for SolverContext<'db> {
|
|||
|
||||
fn is_transmutable(
|
||||
&self,
|
||||
_dst: Ty<'db>,
|
||||
_src: Ty<'db>,
|
||||
_dst: Ty<'db>,
|
||||
_assume: <Self::Interner as rustc_type_ir::Interner>::Const,
|
||||
) -> Result<Certainty, NoSolution> {
|
||||
// It's better to return some value while not fully implement
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue