From 52e520e902cecc579910e6cabe1658720bfab132 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Thu, 30 Apr 2015 00:56:33 +0200 Subject: [PATCH 1/4] rustc: Improve misleading error message for E0282 The error can also occur in cases where a type annotation will not help. --- src/librustc/middle/traits/error_reporting.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index d10ff060418cc..9f87a9ad65f36 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -290,7 +290,7 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, { span_err!(infcx.tcx.sess, obligation.cause.span, E0282, "unable to infer enough type information about `{}`; \ - type annotations required", + type annotations or generic parameter binding required", self_ty.user_string(infcx.tcx)); } else { span_err!(infcx.tcx.sess, obligation.cause.span, E0283, From 6b292cd4c48f0876b4280dfdf0c38d474fe44330 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Thu, 30 Apr 2015 00:58:43 +0200 Subject: [PATCH 2/4] rustc: Add long diagnostics for E0282 --- src/librustc/diagnostics.rs | 68 ++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 8b43f9ada9a33..250252a77cbcd 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -368,6 +368,73 @@ loop. Without a loop to break out of or continue in, no sensible action can be taken. "##, +E0282: r##" +This error indicates that type inference did not result in one unique possible +type, and extra information is required. In most cases this can be provided +by adding a type annotation. Sometimes you need to specify a generic type +parameter manually. + +A common example is the `collect` method on `Iterator`. It has a generic type +parameter with a `FromIterator` bound, which is implemented by `Vec` and +`VecDeque` among others. Consider the following snippet: + +``` +let x = (1_i32 .. 10).collect(); +``` + +In this case, the compiler cannot infer what the type of `x` should be: +`Vec` and `VecDeque` are both suitable candidates. To specify which +type to use, you can use a type annotation on `x`: + +``` +let x: Vec = (1_i32 .. 10).collect(); +``` + +It is not necessary to annotate the full type, once the ambiguity is resolved, +the compiler can infer the rest: + +``` +let x: Vec<_> = (1_i32 .. 10).collect(); +``` + +Another way to provide the compiler with enough information, is to specify the +generic type parameter: + +``` +let x = (1_i32 .. 10).collect::>(); +``` + +Again, you need not specify the full type if the compiler can infer it: + +``` +let x = (1_i32 .. 10).collect::>(); +``` + +Apart from a method or function with a generic type parameter, this error can +occur when a type parameter of a struct or trait cannot be inferred. In that +case it is not always possible to use a type annotation, because all candidates +have the same return type. For instance: + +``` +struct Foo { + // Some fields omitted. +} + +impl Foo { + fn bar() -> i32 { + 0 + } + + fn baz() { + let number = Foo::bar(); + } +} +``` + +This will fail because the compiler does not know which instance of `Foo` to +call `bar` on. Change `Foo::bar()` to `Foo::::bar()` to resolve the error. +"##, + E0296: r##" This error indicates that the given recursion limit could not be parsed. Ensure that the value provided is a positive integer between quotes, like so: @@ -515,7 +582,6 @@ register_diagnostics! { E0279, // requirement is not satisfied E0280, // requirement is not satisfied E0281, // type implements trait but other trait is required - E0282, // unable to infer enough type information about E0283, // cannot resolve type E0284, // cannot resolve type E0285, // overflow evaluation builtin bounds From 414dfb13df96a373c7fd37f6beb299e176675e0e Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Thu, 30 Apr 2015 11:51:40 +0200 Subject: [PATCH 3/4] rustc: Improve long diagnostics for E0282 The new example uses a `char` iterator instead of `i32`, to avoid interplay between type inference and the default type for integer literals. --- src/librustc/diagnostics.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 250252a77cbcd..39ebcda4778c7 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -375,39 +375,40 @@ by adding a type annotation. Sometimes you need to specify a generic type parameter manually. A common example is the `collect` method on `Iterator`. It has a generic type -parameter with a `FromIterator` bound, which is implemented by `Vec` and -`VecDeque` among others. Consider the following snippet: +parameter with a `FromIterator` bound, which for a `char` iterator is +implemented by `Vec` and `String` among others. Consider the following snippet +that reverses the characters of a string: ``` -let x = (1_i32 .. 10).collect(); +let x = "hello".chars().rev().collect(); ``` In this case, the compiler cannot infer what the type of `x` should be: -`Vec` and `VecDeque` are both suitable candidates. To specify which -type to use, you can use a type annotation on `x`: +`Vec` and `String` are both suitable candidates. To specify which type to +use, you can use a type annotation on `x`: ``` -let x: Vec = (1_i32 .. 10).collect(); +let x: Vec = "hello".chars().rev().collect(); ``` -It is not necessary to annotate the full type, once the ambiguity is resolved, +It is not necessary to annotate the full type. Once the ambiguity is resolved, the compiler can infer the rest: ``` -let x: Vec<_> = (1_i32 .. 10).collect(); +let x: Vec<_> = "hello".chars().rev().collect(); ``` Another way to provide the compiler with enough information, is to specify the generic type parameter: ``` -let x = (1_i32 .. 10).collect::>(); +let x = "hello".chars().rev().collect::>(); ``` Again, you need not specify the full type if the compiler can infer it: ``` -let x = (1_i32 .. 10).collect::>(); +let x = "hello".chars().rev().collect::>(); ``` Apart from a method or function with a generic type parameter, this error can From 4b8098bb193d82d18183a8223507f5908adeeb4c Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 5 May 2015 18:22:20 +0200 Subject: [PATCH 4/4] test: Update expected compile-fail message for E0282 --- src/test/compile-fail/issue-12187-1.rs | 4 ++-- src/test/compile-fail/issue-12187-2.rs | 4 ++-- src/test/compile-fail/issue-5062.rs | 4 ++-- src/test/compile-fail/issue-6458-2.rs | 4 ++-- src/test/compile-fail/issue-6458-3.rs | 4 ++-- src/test/compile-fail/issue-6458-4.rs | 4 ++-- src/test/compile-fail/issue-6458.rs | 5 +++-- src/test/compile-fail/issue-7813.rs | 4 ++-- .../compile-fail/method-ambig-one-trait-unknown-int-type.rs | 5 +++-- .../compile-fail/traits-multidispatch-convert-ambig-dest.rs | 5 +++-- src/test/compile-fail/unconstrained-none.rs | 4 ++-- src/test/compile-fail/unconstrained-ref.rs | 4 ++-- src/test/compile-fail/vector-no-ann.rs | 5 +++-- 13 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/test/compile-fail/issue-12187-1.rs b/src/test/compile-fail/issue-12187-1.rs index 74423b041dda3..5322966ae2ea0 100644 --- a/src/test/compile-fail/issue-12187-1.rs +++ b/src/test/compile-fail/issue-12187-1.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -14,5 +14,5 @@ fn new() -> &'static T { fn main() { let &v = new(); - //~^ ERROR type annotations required + //~^ ERROR type annotations or generic parameter binding required } diff --git a/src/test/compile-fail/issue-12187-2.rs b/src/test/compile-fail/issue-12187-2.rs index af5c8b45a483e..dabc0acba370e 100644 --- a/src/test/compile-fail/issue-12187-2.rs +++ b/src/test/compile-fail/issue-12187-2.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -14,5 +14,5 @@ fn new<'r, T>() -> &'r T { fn main() { let &v = new(); - //~^ ERROR type annotations required + //~^ ERROR type annotations or generic parameter binding required } diff --git a/src/test/compile-fail/issue-5062.rs b/src/test/compile-fail/issue-5062.rs index 7bf3449a664b1..392d38a6144f1 100644 --- a/src/test/compile-fail/issue-5062.rs +++ b/src/test/compile-fail/issue-5062.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -9,4 +9,4 @@ // except according to those terms. fn main() { format!("{:?}", None); } - //~^ ERROR type annotations required + //~^ ERROR type annotations or generic parameter binding required diff --git a/src/test/compile-fail/issue-6458-2.rs b/src/test/compile-fail/issue-6458-2.rs index 0143c75bfc604..acf1d766b6a11 100644 --- a/src/test/compile-fail/issue-6458-2.rs +++ b/src/test/compile-fail/issue-6458-2.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -11,5 +11,5 @@ fn main() { // Unconstrained type: format!("{:?}", None); - //~^ ERROR type annotations required + //~^ ERROR type annotations or generic parameter binding required } diff --git a/src/test/compile-fail/issue-6458-3.rs b/src/test/compile-fail/issue-6458-3.rs index f96faeeec4bd1..3f81e51efe2ef 100644 --- a/src/test/compile-fail/issue-6458-3.rs +++ b/src/test/compile-fail/issue-6458-3.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -12,5 +12,5 @@ use std::mem; fn main() { mem::transmute(0); - //~^ ERROR type annotations required + //~^ ERROR type annotations or generic parameter binding required } diff --git a/src/test/compile-fail/issue-6458-4.rs b/src/test/compile-fail/issue-6458-4.rs index 02274e5441e26..7f408be9c02d4 100644 --- a/src/test/compile-fail/issue-6458-4.rs +++ b/src/test/compile-fail/issue-6458-4.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,7 +10,7 @@ fn foo(b: bool) -> Result { Err("bar".to_string()); - //~^ ERROR type annotations required + //~^ ERROR type annotations or generic parameter binding required } fn main() { diff --git a/src/test/compile-fail/issue-6458.rs b/src/test/compile-fail/issue-6458.rs index 0bf9a3c2d4867..c1f9dd6a4b893 100644 --- a/src/test/compile-fail/issue-6458.rs +++ b/src/test/compile-fail/issue-6458.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -16,7 +16,8 @@ pub struct MyState; pub fn foo(_: TypeWithState) {} pub fn bar() { - foo(TypeWithState(marker::PhantomData)); //~ ERROR type annotations required + foo(TypeWithState(marker::PhantomData)); + //~^ ERROR type annotations or generic parameter binding required } fn main() { diff --git a/src/test/compile-fail/issue-7813.rs b/src/test/compile-fail/issue-7813.rs index 81421af4fa839..327fb6adf1d54 100644 --- a/src/test/compile-fail/issue-7813.rs +++ b/src/test/compile-fail/issue-7813.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,5 +10,5 @@ fn main() { let v = &[]; - let it = v.iter(); //~ ERROR type annotations required + let it = v.iter(); //~ ERROR type annotations or generic parameter binding required } diff --git a/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs b/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs index c6d45f1c9db8a..59d75c5a787a6 100644 --- a/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs +++ b/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -31,7 +31,8 @@ impl foo for Vec { fn m1() { // we couldn't infer the type of the vector just based on calling foo()... - let mut x = Vec::new(); //~ ERROR type annotations required + let mut x = Vec::new(); + //~^ ERROR type annotations or generic parameter binding required x.foo(); } diff --git a/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs b/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs index 8fe1f4d2371c4..c77494912bc75 100644 --- a/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs +++ b/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -33,7 +33,8 @@ where T : Convert } fn a() { - test(22, std::default::Default::default()); //~ ERROR type annotations required + test(22, std::default::Default::default()); + //~^ ERROR type annotations or generic parameter binding required } fn main() {} diff --git a/src/test/compile-fail/unconstrained-none.rs b/src/test/compile-fail/unconstrained-none.rs index 9879766a8fa25..c14de98e03f14 100644 --- a/src/test/compile-fail/unconstrained-none.rs +++ b/src/test/compile-fail/unconstrained-none.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -11,5 +11,5 @@ // Issue #5062 fn main() { - None; //~ ERROR type annotations required + None; //~ ERROR type annotations or generic parameter binding required } diff --git a/src/test/compile-fail/unconstrained-ref.rs b/src/test/compile-fail/unconstrained-ref.rs index e03f60e758ce2..02a3f2b9ab8d2 100644 --- a/src/test/compile-fail/unconstrained-ref.rs +++ b/src/test/compile-fail/unconstrained-ref.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -13,5 +13,5 @@ struct S<'a, T:'a> { } fn main() { - S { o: &None }; //~ ERROR type annotations required + S { o: &None }; //~ ERROR type annotations or generic parameter binding required } diff --git a/src/test/compile-fail/vector-no-ann.rs b/src/test/compile-fail/vector-no-ann.rs index d48f5715ec1b9..419b8c4e1b015 100644 --- a/src/test/compile-fail/vector-no-ann.rs +++ b/src/test/compile-fail/vector-no-ann.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,5 +10,6 @@ fn main() { - let _foo = Vec::new(); //~ ERROR type annotations required + let _foo = Vec::new(); + //~^ ERROR type annotations or generic parameter binding required }