Relate binders explicitly, do a leak check too
This commit is contained in:
parent
eb75d20a55
commit
cbb5047d35
2 changed files with 47 additions and 15 deletions
|
@ -27,7 +27,8 @@ use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{DUMMY_SP, Symbol};
|
use rustc_span::{DUMMY_SP, Symbol};
|
||||||
use rustc_target::abi::FIRST_VARIANT;
|
use rustc_target::abi::FIRST_VARIANT;
|
||||||
use rustc_trait_selection::infer::TyCtxtInferExt;
|
use rustc_trait_selection::infer::at::ToTrace;
|
||||||
|
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
|
||||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
|
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
|
@ -113,22 +114,38 @@ pub fn compare_simd_types<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
/// unsound, so let's validate here that the trait refs are subtypes.
|
/// unsound, so let's validate here that the trait refs are subtypes.
|
||||||
pub fn validate_trivial_unsize<'tcx>(
|
pub fn validate_trivial_unsize<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
data_a: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
source_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||||
data_b: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
target_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match (data_a.principal(), data_b.principal()) {
|
match (source_data.principal(), target_data.principal()) {
|
||||||
(Some(principal_a), Some(principal_b)) => {
|
(Some(hr_source_principal), Some(hr_target_principal)) => {
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
|
let universe = infcx.universe();
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
let Ok(()) = ocx.sub(
|
infcx.enter_forall(hr_target_principal, |target_principal| {
|
||||||
&ObligationCause::dummy(),
|
let source_principal = infcx.instantiate_binder_with_fresh_vars(
|
||||||
ty::ParamEnv::reveal_all(),
|
DUMMY_SP,
|
||||||
principal_a,
|
BoundRegionConversionTime::HigherRankedType,
|
||||||
principal_b,
|
hr_source_principal,
|
||||||
) else {
|
);
|
||||||
return false;
|
let Ok(()) = ocx.eq_trace(
|
||||||
};
|
&ObligationCause::dummy(),
|
||||||
ocx.select_all_or_error().is_empty()
|
ty::ParamEnv::reveal_all(),
|
||||||
|
ToTrace::to_trace(
|
||||||
|
&ObligationCause::dummy(),
|
||||||
|
hr_target_principal,
|
||||||
|
hr_source_principal,
|
||||||
|
),
|
||||||
|
target_principal,
|
||||||
|
source_principal,
|
||||||
|
) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if !ocx.select_all_or_error().is_empty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
infcx.leak_check(universe, None).is_ok()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
(None, None) => true,
|
(None, None) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
@ -9,12 +9,13 @@ use rustc_infer::infer::canonical::{
|
||||||
Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
|
Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
|
||||||
};
|
};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError};
|
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError, TypeTrace};
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
use rustc_middle::arena::ArenaAllocatable;
|
use rustc_middle::arena::ArenaAllocatable;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::ty::error::TypeError;
|
use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance};
|
||||||
|
use rustc_type_ir::relate::Relate;
|
||||||
|
|
||||||
use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine};
|
use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine};
|
||||||
use crate::error_reporting::InferCtxtErrorExt;
|
use crate::error_reporting::InferCtxtErrorExt;
|
||||||
|
@ -133,6 +134,20 @@ where
|
||||||
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn eq_trace<T: Relate<TyCtxt<'tcx>>>(
|
||||||
|
&self,
|
||||||
|
cause: &ObligationCause<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
trace: TypeTrace<'tcx>,
|
||||||
|
expected: T,
|
||||||
|
actual: T,
|
||||||
|
) -> Result<(), TypeError<'tcx>> {
|
||||||
|
self.infcx
|
||||||
|
.at(cause, param_env)
|
||||||
|
.eq_trace(DefineOpaqueTypes::Yes, trace, expected, actual)
|
||||||
|
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
|
/// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
|
||||||
pub fn sub<T: ToTrace<'tcx>>(
|
pub fn sub<T: ToTrace<'tcx>>(
|
||||||
&self,
|
&self,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue