use obligations to propagate sub-typing instead of the TV code
This commit is contained in:
parent
4e4bdea0ae
commit
105ec7e3bb
3 changed files with 27 additions and 8 deletions
|
@ -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)), _) => {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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 `_`
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue