1
Fork 0

Make super combine into fns

This commit is contained in:
Michael Goulet 2024-10-10 05:40:56 -04:00
parent a4cd2202ef
commit 8715bfbf0e
5 changed files with 208 additions and 217 deletions

View file

@ -11,7 +11,7 @@ use rustc_middle::span_bug;
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::fold::FnMutDelegate;
use rustc_middle::ty::relate::combine::InferCtxtCombineExt; use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
@ -363,7 +363,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
) if a_def_id == b_def_id || infcx.next_trait_solver() => { ) if a_def_id == b_def_id || infcx.next_trait_solver() => {
infcx.super_combine_tys(self, a, b).map(|_| ()).or_else(|err| { super_combine_tys(&infcx.infcx, self, a, b).map(|_| ()).or_else(|err| {
// This behavior is only there for the old solver, the new solver // This behavior is only there for the old solver, the new solver
// shouldn't ever fail. Instead, it unconditionally emits an // shouldn't ever fail. Instead, it unconditionally emits an
// alias-relate goal. // alias-relate goal.
@ -386,7 +386,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
debug!(?a, ?b, ?self.ambient_variance); debug!(?a, ?b, ?self.ambient_variance);
// Will also handle unification of `IntVar` and `FloatVar`. // Will also handle unification of `IntVar` and `FloatVar`.
self.type_checker.infcx.super_combine_tys(self, a, b)?; super_combine_tys(&self.type_checker.infcx.infcx, self, a, b)?;
} }
} }
@ -423,7 +423,7 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
assert!(!a.has_non_region_infer(), "unexpected inference var {:?}", a); assert!(!a.has_non_region_infer(), "unexpected inference var {:?}", a);
assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b); assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b);
self.type_checker.infcx.super_combine_consts(self, a, b) super_combine_consts(&self.type_checker.infcx.infcx, self, a, b)
} }
#[instrument(skip(self), level = "trace")] #[instrument(skip(self), level = "trace")]

View file

