Skip to content

Commit c683cac

Browse files
committed
new solver: make apply query response infallible
For this we have to provide the necessary information when canonicalizing the input, guaranteeing that if the canonical query successfully instantiates some inference variable, it will also succeed in the caller. This means we have to not merge universes in the canonical input.
1 parent fb4bca0 commit c683cac

27 files changed

+336
-292
lines changed

Diff for: compiler/rustc_infer/src/infer/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub mod opaque_types;
6767
pub mod outlives;
6868
mod projection;
6969
pub mod region_constraints;
70-
mod relate;
70+
pub mod relate;
7171
pub mod resolve;
7272
pub mod type_variable;
7373
mod undo_log;
@@ -824,7 +824,7 @@ impl<'tcx> InferCtxt<'tcx> {
824824
.collect()
825825
}
826826

827-
fn combine_fields<'a>(
827+
pub fn combine_fields<'a>(
828828
&'a self,
829829
trace: TypeTrace<'tcx>,
830830
param_env: ty::ParamEnv<'tcx>,

Diff for: compiler/rustc_infer/src/infer/relate/combine.rs

+37-13
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use super::generalize::{self, CombineDelegate, Generalization};
2727
use super::glb::Glb;
2828
use super::lub::Lub;
2929
use super::sub::Sub;
30+
use super::StructurallyRelateAliases;
3031
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
3132
use crate::traits::{Obligation, PredicateObligations};
3233
use rustc_middle::infer::canonical::OriginalQueryValues;
@@ -48,9 +49,10 @@ pub struct CombineFields<'infcx, 'tcx> {
4849
}
4950

5051
impl<'tcx> InferCtxt<'tcx> {
51-
pub fn super_combine_tys<R>(
52+
pub(super) fn super_combine_tys<R>(
5253
&self,
5354
relation: &mut R,
55+
structurally_relate_aliases: StructurallyRelateAliases,
5456
a: Ty<'tcx>,
5557
b: Ty<'tcx>,
5658
) -> RelateResult<'tcx, Ty<'tcx>>
@@ -117,8 +119,15 @@ impl<'tcx> InferCtxt<'tcx> {
117119
}
118120

119121
(_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
120-
relation.register_type_relate_obligation(a, b);
121-
Ok(a)
122+
match structurally_relate_aliases {
123+
StructurallyRelateAliases::Yes => {
124+
ty::relate::structurally_relate_tys(relation, a, b)
125+
}
126+
StructurallyRelateAliases::No => {
127+
relation.register_type_relate_obligation(a, b);
128+
Ok(a)
129+
}
130+
}
122131
}
123132

124133
// All other cases of inference are errors
@@ -139,9 +148,10 @@ impl<'tcx> InferCtxt<'tcx> {
139148
}
140149
}
141150

142-
pub fn super_combine_consts<R>(
151+
pub(super) fn super_combine_consts<R>(
143152
&self,
144153
relation: &mut R,
154+
structurally_relate_aliases: StructurallyRelateAliases,
145155
a: ty::Const<'tcx>,
146156
b: ty::Const<'tcx>,
147157
) -> RelateResult<'tcx, ty::Const<'tcx>>
@@ -225,11 +235,21 @@ impl<'tcx> InferCtxt<'tcx> {
225235
}
226236

227237
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
228-
return self.unify_const_variable(vid, b, relation.param_env());
238+
return self.unify_const_variable(
239+
structurally_relate_aliases,
240+
relation.param_env(),
241+
vid,
242+
b,
243+
);
229244
}
230245

231246
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
232-
return self.unify_const_variable(vid, a, relation.param_env());
247+
return self.unify_const_variable(
248+
structurally_relate_aliases,
249+
relation.param_env(),
250+
vid,
251+
a,
252+
);
233253
}
234254

