Skip to content

Commit dcdf3d6

Browse files
Plumb obligations through librustc/infer
1 parent 0c07a3c commit dcdf3d6

File tree

18 files changed

+274
-107
lines changed

18 files changed

+274
-107
lines changed

src/librustc/infer/combine.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use super::equate::Equate;
3737
use super::glb::Glb;
3838
use super::lub::Lub;
3939
use super::sub::Sub;
40-
use super::{InferCtxt};
40+
use super::InferCtxt;
4141
use super::{MiscVariable, TypeTrace};
4242
use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf};
4343

@@ -46,6 +46,7 @@ use ty::{self, Ty, TyCtxt};
4646
use ty::error::TypeError;
4747
use ty::fold::{TypeFolder, TypeFoldable};
4848
use ty::relate::{Relate, RelateResult, TypeRelation};
49+
use traits::PredicateObligations;
4950

5051
use syntax::ast;
5152
use syntax::codemap::Span;
@@ -56,6 +57,7 @@ pub struct CombineFields<'a, 'tcx: 'a> {
5657
pub a_is_expected: bool,
5758
pub trace: TypeTrace<'tcx>,
5859
pub cause: Option<ty::relate::Cause>,
60+
pub obligations: PredicateObligations<'tcx>,
5961
}
6062

6163
pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,

src/librustc/infer/equate.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use super::type_variable::{EqTo};
1616
use ty::{self, Ty, TyCtxt};
1717
use ty::TyVar;
1818
use ty::relate::{Relate, RelateResult, TypeRelation};
19+
use traits::PredicateObligations;
1920

2021
/// Ensures `a` is made equal to `b`. Returns `a` on success.
2122
pub struct Equate<'a, 'tcx: 'a> {
@@ -26,6 +27,10 @@ impl<'a, 'tcx> Equate<'a, 'tcx> {
2627
pub fn new(fields: CombineFields<'a, 'tcx>) -> Equate<'a, 'tcx> {
2728
Equate { fields: fields }
2829
}
30+
31+
pub fn obligations(self) -> PredicateObligations<'tcx> {
32+
self.fields.obligations
33+
}
2934
}
3035

3136
impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {

src/librustc/infer/glb.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use super::Subtype;
1616

1717
use ty::{self, Ty, TyCtxt};
1818
use ty::relate::{Relate, RelateResult, TypeRelation};
19+
use traits::PredicateObligations;
1920

2021
/// "Greatest lower bound" (common subtype)
2122
pub struct Glb<'a, 'tcx: 'a> {
@@ -26,6 +27,10 @@ impl<'a, 'tcx> Glb<'a, 'tcx> {
2627
pub fn new(fields: CombineFields<'a, 'tcx>) -> Glb<'a, 'tcx> {
2728
Glb { fields: fields }
2829
}
30+
31+
pub fn obligations(self) -> PredicateObligations<'tcx> {
32+
self.fields.obligations
33+
}
2934
}
3035

3136
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> {

src/librustc/infer/lub.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use super::Subtype;
1616

1717
use ty::{self, Ty, TyCtxt};
1818
use ty::relate::{Relate, RelateResult, TypeRelation};
19+
use traits::PredicateObligations;
1920

2021
/// "Least upper bound" (common supertype)
2122
pub struct Lub<'a, 'tcx: 'a> {
@@ -26,6 +27,10 @@ impl<'a, 'tcx> Lub<'a, 'tcx> {
2627
pub fn new(fields: CombineFields<'a, 'tcx>) -> Lub<'a, 'tcx> {
2728
Lub { fields: fields }
2829
}
30+
31+
pub fn obligations(self) -> PredicateObligations<'tcx> {
32+
self.fields.obligations
33+
}
2934
}
3035

