Skip to content

Commit 9b1d222

Browse files
committed
change the enter_canonical_trait_query method to give a fulfill cx
1 parent f0fdce3 commit 9b1d222

File tree

12 files changed

+79
-69
lines changed

12 files changed

+79
-69
lines changed

src/librustc/infer/canonical/query_result.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> {
5656
pub fn enter_canonical_trait_query<K, R>(
5757
&'tcx mut self,
5858
canonical_key: &Canonical<'tcx, K>,
59-
op: impl FnOnce(&InferCtxt<'_, 'gcx, 'tcx>, K) -> Fallible<InferOk<'tcx, R>>,
59+
op: impl FnOnce(&InferCtxt<'_, 'gcx, 'tcx>, &mut FulfillmentContext<'tcx>, K) -> Fallible<R>,
6060
) -> Fallible<CanonicalizedQueryResult<'gcx, R>>
6161
where
6262
K: TypeFoldable<'tcx>,
@@ -65,9 +65,8 @@ impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> {
6565
self.enter(|ref infcx| {
6666
let (key, canonical_inference_vars) =
6767
infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_key);
68-
let InferOk { value, obligations } = op(infcx, key)?;
6968
let fulfill_cx = &mut FulfillmentContext::new();
70-
fulfill_cx.register_predicate_obligations(infcx, obligations);
69+
let value = op(infcx, fulfill_cx, key)?;
7170
infcx.make_canonicalized_query_result(canonical_inference_vars, value, fulfill_cx)
7271
})
7372
}

src/librustc/infer/mod.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use ty::{self, Ty, TyCtxt, GenericParamDefKind};
2727
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
2828
use ty::fold::TypeFoldable;
2929
use ty::relate::RelateResult;
30-
use traits::{self, ObligationCause, PredicateObligations};
30+
use traits::{self, ObligationCause, PredicateObligations, TraitEngine};
3131
use rustc_data_structures::unify as ut;
3232
use std::cell::{Cell, RefCell, Ref, RefMut};
3333
use std::collections::BTreeMap;
@@ -485,6 +485,19 @@ impl<'tcx, T> InferOk<'tcx, T> {
485485
pub fn unit(self) -> InferOk<'tcx, ()> {
486486
InferOk { value: (), obligations: self.obligations }
487487
}
488+
489+
/// Extract `value`, registering any obligations into `fulfill_cx`
490+
pub fn into_value_registering_obligations(
491+
self,
492+
infcx: &InferCtxt<'_, '_, 'tcx>,
493+
fulfill_cx: &mut impl TraitEngine<'tcx>,
494+
) -> T {
495+
let InferOk { value, obligations } = self;
496+
for obligation in obligations {
497+
fulfill_cx.register_predicate_obligation(infcx, obligation);
498+
}
499+
value
500+
}
488501
}
489502