235255
(ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
@@ -308,9 +328,10 @@ impl<'tcx> InferCtxt<'tcx> {
308328
#[instrument(level = "debug", skip(self))]
309329
fn unify_const_variable(
310330
&self,
331+
structurally_relate_aliases: StructurallyRelateAliases,
332+
param_env: ty::ParamEnv<'tcx>,
311333
target_vid: ty::ConstVid,
312334
ct: ty::Const<'tcx>,
313-
param_env: ty::ParamEnv<'tcx>,
314335
) -> RelateResult<'tcx, ty::Const<'tcx>> {
315336
let span = match self.inner.borrow_mut().const_unification_table().probe_value(target_vid) {
316337
ConstVariableValue::Known { value } => {
@@ -323,6 +344,7 @@ impl<'tcx> InferCtxt<'tcx> {
323344
let Generalization { value_may_be_infer: value, needs_wf: _ } = generalize::generalize(
324345
self,
325346
&mut CombineDelegate { infcx: self, span },
347+
structurally_relate_aliases,
326348
ct,
327349
target_vid,
328350
ty::Variance::Invariant,
@@ -335,7 +357,7 @@ impl<'tcx> InferCtxt<'tcx> {
335357
Ok(value)
336358
}
337359

338-
fn unify_integral_variable(
360+
pub(super) fn unify_integral_variable(
339361
&self,
340362
vid_is_expected: bool,
341363
vid: ty::IntVid,
@@ -352,7 +374,7 @@ impl<'tcx> InferCtxt<'tcx> {
352374
}
353375
}
354376

355-
fn unify_float_variable(
377+
pub(super) fn unify_float_variable(
356378
&self,
357379
vid_is_expected: bool,
358380
vid: ty::FloatVid,
@@ -366,7 +388,7 @@ impl<'tcx> InferCtxt<'tcx> {
366388
Ok(Ty::new_float(self.tcx, val))
367389
}
368390

369-
fn unify_effect_variable(
391+
pub(super) fn unify_effect_variable(
370392
&self,
371393
vid_is_expected: bool,
372394
vid: ty::EffectVid,
@@ -414,6 +436,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
414436
#[instrument(skip(self), level = "debug")]
415437
pub fn instantiate(
416438
&mut self,
439+
structurally_relate_aliases: StructurallyRelateAliases,
417440
a_ty: Ty<'tcx>,
418441
ambient_variance: ty::Variance,
419442
b_vid: ty::TyVid,
@@ -436,6 +459,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
436459
let Generalization { value_may_be_infer: b_ty, needs_wf } = generalize::generalize(
437460
self.infcx,
438461
&mut CombineDelegate { infcx: self.infcx, span: self.trace.span() },
462+
structurally_relate_aliases,
439463
a_ty,
440464
b_vid,
441465
ambient_variance,
@@ -564,23 +588,23 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
564588
fn alias_relate_direction(&self) -> ty::AliasRelationDirection;
565589
}
566590

567-
fn int_unification_error<'tcx>(
591+
pub(super) fn int_unification_error<'tcx>(
568592
a_is_expected: bool,
569593
v: (ty::IntVarValue, ty::IntVarValue),
570594
) -> TypeError<'tcx> {
571595
let (a, b) = v;
572596
TypeError::IntMismatch(ExpectedFound::new(a_is_expected, a, b))
573597
}
574598

575-
fn float_unification_error<'tcx>(
599+
pub(super) fn float_unification_error<'tcx>(
576600
a_is_expected: bool,
577601
v: (ty::FloatVarValue, ty::FloatVarValue),
578602
) -> TypeError<'tcx> {
579603
let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
580604
TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
581605
}
582606

583-
fn effect_unification_error<'tcx>(
607+
pub(super) fn effect_unification_error<'tcx>(
584608
_tcx: TyCtxt<'tcx>,
585609
_a_is_expected: bool,
586610
(_a, _b): (EffectVarValue<'tcx>, EffectVarValue<'tcx>),

Diff for: compiler/rustc_infer/src/infer/relate/equate.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::combine::{CombineFields, ObligationEmittingRelation};
2+
use super::StructurallyRelateAliases;
23
use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
34
use crate::traits::PredicateObligations;
45

@@ -12,6 +13,7 @@ use rustc_hir::def_id::DefId;
1213
/// Ensures `a` is made equal to `b`. Returns `a` on success.
1314
pub struct Equate<'combine, 'infcx, 'tcx> {
1415
fields: &'combine mut CombineFields<'infcx, 'tcx>,
16+
structurally_relate_aliases: StructurallyRelateAliases,
1517
a_is_expected: bool,
1618
}
1719

@@ -20,7 +22,11 @@ impl<'combine, 'infcx, 'tcx> Equate<'combine, 'infcx, 'tcx> {
2022
fields: &'combine mut CombineFields<'infcx, 'tcx>,
2123
a_is_expected: bool,
2224
) -> Equate<'combine, 'infcx, 'tcx> {
23-
Equate { fields, a_is_expected }
25+
Equate { fields, structurally_relate_aliases: StructurallyRelateAliases::No, a_is_expected }
26+
}
27+
28+
pub fn structurally_relate_aliases(self) -> Self {
29+
Equate { structurally_relate_aliases: StructurallyRelateAliases::Yes, ..self }
2430
}
2531
}
2632

@@ -82,18 +88,30 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
8288
}
8389

8490
(&ty::Infer(TyVar(a_id)), _) => {
85-
self.fields.instantiate(b, ty::Invariant, a_id, self.a_is_expected)?;
91+
self.fields.instantiate(
92+
self.structurally_relate_aliases,
93+
b,
94+
ty::Invariant,
95+
a_id,
96+
self.a_is_expected,
97+
)?;
8698
}
8799

88100
(_, &ty::Infer(TyVar(b_id))) => {
89-
self.fields.instantiate(a, ty::Invariant, b_id, self.a_is_expected)?;
101+
self.fields.instantiate(
102+
self.structurally_relate_aliases,
103+
a,
104+
ty::Invariant,
105+
b_id,
106+
self.a_is_expected,
107+
)?;
90108
}
91109

92110
(
93111
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
94112
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
95113
) if a_def_id == b_def_id => {
96-
self.fields.infcx.super_combine_tys(self, a, b)?;
114+
infcx.super_combine_tys(self, self.structurally_relate_aliases, a, b)?;
97115
}
98116
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
99117
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
@@ -114,7 +132,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
114132
);
115133
}
116134
_ => {
117-
self.fields.infcx.super_combine_tys(self, a, b)?;
135+
infcx.super_combine_tys(self, self.structurally_relate_aliases, a, b)?;
118136
}
119137
}
120138

@@ -142,7 +160,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
142160
a: ty::Const<'tcx>,
143161
b: ty::Const<'tcx>,
144162
) -> RelateResult<'tcx, ty::Const<'tcx>> {
145-
self.fields.infcx.super_combine_consts(self, a, b)
163+
self.fields.infcx.super_combine_consts(self, StructurallyRelateAliases::No, a, b)
146164
}
147165

148166
fn binders<T>(

0 commit comments

Comments
 (0)