Auto merge of #126130 - compiler-errors:goal-relations, r=lcnr

Make `ObligationEmittingRelation`s emit `Goal` rather than `Obligation`

Helps avoid needing to uplift `Obligation` into the solver. We still can't get rid of `ObligationCause`, but we can keep it as an associated type for `InferCtxtLike` and just give it a `dummy` function.

There's some shuttling between `Goal` and `Obligation` that may be perf-sensitive... Let's see what rust-timer says.

r? lcnr
This commit is contained in:
bors 2024-06-12 03:35:31 +00:00
commit 76c73827dc
17 changed files with 216 additions and 178 deletions

View File

@ -1,9 +1,10 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::ErrorGuaranteed;
use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases};
use rustc_infer::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation};
use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_infer::traits::{Obligation, PredicateObligations};
use rustc_infer::traits::solve::Goal;
use rustc_infer::traits::Obligation;
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::span_bug;
use rustc_middle::traits::query::NoSolution;
@ -153,9 +154,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
"expected at least one opaque type in `relate_opaques`, got {a} and {b}."
),
};
let cause = ObligationCause::dummy_with_span(self.span());
let obligations = infcx.handle_opaque_type(a, b, &cause, self.param_env())?.obligations;
self.register_obligations(obligations);
self.register_goals(infcx.handle_opaque_type(a, b, self.span(), self.param_env())?);
Ok(())
}
@ -533,7 +532,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
}
}
impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
fn span(&self) -> Span {
self.locations.span(self.type_checker.body)
}
@ -550,22 +549,32 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx
&mut self,
obligations: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
) {
self.register_obligations(
obligations
.into_iter()
.map(|to_pred| {
Obligation::new(self.tcx(), ObligationCause::dummy(), self.param_env(), to_pred)
})
.collect(),
let tcx = self.tcx();
let param_env = self.param_env();
self.register_goals(
obligations.into_iter().map(|to_pred| Goal::new(tcx, param_env, to_pred)),
);
}
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
fn register_goals(
&mut self,
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
) {
let _: Result<_, ErrorGuaranteed> = self.type_checker.fully_perform_op(
self.locations,
self.category,
InstantiateOpaqueType {
obligations,
obligations: obligations
.into_iter()
.map(|goal| {
Obligation::new(
self.tcx(),
ObligationCause::dummy_with_span(self.span()),
goal.param_env,
goal.predicate,
)
})
.collect(),
// These fields are filled in during execution of the operation
base_universe: None,
region_constraints: None,
@ -573,7 +582,7 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx
);
}
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
a.into(),

View File

@ -113,7 +113,7 @@ fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'
fn success<'tcx>(
adj: Vec<Adjustment<'tcx>>,
target: Ty<'tcx>,
obligations: traits::PredicateObligations<'tcx>,
obligations: Vec<traits::PredicateObligation<'tcx>>,
) -> CoerceResult<'tcx> {
Ok(InferOk { value: (adj, target), obligations })
}

View File

