Skip to content

Commit 105ec7e

Browse files
committed
use obligations to propagate sub-typing instead of the TV code
1 parent 4e4bdea commit 105ec7e

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

src/librustc/infer/sub.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ use super::SubregionOrigin;
1212
use super::combine::CombineFields;
1313
use super::type_variable::{SubtypeOf, SupertypeOf};
1414

15+
use traits::Obligation;
1516
use ty::{self, Ty, TyCtxt};
1617
use ty::TyVar;
18+
use ty::fold::TypeFoldable;
1719
use ty::relate::{Cause, Relate, RelateResult, TypeRelation};
1820
use std::mem;
1921

@@ -79,10 +81,25 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
7981
let a = infcx.type_variables.borrow_mut().replace_if_possible(a);
8082
let b = infcx.type_variables.borrow_mut().replace_if_possible(b);
8183
match (&a.sty, &b.sty) {
82-
(&ty::TyInfer(TyVar(a_id)), &ty::TyInfer(TyVar(b_id))) => {
83-
infcx.type_variables
84-
.borrow_mut()
85-
.relate_vars(a_id, SubtypeOf, b_id);
84+
(&ty::TyInfer(TyVar(_)), &ty::TyInfer(TyVar(_))) => {
85+
// Shouldn't have any LBR here, so we can safely put
86+
// this under a binder below without fear of accidental
87+
// capture.
88+
assert!(!a.has_escaping_regions());
89+
assert!(!b.has_escaping_regions());
90+
91+
// can't make progress on `A <: B` if both A and B are
92+
// type variables, so record an obligation.
93+
self.fields.obligations.push(
94+
Obligation::new(
95+
self.fields.trace.cause.clone(),
96+
ty::Predicate::Subtype(
97+
ty::Binder(ty::SubtypePredicate {
98+
a_is_expected: self.a_is_expected,
99+
a,
100+
b,
101+
}))));
102+
86103
Ok(a)
87104
}
88105
(&ty::TyInfer(TyVar(a_id)), _) => {

src/librustc/traits/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use hir::def_id::DefId;
2020
use middle::free_region::FreeRegionMap;
2121
use ty::subst::Substs;
2222
use ty::{self, Ty, TyCtxt, TypeFoldable, ToPredicate};
23-
use infer::InferCtxt;
23+
use ty::error::{ExpectedFound, TypeError};
24+
use infer::{InferCtxt};
2425

2526
use std::rc::Rc;
2627
use syntax::ast;
@@ -214,6 +215,8 @@ pub struct FulfillmentError<'tcx> {
214215
pub enum FulfillmentErrorCode<'tcx> {
215216
CodeSelectionError(SelectionError<'tcx>),
216217
CodeProjectionError(MismatchedProjectionTypes<'tcx>),
218+
CodeSubtypeError(ExpectedFound<Ty<'tcx>>,
219+
TypeError<'tcx>), // always comes from a SubtypePredicate
217220
CodeAmbiguity,
218221
}
219222

src/test/compile-fail/issue-7813.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
fn main() {
1212
let v = &[];
13-
let it = v.iter(); //~ ERROR type annotations needed [E0282]
14-
//~| NOTE cannot infer type for `T`
15-
//~| NOTE consider giving `it` a type
13+
//~^ NOTE consider giving `it` a type
14+
let it = v.iter(); //~ ERROR cannot infer type for `_`
1615
}

0 commit comments

Comments
 (0)