mv utility methods into separate module

This commit is contained in:
lcnr 2022-11-15 13:42:14 +01:00
parent 45f441a7b4
commit 6aa611a84c
6 changed files with 72 additions and 65 deletions

View file

@ -2,8 +2,6 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
@ -18,7 +16,6 @@ use rustc_mir_dataflow::impls::MaybeStorageLive;
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_mir_dataflow::{Analysis, ResultsCursor};
use rustc_target::abi::{Size, VariantIdx};
use rustc_trait_selection::traits::ObligationCtxt;
#[derive(Copy, Clone, Debug)]
enum EdgeKind {
@ -71,55 +68,6 @@ impl<'tcx> MirPass<'tcx> for Validator {
}
}
/// Returns whether the two types are equal up to subtyping.
///
/// This is used in case we don't know the expected subtyping direction
/// and still want to check whether anything is broken.
pub fn is_equal_up_to_subtyping<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
src: Ty<'tcx>,
dest: Ty<'tcx>,
) -> bool {
// Fast path.
if src == dest {
return true;
}
// Check for subtyping in either direction.
is_subtype(tcx, param_env, src, dest) || is_subtype(tcx, param_env, dest, src)
}
pub fn is_subtype<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
src: Ty<'tcx>,
dest: Ty<'tcx>,
) -> bool {
if src == dest {
return true;
}
let mut builder =
tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble);
let infcx = builder.build();
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy();
let src = ocx.normalize(cause.clone(), param_env, src);
let dest = ocx.normalize(cause.clone(), param_env, dest);
let Ok(infer_ok) = infcx.at(&cause, param_env).sub(src, dest) else {
return false;
};
let () = ocx.register_infer_ok_obligations(infer_ok);
let errors = ocx.select_all_or_error();
// With `Reveal::All`, opaque types get normalized away, with `Reveal::UserFacing`
// we would get unification errors because we're unable to look into opaque types,
// even if they're constrained in our current function.
//
// It seems very unlikely that this hides any bugs.
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
errors.is_empty()
}
struct TypeChecker<'a, 'tcx> {
when: &'a str,
body: &'a Body<'tcx>,
@ -195,7 +143,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
return true;
}
is_subtype(self.tcx, self.param_env, src, dest)
crate::util::is_subtype(self.tcx, self.param_env, src, dest)
}
}