Skip to content

Commit 8d94e06

Browse files
committed
Auto merge of rust-lang#131263 - compiler-errors:solver-relating, r=lcnr
Introduce SolverRelating type relation to the new solver Redux of rust-lang#128744. Splits out relate for the new solver so that implementors don't need to implement it themselves. r? lcnr
2 parents 4cc494b + 8715bfb commit 8d94e06

31 files changed

+911
-517
lines changed

compiler/rustc_borrowck/src/type_check/relate_tys.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_middle::span_bug;
1111
use rustc_middle::traits::ObligationCause;
1212
use rustc_middle::traits::query::NoSolution;
1313
use rustc_middle::ty::fold::FnMutDelegate;
14+
use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
1415
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
1516
use rustc_span::symbol::sym;
1617
use rustc_span::{Span, Symbol};
@@ -362,7 +363,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
362363
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
363364
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
364365
) if a_def_id == b_def_id || infcx.next_trait_solver() => {
365-
infcx.super_combine_tys(self, a, b).map(|_| ()).or_else(|err| {
366+
super_combine_tys(&infcx.infcx, self, a, b).map(|_| ()).or_else(|err| {
366367
// This behavior is only there for the old solver, the new solver
367368
// shouldn't ever fail. Instead, it unconditionally emits an
368369
// alias-relate goal.
@@ -385,7 +386,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
385386
debug!(?a, ?b, ?self.ambient_variance);
386387

387388
// Will also handle unification of `IntVar` and `FloatVar`.
388-
self.type_checker.infcx.super_combine_tys(self, a, b)?;
389+
super_combine_tys(&self.type_checker.infcx.infcx, self, a, b)?;
389390
}
390391
}
391392

@@ -422,7 +423,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
422423
assert!(!a.has_non_region_infer(), "unexpected inference var {:?}", a);
423424
assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b);
424425

425-
self.type_checker.infcx.super_combine_consts(self, a, b)
426+
super_combine_consts(&self.type_checker.infcx.infcx, self, a, b)
426427
}
427428

428429
#[instrument(skip(self), level = "trace")]

compiler/rustc_infer/src/infer/at.rs

+72-74
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@
2727
2828
use relate::lattice::{LatticeOp, LatticeOpKind};
2929
use rustc_middle::bug;
30+
use rustc_middle::ty::relate::solver_relating::RelateExt as NextSolverRelate;
3031
use rustc_middle::ty::{Const, ImplSubject};
3132

3233
use super::*;
3334
use crate::infer::relate::type_relating::TypeRelating;
34-
use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation};
35+
use crate::infer::relate::{Relate, TypeRelation};
36+
use crate::traits::Obligation;
37+
use crate::traits::solve::Goal;
3538

3639
/// Whether we should define opaque types or just treat them opaquely.
3740
///
@@ -109,16 +112,26 @@ impl<'a, 'tcx> At<'a, 'tcx> {
109112
where
110113
T: ToTrace<'tcx>,
111114
{
112-
let mut op = TypeRelating::new(
113-
self.infcx,
114-
ToTrace::to_trace(self.cause, expected, actual),
115-
self.param_env,
116-
define_opaque_types,
117-
StructurallyRelateAliases::No,
118-
ty::Contravariant,
119-
);
120-
op.relate(expected, actual)?;
121-
Ok(InferOk { value: (), obligations: op.into_obligations() })
115+
if self.infcx.next_trait_solver {
116+
NextSolverRelate::relate(
117+
self.infcx,
118+
self.param_env,
119+
expected,
120+
ty::Contravariant,
121+
actual,
122+
)
123+
.map(|goals| self.goals_to_obligations(goals))
124+
} else {
125+
let mut op = TypeRelating::new(
126+
self.infcx,
127+
ToTrace::to_trace(self.cause, expected, actual),
128+
self.param_env,
129+
define_opaque_types,
130+
ty::Contravariant,
131+
);
132+
op.relate(expected, actual)?;
133+
Ok(InferOk { value: (), obligations: op.into_obligations() })
134+
}
122135
}
123136

124137
/// Makes `expected <: actual`.
@@ -131,16 +144,20 @@ impl<'a, 'tcx> At<'a, 'tcx> {
131144
where
132145
T: ToTrace<'tcx>,
133146
{
134-
let mut op = TypeRelating::new(
135-
self.infcx,
136-
ToTrace::to_trace(self.cause, expected, actual),
137-
self.param_env,
138-
define_opaque_types,
139-
StructurallyRelateAliases::No,
140-
ty::Covariant,
141-
);
142-
op.relate(expected, actual)?;
143-
Ok(InferOk { value: (), obligations: op.into_obligations() })
147+
if self.infcx.next_trait_solver {
148+
NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Covariant, actual)
149+
.map(|goals| self.goals_to_obligations(goals))
150+
} else {
151+
let mut op = TypeRelating::new(
152+
self.infcx,
153+
ToTrace::to_trace(self.cause, expected, actual),
154+
self.param_env,
155+
define_opaque_types,
156+
ty::Covariant,
157+
);
158+
op.relate(expected, actual)?;
159+
Ok(InferOk { value: (), obligations: op.into_obligations() })
160+
}
144161
}
145162

146163
/// Makes `expected == actual`.
@@ -172,16 +189,20 @@ impl<'a, 'tcx> At<'a, 'tcx> {
172189
where
173190
T: Relate<TyCtxt<'tcx>>,
174191
{
175-
let mut op = TypeRelating::new(
176-
self.infcx,
177-
trace,
178-
self.param_env,
179-
define_opaque_types,
180-
StructurallyRelateAliases::No,
181-
ty::Invariant,
182-
);
183-
op.relate(expected, actual)?;
184-
Ok(InferOk { value: (), obligations: op.into_obligations() })
192+
if self.infcx.next_trait_solver {
193+
NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Invariant, actual)
194+
.map(|goals| self.goals_to_obligations(goals))
195+
} else {
196+
let mut op = TypeRelating::new(
197+
self.infcx,
198+
trace,
199+
self.param_env,
200+
define_opaque_types,
201+
ty::Invariant,
202+
);
203+
op.relate(expected, actual)?;
204+
Ok(InferOk { value: (), obligations: op.into_obligations() })
205+
}
185206
}
186207

187208
pub fn relate<T>(
@@ -208,49 +229,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
208229
}
209230
}
210231

