diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 2c34fc583c8..c531c9b209b 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -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 @@ fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'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 @@ fn binders( } } -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 @@ fn register_predicates( &mut self, obligations: impl IntoIterator, 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>>, + ) { 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 @@ fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { ); } - 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(), diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index dbaa6e398c8..e54a07786cd 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -113,7 +113,7 @@ fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec( adj: Vec>, target: Ty<'tcx>, - obligations: traits::PredicateObligations<'tcx>, + obligations: Vec>, ) -> CoerceResult<'tcx> { Ok(InferOk { value: (adj, target), obligations }) } diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 046d908d148..01bd732a4cd 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -31,6 +31,8 @@ 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 @@ pub fn sup( 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 @@ pub fn sub( 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 @@ pub fn eq( 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 @@ pub fn eq_structurally_relating_aliases( 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( @@ -237,10 +245,8 @@ pub fn lub( 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 @@ pub fn glb( 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() }) } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c606ab808ef..32b50053b50 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -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 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 @@ #[derive(Debug)] pub struct InferOk<'tcx, T> { pub value: T, - pub obligations: PredicateObligations<'tcx>, + pub obligations: Vec>, } pub type InferResult<'tcx, T> = Result, TypeError<'tcx>>; @@ -748,7 +749,7 @@ pub fn into_value_registering_obligations( } impl<'tcx> InferOk<'tcx, ()> { - pub fn into_obligations(self) -> PredicateObligations<'tcx> { + pub fn into_obligations(self) -> Vec> { self.obligations } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 8eb3185673b..7114b888718 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -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 @@ pub type OpaqueTypeMap<'tcx> = FxIndexMap, 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 @@ pub fn replace_opaque_types_with_inference_vars>>( { 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 @@ pub fn handle_opaque_type( &self, a: Ty<'tcx>, b: Ty<'tcx>, - cause: &ObligationCause<'tcx>, + span: Span, param_env: ty::ParamEnv<'tcx>, - ) -> InferResult<'tcx, ()> { + ) -> Result>>, 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 @@ pub fn handle_opaque_type( // 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 @@ pub fn handle_opaque_type( && 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>>, 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 @@ pub fn inject_new_hidden_type_unchecked( 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>, + goals: &mut Vec>>, ) -> 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 @@ pub fn insert_hidden_type( .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 @@ pub fn add_item_bounds_for_hidden_type( &self, def_id: DefId, args: ty::GenericArgsRef<'tcx>, - cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, - obligations: &mut Vec>, + goals: &mut Vec>>, ) { let tcx = self.tcx; // Require that the hidden type is well-formed. We have to @@ -567,12 +571,7 @@ pub fn add_item_bounds_for_hidden_type( // 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 @@ pub fn add_item_bounds_for_hidden_type( && !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 @@ pub fn add_item_bounds_for_hidden_type( // 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)); } } } diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index 16786347980..a1ba43eb171 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -21,11 +21,12 @@ pub fn projection_ty_to_infer( obligations: &mut Vec>, ) -> 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); diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 30cb2bab900..0a2e85cc891 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -25,9 +25,10 @@ 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>>, pub define_opaque_types: DefineOpaqueTypes, } @@ -49,7 +50,21 @@ pub fn new( 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> { + 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 @@ pub fn super_combine_tys( 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 @@ pub fn super_combine_tys( 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 @@ pub fn super_combine_consts( 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 @@ pub fn glb<'a>(&'a mut self) -> Glb<'a, '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>>, + ) { + self.goals.extend(obligations); } pub fn register_predicates( &mut self, obligations: impl IntoIterator, 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> { +pub trait PredicateEmittingRelation<'tcx>: TypeRelation> { fn span(&self) -> Span; fn param_env(&self) -> ty::ParamEnv<'tcx>; @@ -315,16 +335,18 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation> { 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>>, + ); - /// 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, 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>); } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 5478afda455..87a2f0b4580 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -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>( + pub fn instantiate_ty_var>( &self, relation: &mut R, target_is_expected: bool, @@ -178,7 +178,7 @@ pub fn instantiate_ty_var>( /// /// 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>( + pub(super) fn instantiate_const_var>( &self, relation: &mut R, target_is_expected: bool, diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index 98e8f07c7a2..cc17e60a79b 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -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 @@ fn define_opaque_types(&self) -> DefineOpaqueTypes { } } -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 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_goals( + &mut self, + obligations: impl IntoIterator>>, + ) { 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(), diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index f05b984142a..6cc8d6d910a 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -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 @@ /// /// 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 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>( && 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) } diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 28dbaa94f95..e9d300d349c 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -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 @@ fn define_opaque_types(&self) -> DefineOpaqueTypes { } } -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 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_goals( + &mut self, + obligations: impl IntoIterator>>, + ) { 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(), diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs index 627c527cba1..e7b50479b85 100644 --- a/compiler/rustc_infer/src/infer/relate/mod.rs +++ b/compiler/rustc_infer/src/infer/relate/mod.rs @@ -6,7 +6,7 @@ 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; diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index fd0bc9f44f7..f7b2f11e3d7 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -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 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'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 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'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 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'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 @@ fn binders( } } -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 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_goals( + &mut self, + obligations: impl IntoIterator>>, + ) { 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(), diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index ca6c6570e07..556b3bd063d 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -114,8 +114,6 @@ pub fn derived_cause( #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(PredicateObligation<'_>, 48); -pub type PredicateObligations<'tcx> = Vec>; - pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>; /// A callback that can be provided to `inspect_typeck`. Invoked on evaluation diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index b522022c206..43013a01069 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -961,15 +961,15 @@ pub(super) fn insert_hidden_type( 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 @@ pub(super) fn add_item_bounds_for_hidden_type( 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 diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 1ef2f26cd09..fc5c71252e1 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -12,9 +12,7 @@ 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> { +) -> Option>> { let result = match (impl1.trait_ref, impl2.trait_ref) { (Some(impl1_ref), Some(impl2_ref)) => infcx diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index ae4cdb9258e..c1b1bfd300b 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -5,7 +5,7 @@ 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 @@ fn fully_perform_into( ( Self::QueryResponse, Option>>, - PredicateObligations<'tcx>, + Vec>, Certainty, ), NoSolution,