Skip to content

Commit f601976

Browse files
committed
Rollup merge of rust-lang#32596 - soltanmm:lazy, r=nikomatsakis
Plumb obligations through librustc/infer Like rust-lang#32542, but more like rust-lang#31867. TODO before merge: make an issue for the propagation of obligations through... uh, everywhere... then replace the `#????`s with the actual issue number. cc @jroesch r? @nikomatsakis
2 parents bdd264a + 86071ac commit f601976

File tree

18 files changed

+276
-108
lines changed

18 files changed

+276
-108
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: 61 additions & 36 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) {
@@ -574,6 +579,12 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
574579
Ok(infcx.tcx.erase_regions(&result))
575580
}
576581

582+
impl<'tcx, T> InferOk<'tcx, T> {
583+
fn unit(self) -> InferOk<'tcx, ()> {
584+
InferOk { value: (), obligations: self.obligations }
585+
}
586+
}
587+
577588
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
578589
pub fn projection_mode(&self) -> ProjectionMode {
579590
self.projection_mode
@@ -661,39 +672,51 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
661672
}
662673

663674
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}
675+
-> CombineFields<'a, 'tcx>
676+
{
677+
CombineFields {
678+
infcx: self,
679+
a_is_expected: a_is_expected,
680+
trace: trace,
681+
cause: None,
682+
obligations: PredicateObligations::new(),
683+
}
669684
}
670685

671686
pub fn equate<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
672-
-> RelateResult<'tcx, T>
687+
-> InferResult<'tcx, T>
673688
where T: Relate<'a, 'tcx>
674689
{
675-
self.combine_fields(a_is_expected, trace).equate().relate(a, b)
690+
let mut equate = self.combine_fields(a_is_expected, trace).equate();
691+
let result = equate.relate(a, b);
692+
result.map(|t| InferOk { value: t, obligations: equate.obligations() })
676693
}
677694

678695
pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
679-
-> RelateResult<'tcx, T>
696+
-> InferResult<'tcx, T>
680697
where T: Relate<'a, 'tcx>
681698
{
682-
self.combine_fields(a_is_expected, trace).sub().relate(a, b)
699+
let mut sub = self.combine_fields(a_is_expected, trace).sub();
700+
let result = sub.relate(a, b);
701+
result.map(|t| InferOk { value: t, obligations: sub.obligations() })
683702
}
684703

685704
pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
686-
-> RelateResult<'tcx, T>
705+
-> InferResult<'tcx, T>
687706
where T: Relate<'a, 'tcx>
688707
{
689-
self.combine_fields(a_is_expected, trace).lub().relate(a, b)
708+
let mut lub = self.combine_fields(a_is_expected, trace).lub();
709+
let result = lub.relate(a, b);
710+
result.map(|t| InferOk { value: t, obligations: lub.obligations() })
690711
}
691712

692713
pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
693-
-> RelateResult<'tcx, T>
714+
-> InferResult<'tcx, T>
694715
where T: Relate<'a, 'tcx>
695716
{
696-
self.combine_fields(a_is_expected, trace).glb().relate(a, b)
717+
let mut glb = self.combine_fields(a_is_expected, trace).glb();
718+
let result = glb.relate(a, b);
719+
result.map(|t| InferOk { value: t, obligations: glb.obligations() })
697720
}
698721

699722
fn start_snapshot(&self) -> CombinedSnapshot {
@@ -829,12 +852,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
829852
origin: TypeOrigin,
830853
a: Ty<'tcx>,
831854
b: Ty<'tcx>)
832-
-> UnitResult<'tcx>
855+
-> InferResult<'tcx, ()>
833856
{
834857
debug!("sub_types({:?} <: {:?})", a, b);
835858
self.commit_if_ok(|_| {
836859
let trace = TypeTrace::types(origin, a_is_expected, a, b);
837-
self.sub(a_is_expected, trace, &a, &b).map(|_| ())
860+
self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
838861
})
839862
}
840863

@@ -843,11 +866,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
843866
origin: TypeOrigin,
844867
a: Ty<'tcx>,
845868
b: Ty<'tcx>)
846-
-> UnitResult<'tcx>
869+
-> InferResult<'tcx, ()>
847870
{
848871
self.commit_if_ok(|_| {
849872
let trace = TypeTrace::types(origin, a_is_expected, a, b);
850-
self.equate(a_is_expected, trace, &a, &b).map(|_| ())
873+
self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
851874
})
852875
}
853876

@@ -856,7 +879,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
856879
origin: TypeOrigin,
857880
a: ty::TraitRef<'tcx>,
858881
b: ty::TraitRef<'tcx>)
859-
-> UnitResult<'tcx>
882+
-> InferResult<'tcx, ()>
860883
{
861884
debug!("eq_trait_refs({:?} <: {:?})",
862885
a,
@@ -866,7 +889,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
866889
origin: origin,
867890
values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
868891
};
869-
self.equate(a_is_expected, trace, &a, &b).map(|_| ())
892+
self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
870893
})
871894
}
872895

@@ -875,7 +898,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
875898
origin: TypeOrigin,
876899
a: ty::PolyTraitRef<'tcx>,
877900
b: ty::PolyTraitRef<'tcx>)
878-
-> UnitResult<'tcx>
901+
-> InferResult<'tcx, ()>
879902
{
880903
debug!("sub_poly_trait_refs({:?} <: {:?})",
881904
a,
@@ -885,7 +908,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
885908
origin: origin,
886909
values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
887910
};
888-
self.sub(a_is_expected, trace, &a, &b).map(|_| ())
911+
self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
889912
})
890913
}
891914

@@ -928,20 +951,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
928951
pub fn equality_predicate(&self,
929952
span: Span,
930953
predicate: &ty::PolyEquatePredicate<'tcx>)
931-
-> UnitResult<'tcx> {
954+
-> InferResult<'tcx, ()>
955+
{
932956
self.commit_if_ok(|snapshot| {
933957
let (ty::EquatePredicate(a, b), skol_map) =
934958
self.skolemize_late_bound_regions(predicate, snapshot);
935959
let origin = TypeOrigin::EquatePredicate(span);
936-
let () = mk_eqty(self, false, origin, a, b)?;
937-
self.leak_check(&skol_map, snapshot)
960+
let eqty_ok = mk_eqty(self, false, origin, a, b)?;
961+
self.leak_check(&skol_map, snapshot).map(|_| eqty_ok.unit())
938962
})
939963
}
940964

941965
pub fn region_outlives_predicate(&self,
942966
span: Span,
943967
predicate: &ty::PolyRegionOutlivesPredicate)
944-
-> UnitResult<'tcx> {
968+
-> UnitResult<'tcx>
969+
{
945970
self.commit_if_ok(|snapshot| {
946971
let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
947972
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;
@@ -580,7 +580,11 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
580580

581581
ty::Predicate::Equate(ref binder) => {
582582
match selcx.infcx().equality_predicate(obligation.cause.span, binder) {
583-
Ok(()) => Ok(Some(Vec::new())),
583+
Ok(InferOk { obligations, .. }) => {
584+
// FIXME(#32730) propagate obligations
585+
assert!(obligations.is_empty());
586+
Ok(Some(Vec::new()))
587+
},
584588
Err(_) => Err(CodeSelectionError(Unimplemented)),
585589
}
586590
}

0 commit comments

Comments
 (0)