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)
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);
+}