Skip to content

Commit cbb5047

Browse files
Relate binders explicitly, do a leak check too
1 parent eb75d20 commit cbb5047

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

compiler/rustc_codegen_ssa/src/base.rs

+31-14
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
2727
use rustc_span::symbol::sym;
2828
use rustc_span::{DUMMY_SP, Symbol};
2929
use rustc_target::abi::FIRST_VARIANT;
30-
use rustc_trait_selection::infer::TyCtxtInferExt;
30+
use rustc_trait_selection::infer::at::ToTrace;
31+
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
3132
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
3233
use tracing::{debug, info};
3334

@@ -113,22 +114,38 @@ pub fn compare_simd_types<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
113114
/// unsound, so let's validate here that the trait refs are subtypes.
114115
pub fn validate_trivial_unsize<'tcx>(
115116
tcx: TyCtxt<'tcx>,
116-
data_a: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
117-
data_b: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
117+
source_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
118+
target_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
118119
) -> bool {
119-
match (data_a.principal(), data_b.principal()) {
120-
(Some(principal_a), Some(principal_b)) => {
120+
match (source_data.principal(), target_data.principal()) {
121+
(Some(hr_source_principal), Some(hr_target_principal)) => {
121122
let infcx = tcx.infer_ctxt().build();
123+
let universe = infcx.universe();
122124
let ocx = ObligationCtxt::new(&infcx);
123-
let Ok(()) = ocx.sub(
124-
&ObligationCause::dummy(),
125-
ty::ParamEnv::reveal_all(),
126-
principal_a,
127-
principal_b,
128-
) else {
129-
return false;
130-
};
131-
ocx.select_all_or_error().is_empty()
125+
infcx.enter_forall(hr_target_principal, |target_principal| {
126+
let source_principal = infcx.instantiate_binder_with_fresh_vars(
127+
DUMMY_SP,
128+
BoundRegionConversionTime::HigherRankedType,
129+
hr_source_principal,
130+
);
131+
let Ok(()) = ocx.eq_trace(
132+
&ObligationCause::dummy(),
133+
ty::ParamEnv::reveal_all(),
134+
ToTrace::to_trace(
135+
&ObligationCause::dummy(),
136+
hr_target_principal,
137+
hr_source_principal,
138+
),
139+
target_principal,
140+
source_principal,
141+
) else {
142+
return false;
143+
};
144+
if !ocx.select_all_or_error().is_empty() {
145+
return false;
146+
}
147+
infcx.leak_check(universe, None).is_ok()
148+
})
132149
}
133150
(None, None) => true,
134151
_ => false,

compiler/rustc_trait_selection/src/traits/engine.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ use rustc_infer::infer::canonical::{
99
Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
1010
};
1111
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
12-
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError};
12+
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError, TypeTrace};
1313
use rustc_macros::extension;
1414
use rustc_middle::arena::ArenaAllocatable;
1515
use rustc_middle::traits::query::NoSolution;
1616
use rustc_middle::ty::error::TypeError;
1717
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance};
18+
use rustc_type_ir::relate::Relate;
1819

1920
use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine};
2021
use crate::error_reporting::InferCtxtErrorExt;
@@ -133,6 +134,20 @@ where
133134
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
134135
}
135136

137+
pub fn eq_trace<T: Relate<TyCtxt<'tcx>>>(
138+
&self,
139+
cause: &ObligationCause<'tcx>,
140+
param_env: ty::ParamEnv<'tcx>,
141+
trace: TypeTrace<'tcx>,
142+
expected: T,
143+
actual: T,
144+
) -> Result<(), TypeError<'tcx>> {
145+
self.infcx
146+
.at(cause, param_env)
147+
.eq_trace(DefineOpaqueTypes::Yes, trace, expected, actual)
148+
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
149+
}
150+
136151
/// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
137152
pub fn sub<T: ToTrace<'tcx>>(
138153
&self,

0 commit comments

Comments
 (0)