@ -31,6 +31,8 @@ use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation};
use rustc_middle::bug;
use rustc_middle::ty::{Const, ImplSubject};
use crate::traits::Obligation;
/// Whether we should define opaque types or just treat them opaquely.
///
/// Currently only used to prevent predicate matching from matching anything
@ -119,10 +121,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
self.param_env,
define_opaque_types,
);
fields
.sup()
.relate(expected, actual)
.map(|_| InferOk { value: (), obligations: fields.obligations })
fields.sup().relate(expected, actual)?;
Ok(InferOk { value: (), obligations: fields.into_obligations() })
}
/// Makes `expected <: actual`.
@ -141,10 +141,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
self.param_env,
define_opaque_types,
);
fields
.sub()
.relate(expected, actual)
.map(|_| InferOk { value: (), obligations: fields.obligations })
fields.sub().relate(expected, actual)?;
Ok(InferOk { value: (), obligations: fields.into_obligations() })
}
/// Makes `expected == actual`.
@ -163,10 +161,22 @@ impl<'a, 'tcx> At<'a, 'tcx> {
self.param_env,
define_opaque_types,
);
fields
.equate(StructurallyRelateAliases::No)
.relate(expected, actual)
.map(|_| InferOk { value: (), obligations: fields.obligations })
fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?;
Ok(InferOk {
value: (),
obligations: fields
.goals
.into_iter()
.map(|goal| {
Obligation::new(
self.infcx.tcx,
fields.trace.cause.clone(),
goal.param_env,
goal.predicate,
)
})
.collect(),
})
}
/// Equates `expected` and `found` while structurally relating aliases.
@ -187,10 +197,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
self.param_env,
DefineOpaqueTypes::Yes,
);
fields
.equate(StructurallyRelateAliases::Yes)
.relate(expected, actual)
.map(|_| InferOk { value: (), obligations: fields.obligations })
fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
Ok(InferOk { value: (), obligations: fields.into_obligations() })
}
pub fn relate<T>(
@ -237,10 +245,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
self.param_env,
define_opaque_types,
);
fields
.lub()
.relate(expected, actual)
.map(|value| InferOk { value, obligations: fields.obligations })
let value = fields.lub().relate(expected, actual)?;
Ok(InferOk { value, obligations: fields.into_obligations() })
}
/// Computes the greatest-lower-bound, or mutual subtype, of two
@ -261,10 +267,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
self.param_env,
define_opaque_types,
);
fields
.glb()
.relate(expected, actual)
.map(|value| InferOk { value, obligations: fields.obligations })
let value = fields.glb().relate(expected, actual)?;
Ok(InferOk { value, obligations: fields.into_obligations() })
}
}

View File

@ -1,6 +1,9 @@
pub use at::DefineOpaqueTypes;
pub use freshen::TypeFreshener;
pub use lexical_region_resolve::RegionResolutionError;
pub use relate::combine::CombineFields;
pub use relate::combine::PredicateEmittingRelation;
pub use relate::StructurallyRelateAliases;
pub use rustc_macros::{TypeFoldable, TypeVisitable};
pub use rustc_middle::ty::IntVarValue;
pub use BoundRegionConversionTime::*;
@ -8,10 +11,8 @@ pub use RegionVariableOrigin::*;
pub use SubregionOrigin::*;
pub use ValuePairs::*;
use crate::infer::relate::{CombineFields, RelateResult};
use crate::traits::{
self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine,
};
use crate::infer::relate::RelateResult;
use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
use error_reporting::TypeErrCtxt;
use free_regions::RegionRelations;
use lexical_region_resolve::LexicalRegionResolutions;
@ -68,7 +69,7 @@ pub mod type_variable;
#[derive(Debug)]
pub struct InferOk<'tcx, T> {
pub value: T,
pub obligations: PredicateObligations<'tcx>,
pub obligations: Vec<PredicateObligation<'tcx>>,
}
pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
@ -748,7 +749,7 @@ impl<'tcx, T> InferOk<'tcx, T> {
}
impl<'tcx> InferOk<'tcx, ()> {
pub fn into_obligations(self) -> PredicateObligations<'tcx> {
pub fn into_obligations(self) -> Vec<PredicateObligation<'tcx>> {
self.obligations
}
}

View File