3136
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> {

src/librustc/infer/mod.rs

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ use middle::region::CodeExtent;
2727
use ty::subst;
2828
use ty::subst::Substs;
2929
use ty::subst::Subst;
30-
use traits::{self, ProjectionMode};
3130
use ty::adjustment;
3231
use ty::{TyVid, IntVid, FloatVid};
3332
use ty::{self, Ty, TyCtxt};
3433
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
3534
use ty::fold::{TypeFolder, TypeFoldable};
3635
use ty::relate::{Relate, RelateResult, TypeRelation};
36+
use traits::{self, PredicateObligations, ProjectionMode};
3737
use rustc_data_structures::unify::{self, UnificationTable};
3838
use std::cell::{RefCell, Ref};
3939
use std::fmt;
@@ -63,6 +63,12 @@ pub mod sub;
6363
pub mod type_variable;
6464
pub mod unify_key;
6565

66+
pub struct InferOk<'tcx, T> {
67+
pub value: T,
68+
pub obligations: PredicateObligations<'tcx>,
69+
}
70+
pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
71+
6672
pub type Bound<T> = Option<T>;
6773
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
6874
pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
@@ -391,16 +397,15 @@ pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
391397
origin: TypeOrigin,
392398
a: Ty<'tcx>,
393399
b: Ty<'tcx>)
394-
-> UnitResult<'tcx>
400+
-> InferResult<'tcx, ()>
395401
{
396402
debug!("mk_subty({:?} <: {:?})", a, b);
397403
cx.sub_types(a_is_expected, origin, a, b)
398404
}
399405

