diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2017-03-10 05:21:27 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2017-04-11 20:32:46 -0400 |
| commit | 105ec7e3bbbef50076f0e6963e8a9327bacf7b5f (patch) | |
| tree | f54223d1bf3625ca4153db54f3da5b3be18e2ca6 /src | |
| parent | 4e4bdea0ae8b3b1995b002374db1a7b7639eb52d (diff) | |
| download | rust-105ec7e3bbbef50076f0e6963e8a9327bacf7b5f.tar.gz rust-105ec7e3bbbef50076f0e6963e8a9327bacf7b5f.zip | |
use obligations to propagate sub-typing instead of the TV code
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/infer/sub.rs | 25 | ||||
| -rw-r--r-- | src/librustc/traits/mod.rs | 5 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-7813.rs | 5 |
3 files changed, 27 insertions, 8 deletions
diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index a6b0e02d477..1a94f12973d 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 47cbccdd2ab..ea243d65881 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<Ty<'tcx>>, + 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 fdd89058fd3..662b9e894ba 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 `_` } |