@ -1,11 +1,11 @@
use super::{DefineOpaqueTypes, InferResult};
use crate::errors::OpaqueHiddenTypeDiag;
use crate::infer::{InferCtxt, InferOk};
use crate::traits::{self, PredicateObligation};
use crate::traits::{self, Obligation};
use hir::def_id::{DefId, LocalDefId};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::Lrc;
use rustc_hir as hir;
use rustc_middle::traits::solve::Goal;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::BottomUpFolder;
@ -21,6 +21,8 @@ mod table;
pub type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
use super::DefineOpaqueTypes;
/// Information about the opaque types whose values we
/// are inferring in this function (these are the `impl Trait` that
/// appear in the return type).
@ -62,11 +64,23 @@ impl<'tcx> InferCtxt<'tcx> {
{
let def_span = self.tcx.def_span(def_id);
let span = if span.contains(def_span) { def_span } else { span };
let code = traits::ObligationCauseCode::OpaqueReturnType(None);
let cause = ObligationCause::new(span, body_id, code);
let ty_var = self.next_ty_var(span);
obligations.extend(
self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations,
self.handle_opaque_type(ty, ty_var, span, param_env)
.unwrap()
.into_iter()
.map(|goal| {
Obligation::new(
self.tcx,
ObligationCause::new(
span,
body_id,
traits::ObligationCauseCode::OpaqueReturnType(None),
),
goal.param_env,
goal.predicate,
)
}),
);
ty_var
}
@ -80,9 +94,9 @@ impl<'tcx> InferCtxt<'tcx> {
&self,
a: Ty<'tcx>,
b: Ty<'tcx>,
cause: &ObligationCause<'tcx>,
span: Span,
param_env: ty::ParamEnv<'tcx>,
) -> InferResult<'tcx, ()> {
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
let def_id = def_id.expect_local();
@ -90,7 +104,7 @@ impl<'tcx> InferCtxt<'tcx> {
// See comment on `insert_hidden_type` for why this is sufficient in coherence
return Some(self.register_hidden_type(
OpaqueTypeKey { def_id, args },
cause.clone(),
span,
param_env,
b,
));
@ -143,18 +157,13 @@ impl<'tcx> InferCtxt<'tcx> {
&& self.tcx.is_type_alias_impl_trait(b_def_id)
{
self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag {
span: cause.span,
span,
hidden_type: self.tcx.def_span(b_def_id),
opaque_type: self.tcx.def_span(def_id),
});
}
}
Some(self.register_hidden_type(
OpaqueTypeKey { def_id, args },
cause.clone(),
param_env,
b,
))
Some(self.register_hidden_type(OpaqueTypeKey { def_id, args }, span, param_env, b))
}
_ => None,
};
@ -464,24 +473,23 @@ impl<'tcx> InferCtxt<'tcx> {
fn register_hidden_type(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
cause: ObligationCause<'tcx>,
span: Span,
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
) -> InferResult<'tcx, ()> {
let mut obligations = Vec::new();
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
let mut goals = Vec::new();
self.insert_hidden_type(opaque_type_key, &cause, param_env, hidden_ty, &mut obligations)?;
self.insert_hidden_type(opaque_type_key, span, param_env, hidden_ty, &mut goals)?;
self.add_item_bounds_for_hidden_type(
opaque_type_key.def_id.to_def_id(),
opaque_type_key.args,
cause,
param_env,
hidden_ty,
&mut obligations,
&mut goals,
);
Ok(InferOk { value: (), obligations })
Ok(goals)
}
/// Insert a hidden type into the opaque type storage, making sure
@ -507,27 +515,21 @@ impl<'tcx> InferCtxt<'tcx> {
pub fn insert_hidden_type(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
cause: &ObligationCause<'tcx>,
span: Span,
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
obligations: &mut Vec<PredicateObligation<'tcx>>,
goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
) -> Result<(), TypeError<'tcx>> {
// Ideally, we'd get the span where *this specific `ty` came
// from*, but right now we just use the span from the overall
// value being folded. In simple cases like `-> impl Foo`,
// these are the same span, but not in cases like `-> (impl
// Foo, impl Bar)`.
let span = cause.span;
if self.intercrate {
// During intercrate we do not define opaque types but instead always
// force ambiguity unless the hidden type is known to not implement
// our trait.
obligations.push(traits::Obligation::new(
self.tcx,
cause.clone(),
param_env,
ty::PredicateKind::Ambiguous,
))
goals.push(Goal::new(self.tcx, param_env, ty::PredicateKind::Ambiguous))
} else {
let prev = self
.inner
@ -535,10 +537,13 @@ impl<'tcx> InferCtxt<'tcx> {
.opaque_types()
.register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span });
if let Some(prev) = prev {
obligations.extend(
self.at(cause, param_env)
goals.extend(
self.at(&ObligationCause::dummy_with_span(span), param_env)
.eq(DefineOpaqueTypes::Yes, prev, hidden_ty)?
.obligations,
.obligations
.into_iter()
// FIXME: Shuttling between obligations and goals is awkward.
.map(Goal::from),
);
}
};
@ -550,10 +555,9 @@ impl<'tcx> InferCtxt<'tcx> {
&self,
def_id: DefId,
args: ty::GenericArgsRef<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
obligations: &mut Vec<PredicateObligation<'tcx>>,
goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
) {
let tcx = self.tcx;
// Require that the hidden type is well-formed. We have to
@ -567,12 +571,7 @@ impl<'tcx> InferCtxt<'tcx> {
// type during MIR borrowck, causing us to infer the wrong
// lifetime for its member constraints which then results in
// unexpected region errors.
obligations.push(traits::Obligation::new(
tcx,
cause.clone(),
param_env,
ty::ClauseKind::WellFormed(hidden_ty.into()),
));
goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into())));
let item_bounds = tcx.explicit_item_bounds(def_id);
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
@ -588,13 +587,18 @@ impl<'tcx> InferCtxt<'tcx> {
&& !tcx.is_impl_trait_in_trait(projection_ty.def_id)
&& !self.next_trait_solver() =>
{
self.projection_ty_to_infer(
let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id));
goals.push(Goal::new(
self.tcx,
param_env,
projection_ty,
cause.clone(),
0,
obligations,
)
ty::PredicateKind::Clause(ty::ClauseKind::Projection(
ty::ProjectionPredicate {
projection_term: projection_ty.into(),
term: ty_var.into(),
},
)),
));
ty_var
}
// Replace all other mentions of the same opaque type with the hidden type,
// as the bounds must hold on the hidden type after all.
@ -611,12 +615,7 @@ impl<'tcx> InferCtxt<'tcx> {
// Require that the predicate holds for the concrete type.
debug!(?predicate);
obligations.push(traits::Obligation::new(
self.tcx,
cause.clone(),
param_env,
predicate,
));
goals.push(Goal::new(self.tcx, param_env, predicate));
}
}
}