400-
pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
401-
a: Ty<'tcx>,
402-
b: Ty<'tcx>)
403-
-> UnitResult<'tcx> {
406+
pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
407+
-> UnitResult<'tcx>
408+
{
404409
debug!("can_mk_subty({:?} <: {:?})", a, b);
405410
cx.probe(|_| {
406411
let trace = TypeTrace {
@@ -412,7 +417,7 @@ pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
412417
}
413418

414419
pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
415-
-> UnitResult<'tcx>
420+
-> UnitResult<'tcx>
416421
{
417422
cx.can_equate(&a, &b)
418423
}
@@ -432,7 +437,7 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
432437
origin: TypeOrigin,
433438
a: Ty<'tcx>,
434439
b: Ty<'tcx>)
435-
-> UnitResult<'tcx>
440+
-> InferResult<'tcx, ()>
436441
{
437442
debug!("mk_eqty({:?} <: {:?})", a, b);
438443
cx.eq_types(a_is_expected, origin, a, b)
@@ -443,7 +448,7 @@ pub fn mk_eq_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
443448
origin: TypeOrigin,
444449
a: ty::TraitRef<'tcx>,
445450
b: ty::TraitRef<'tcx>)
446-
-> UnitResult<'tcx>
451+
-> InferResult<'tcx, ()>
447452
{
448453
debug!("mk_eq_trait_refs({:?} = {:?})", a, b);
449454
cx.eq_trait_refs(a_is_expected, origin, a, b)
@@ -454,7 +459,7 @@ pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
454459
origin: TypeOrigin,
455460
a: ty::PolyTraitRef<'tcx>,
456461
b: ty::PolyTraitRef<'tcx>)
457-
-> UnitResult<'tcx>
462+
-> InferResult<'tcx, ()>
458463
{
459464
debug!("mk_sub_poly_trait_refs({:?} <: {:?})", a, b);
460465
cx.sub_poly_trait_refs(a_is_expected, origin, a, b)
@@ -465,7 +470,7 @@ pub fn mk_eq_impl_headers<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
465470
origin: TypeOrigin,
466471
a: &ty::ImplHeader<'tcx>,
467472
b: &ty::ImplHeader<'tcx>)
468-
-> UnitResult<'tcx>
473+
-> InferResult<'tcx, ()>
469474
{
470475
debug!("mk_eq_impl_header({:?} = {:?})", a, b);
471476
match (a.trait_ref, b.trait_ref) {
@@ -661,39 +666,51 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
661666
}
662667

663668
fn combine_fields(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
664-
-> CombineFields<'a, 'tcx> {
665-
CombineFields {infcx: self,
666-
a_is_expected: a_is_expected,
667-
trace: trace,
668-
cause: None}
669+
-> CombineFields<'a, 'tcx>
670+
{
671+
CombineFields {
672+
infcx: self,
673+
a_is_expected: a_is_expected,
674+
trace: trace,
675+
cause: None,
676+
obligations: PredicateObligations::new(),
677+
}
669678
}
670679

671680
pub fn equate<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
672-
-> RelateResult<'tcx, T>
681+
-> InferResult<'tcx, T>
673682
where T: Relate<'a, 'tcx>
674683
{
675-
self.combine_fields(a_is_expected, trace).equate().relate(a, b)
684+
let mut equate = self.combine_fields(a_is_expected, trace).equate();
685+
let result = equate.relate(a, b);
686+
result.map(|t| InferOk { value: t, obligations: equate.obligations() })
676687
}
677688

678689
pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
679-
-> RelateResult<'tcx, T>
690+
-> InferResult<'tcx, T>
680691
where T: Relate<'a, 'tcx>
681692
{
682-
self.combine_fields(a_is_expected, trace).sub().relate(a, b)
693+
let mut sub = self.combine_fields(a_is_expected, trace).sub();
694+
let result = sub.relate(a, b);
695+
result.map(|t| InferOk { value: t, obligations: sub.obligations() })
683696
}
684697

685698
pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
686-
-> RelateResult<'tcx, T>
699+
-> InferResult<'tcx, T>
687700
where T: Relate<'a, 'tcx>
688701
{
689-
self.combine_fields(a_is_expected, trace).lub().relate(a, b)
702+
let mut lub = self.combine_fields(a_is_expected, trace).lub();
703+
let result = lub.relate(a, b);
704+
result.map(|t| InferOk { value: t, obligations: lub.obligations() })
690705
}
691706

692707
pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
693-
-> RelateResult<'tcx, T>
708+
-> InferResult<'tcx, T>
694709
where T: Relate<'a, 'tcx>
695710
{
696-
self.combine_fields(a_is_expected, trace).glb().relate(a, b)
711+
let mut glb = self.combine_fields(a_is_expected, trace).glb();
712+
let result = glb.relate(a, b);
713+
result.map(|t| InferOk { value: t, obligations: glb.obligations() })
697714
}
698715

699716
fn start_snapshot(&self) -> CombinedSnapshot {
@@ -829,12 +846,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
829846
origin: TypeOrigin,
830847
a: Ty<'tcx>,
831848
b: Ty<'tcx>)
832-
-> UnitResult<'tcx>
849+
-> InferResult<'tcx, ()>
833850
{
834851
debug!("sub_types({:?} <: {:?})", a, b);
835852
self.commit_if_ok(|_| {
836853
let trace = TypeTrace::types(origin, a_is_expected, a, b);
837-
self.sub(a_is_expected, trace, &a, &b).map(|_| ())
854+
self.sub(a_is_expected, trace, &a, &b)
855+
.map(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations })
838856
})
839857
}
840858

@@ -843,11 +861,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
843861
origin: TypeOrigin,
844862
a: Ty<'tcx>,
845863
b: Ty<'tcx>)
846-
-> UnitResult<'tcx>
864+
-> InferResult<'tcx, ()>
847865
{
848866
self.commit_if_ok(|_| {
849867
let trace = TypeTrace::types(origin, a_is_expected, a, b);
850-
self.equate(a_is_expected, trace, &a, &b).map(|_| ())
868+
self.equate(a_is_expected, trace, &a, &b)
869+
.map(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations })
851870
})
852871
}
853872

@@ -856,7 +875,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
856875
origin: TypeOrigin,
857876
a: ty::TraitRef<'tcx>,
858877
b: ty::TraitRef<'tcx>)
859-
-> UnitResult<'tcx>
878+
-> InferResult<'tcx, ()>
860879
{
861880
debug!("eq_trait_refs({:?} <: {:?})",
862881
a,
@@ -866,7 +885,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
866885
origin: origin,
867886
values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
868887
};
869-
self.equate(a_is_expected, trace, &a, &b).map(|_| ())
888+
self.equate(a_is_expected, trace, &a, &b)
889+
.map(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations })
870890
})
871891
}
872892

@@ -875,7 +895,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
875895
origin: TypeOrigin,
876896
a: ty::PolyTraitRef<'tcx>,
877897
b: ty::PolyTraitRef<'tcx>)
878-
-> UnitResult<'tcx>
898+
-> InferResult<'tcx, ()>
879899
{
880900
debug!("sub_poly_trait_refs({:?} <: {:?})",
881901
a,
@@ -885,7 +905,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
885905
origin: origin,
886906
values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
887907
};
888-
self.sub(a_is_expected, trace, &a, &b).map(|_| ())
908+
self.sub(a_is_expected, trace, &a, &b)
909+
.map(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations })
889910
})
890911
}
891912

@@ -928,20 +949,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
928949
pub fn equality_predicate(&self,
929950
span: Span,
930951
predicate: &ty::PolyEquatePredicate<'tcx>)
931-
-> UnitResult<'tcx> {
952+
-> InferResult<'tcx, ()>
953+
{
932954
self.commit_if_ok(|snapshot| {
933955
let (ty::EquatePredicate(a, b), skol_map) =
934956
self.skolemize_late_bound_regions(predicate, snapshot);
935957
let origin = TypeOrigin::EquatePredicate(span);
936-
let () = mk_eqty(self, false, origin, a, b)?;
958+
let InferOk { obligations, .. } = mk_eqty(self, false, origin, a, b)?;
937959
self.leak_check(&skol_map, snapshot)
960+
.map(|_| InferOk { value: (), obligations: obligations })
938961
})
939962
}
940963

941964
pub fn region_outlives_predicate(&self,
942965
span: Span,
943966
predicate: &ty::PolyRegionOutlivesPredicate)
944-
-> UnitResult<'tcx> {
967+
-> UnitResult<'tcx>
968+
{
945969
self.commit_if_ok(|snapshot| {
946970
let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
947971
self.skolemize_late_bound_regions(predicate, snapshot);

src/librustc/infer/sub.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use super::type_variable::{SubtypeOf, SupertypeOf};
1616
use ty::{self, Ty, TyCtxt};
1717
use ty::TyVar;
1818
use ty::relate::{Cause, Relate, RelateResult, TypeRelation};
19+
use traits::PredicateObligations;
1920
use std::mem;
2021

2122
/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
@@ -27,6 +28,10 @@ impl<'a, 'tcx> Sub<'a, 'tcx> {
2728
pub fn new(f: CombineFields<'a, 'tcx>) -> Sub<'a, 'tcx> {
2829
Sub { fields: f }
2930
}
31+
32+
pub fn obligations(self) -> PredicateObligations<'tcx> {
33+
self.fields.obligations
34+
}
3035
}
3136

3237
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {

src/librustc/traits/fulfill.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use dep_graph::DepGraph;
12-
use infer::InferCtxt;
12+
use infer::{InferCtxt, InferOk};
1313
use ty::{self, Ty, TyCtxt, TypeFoldable, ToPolyTraitRef};
1414
use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, Error};
1515
use std::iter;
@@ -526,7 +526,11 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
526526

527527
ty::Predicate::Equate(ref binder) => {
528528
match selcx.infcx().equality_predicate(obligation.cause.span, binder) {
529-
Ok(()) => Ok(Some(Vec::new())),
529+
Ok(InferOk { obligations, .. }) => {
530+
// FIXME(#????) propagate obligations
531+
assert!(obligations.is_empty());
532+
Ok(Some(Vec::new()))
533+
},
530534
Err(_) => Err(CodeSelectionError(Unimplemented)),
531535
}
532536
}

0 commit comments

Comments
 (0)