Skip to content

Commit

Permalink
new solver: make apply query response infallible
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lcnr committed Feb 2, 2024
1 parent fb4bca0 commit c683cac
Show file tree
Hide file tree
Showing 27 changed files with 336 additions and 292 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub mod opaque_types;
pub mod outlives;
mod projection;
pub mod region_constraints;
mod relate;
pub mod relate;
pub mod resolve;
pub mod type_variable;
mod undo_log;
Expand Down Expand Up @@ -824,7 +824,7 @@ impl<'tcx> InferCtxt<'tcx> {
.collect()
}

fn combine_fields<'a>(
pub fn combine_fields<'a>(
&'a self,
trace: TypeTrace<'tcx>,
param_env: ty::ParamEnv<'tcx>,
Expand Down
50 changes: 37 additions & 13 deletions compiler/rustc_infer/src/infer/relate/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use super::generalize::{self, CombineDelegate, Generalization};
use super::glb::Glb;
use super::lub::Lub;
use super::sub::Sub;
use super::StructurallyRelateAliases;
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
use crate::traits::{Obligation, PredicateObligations};
use rustc_middle::infer::canonical::OriginalQueryValues;
Expand All @@ -48,9 +49,10 @@ pub struct CombineFields<'infcx, 'tcx> {
}