490503
impl<'tcx> InferOk<'tcx, ()> {

src/librustc/infer/outlives/bounds.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use infer::InferCtxt;
1212
use syntax::ast;
1313
use syntax::codemap::Span;
14-
use traits::{FulfillmentContext, TraitEngine};
14+
use traits::{FulfillmentContext, TraitEngine, TraitEngineExt};
1515
use ty::{self, Ty, TypeFoldable};
1616
use ty::outlives::Component;
1717
use ty::wf;

src/librustc/traits/engine.rs

+28-20
Original file line numberDiff line numberDiff line change
@@ -16,56 +16,64 @@ use super::{FulfillmentContext, FulfillmentError};
1616
use super::{ObligationCause, PredicateObligation};
1717

1818
pub trait TraitEngine<'tcx>: 'tcx {
19-
fn normalize_projection_type<'a, 'gcx>(
19+
fn normalize_projection_type(
2020
&mut self,
21-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
21+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
2222
param_env: ty::ParamEnv<'tcx>,
2323
projection_ty: ty::ProjectionTy<'tcx>,
2424
cause: ObligationCause<'tcx>,
2525
) -> Ty<'tcx>;
2626

27-
fn register_bound<'a, 'gcx>(
27+
fn register_bound(
2828
&mut self,
29-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
29+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
3030
param_env: ty::ParamEnv<'tcx>,
3131
ty: Ty<'tcx>,
3232
def_id: DefId,
3333
cause: ObligationCause<'tcx>,
3434
);
3535

36-
fn register_predicate_obligation<'a, 'gcx>(
36+
fn register_predicate_obligation(
3737
&mut self,
38-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
38+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
3939
obligation: PredicateObligation<'tcx>,
4040
);
4141

42-
fn select_all_or_error<'a, 'gcx>(
42+
fn select_all_or_error(
4343
&mut self,
44-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
44+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
4545
) -> Result<(), Vec<FulfillmentError<'tcx>>>;
4646

47-
fn select_where_possible<'a, 'gcx>(
47+
fn select_where_possible(
4848
&mut self,
49-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
49+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
5050
) -> Result<(), Vec<FulfillmentError<'tcx>>>;
5151

5252
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
5353
}
5454

55-
impl<'a, 'gcx, 'tcx> dyn TraitEngine<'tcx> {
56-
pub fn new(_tcx: TyCtxt<'_, '_, 'tcx>) -> Box<Self> {
57-
Box::new(FulfillmentContext::new())
58-
}
55+
pub trait TraitEngineExt<'tcx> {
56+
fn register_predicate_obligations(
57+
&mut self,
58+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
59+
obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
60+
);
61+
}
5962

60-
pub fn register_predicate_obligations<I>(
63+
impl<T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
64+
fn register_predicate_obligations(
6165
&mut self,
62-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
63-
obligations: I,
64-
) where
65-
I: IntoIterator<Item = PredicateObligation<'tcx>>,
66-
{
66+
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
67+
obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
68+
) {
6769
for obligation in obligations {
6870
self.register_predicate_obligation(infcx, obligation);
6971
}
7072
}
7173
}
74+
75+
impl dyn TraitEngine<'tcx> {
76+
pub fn new(_tcx: TyCtxt<'_, '_, 'tcx>) -> Box<Self> {
77+
Box::new(FulfillmentContext::new())
78+
}
79+
}

src/librustc/traits/fulfill.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use middle::const_val::{ConstEvalErr, ErrKind};
2121
use super::CodeAmbiguity;
2222
use super::CodeProjectionError;
2323
use super::CodeSelectionError;
24-
use super::engine::TraitEngine;
24+
use super::engine::{TraitEngine, TraitEngineExt};
2525
use super::{FulfillmentError, FulfillmentErrorCode};
2626
use super::{ObligationCause, PredicateObligation, Obligation};
2727
use super::project;
@@ -86,16 +86,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
8686
}
8787
}
8888

89-
pub fn register_predicate_obligations<I>(&mut self,
90-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
91-
obligations: I)
92-
where I: IntoIterator<Item = PredicateObligation<'tcx>>
93-
{
94-
for obligation in obligations {
95-
self.register_predicate_obligation(infcx, obligation);
96-
}
97-
}
98-
9989
/// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
10090
/// only attempts to select obligations that haven't been seen before.
10191
fn select(&mut self, selcx: &mut SelectionContext<'a, 'gcx, 'tcx>)

src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
4747
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
4848
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
4949
pub use self::specialize::{SpecializesCache, find_associated_item};
50-
pub use self::engine::TraitEngine;
50+
pub use self::engine::{TraitEngine, TraitEngineExt};
5151
pub use self::util::elaborate_predicates;
5252
pub use self::util::supertraits;
5353
pub use self::util::Supertraits;

src/librustc/traits/query/type_op/custom.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use infer::canonical::query_result;
1616
use infer::canonical::QueryRegionConstraint;
1717
use std::rc::Rc;
1818
use syntax::codemap::DUMMY_SP;
19-
use traits::{ObligationCause, TraitEngine};
19+
use traits::{ObligationCause, TraitEngine, TraitEngineExt};
2020

2121
pub struct CustomTypeOp<F, G> {
2222
closure: F,

src/librustc_traits/dropck_outlives.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc::hir::def_id::DefId;
1212
use rustc::infer::canonical::{Canonical, QueryResult};
1313
use rustc::traits::query::dropck_outlives::{DropckOutlivesResult, DtorckConstraint};
1414
use rustc::traits::query::{CanonicalTyGoal, NoSolution};
15-
use rustc::traits::{FulfillmentContext, Normalized, ObligationCause};
15+
use rustc::traits::{FulfillmentContext, Normalized, ObligationCause, TraitEngineExt};
1616
use rustc::ty::query::Providers;
1717
use rustc::ty::subst::{Subst, Substs};
1818
use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt};

src/librustc_traits/normalize_projection_ty.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
// except according to those terms.
1010

1111
use rustc::infer::canonical::{Canonical, QueryResult};
12-
use rustc::infer::InferOk;
1312
use rustc::traits::query::{normalize::NormalizationResult, CanonicalProjectionGoal, NoSolution};
14-
use rustc::traits::{self, ObligationCause, SelectionContext};
13+
use rustc::traits::{self, ObligationCause, SelectionContext, TraitEngineExt};
1514
use rustc::ty::query::Providers;
1615
use rustc::ty::{ParamEnvAnd, TyCtxt};
1716
use rustc_data_structures::sync::Lrc;
@@ -39,6 +38,7 @@ fn normalize_projection_ty<'tcx>(
3938
tcx.infer_ctxt().enter_canonical_trait_query(
4039
&goal,
4140
|infcx,
41+
fulfill_cx,
4242
ParamEnvAnd {
4343
param_env,
4444
value: goal,
@@ -54,11 +54,9 @@ fn normalize_projection_ty<'tcx>(
5454
0,
5555
&mut obligations,
5656
);
57-
Ok(InferOk {
58-
value: NormalizationResult {
59-
normalized_ty: answer,
60-
},
61-
obligations,
57+
fulfill_cx.register_predicate_obligations(infcx, obligations);
58+
Ok(NormalizationResult {
59+
normalized_ty: answer,
6260
})
6361
},
6462
)

src/librustc_traits/type_op.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
// except according to those terms.
1010

1111
use rustc::infer::canonical::{Canonical, QueryResult};
12-
use rustc::infer::{InferCtxt, InferOk};
12+
use rustc::infer::InferCtxt;
1313
use rustc::traits::query::type_op::eq::Eq;
1414
use rustc::traits::query::type_op::normalize::Normalize;
1515
use rustc::traits::query::type_op::prove_predicate::ProvePredicate;
1616
use rustc::traits::query::type_op::subtype::Subtype;
1717
use rustc::traits::query::{Fallible, NoSolution};
18-
use rustc::traits::{Obligation, Normalized, ObligationCause};
18+
use rustc::traits::{FulfillmentContext, Normalized, Obligation, ObligationCause, TraitEngine, TraitEngineExt};
1919
use rustc::ty::query::Providers;
20-
use rustc::ty::{ParamEnvAnd, FnSig, Lift, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable};
20+
use rustc::ty::{FnSig, Lift, ParamEnvAnd, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable};
2121
use rustc_data_structures::sync::Lrc;
2222
use std::fmt;
2323

@@ -39,24 +39,29 @@ fn type_op_eq<'tcx>(
3939
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>,
4040
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
4141
tcx.infer_ctxt()
42-
.enter_canonical_trait_query(&canonicalized, |infcx, key| {
42+
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
4343
let (param_env, Eq { a, b }) = key.into_parts();
44-
Ok(infcx.at(&ObligationCause::dummy(), param_env).eq(a, b)?)
44+
Ok(infcx
45+
.at(&ObligationCause::dummy(), param_env)
46+
.eq(a, b)?
47+
.into_value_registering_obligations(infcx, fulfill_cx))
4548
})
4649
}
4750

4851
fn type_op_normalize<T>(
4952
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
53+
fulfill_cx: &mut FulfillmentContext<'tcx>,
5054
key: ParamEnvAnd<'tcx, Normalize<T>>,
51-
) -> Fallible<InferOk<'tcx, T>>
55+
) -> Fallible<T>
5256
where
5357
T: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx>,
5458
{
5559
let (param_env, Normalize { value }) = key.into_parts();
5660
let Normalized { value, obligations } = infcx
5761
.at(&ObligationCause::dummy(), param_env)
5862
.normalize(&value)?;
59-
Ok(InferOk { value, obligations }) // ugh we should merge these two structs
63+
fulfill_cx.register_predicate_obligations(infcx, obligations);
64+
Ok(value)
6065
}
6166

6267
fn type_op_normalize_ty(
@@ -95,30 +100,27 @@ fn type_op_subtype<'tcx>(
95100
tcx: TyCtxt<'_, 'tcx, 'tcx>,
96101
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>,
97102
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
98-
tcx.infer_ctxt().enter_canonical_trait_query(
99-
&canonicalized, |infcx, key| {
103+
tcx.infer_ctxt()
104+
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
100105
let (param_env, Subtype { sub, sup }) = key.into_parts();
101106
Ok(infcx
102107
.at(&ObligationCause::dummy(), param_env)
103-
.sup(sup, sub)?)
104-
},
105-
)
108+
.sup(sup, sub)?
109+
.into_value_registering_obligations(infcx, fulfill_cx))
110+
})
106111
}
107112