View File

@ -21,11 +21,12 @@ impl<'tcx> InferCtxt<'tcx> {
obligations: &mut Vec<PredicateObligation<'tcx>>,
) -> Ty<'tcx> {
debug_assert!(!self.next_trait_solver());
let def_id = projection_ty.def_id;
let ty_var = self.next_ty_var(self.tcx.def_span(def_id));
let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection(
ty::ProjectionPredicate { projection_term: projection_ty.into(), term: ty_var.into() },
)));
let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id));
let projection =
ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_term: projection_ty.into(),
term: ty_var.into(),
}));
let obligation =
Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection);
obligations.push(obligation);

View File

@ -25,9 +25,10 @@ use super::StructurallyRelateAliases;
use super::{RelateResult, TypeRelation};
use crate::infer::relate;
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
use crate::traits::{Obligation, PredicateObligations};
use crate::traits::{Obligation, PredicateObligation};
use rustc_middle::bug;
use rustc_middle::infer::unify_key::EffectVarValue;
use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
use rustc_middle::ty::{IntType, UintType};
@ -38,7 +39,7 @@ pub struct CombineFields<'infcx, 'tcx> {
pub infcx: &'infcx InferCtxt<'tcx>,
pub trace: TypeTrace<'tcx>,
pub param_env: ty::ParamEnv<'tcx>,
pub obligations: PredicateObligations<'tcx>,
pub goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
pub define_opaque_types: DefineOpaqueTypes,
}
@ -49,7 +50,21 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
define_opaque_types: DefineOpaqueTypes,
) -> Self {
Self { infcx, trace, param_env, define_opaque_types, obligations: vec![] }
Self { infcx, trace, param_env, define_opaque_types, goals: vec![] }
}
pub(crate) fn into_obligations(self) -> Vec<PredicateObligation<'tcx>> {
self.goals
.into_iter()
.map(|goal| {
Obligation::new(
self.infcx.tcx,
self.trace.cause.clone(),
goal.param_env,
goal.predicate,
)
})
.collect()
}
}
@ -61,7 +76,7 @@ impl<'tcx> InferCtxt<'tcx> {
b: Ty<'tcx>,
) -> RelateResult<'tcx, Ty<'tcx>>
where
R: ObligationEmittingRelation<'tcx>,
R: PredicateEmittingRelation<'tcx>,
{
debug_assert!(!a.has_escaping_bound_vars());
debug_assert!(!b.has_escaping_bound_vars());
@ -125,7 +140,7 @@ impl<'tcx> InferCtxt<'tcx> {
relate::structurally_relate_tys(relation, a, b)
}
StructurallyRelateAliases::No => {
relation.register_type_relate_obligation(a, b);
relation.register_alias_relate_predicate(a, b);
Ok(a)
}
}
@ -156,7 +171,7 @@ impl<'tcx> InferCtxt<'tcx> {
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>>
where
R: ObligationEmittingRelation<'tcx>,
R: PredicateEmittingRelation<'tcx>,
{
debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
debug_assert!(!a.has_escaping_bound_vars());
@ -290,21 +305,26 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
Glb::new(self)
}
pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
self.obligations.extend(obligations);
pub fn register_obligations(
&mut self,
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
) {
self.goals.extend(obligations);
}
pub fn register_predicates(
&mut self,
obligations: impl IntoIterator<Item: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
) {
self.obligations.extend(obligations.into_iter().map(|to_pred| {
Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, to_pred)
}))
self.goals.extend(
obligations
.into_iter()
.map(|to_pred| Goal::new(self.infcx.tcx, self.param_env, to_pred)),
)
}
}
pub trait ObligationEmittingRelation<'tcx>: TypeRelation<TyCtxt<'tcx>> {
pub trait PredicateEmittingRelation<'tcx>: TypeRelation<TyCtxt<'tcx>> {
fn span(&self) -> Span;
fn param_env(&self) -> ty::ParamEnv<'tcx>;
@ -315,16 +335,18 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<TyCtxt<'tcx>> {
fn structurally_relate_aliases(&self) -> StructurallyRelateAliases;
/// Register obligations that must hold in order for this relation to hold
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>);
fn register_goals(
&mut self,
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
);
/// Register predicates that must hold in order for this relation to hold. Uses
/// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should
/// be used if control over the obligation causes is required.
/// Register predicates that must hold in order for this relation to hold.
/// This uses the default `param_env` of the obligation.
fn register_predicates(
&mut self,
obligations: impl IntoIterator<Item: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
);
/// Register `AliasRelate` obligation(s) that both types must be related to each other.
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>);
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>);
}