@ -18,7 +18,7 @@
//! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order) //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order)
use rustc_middle::traits::solve::Goal; use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::relate::combine::InferCtxtCombineExt; use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, Ty, TyCtxt, TyVar, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TyCtxt, TyVar, TypeVisitableExt};
use rustc_span::Span; use rustc_span::Span;
@ -149,7 +149,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
( (
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
) if a_def_id == b_def_id => infcx.super_combine_tys(self, a, b), ) if a_def_id == b_def_id => super_combine_tys(infcx, self, a, b),
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _) (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
@ -164,7 +164,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
Ok(a) Ok(a)
} }
_ => infcx.super_combine_tys(self, a, b), _ => super_combine_tys(infcx, self, a, b),
} }
} }
@ -192,7 +192,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
a: ty::Const<'tcx>, a: ty::Const<'tcx>,
b: ty::Const<'tcx>, b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.infcx.super_combine_consts(self, a, b) super_combine_consts(self.infcx, self, a, b)
} }
fn binders<T>( fn binders<T>(

View file

@ -1,5 +1,5 @@
use rustc_middle::traits::solve::Goal; use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::relate::combine::InferCtxtCombineExt; use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
use rustc_middle::ty::relate::{ use rustc_middle::ty::relate::{
Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances,
}; };
@ -186,7 +186,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
) if a_def_id == b_def_id => { ) if a_def_id == b_def_id => {
infcx.super_combine_tys(self, a, b)?; super_combine_tys(infcx, self, a, b)?;
} }
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _) (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
@ -202,7 +202,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
} }
_ => { _ => {
infcx.super_combine_tys(self, a, b)?; super_combine_tys(infcx, self, a, b)?;
} }
} }
@ -257,7 +257,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
a: ty::Const<'tcx>, a: ty::Const<'tcx>,
b: ty::Const<'tcx>, b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.infcx.super_combine_consts(self, a, b) super_combine_consts(self.infcx, self, a, b)
} }
fn binders<T>( fn binders<T>(

View file

@ -39,75 +39,66 @@ where
fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty); fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty);
} }
pub trait InferCtxtCombineExt<I: Interner>: InferCtxtLike { pub fn super_combine_tys<Infcx, I, R>(
fn super_combine_tys<R>(&self, relation: &mut R, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty> infcx: &Infcx,
where
R: PredicateEmittingRelation<Self>;
fn super_combine_consts<R>(
&self,
relation: &mut R, relation: &mut R,
a: I::Const, a: I::Ty,
b: I::Const, b: I::Ty,
) -> RelateResult<I, I::Const> ) -> RelateResult<I, I::Ty>
where where
R: PredicateEmittingRelation<Self>; Infcx: InferCtxtLike<Interner = I>,
} I: Interner,
impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for Infcx {
fn super_combine_tys<R>(&self, relation: &mut R, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty>
where
R: PredicateEmittingRelation<Infcx>, R: PredicateEmittingRelation<Infcx>,
{ {
debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b); debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
debug_assert!(!a.has_escaping_bound_vars()); debug_assert!(!a.has_escaping_bound_vars());
debug_assert!(!b.has_escaping_bound_vars()); debug_assert!(!b.has_escaping_bound_vars());
match (a.kind(), b.kind()) { match (a.kind(), b.kind()) {
(ty::Error(e), _) | (_, ty::Error(e)) => { (ty::Error(e), _) | (_, ty::Error(e)) => {
self.set_tainted_by_errors(e); infcx.set_tainted_by_errors(e);
return Ok(Ty::new_error(self.cx(), e)); return Ok(Ty::new_error(infcx.cx(), e));
} }
// Relate integral variables to other types // Relate integral variables to other types
(ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) => { (ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) => {
self.equate_int_vids_raw(a_id, b_id); infcx.equate_int_vids_raw(a_id, b_id);
Ok(a) Ok(a)
} }
(ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => { (ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => {
self.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v)); infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
Ok(b) Ok(b)
} }
(ty::Int(v), ty::Infer(ty::IntVar(v_id))) => { (ty::Int(v), ty::Infer(ty::IntVar(v_id))) => {
self.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v)); infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
Ok(a) Ok(a)
} }
(ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => { (ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => {
self.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v)); infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
Ok(b) Ok(b)
} }
(ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => { (ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => {
self.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v)); infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
Ok(a) Ok(a)
} }
// Relate floating-point variables to other types // Relate floating-point variables to other types
(ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id))) => { (ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id))) => {
self.equate_float_vids_raw(a_id, b_id); infcx.equate_float_vids_raw(a_id, b_id);
Ok(a) Ok(a)
} }
(ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => { (ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => {
self.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v)); infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
Ok(b) Ok(b)
} }
(ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => { (ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => {
self.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v)); infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
Ok(a) Ok(a)
} }
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm. // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
(ty::Alias(..), ty::Infer(ty::TyVar(_))) | (ty::Infer(ty::TyVar(_)), ty::Alias(..)) (ty::Alias(..), ty::Infer(ty::TyVar(_))) | (ty::Infer(ty::TyVar(_)), ty::Alias(..))
if self.next_trait_solver() => if infcx.next_trait_solver() =>
{ {
panic!( panic!(
"We do not expect to encounter `TyVar` this late in combine \ "We do not expect to encounter `TyVar` this late in combine \
@ -116,12 +107,12 @@ impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for
} }
(_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))) (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)))
| (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _) | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _)
if self.next_trait_solver() => if infcx.next_trait_solver() =>
{ {
panic!("We do not expect to encounter `Fresh` variables in the new solver") panic!("We do not expect to encounter `Fresh` variables in the new solver")
} }
(_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => { (_, ty::Alias(..)) | (ty::Alias(..), _) if infcx.next_trait_solver() => {
match relation.structurally_relate_aliases() { match relation.structurally_relate_aliases() {
StructurallyRelateAliases::Yes => structurally_relate_tys(relation, a, b), StructurallyRelateAliases::Yes => structurally_relate_tys(relation, a, b),
StructurallyRelateAliases::No => { StructurallyRelateAliases::No => {
@ -137,18 +128,17 @@ impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for
} }
(ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => { (ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => {
match self.solver_mode() { match infcx.solver_mode() {
SolverMode::Normal => { SolverMode::Normal => {
assert!(!self.next_trait_solver()); assert!(!infcx.next_trait_solver());
structurally_relate_tys(relation, a, b) structurally_relate_tys(relation, a, b)
} }
// During coherence, opaque types should be treated as *possibly* // During coherence, opaque types should be treated as *possibly*
// equal to any other type (except for possibly itself). This is an // equal to any other type (except for possibly itinfcx). This is an
// extremely heavy hammer, but can be relaxed in a forwards-compatible // extremely heavy hammer, but can be relaxed in a forwards-compatible
// way later. // way later.
SolverMode::Coherence => { SolverMode::Coherence => {
relation relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
Ok(a) Ok(a)
} }
} }
@ -156,17 +146,19 @@ impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for
_ => structurally_relate_tys(relation, a, b), _ => structurally_relate_tys(relation, a, b),
} }
} }
fn super_combine_consts<R>( pub fn super_combine_consts<Infcx, I, R>(
&self, infcx: &Infcx,
relation: &mut R, relation: &mut R,
a: I::Const, a: I::Const,
b: I::Const, b: I::Const,
) -> RelateResult<I, I::Const> ) -> RelateResult<I, I::Const>
where where
Infcx: InferCtxtLike<Interner = I>,
I: Interner,
R: PredicateEmittingRelation<Infcx>, R: PredicateEmittingRelation<Infcx>,
{ {
debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b); debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
debug_assert!(!a.has_escaping_bound_vars()); debug_assert!(!a.has_escaping_bound_vars());
debug_assert!(!b.has_escaping_bound_vars()); debug_assert!(!b.has_escaping_bound_vars());
@ -175,15 +167,15 @@ impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for
return Ok(a); return Ok(a);
} }
let a = self.shallow_resolve_const(a); let a = infcx.shallow_resolve_const(a);
let b = self.shallow_resolve_const(b); let b = infcx.shallow_resolve_const(b);
match (a.kind(), b.kind()) { match (a.kind(), b.kind()) {
( (
ty::ConstKind::Infer(ty::InferConst::Var(a_vid)), ty::ConstKind::Infer(ty::InferConst::Var(a_vid)),
ty::ConstKind::Infer(ty::InferConst::Var(b_vid)), ty::ConstKind::Infer(ty::InferConst::Var(b_vid)),
) => { ) => {
self.equate_const_vids_raw(a_vid, b_vid); infcx.equate_const_vids_raw(a_vid, b_vid);
Ok(a) Ok(a)
} }
@ -191,7 +183,7 @@ impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for
ty::ConstKind::Infer(ty::InferConst::EffectVar(a_vid)), ty::ConstKind::Infer(ty::InferConst::EffectVar(a_vid)),
ty::ConstKind::Infer(ty::InferConst::EffectVar(b_vid)), ty::ConstKind::Infer(ty::InferConst::EffectVar(b_vid)),
) => { ) => {
self.equate_effect_vids_raw(a_vid, b_vid); infcx.equate_effect_vids_raw(a_vid, b_vid);
Ok(a) Ok(a)
} }
@ -210,31 +202,31 @@ impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for
} }
(ty::ConstKind::Infer(ty::InferConst::Var(vid)), _) => { (ty::ConstKind::Infer(ty::InferConst::Var(vid)), _) => {
self.instantiate_const_var_raw(relation, true, vid, b)?; infcx.instantiate_const_var_raw(relation, true, vid, b)?;
Ok(b) Ok(b)
} }
(_, ty::ConstKind::Infer(ty::InferConst::Var(vid))) => { (_, ty::ConstKind::Infer(ty::InferConst::Var(vid))) => {
self.instantiate_const_var_raw(relation, false, vid, a)?; infcx.instantiate_const_var_raw(relation, false, vid, a)?;
Ok(a) Ok(a)
} }
(ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)), _) => { (ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)), _) => {
self.instantiate_effect_var_raw(vid, b); infcx.instantiate_effect_var_raw(vid, b);
Ok(b) Ok(b)
} }
(_, ty::ConstKind::Infer(ty::InferConst::EffectVar(vid))) => { (_, ty::ConstKind::Infer(ty::InferConst::EffectVar(vid))) => {
self.instantiate_effect_var_raw(vid, a); infcx.instantiate_effect_var_raw(vid, a);
Ok(a) Ok(a)
} }
(ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..)) (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
if self.cx().features().generic_const_exprs() || self.next_trait_solver() => if infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver() =>
{ {
match relation.structurally_relate_aliases() { match relation.structurally_relate_aliases() {
StructurallyRelateAliases::No => { StructurallyRelateAliases::No => {
relation.register_predicates([if self.next_trait_solver() { relation.register_predicates([if infcx.next_trait_solver() {
ty::PredicateKind::AliasRelate( ty::PredicateKind::AliasRelate(
a.into(), a.into(),
b.into(), b.into(),
@ -251,5 +243,4 @@ impl<I: Interner, Infcx: InferCtxtLike<Interner = I>> InferCtxtCombineExt<I> for
} }
_ => structurally_relate_consts(relation, a, b), _ => structurally_relate_consts(relation, a, b),
} }
}
} }

View file

@ -3,7 +3,7 @@ use rustc_type_ir::solve::Goal;
use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
use tracing::{debug, instrument}; use tracing::{debug, instrument};
use self::combine::{InferCtxtCombineExt, PredicateEmittingRelation}; use self::combine::{PredicateEmittingRelation, super_combine_consts, super_combine_tys};
use crate::data_structures::DelayedSet; use crate::data_structures::DelayedSet;
pub trait RelateExt: InferCtxtLike { pub trait RelateExt: InferCtxtLike {
@ -228,7 +228,7 @@ where
} }
_ => { _ => {
self.infcx.super_combine_tys(self, a, b)?; super_combine_tys(self.infcx, self, a, b)?;
} }
} }
@ -255,7 +255,7 @@ where
#[instrument(skip(self), level = "trace")] #[instrument(skip(self), level = "trace")]
fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult<I, I::Const> { fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult<I, I::Const> {
self.infcx.super_combine_consts(self, a, b) super_combine_consts(self.infcx, self, a, b)
} }
fn binders<T>( fn binders<T>(