impl<'tcx> InferCtxt<'tcx> {
pub fn super_combine_tys<R>(
pub(super) fn super_combine_tys<R>(
&self,
relation: &mut R,
structurally_relate_aliases: StructurallyRelateAliases,
a: Ty<'tcx>,
b: Ty<'tcx>,
) -> RelateResult<'tcx, Ty<'tcx>>
Expand Down Expand Up @@ -117,8 +119,15 @@ impl<'tcx> InferCtxt<'tcx> {
}

(_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
relation.register_type_relate_obligation(a, b);
Ok(a)
match structurally_relate_aliases {
StructurallyRelateAliases::Yes => {
ty::relate::structurally_relate_tys(relation, a, b)
}
StructurallyRelateAliases::No => {
relation.register_type_relate_obligation(a, b);
Ok(a)
}
}
}

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

pub fn super_combine_consts<R>(
pub(super) fn super_combine_consts<R>(
&self,
relation: &mut R,
structurally_relate_aliases: StructurallyRelateAliases,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>>
Expand Down Expand Up @@ -225,11 +235,21 @@ impl<'tcx> InferCtxt<'tcx> {
}

(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
return self.unify_const_variable(vid, b, relation.param_env());
return self.unify_const_variable(
structurally_relate_aliases,
relation.param_env(),
vid,
b,
);
}

(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
return self.unify_const_variable(vid, a, relation.param_env());
return self.unify_const_variable(
structurally_relate_aliases,
relation.param_env(),
vid,
a,
);
}

(ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
Expand Down Expand Up @@ -308,9 +328,10 @@ impl<'tcx> InferCtxt<'tcx> {
#[instrument(level = "debug", skip(self))]
fn unify_const_variable(
&self,
structurally_relate_aliases: StructurallyRelateAliases,
param_env: ty::ParamEnv<'tcx>,
target_vid: ty::ConstVid,
ct: ty::Const<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
let span = match self.inner.borrow_mut().const_unification_table().probe_value(target_vid) {
ConstVariableValue::Known { value } => {
Expand All @@ -323,6 +344,7 @@ impl<'tcx> InferCtxt<'tcx> {
let Generalization { value_may_be_infer: value, needs_wf: _ } = generalize::generalize(
self,
&mut CombineDelegate { infcx: self, span },
structurally_relate_aliases,
ct,
target_vid,
ty::Variance::Invariant,
Expand All @@ -335,7 +357,7 @@ impl<'tcx> InferCtxt<'tcx> {
Ok(value)
}

fn unify_integral_variable(
pub(super) fn unify_integral_variable(
&self,
vid_is_expected: bool,
vid: ty::IntVid,
Expand All @@ -352,7 +374,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
}

fn unify_float_variable(
pub(super) fn unify_float_variable(
&self,
vid_is_expected: bool,
vid: ty::FloatVid,
Expand All @@ -366,7 +388,7 @@ impl<'tcx> InferCtxt<'tcx> {
Ok(Ty::new_float(self.tcx, val))
}

fn unify_effect_variable(
pub(super) fn unify_effect_variable(
&self,
vid_is_expected: bool,
vid: ty::EffectVid,
Expand Down Expand Up @@ -414,6 +436,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
#[instrument(skip(self), level = "debug")]
pub fn instantiate(
&mut self,
structurally_relate_aliases: StructurallyRelateAliases,
a_ty: Ty<'tcx>,
ambient_variance: ty::Variance,
b_vid: ty::TyVid,
Expand All @@ -436,6 +459,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
let Generalization { value_may_be_infer: b_ty, needs_wf } = generalize::generalize(
self.infcx,
&mut CombineDelegate { infcx: self.infcx, span: self.trace.span() },
structurally_relate_aliases,
a_ty,
b_vid,
ambient_variance,
Expand Down Expand Up @@ -564,23 +588,23 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
fn alias_relate_direction(&self) -> ty::AliasRelationDirection;
}

fn int_unification_error<'tcx>(
pub(super) fn int_unification_error<'tcx>(
a_is_expected: bool,
v: (ty::IntVarValue, ty::IntVarValue),
) -> TypeError<'tcx> {
let (a, b) = v;
TypeError::IntMismatch(ExpectedFound::new(a_is_expected, a, b))
}

fn float_unification_error<'tcx>(
pub(super) fn float_unification_error<'tcx>(
a_is_expected: bool,
v: (ty::FloatVarValue, ty::FloatVarValue),
) -> TypeError<'tcx> {
let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
}

fn effect_unification_error<'tcx>(
pub(super) fn effect_unification_error<'tcx>(
_tcx: TyCtxt<'tcx>,
_a_is_expected: bool,
(_a, _b): (EffectVarValue<'tcx>, EffectVarValue<'tcx>),
Expand Down
30 changes: 24 additions & 6 deletions compiler/rustc_infer/src/infer/relate/equate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::combine::{CombineFields, ObligationEmittingRelation};
use super::StructurallyRelateAliases;
use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
use crate::traits::PredicateObligations;

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

Expand All @@ -20,7 +22,11 @@ impl<'combine, 'infcx, 'tcx> Equate<'combine, 'infcx, 'tcx> {
fields: &'combine mut CombineFields<'infcx, 'tcx>,
a_is_expected: bool,
) -> Equate<'combine, 'infcx, 'tcx> {
Equate { fields, a_is_expected }
Equate { fields, structurally_relate_aliases: StructurallyRelateAliases::No, a_is_expected }
}

pub fn structurally_relate_aliases(self) -> Self {
Equate { structurally_relate_aliases: StructurallyRelateAliases::Yes, ..self }
}
}

Expand Down Expand Up @@ -82,18 +88,30 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
}

(&ty::Infer(TyVar(a_id)), _) => {
self.fields.instantiate(b, ty::Invariant, a_id, self.a_is_expected)?;
self.fields.instantiate(
self.structurally_relate_aliases,
b,
ty::Invariant,
a_id,
self.a_is_expected,
)?;
}

(_, &ty::Infer(TyVar(b_id))) => {
self.fields.instantiate(a, ty::Invariant, b_id, self.a_is_expected)?;
self.fields.instantiate(
self.structurally_relate_aliases,
a,
ty::Invariant,
b_id,
self.a_is_expected,
)?;
}

(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
) if a_def_id == b_def_id => {
self.fields.infcx.super_combine_tys(self, a, b)?;
infcx.super_combine_tys(self, self.structurally_relate_aliases, a, b)?;
}
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
Expand All @@ -114,7 +132,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
);
}
_ => {
self.fields.infcx.super_combine_tys(self, a, b)?;
infcx.super_combine_tys(self, self.structurally_relate_aliases, a, b)?;
}
}

Expand Down Expand Up @@ -142,7 +160,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
self.fields.infcx.super_combine_consts(self, StructurallyRelateAliases::No, a, b)
}

fn binders<T>(
Expand Down
Loading

0 comments on commit c683cac

Please sign in to comment.