108113
fn type_op_prove_predicate<'tcx>(
109114
tcx: TyCtxt<'_, 'tcx, 'tcx>,
110115
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>,
111116
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
112117
tcx.infer_ctxt()
113-
.enter_canonical_trait_query(&canonicalized, |_infcx, key| {
118+
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
114119
let (param_env, ProvePredicate { predicate }) = key.into_parts();
115-
Ok(InferOk {
116-
value: (),
117-
obligations: vec![Obligation::new(
118-
ObligationCause::dummy(),
119-
param_env,
120-
predicate,
121-
)],
122-
})
120+
fulfill_cx.register_predicate_obligation(
121+
infcx,
122+
Obligation::new(ObligationCause::dummy(), param_env, predicate),
123+
);
124+
Ok(())
123125
})
124126
}

src/librustc_typeck/check/dropck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc::infer::outlives::env::OutlivesEnvironment;
1616
use rustc::middle::region;
1717
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
1818
use rustc::ty::{self, Ty, TyCtxt};
19-
use rustc::traits::{ObligationCause, TraitEngine};
19+
use rustc::traits::{ObligationCause, TraitEngine, TraitEngineExt};
2020
use util::common::ErrorReported;
2121

2222
use syntax::ast;

src/librustc_typeck/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ use rustc::infer::InferOk;
108108
use rustc::ty::subst::Substs;
109109
use rustc::ty::{self, Ty, TyCtxt};
110110
use rustc::ty::query::Providers;
111-
use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine};
111+
use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
112112
use session::{CompileIncomplete, config};
113113
use util::common::time;
114114

0 commit comments

Comments
 (0)