View File

@ -1,7 +1,7 @@
use std::mem;
use super::StructurallyRelateAliases;
use super::{ObligationEmittingRelation, Relate, RelateResult, TypeRelation};
use super::{PredicateEmittingRelation, Relate, RelateResult, TypeRelation};
use crate::infer::relate;
use crate::infer::type_variable::TypeVariableValue;
use crate::infer::{InferCtxt, RegionVariableOrigin};
@ -30,7 +30,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
/// other usecases (i.e. setting the value of a type var).
#[instrument(level = "debug", skip(self, relation))]
pub fn instantiate_ty_var<R: ObligationEmittingRelation<'tcx>>(
pub fn instantiate_ty_var<R: PredicateEmittingRelation<'tcx>>(
&self,
relation: &mut R,
target_is_expected: bool,
@ -178,7 +178,7 @@ impl<'tcx> InferCtxt<'tcx> {
///
/// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant.
#[instrument(level = "debug", skip(self, relation))]
pub(super) fn instantiate_const_var<R: ObligationEmittingRelation<'tcx>>(
pub(super) fn instantiate_const_var<R: PredicateEmittingRelation<'tcx>>(
&self,
relation: &mut R,
target_is_expected: bool,

View File

@ -1,14 +1,15 @@
//! Greatest lower bound. See [`lattice`].
use super::{Relate, RelateResult, TypeRelation};
use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
use super::combine::{CombineFields, ObligationEmittingRelation};
use super::combine::{CombineFields, PredicateEmittingRelation};
use super::lattice::{self, LatticeDir};
use super::StructurallyRelateAliases;
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
use crate::traits::{ObligationCause, PredicateObligations};
use crate::traits::ObligationCause;
/// "Greatest lower bound" (common subtype)
pub struct Glb<'combine, 'infcx, 'tcx> {
@ -127,7 +128,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
}
}
impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
impl<'tcx> PredicateEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
fn span(&self) -> Span {
self.fields.trace.span()
}
@ -147,11 +148,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
self.fields.register_predicates(obligations);
}
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
fn register_goals(
&mut self,
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
) {
self.fields.register_obligations(obligations);
}
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
a.into(),
b.into(),

