Skip to content

Commit 76c7382

Browse files
committed
Auto merge of #126130 - compiler-errors:goal-relations, r=lcnr
Make `ObligationEmittingRelation`s emit `Goal` rather than `Obligation` Helps avoid needing to uplift `Obligation` into the solver. We still can't get rid of `ObligationCause`, but we can keep it as an associated type for `InferCtxtLike` and just give it a `dummy` function. There's some shuttling between `Goal` and `Obligation` that may be perf-sensitive... Let's see what rust-timer says. r? lcnr
2 parents 9a7bf4a + e4be97c commit 76c7382

File tree

17 files changed

+216
-178
lines changed

17 files changed

+216
-178
lines changed

compiler/rustc_borrowck/src/type_check/relate_tys.rs

+25-16
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use rustc_data_structures::fx::FxHashMap;
22
use rustc_errors::ErrorGuaranteed;
3-
use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases};
3+
use rustc_infer::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
44
use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation};
55
use rustc_infer::infer::NllRegionVariableOrigin;
6-
use rustc_infer::traits::{Obligation, PredicateObligations};
6+
use rustc_infer::traits::solve::Goal;
7+
use rustc_infer::traits::Obligation;
78
use rustc_middle::mir::ConstraintCategory;
89
use rustc_middle::span_bug;
910
use rustc_middle::traits::query::NoSolution;
@@ -153,9 +154,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
153154
"expected at least one opaque type in `relate_opaques`, got {a} and {b}."
154155
),
155156
};
156-
let cause = ObligationCause::dummy_with_span(self.span());
157-
let obligations = infcx.handle_opaque_type(a, b, &cause, self.param_env())?.obligations;
158-
self.register_obligations(obligations);
157+
self.register_goals(infcx.handle_opaque_type(a, b, self.span(), self.param_env())?);
159158
Ok(())
160159
}
161160

@@ -533,7 +532,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
533532
}
534533
}
535534

536-
impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
535+
impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
537536
fn span(&self) -> Span {
538537
self.locations.span(self.type_checker.body)
539538
}
@@ -550,30 +549,40 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx
550549
&mut self,
551550
obligations: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
552551
) {
553-
self.register_obligations(
554-
obligations
555-
.into_iter()
556-
.map(|to_pred| {
557-
Obligation::new(self.tcx(), ObligationCause::dummy(), self.param_env(), to_pred)
558-
})
559-
.collect(),
552+
let tcx = self.tcx();
553+
let param_env = self.param_env();
554+
self.register_goals(
555+
obligations.into_iter().map(|to_pred| Goal::new(tcx, param_env, to_pred)),
560556
);
561557
}
562558

563-
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
559+
fn register_goals(
560+
&mut self,
561+
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
562+
) {
564563
let _: Result<_, ErrorGuaranteed> = self.type_checker.fully_perform_op(
565564
self.locations,
566565
self.category,
567566
InstantiateOpaqueType {
568-
obligations,
567+
obligations: obligations
568+
.into_iter()
569+
.map(|goal| {
570+
Obligation::new(
571+
self.tcx(),
572+
ObligationCause::dummy_with_span(self.span()),
573+
goal.param_env,
574+
goal.predicate,
575+
)
576+
})
577+
.collect(),
569578
// These fields are filled in during execution of the operation
570579
base_universe: None,
571580
region_constraints: None,
572581
},
573582
);
574583
}
575584

576-
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
585+
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
577586
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
578587
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
579588
a.into(),

compiler/rustc_hir_typeck/src/coercion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'
113113
fn success<'tcx>(
114114
adj: Vec<Adjustment<'tcx>>,
115115
target: Ty<'tcx>,
116-
obligations: traits::PredicateObligations<'tcx>,
116+
obligations: Vec<traits::PredicateObligation<'tcx>>,
117117
) -> CoerceResult<'tcx> {
118118
Ok(InferOk { value: (adj, target), obligations })
119119
}

compiler/rustc_infer/src/infer/at.rs

+28-24
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation};
3131
use rustc_middle::bug;
3232
use rustc_middle::ty::{Const, ImplSubject};
3333

34+
use crate::traits::Obligation;
35+
3436
/// Whether we should define opaque types or just treat them opaquely.
3537
///
3638
/// Currently only used to prevent predicate matching from matching anything
@@ -119,10 +121,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
119121
self.param_env,
120122
define_opaque_types,
121123
);
122-
fields
123-
.sup()
124-
.relate(expected, actual)
125-
.map(|_| InferOk { value: (), obligations: fields.obligations })
124+
fields.sup().relate(expected, actual)?;
125+
Ok(InferOk { value: (), obligations: fields.into_obligations() })
126126
}
127127

