Skip to content

Commit

Permalink
Auto merge of #126130 - compiler-errors:goal-relations, r=lcnr
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jun 12, 2024
2 parents 9a7bf4a + e4be97c commit 76c7382
Show file tree
Hide file tree
Showing 17 changed files with 216 additions and 178 deletions.
41 changes: 25 additions & 16 deletions compiler/rustc_borrowck/src/type_check/relate_tys.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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(())
}

Expand Down Expand Up @@ -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)
}
Expand All @@ -550,30 +549,40 @@ 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,
},
);
}

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(),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
}
Expand Down
52 changes: 28 additions & 24 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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`.
Expand All @@ -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`.
Expand All @@ -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.
Expand All @@ -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>(
Expand Down Expand Up @@ -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
Expand All @@ -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() })
}
}

Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
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::*;
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;
Expand Down Expand Up @@ -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>>;

Expand Down Expand Up @@ -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
}
}
Expand Down
Loading

0 comments on commit 76c7382

Please sign in to comment.