View File

@ -17,11 +17,11 @@
//!
//! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order)
use super::combine::ObligationEmittingRelation;
use super::combine::PredicateEmittingRelation;
use crate::infer::{DefineOpaqueTypes, InferCtxt};
use crate::traits::ObligationCause;
use super::RelateResult;
use rustc_middle::ty::relate::RelateResult;
use rustc_middle::ty::TyVar;
use rustc_middle::ty::{self, Ty};
@ -30,7 +30,7 @@ use rustc_middle::ty::{self, Ty};
///
/// GLB moves "down" the lattice (to smaller values); LUB moves
/// "up" the lattice (to bigger values).
pub trait LatticeDir<'f, 'tcx>: ObligationEmittingRelation<'tcx> {
pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<'tcx> {
fn infcx(&self) -> &'f InferCtxt<'tcx>;
fn cause(&self) -> &ObligationCause<'tcx>;
@ -108,9 +108,7 @@ where
&& def_id.is_local()
&& !this.infcx().next_trait_solver() =>
{
this.register_obligations(
infcx.handle_opaque_type(a, b, this.cause(), this.param_env())?.obligations,
);
this.register_goals(infcx.handle_opaque_type(a, b, this.span(), this.param_env())?);
Ok(a)
}

View File

@ -1,12 +1,13 @@
//! Least upper bound. See [`lattice`].
use super::combine::{CombineFields, ObligationEmittingRelation};
use super::combine::{CombineFields, PredicateEmittingRelation};
use super::lattice::{self, LatticeDir};
use super::StructurallyRelateAliases;
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
use crate::traits::{ObligationCause, PredicateObligations};
use crate::traits::ObligationCause;
use super::{Relate, RelateResult, TypeRelation};
use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
@ -127,7 +128,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
}
}
impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
impl<'tcx> PredicateEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
fn span(&self) -> Span {
self.fields.trace.span()
}
@ -147,11 +148,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
self.fields.register_predicates(obligations);
}
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
fn register_goals(
&mut self,
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
) {
self.fields.register_obligations(obligations)
}
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
a.into(),
b.into(),

View File

@ -6,7 +6,7 @@ pub use rustc_middle::ty::relate::*;
pub use self::_match::MatchAgainstFreshVars;
pub use self::combine::CombineFields;
pub use self::combine::ObligationEmittingRelation;
pub use self::combine::PredicateEmittingRelation;
pub mod _match;
pub(super) mod combine;

View File

