diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index a6b0e02d4772..1a94f12973de 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -12,8 +12,10 @@ use super::SubregionOrigin; use super::combine::CombineFields; use super::type_variable::{SubtypeOf, SupertypeOf}; +use traits::Obligation; use ty::{self, Ty, TyCtxt}; use ty::TyVar; +use ty::fold::TypeFoldable; use ty::relate::{Cause, Relate, RelateResult, TypeRelation}; use std::mem; @@ -79,10 +81,25 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> let a = infcx.type_variables.borrow_mut().replace_if_possible(a); let b = infcx.type_variables.borrow_mut().replace_if_possible(b); match (&a.sty, &b.sty) { - (&ty::TyInfer(TyVar(a_id)), &ty::TyInfer(TyVar(b_id))) => { - infcx.type_variables - .borrow_mut() - .relate_vars(a_id, SubtypeOf, b_id); + (&ty::TyInfer(TyVar(_)), &ty::TyInfer(TyVar(_))) => { + // Shouldn't have any LBR here, so we can safely put + // this under a binder below without fear of accidental + // capture. + assert!(!a.has_escaping_regions()); + assert!(!b.has_escaping_regions()); + + // can't make progress on `A <: B` if both A and B are + // type variables, so record an obligation. + self.fields.obligations.push( + Obligation::new( + self.fields.trace.cause.clone(), + ty::Predicate::Subtype( + ty::Binder(ty::SubtypePredicate { + a_is_expected: self.a_is_expected, + a, + b, + })))); + Ok(a) } (&ty::TyInfer(TyVar(a_id)), _) => { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 47cbccdd2ab1..ea243d65881e 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -20,7 +20,8 @@ use hir::def_id::DefId; use middle::free_region::FreeRegionMap; use ty::subst::Substs; use ty::{self, Ty, TyCtxt, TypeFoldable, ToPredicate}; -use infer::InferCtxt; +use ty::error::{ExpectedFound, TypeError}; +use infer::{InferCtxt}; use std::rc::Rc; use syntax::ast; @@ -214,6 +215,8 @@ pub struct FulfillmentError<'tcx> { pub enum FulfillmentErrorCode<'tcx> { CodeSelectionError(SelectionError<'tcx>), CodeProjectionError(MismatchedProjectionTypes<'tcx>), + CodeSubtypeError(ExpectedFound>, + TypeError<'tcx>), // always comes from a SubtypePredicate CodeAmbiguity, } diff --git a/src/test/compile-fail/issue-7813.rs b/src/test/compile-fail/issue-7813.rs index fdd89058fd39..662b9e894ba3 100644 --- a/src/test/compile-fail/issue-7813.rs +++ b/src/test/compile-fail/issue-7813.rs @@ -10,7 +10,6 @@ fn main() { let v = &[]; - let it = v.iter(); //~ ERROR type annotations needed [E0282] - //~| NOTE cannot infer type for `T` - //~| NOTE consider giving `it` a type + //~^ NOTE consider giving `it` a type + let it = v.iter(); //~ ERROR cannot infer type for `_` }