211-
/// Used in the new solver since we don't care about tracking an `ObligationCause`.
212-
pub fn relate_no_trace<T>(
213-
self,
214-
expected: T,
215-
variance: ty::Variance,
216-
actual: T,
217-
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>
218-
where
219-
T: Relate<TyCtxt<'tcx>>,
220-
{
221-
let mut op = TypeRelating::new(
222-
self.infcx,
223-
TypeTrace::dummy(self.cause),
224-
self.param_env,
225-
DefineOpaqueTypes::Yes,
226-
StructurallyRelateAliases::No,
227-
variance,
228-
);
229-
op.relate(expected, actual)?;
230-
Ok(op.into_obligations().into_iter().map(|o| o.into()).collect())
231-
}
232-
233-
/// Used in the new solver since we don't care about tracking an `ObligationCause`.
234-
pub fn eq_structurally_relating_aliases_no_trace<T>(
235-
self,
236-
expected: T,
237-
actual: T,
238-
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>
239-
where
240-
T: Relate<TyCtxt<'tcx>>,
241-
{
242-
let mut op = TypeRelating::new(
243-
self.infcx,
244-
TypeTrace::dummy(self.cause),
245-
self.param_env,
246-
DefineOpaqueTypes::Yes,
247-
StructurallyRelateAliases::Yes,
248-
ty::Invariant,
249-
);
250-
op.relate(expected, actual)?;
251-
Ok(op.into_obligations().into_iter().map(|o| o.into()).collect())
252-
}
253-
254232
/// Computes the least-upper-bound, or mutual supertype, of two
255233
/// values. The order of the arguments doesn't matter, but since
256234
/// this can result in an error (e.g., if asked to compute LUB of
@@ -269,6 +247,26 @@ impl<'a, 'tcx> At<'a, 'tcx> {
269247
let value = op.relate(expected, actual)?;
270248
Ok(InferOk { value, obligations: op.into_obligations() })
271249
}
250+
251+
fn goals_to_obligations(
252+
&self,
253+
goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
254+
) -> InferOk<'tcx, ()> {
255+
InferOk {
256+
value: (),
257+
obligations: goals
258+
.into_iter()
259+
.map(|goal| {
260+
Obligation::new(
261+
self.infcx.tcx,
262+
self.cause.clone(),
263+
goal.param_env,
264+
goal.predicate,
265+
)
266+
})
267+
.collect(),
268+
}
269+
}
272270
}
273271

274272
impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> {

compiler/rustc_infer/src/infer/context.rs

+94-20
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
///! Definition of `InferCtxtLike` from the librarified type layer.
22
use rustc_hir::def_id::{DefId, LocalDefId};
3+
use rustc_middle::infer::unify_key::EffectVarValue;
34
use rustc_middle::traits::ObligationCause;
4-
use rustc_middle::traits::solve::{Goal, NoSolution, SolverMode};
5+
use rustc_middle::traits::solve::SolverMode;
56
use rustc_middle::ty::fold::TypeFoldable;
7+
use rustc_middle::ty::relate::RelateResult;
8+
use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
69
use rustc_middle::ty::{self, Ty, TyCtxt};
7-
use rustc_span::DUMMY_SP;
8-
use rustc_type_ir::InferCtxtLike;
9-
use rustc_type_ir::relate::Relate;
10+
use rustc_span::{DUMMY_SP, ErrorGuaranteed};
1011

1112
use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin};
1213