@ -1,11 +1,10 @@
use super::combine::CombineFields;
use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
use crate::infer::BoundRegionConversionTime::HigherRankedType;
use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
use crate::traits::{Obligation, PredicateObligations};
use super::{
relate_args_invariantly, relate_args_with_variances, ObligationEmittingRelation, Relate,
RelateResult, StructurallyRelateAliases, TypeRelation,
use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::relate::{
relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation,
};
use rustc_middle::ty::TyVar;
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -88,9 +87,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
ty::Covariant => {
// can't make progress on `A <: B` if both A and B are
// type variables, so record an obligation.
self.fields.obligations.push(Obligation::new(
self.fields.goals.push(Goal::new(
self.tcx(),
self.fields.trace.cause.clone(),
self.fields.param_env,
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
a_is_expected: true,
@ -102,9 +100,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
ty::Contravariant => {
// can't make progress on `B <: A` if both A and B are
// type variables, so record an obligation.
self.fields.obligations.push(Obligation::new(
self.fields.goals.push(Goal::new(
self.tcx(),
self.fields.trace.cause.clone(),
self.fields.param_env,
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
a_is_expected: false,
@ -153,11 +150,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
&& def_id.is_local()
&& !infcx.next_trait_solver() =>
{
self.fields.obligations.extend(
infcx
.handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())?
.obligations,
);
self.fields.goals.extend(infcx.handle_opaque_type(
a,
b,
self.fields.trace.cause.span,
self.param_env(),
)?);
}
_ => {
@ -298,7 +296,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
}
}
impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
fn span(&self) -> Span {
self.fields.trace.span()
}
@ -318,11 +316,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
self.fields.register_predicates(obligations);
}
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
fn register_goals(
&mut self,
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
) {
self.fields.register_obligations(obligations);
}
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
a.into(),

View File

@ -114,8 +114,6 @@ impl<'tcx> PolyTraitObligation<'tcx> {
#[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(PredicateObligation<'_>, 48);
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;
/// A callback that can be provided to `inspect_typeck`. Invoked on evaluation

View File

@ -961,15 +961,15 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
) -> Result<(), NoSolution> {
let mut obligations = Vec::new();
let mut goals = Vec::new();
self.infcx.insert_hidden_type(
opaque_type_key,
&ObligationCause::dummy(),
DUMMY_SP,
param_env,
hidden_ty,
&mut obligations,
&mut goals,
)?;
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
self.add_goals(GoalSource::Misc, goals);
Ok(())
}
@ -980,16 +980,15 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
) {
let mut obligations = Vec::new();
let mut goals = Vec::new();
self.infcx.add_item_bounds_for_hidden_type(
opaque_def_id,
opaque_args,
ObligationCause::dummy(),
param_env,
hidden_ty,
&mut obligations,
&mut goals,
);
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
self.add_goals(GoalSource::Misc, goals);
}
// Do something for each opaque/hidden pair defined with `def_id` in the

View File

@ -12,9 +12,7 @@ use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::NormalizeExt;
use crate::traits::SkipLeakCheck;
use crate::traits::{util, FulfillmentErrorCode};
use crate::traits::{
Obligation, ObligationCause, PredicateObligation, PredicateObligations, SelectionContext,
};
use crate::traits::{Obligation, ObligationCause, PredicateObligation, SelectionContext};
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir::def::DefKind;
@ -305,7 +303,7 @@ fn equate_impl_headers<'tcx>(
param_env: ty::ParamEnv<'tcx>,
impl1: &ty::ImplHeader<'tcx>,
impl2: &ty::ImplHeader<'tcx>,
) -> Option<PredicateObligations<'tcx>> {
) -> Option<Vec<PredicateObligation<'tcx>>> {
let result =
match (impl1.trait_ref, impl2.trait_ref) {
(Some(impl1_ref), Some(impl2_ref)) => infcx

View File

@ -5,7 +5,7 @@ use crate::infer::{InferCtxt, InferOk};
use crate::traits::{ObligationCause, ObligationCtxt};
use rustc_errors::ErrorGuaranteed;
use rustc_infer::infer::canonical::Certainty;
use rustc_infer::traits::PredicateObligations;
use rustc_infer::traits::PredicateObligation;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
@ -103,7 +103,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
(
Self::QueryResponse,
Option<Canonical<'tcx, ParamEnvAnd<'tcx, Self>>>,
PredicateObligations<'tcx>,
Vec<PredicateObligation<'tcx>>,
Certainty,
),
NoSolution,