about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-12-29 11:22:16 -0500
committerNiko Matsakis <niko@alum.mit.edu>2014-12-30 09:36:23 -0500
commit05eb2eeb61985f481982285ae7714d5cc0d7bdb7 (patch)
tree1b77cdd4a3331cc22f92d34c0f37d53c6cac2893
parentc197911c60ce7eaea53ecb357d0409d3e38ff914 (diff)
downloadrust-05eb2eeb61985f481982285ae7714d5cc0d7bdb7.tar.gz
rust-05eb2eeb61985f481982285ae7714d5cc0d7bdb7.zip
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.
-rw-r--r--src/librustc/metadata/decoder.rs2
-rw-r--r--src/librustc/middle/traits/select.rs11
-rw-r--r--src/librustc_typeck/check/method/confirm.rs15
-rw-r--r--src/test/compile-fail/associated-types-bound-failure.rs (renamed from src/test/run-pass/multidispatch-infer-from-single-impl.rs)35
-rw-r--r--src/test/compile-fail/issue-12028.rs (renamed from src/test/run-pass/issue-12028.rs)7
-rw-r--r--src/test/run-pass/associated-types-bound.rs53
6 files changed, 100 insertions, 23 deletions
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index c189aed05ab..0a001d47504 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -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")
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 4ca98a6de64..9670ebdb03c 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -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; }
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 1aa9adaf9ec..9704439c468 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -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
diff --git a/src/test/run-pass/multidispatch-infer-from-single-impl.rs b/src/test/compile-fail/associated-types-bound-failure.rs
index f4ca67548fd..7981fe31827 100644
--- a/src/test/run-pass/multidispatch-infer-from-single-impl.rs
+++ b/src/test/compile-fail/associated-types-bound-failure.rs
@@ -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;
+}
+
+pub trait GetToInt
+{
+    type R;
+
+    fn get(&self) -> <Self as GetToInt>::R;
 }
 
-impl<E> FromError<E> for E {
-    fn from_error(err: E) -> E {
-        err
-    }
+fn foo<G>(g: G) -> int
+    where G : GetToInt
+{
+    ToInt::to_int(&g.get()) //~ ERROR not implemented
 }
 
-fn test() -> Result<(), ()> {
-    Err(FromError::from_error(()))
+fn bar<G : GetToInt>(g: G) -> int
+    where G::R : ToInt
+{
+    ToInt::to_int(&g.get()) // OK
 }
 
-fn main() {
-    let result = (|| Err(FromError::from_error(())))();
-    let foo: () = result.unwrap_or(());
+pub fn main() {
 }
diff --git a/src/test/run-pass/issue-12028.rs b/src/test/compile-fail/issue-12028.rs
index dbfa330d33d..78502efdec5 100644
--- a/src/test/run-pass/issue-12028.rs
+++ b/src/test/compile-fail/issue-12028.rs
@@ -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()
     }
 }
diff --git a/src/test/run-pass/associated-types-bound.rs b/src/test/run-pass/associated-types-bound.rs
new file mode 100644
index 00000000000..db5119132cc
--- /dev/null
+++ b/src/test/run-pass/associated-types-bound.rs
@@ -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);
+}