13-
impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
14+
impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
1415
type Interner = TyCtxt<'tcx>;
1516

1617
fn cx(&self) -> TyCtxt<'tcx> {
1718
self.tcx
1819
}
1920

21+
fn next_trait_solver(&self) -> bool {
22+
self.next_trait_solver
23+
}
24+
2025
fn solver_mode(&self) -> ty::solve::SolverMode {
2126
match self.intercrate {
2227
true => SolverMode::Coherence,
@@ -131,29 +136,86 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
131136
self.enter_forall(value, f)
132137
}
133138

134-
fn relate<T: Relate<TyCtxt<'tcx>>>(
139+
fn equate_ty_vids_raw(&self, a: rustc_type_ir::TyVid, b: rustc_type_ir::TyVid) {
140+
self.inner.borrow_mut().type_variables().equate(a, b);
141+
}
142+
143+
fn equate_int_vids_raw(&self, a: rustc_type_ir::IntVid, b: rustc_type_ir::IntVid) {
144+
self.inner.borrow_mut().int_unification_table().union(a, b);
145+
}
146+
147+
fn equate_float_vids_raw(&self, a: rustc_type_ir::FloatVid, b: rustc_type_ir::FloatVid) {
148+
self.inner.borrow_mut().float_unification_table().union(a, b);
149+
}
150+
151+
fn equate_const_vids_raw(&self, a: rustc_type_ir::ConstVid, b: rustc_type_ir::ConstVid) {
152+
self.inner.borrow_mut().const_unification_table().union(a, b);
153+
}
154+
155+
fn equate_effect_vids_raw(&self, a: rustc_type_ir::EffectVid, b: rustc_type_ir::EffectVid) {
156+
self.inner.borrow_mut().effect_unification_table().union(a, b);
157+
}
158+
159+
fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
135160
&self,
136-
param_env: ty::ParamEnv<'tcx>,
137-
lhs: T,
138-
variance: ty::Variance,
139-
rhs: T,
140-
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
141-
self.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs)
161+
relation: &mut R,
162+
target_is_expected: bool,
163+
target_vid: rustc_type_ir::TyVid,
164+
instantiation_variance: rustc_type_ir::Variance,
165+
source_ty: Ty<'tcx>,
166+
) -> RelateResult<'tcx, ()> {
167+
self.instantiate_ty_var(
168+
relation,
169+
target_is_expected,
170+
target_vid,
171+
instantiation_variance,
172+
source_ty,
173+
)
174+
}
175+
176+
fn instantiate_int_var_raw(
177+
&self,
178+
vid: rustc_type_ir::IntVid,
179+
value: rustc_type_ir::IntVarValue,
180+
) {
181+
self.inner.borrow_mut().int_unification_table().union_value(vid, value);
182+
}
183+
184+
fn instantiate_float_var_raw(
185+
&self,
186+
vid: rustc_type_ir::FloatVid,
187+
value: rustc_type_ir::FloatVarValue,
188+
) {
189+
self.inner.borrow_mut().float_unification_table().union_value(vid, value);
190+
}
191+
192+
fn instantiate_effect_var_raw(&self, vid: rustc_type_ir::EffectVid, value: ty::Const<'tcx>) {
193+
self.inner
194+
.borrow_mut()
195+
.effect_unification_table()
196+
.union_value(vid, EffectVarValue::Known(value));
142197
}
143198

144-
fn eq_structurally_relating_aliases<T: Relate<TyCtxt<'tcx>>>(
199+
fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
145200
&self,
146-
param_env: ty::ParamEnv<'tcx>,
147-
lhs: T,
148-
rhs: T,
149-
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
150-
self.at(&ObligationCause::dummy(), param_env)
151-
.eq_structurally_relating_aliases_no_trace(lhs, rhs)
201+
relation: &mut R,
202+
target_is_expected: bool,
203+
target_vid: rustc_type_ir::ConstVid,
204+
source_ct: ty::Const<'tcx>,
205+
) -> RelateResult<'tcx, ()> {
206+
self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
207+
}
208+
209+
fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
210+
self.set_tainted_by_errors(e)
152211
}
153212

154213
fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
155214
self.shallow_resolve(ty)
156215
}
216+
fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
217+
self.shallow_resolve_const(ct)
218+
}
157219

158220
fn resolve_vars_if_possible<T>(&self, value: T) -> T
159221
where
@@ -167,7 +229,19 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
167229
}
168230

169231
fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) {
170-
self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None), sub, sup)
232+
self.inner.borrow_mut().unwrap_region_constraints().make_subregion(
233+
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
234+
sub,
235+
sup,
236+
);
237+
}
238+
239+
fn equate_regions(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) {
240+
self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
241+
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
242+
a,
243+
b,
244+
);
171245
}
172246

173247
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) {

0 commit comments

Comments
 (0)