128128
/// Makes `expected <: actual`.
@@ -141,10 +141,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
141141
self.param_env,
142142
define_opaque_types,
143143
);
144-
fields
145-
.sub()
146-
.relate(expected, actual)
147-
.map(|_| InferOk { value: (), obligations: fields.obligations })
144+
fields.sub().relate(expected, actual)?;
145+
Ok(InferOk { value: (), obligations: fields.into_obligations() })
148146
}
149147

150148
/// Makes `expected == actual`.
@@ -163,10 +161,22 @@ impl<'a, 'tcx> At<'a, 'tcx> {
163161
self.param_env,
164162
define_opaque_types,
165163
);
166-
fields
167-
.equate(StructurallyRelateAliases::No)
168-
.relate(expected, actual)
169-
.map(|_| InferOk { value: (), obligations: fields.obligations })
164+
fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?;
165+
Ok(InferOk {
166+
value: (),
167+
obligations: fields
168+
.goals
169+
.into_iter()
170+
.map(|goal| {
171+
Obligation::new(
172+
self.infcx.tcx,
173+
fields.trace.cause.clone(),
174+
goal.param_env,
175+
goal.predicate,
176+
)
177+
})
178+
.collect(),
179+
})
170180
}
171181

172182
/// Equates `expected` and `found` while structurally relating aliases.
@@ -187,10 +197,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
187197
self.param_env,
188198
DefineOpaqueTypes::Yes,
189199
);
190-
fields
191-
.equate(StructurallyRelateAliases::Yes)
192-
.relate(expected, actual)
193-
.map(|_| InferOk { value: (), obligations: fields.obligations })
200+
fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
201+
Ok(InferOk { value: (), obligations: fields.into_obligations() })
194202
}
195203

196204
pub fn relate<T>(
@@ -237,10 +245,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
237245
self.param_env,
238246
define_opaque_types,
239247
);
240-
fields
241-
.lub()
242-
.relate(expected, actual)
243-
.map(|value| InferOk { value, obligations: fields.obligations })
248+
let value = fields.lub().relate(expected, actual)?;
249+
Ok(InferOk { value, obligations: fields.into_obligations() })
244250
}
245251

246252
/// Computes the greatest-lower-bound, or mutual subtype, of two
@@ -261,10 +267,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
261267
self.param_env,
262268
define_opaque_types,
263269
);
264-
fields
265-
.glb()
266-
.relate(expected, actual)
267-
.map(|value| InferOk { value, obligations: fields.obligations })
270+
let value = fields.glb().relate(expected, actual)?;
271+
Ok(InferOk { value, obligations: fields.into_obligations() })
268272
}
269273
}
270274

compiler/rustc_infer/src/infer/mod.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
pub use at::DefineOpaqueTypes;
22
pub use freshen::TypeFreshener;
33
pub use lexical_region_resolve::RegionResolutionError;
4+
pub use relate::combine::CombineFields;
5+
pub use relate::combine::PredicateEmittingRelation;
6+
pub use relate::StructurallyRelateAliases;
47
pub use rustc_macros::{TypeFoldable, TypeVisitable};
58
pub use rustc_middle::ty::IntVarValue;
69
pub use BoundRegionConversionTime::*;
710
pub use RegionVariableOrigin::*;
811
pub use SubregionOrigin::*;
912
pub use ValuePairs::*;
1013

11-
use crate::infer::relate::{CombineFields, RelateResult};
12-
use crate::traits::{
13-
self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine,
14-
};
14+
use crate::infer::relate::RelateResult;
15+
use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
1516
use error_reporting::TypeErrCtxt;
1617
use free_regions::RegionRelations;
1718
use lexical_region_resolve::LexicalRegionResolutions;
@@ -68,7 +69,7 @@ pub mod type_variable;
6869
#[derive(Debug)]
6970
pub struct InferOk<'tcx, T> {
7071
pub value: T,
71-
pub obligations: PredicateObligations<'tcx>,
72+
pub obligations: Vec<PredicateObligation<'tcx>>,
7273
}
7374
pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
7475

@@ -748,7 +749,7 @@ impl<'tcx, T> InferOk<'tcx, T> {
748749
}
749750

750751
impl<'tcx> InferOk<'tcx, ()> {
751-
pub fn into_obligations(self) -> PredicateObligations<'tcx> {
752+
pub fn into_obligations(self) -> Vec<PredicateObligation<'tcx>> {
752753
self.obligations
753754
}
754755
}

0 commit comments

Comments
 (0)