Adjust tests for inferenceGet more conservative about inference for now. Seems better to err on the side of being more correct rather than less. Fix a bug in typing index expressions that was exposed as a result, and add one type annotation that is not required. Delete some random tests that were relying on old behavior and don't seem to add anything anymore.

This commit is contained in:
Niko Matsakis 2014-12-29 11:22:16 -05:00
parent c197911c60
commit 05eb2eeb61
6 changed files with 100 additions and 23 deletions

View file

@ -1366,7 +1366,7 @@ pub fn get_dylib_dependency_formats(cdata: Cmd)
if spec.len() == 0 { continue }
let cnum = spec.split(':').nth(0).unwrap();
let link = spec.split(':').nth(1).unwrap();
let cnum = cnum.parse().unwrap();
let cnum: ast::CrateNum = cnum.parse().unwrap();
let cnum = match cdata.cnum_map.get(&cnum) {
Some(&n) => n,
None => panic!("didn't find a crate in the cnum_map")

View file

@ -736,10 +736,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let trait_def_id = match poly_trait_predicate.0.trait_ref.self_ty().sty {
ty::ty_projection(ref data) => data.trait_ref.def_id,
ty::ty_infer(ty::TyVar(_)) => {
// TODO ignore potential ambiguity so that we can do
// better inference, need to get our story
// straight(er) here, I think.
// candidates.ambiguous = true;
// If the self-type is an inference variable, then it MAY wind up
// being a projected type, so induce an ambiguity.
//
// FIXME(#20297) -- being strict about this can cause
// inference failures with BorrowFrom, which is
// unfortunate. Can we do better here?
candidates.ambiguous = true;
return;
}
_ => { return; }

View file

@ -10,7 +10,8 @@
use super::probe;
use check::{mod, FnCtxt, NoPreference, PreferMutLvalue, callee};
use check::{mod, FnCtxt, NoPreference, PreferMutLvalue, callee, demand};
use middle::mem_categorization::Typer;
use middle::subst::{mod};
use middle::traits;
use middle::ty::{mod, Ty};
@ -540,7 +541,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
// Don't retry the first one or we might infinite loop!
if i != 0 {
match expr.node {
ast::ExprIndex(ref base_expr, _) => {
ast::ExprIndex(ref base_expr, ref index_expr) => {
let mut base_adjustment =
match self.fcx.inh.adjustments.borrow().get(&base_expr.id) {
Some(&ty::AdjustDerefRef(ref adr)) => (*adr).clone(),
@ -576,7 +577,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
&**base_expr,
Some(&ty::AdjustDerefRef(base_adjustment.clone())));
check::try_index_step(
let result = check::try_index_step(
self.fcx,
MethodCall::expr(expr.id),
*expr,
@ -584,6 +585,14 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
adjusted_base_ty,
base_adjustment,
PreferMutLvalue);
if let Some((input_ty, return_ty)) = result {
let index_expr_ty = self.fcx.expr_ty(&**index_expr);
demand::suptype(self.fcx, index_expr.span, input_ty, index_expr_ty);
let expr_ty = self.fcx.expr_ty(&**expr);
demand::suptype(self.fcx, expr.span, expr_ty, return_ty);
}
}
ast::ExprUnary(ast::UnDeref, ref base_expr) => {
// if this is an overloaded deref, then re-evaluate with

View file

@ -8,25 +8,32 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that we correctly infer that `E` must be `()` here. This is
// known because there is just one impl that could apply where
// `Self=()`.
// Test equality constraints on associated types in a where clause.
pub trait FromError<E> {
fn from_error(err: E) -> Self;
#![feature(associated_types)]
pub trait ToInt {
fn to_int(&self) -> int;
}
impl<E> FromError<E> for E {
fn from_error(err: E) -> E {
err
}
pub trait GetToInt
{
type R;
fn get(&self) -> <Self as GetToInt>::R;
}
fn test() -> Result<(), ()> {
Err(FromError::from_error(()))
fn foo<G>(g: G) -> int
where G : GetToInt
{
ToInt::to_int(&g.get()) //~ ERROR not implemented
}
fn main() {
let result = (|| Err(FromError::from_error(())))();
let foo: () = result.unwrap_or(());
fn bar<G : GetToInt>(g: G) -> int
where G::R : ToInt
{
ToInt::to_int(&g.get()) // OK
}
pub fn main() {
}

View file

@ -8,6 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test an example where we fail to infer the type parameter H. This
// is because there is really nothing constraining it. At one time, we
// would infer based on the where clauses in scope, but that no longer
// works.
trait Hash<H> {
fn hash2(&self, hasher: &H) -> u64;
}
@ -30,7 +35,7 @@ trait StreamHash<S: Stream, H: StreamHasher<S>>: Hash<H> {
impl<S: Stream, H: StreamHasher<S>> Hash<H> for u8 {
fn hash2(&self, hasher: &H) -> u64 {
let mut stream = hasher.stream();
self.input_stream(&mut stream);
self.input_stream(&mut stream); //~ ERROR type annotations required
stream.result()
}
}

View file

@ -0,0 +1,53 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test equality constraints on associated types in a where clause.
#![feature(associated_types)]
pub trait ToInt {
fn to_int(&self) -> int;
}
impl ToInt for int {
fn to_int(&self) -> int { *self }
}
impl ToInt for uint {
fn to_int(&self) -> int { *self as int }
}
pub trait GetToInt
{
type R : ToInt;
fn get(&self) -> <Self as GetToInt>::R;
}
impl GetToInt for int {
type R = int;
fn get(&self) -> int { *self }
}
impl GetToInt for uint {
type R = uint;
fn get(&self) -> uint { *self }
}
fn foo<G>(g: G) -> int
where G : GetToInt
{
ToInt::to_int(&g.get())
}
pub fn main() {
assert_eq!(foo(22i), 22i);
assert_eq!(foo(22u), 22i);
}