From 4038010436d18725dd5c6c8cd91f9f1fca617373 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 09:48:12 -0400 Subject: [PATCH 1/4] Get rid of PredicateObligations --- compiler/rustc_borrowck/src/type_check/relate_tys.rs | 4 ++-- compiler/rustc_hir_typeck/src/coercion.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 8 +++----- compiler/rustc_infer/src/infer/relate/combine.rs | 8 ++++---- compiler/rustc_infer/src/infer/relate/glb.rs | 4 ++-- compiler/rustc_infer/src/infer/relate/lub.rs | 4 ++-- compiler/rustc_infer/src/infer/relate/type_relating.rs | 4 ++-- compiler/rustc_infer/src/traits/mod.rs | 2 -- compiler/rustc_trait_selection/src/traits/coherence.rs | 6 ++---- .../rustc_trait_selection/src/traits/query/type_op/mod.rs | 4 ++-- 10 files changed, 20 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 2c34fc583c8..cd51d73ba55 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -3,7 +3,7 @@ use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases}; use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation}; use rustc_infer::infer::NllRegionVariableOrigin; -use rustc_infer::traits::{Obligation, PredicateObligations}; +use rustc_infer::traits::{Obligation, PredicateObligation}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::span_bug; use rustc_middle::traits::query::NoSolution; @@ -560,7 +560,7 @@ fn register_predicates( ); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_obligations(&mut self, obligations: Vec>) { let _: Result<_, ErrorGuaranteed> = self.type_checker.fully_perform_op( self.locations, self.category, 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/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c606ab808ef..98a795e67f8 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -9,9 +9,7 @@ pub use ValuePairs::*; use crate::infer::relate::{CombineFields, RelateResult}; -use crate::traits::{ - self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine, -}; +use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine}; use error_reporting::TypeErrCtxt; use free_regions::RegionRelations; use lexical_region_resolve::LexicalRegionResolutions; @@ -68,7 +66,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 +746,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/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 30cb2bab900..e62ef5d4ea4 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -25,7 +25,7 @@ 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::ty::error::{ExpectedFound, TypeError}; @@ -38,7 +38,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 obligations: Vec>, pub define_opaque_types: DefineOpaqueTypes, } @@ -290,7 +290,7 @@ pub fn glb<'a>(&'a mut self) -> Glb<'a, 'infcx, 'tcx> { Glb::new(self) } - pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + pub fn register_obligations(&mut self, obligations: Vec>) { self.obligations.extend(obligations); } @@ -315,7 +315,7 @@ 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_obligations(&mut self, obligations: Vec>); /// Register predicates that must hold in order for this relation to hold. Uses /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index 98e8f07c7a2..ca772b349d2 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -8,7 +8,7 @@ use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; -use crate::traits::{ObligationCause, PredicateObligations}; +use crate::traits::{ObligationCause, PredicateObligation}; /// "Greatest lower bound" (common subtype) pub struct Glb<'combine, 'infcx, 'tcx> { @@ -147,7 +147,7 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_obligations(&mut self, obligations: Vec>) { self.fields.register_obligations(obligations); } diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 28dbaa94f95..0b9de8de001 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -4,7 +4,7 @@ use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; -use crate::traits::{ObligationCause, PredicateObligations}; +use crate::traits::{ObligationCause, PredicateObligation}; use super::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; @@ -147,7 +147,7 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_obligations(&mut self, obligations: Vec>) { self.fields.register_obligations(obligations) } diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index fd0bc9f44f7..447e4d6bfd8 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -1,7 +1,7 @@ use super::combine::CombineFields; use crate::infer::BoundRegionConversionTime::HigherRankedType; use crate::infer::{DefineOpaqueTypes, SubregionOrigin}; -use crate::traits::{Obligation, PredicateObligations}; +use crate::traits::{Obligation, PredicateObligation}; use super::{ relate_args_invariantly, relate_args_with_variances, ObligationEmittingRelation, Relate, @@ -318,7 +318,7 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_obligations(&mut self, obligations: Vec>) { self.fields.register_obligations(obligations); } 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/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, From 44a6f72a725d1e274d734473c95f95caa5c6fbb6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 10:05:47 -0400 Subject: [PATCH 2/4] Make ObligationEmittingRelation deal with Goals only --- .../src/type_check/relate_tys.rs | 38 ++++++++++---- compiler/rustc_infer/src/infer/at.rs | 52 ++++++++++--------- .../rustc_infer/src/infer/relate/combine.rs | 35 ++++++++++--- compiler/rustc_infer/src/infer/relate/glb.rs | 10 ++-- .../rustc_infer/src/infer/relate/lattice.rs | 9 +++- compiler/rustc_infer/src/infer/relate/lub.rs | 10 ++-- .../src/infer/relate/type_relating.rs | 25 +++++---- 7 files changed, 119 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index cd51d73ba55..a87b9f7a23d 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -3,7 +3,8 @@ use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases}; use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation}; use rustc_infer::infer::NllRegionVariableOrigin; -use rustc_infer::traits::{Obligation, PredicateObligation}; +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; @@ -154,8 +155,13 @@ fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> ), }; 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_obligations( + infcx + .handle_opaque_type(a, b, &cause, self.param_env())? + .obligations + .into_iter() + .map(Goal::from), + ); Ok(()) } @@ -550,22 +556,32 @@ fn register_predicates( &mut self, obligations: impl IntoIterator, ty::Predicate<'tcx>>>, ) { + let tcx = self.tcx(); + let param_env = self.param_env(); self.register_obligations( - obligations - .into_iter() - .map(|to_pred| { - Obligation::new(self.tcx(), ObligationCause::dummy(), self.param_env(), to_pred) - }) - .collect(), + obligations.into_iter().map(|to_pred| Goal::new(tcx, param_env, to_pred)), ); } - fn register_obligations(&mut self, obligations: Vec>) { + fn register_obligations( + &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, diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 046d908d148..8994739f5c7 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 + .obligations + .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/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index e62ef5d4ea4..1a0a0d10c6d 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -28,6 +28,7 @@ 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: Vec>, + pub obligations: Vec>>, pub define_opaque_types: DefineOpaqueTypes, } @@ -51,6 +52,20 @@ pub fn new( ) -> Self { Self { infcx, trace, param_env, define_opaque_types, obligations: vec![] } } + + pub(crate) fn into_obligations(self) -> Vec> { + self.obligations + .into_iter() + .map(|goal| { + Obligation::new( + self.infcx.tcx, + self.trace.cause.clone(), + goal.param_env, + goal.predicate, + ) + }) + .collect() + } } impl<'tcx> InferCtxt<'tcx> { @@ -290,7 +305,10 @@ pub fn glb<'a>(&'a mut self) -> Glb<'a, 'infcx, 'tcx> { Glb::new(self) } - pub fn register_obligations(&mut self, obligations: Vec>) { + pub fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { self.obligations.extend(obligations); } @@ -298,9 +316,11 @@ 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.obligations.extend( + obligations + .into_iter() + .map(|to_pred| Goal::new(self.infcx.tcx, self.param_env, to_pred)), + ) } } @@ -315,7 +335,10 @@ 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: Vec>); + fn register_obligations( + &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 diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index ca772b349d2..6f37995ac1e 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -1,6 +1,7 @@ //! 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; @@ -8,7 +9,7 @@ use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::ObligationCause; /// "Greatest lower bound" (common subtype) pub struct Glb<'combine, 'infcx, 'tcx> { @@ -147,7 +148,10 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: Vec>) { + fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { self.fields.register_obligations(obligations); } diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index f05b984142a..8c6f1690ade 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -21,7 +21,8 @@ use crate::infer::{DefineOpaqueTypes, InferCtxt}; use crate::traits::ObligationCause; -use super::RelateResult; +use rustc_middle::traits::solve::Goal; +use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty}; @@ -109,7 +110,11 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>( && !this.infcx().next_trait_solver() => { this.register_obligations( - infcx.handle_opaque_type(a, b, this.cause(), this.param_env())?.obligations, + infcx + .handle_opaque_type(a, b, this.cause(), this.param_env())? + .obligations + .into_iter() + .map(Goal::from), ); Ok(a) } diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 0b9de8de001..625cc02115a 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -4,9 +4,10 @@ use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; -use crate::traits::{ObligationCause, PredicateObligation}; +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; @@ -147,7 +148,10 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: Vec>) { + fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { self.fields.register_obligations(obligations) } diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 447e4d6bfd8..328e4d8902f 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::{ObligationEmittingRelation, StructurallyRelateAliases}; use crate::infer::BoundRegionConversionTime::HigherRankedType; use crate::infer::{DefineOpaqueTypes, SubregionOrigin}; -use crate::traits::{Obligation, PredicateObligation}; - -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.obligations.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.obligations.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,10 +150,13 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { && def_id.is_local() && !infcx.next_trait_solver() => { + // FIXME: Don't shuttle between Goal and Obligation self.fields.obligations.extend( infcx .handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())? - .obligations, + .obligations + .into_iter() + .map(Goal::from), ); } @@ -318,7 +318,10 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: Vec>) { + fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { self.fields.register_obligations(obligations); } From 4efb13b0c24363daf63be0ce98ab612a42fbff30 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 10:13:05 -0400 Subject: [PATCH 3/4] Rename some things --- .../src/type_check/relate_tys.rs | 12 ++++----- compiler/rustc_infer/src/infer/at.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 5 +++- .../rustc_infer/src/infer/relate/combine.rs | 27 +++++++++---------- .../src/infer/relate/generalize.rs | 6 ++--- compiler/rustc_infer/src/infer/relate/glb.rs | 8 +++--- .../rustc_infer/src/infer/relate/lattice.rs | 6 ++--- compiler/rustc_infer/src/infer/relate/lub.rs | 8 +++--- compiler/rustc_infer/src/infer/relate/mod.rs | 2 +- .../src/infer/relate/type_relating.rs | 14 +++++----- 10 files changed, 46 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index a87b9f7a23d..e9215a102c3 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,6 +1,6 @@ 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::solve::Goal; @@ -155,7 +155,7 @@ fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> ), }; let cause = ObligationCause::dummy_with_span(self.span()); - self.register_obligations( + self.register_goals( infcx .handle_opaque_type(a, b, &cause, self.param_env())? .obligations @@ -539,7 +539,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) } @@ -558,12 +558,12 @@ fn register_predicates( ) { let tcx = self.tcx(); let param_env = self.param_env(); - self.register_obligations( + self.register_goals( obligations.into_iter().map(|to_pred| Goal::new(tcx, param_env, to_pred)), ); } - fn register_obligations( + fn register_goals( &mut self, obligations: impl IntoIterator>>, ) { @@ -589,7 +589,7 @@ fn register_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/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 8994739f5c7..01bd732a4cd 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -165,7 +165,7 @@ pub fn eq( Ok(InferOk { value: (), obligations: fields - .obligations + .goals .into_iter() .map(|goal| { Obligation::new( diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 98a795e67f8..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,7 +11,7 @@ pub use SubregionOrigin::*; pub use ValuePairs::*; -use crate::infer::relate::{CombineFields, RelateResult}; +use crate::infer::relate::RelateResult; use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine}; use error_reporting::TypeErrCtxt; use free_regions::RegionRelations; diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 1a0a0d10c6d..0a2e85cc891 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -39,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: Vec>>, + pub goals: Vec>>, pub define_opaque_types: DefineOpaqueTypes, } @@ -50,11 +50,11 @@ 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.obligations + self.goals .into_iter() .map(|goal| { Obligation::new( @@ -76,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()); @@ -140,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) } } @@ -171,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()); @@ -309,14 +309,14 @@ pub fn register_obligations( &mut self, obligations: impl IntoIterator>>, ) { - self.obligations.extend(obligations); + self.goals.extend(obligations); } pub fn register_predicates( &mut self, obligations: impl IntoIterator, ty::Predicate<'tcx>>>, ) { - self.obligations.extend( + self.goals.extend( obligations .into_iter() .map(|to_pred| Goal::new(self.infcx.tcx, self.param_env, to_pred)), @@ -324,7 +324,7 @@ pub fn register_predicates( } } -pub trait ObligationEmittingRelation<'tcx>: TypeRelation> { +pub trait PredicateEmittingRelation<'tcx>: TypeRelation> { fn span(&self) -> Span; fn param_env(&self) -> ty::ParamEnv<'tcx>; @@ -335,19 +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( + 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 6f37995ac1e..cc17e60a79b 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -5,7 +5,7 @@ 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}; @@ -128,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() } @@ -148,14 +148,14 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations( + 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 8c6f1690ade..c9b70608ddd 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -17,7 +17,7 @@ //! //! [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; @@ -31,7 +31,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>; @@ -109,7 +109,7 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>( && def_id.is_local() && !this.infcx().next_trait_solver() => { - this.register_obligations( + this.register_goals( infcx .handle_opaque_type(a, b, this.cause(), this.param_env())? .obligations diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 625cc02115a..e9d300d349c 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -1,6 +1,6 @@ //! 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}; @@ -128,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() } @@ -148,14 +148,14 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations( + 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 328e4d8902f..7e64a9b936c 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -1,5 +1,5 @@ use super::combine::CombineFields; -use crate::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases}; +use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases}; use crate::infer::BoundRegionConversionTime::HigherRankedType; use crate::infer::{DefineOpaqueTypes, SubregionOrigin}; use rustc_middle::traits::solve::Goal; @@ -87,7 +87,7 @@ 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(Goal::new( + self.fields.goals.push(Goal::new( self.tcx(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { @@ -100,7 +100,7 @@ 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(Goal::new( + self.fields.goals.push(Goal::new( self.tcx(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { @@ -151,7 +151,7 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { && !infcx.next_trait_solver() => { // FIXME: Don't shuttle between Goal and Obligation - self.fields.obligations.extend( + self.fields.goals.extend( infcx .handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())? .obligations @@ -298,7 +298,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,14 +318,14 @@ fn register_predicates( self.fields.register_predicates(obligations); } - fn register_obligations( + 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(), From e4be97cfe763fc5550e048ae3db288fd27a1954c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 11:51:03 -0400 Subject: [PATCH 4/4] Try not to make obligations in handle_opaque_type --- .../src/type_check/relate_tys.rs | 9 +- .../rustc_infer/src/infer/opaque_types/mod.rs | 107 +++++++++--------- compiler/rustc_infer/src/infer/projection.rs | 11 +- .../rustc_infer/src/infer/relate/lattice.rs | 9 +- .../src/infer/relate/type_relating.rs | 14 +-- .../src/solve/eval_ctxt/mod.rs | 15 ++- 6 files changed, 74 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index e9215a102c3..c531c9b209b 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -154,14 +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()); - self.register_goals( - infcx - .handle_opaque_type(a, b, &cause, self.param_env())? - .obligations - .into_iter() - .map(Goal::from), - ); + self.register_goals(infcx.handle_opaque_type(a, b, self.span(), self.param_env())?); Ok(()) } 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/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index c9b70608ddd..6cc8d6d910a 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -21,7 +21,6 @@ use crate::infer::{DefineOpaqueTypes, InferCtxt}; use crate::traits::ObligationCause; -use rustc_middle::traits::solve::Goal; use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty}; @@ -109,13 +108,7 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>( && def_id.is_local() && !this.infcx().next_trait_solver() => { - this.register_goals( - infcx - .handle_opaque_type(a, b, this.cause(), this.param_env())? - .obligations - .into_iter() - .map(Goal::from), - ); + 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/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 7e64a9b936c..f7b2f11e3d7 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -150,14 +150,12 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { && def_id.is_local() && !infcx.next_trait_solver() => { - // FIXME: Don't shuttle between Goal and Obligation - self.fields.goals.extend( - infcx - .handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())? - .obligations - .into_iter() - .map(Goal::from), - ); + self.fields.goals.extend(infcx.handle_opaque_type( + a, + b, + self.fields.trace.cause.span, + self.param_env(), + )?); } _ => { 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