Auto merge of #40565 - estebank:binops-help, r=arielb1

Explicit help message for binop type mismatch

When trying to do `1 + Some(2)`, or some other binary operation on two
types different types without an appropriate trait implementation, provide
an explicit help message:

```rust
help: `{integer} + std::option::Option<{integer}>` has no implementation
```

Re: #39579, #38564, #37626, #39942, #34698.
This commit is contained in:
bors 2017-04-10 21:56:13 +00:00
commit 730e5ad04e
8 changed files with 164 additions and 17 deletions

View file

@ -0,0 +1,72 @@
// Copyright 2016 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.
#![feature(conservative_impl_trait, specialization)]
trait Foo: Copy + ToString {}
impl<T: Copy + ToString> Foo for T {}
fn hide<T: Foo>(x: T) -> impl Foo {
x
}
fn two(x: bool) -> impl Foo {
if x {
return 1_i32;
}
0_u32
//~^ ERROR mismatched types
//~| expected i32, found u32
}
fn sum_to(n: u32) -> impl Foo {
if n == 0 {
0
} else {
n + sum_to(n - 1)
//~^ ERROR no implementation for `u32 + impl Foo`
}
}
trait Leak: Sized {
type T;
fn leak(self) -> Self::T;
}
impl<T> Leak for T {
default type T = ();
default fn leak(self) -> Self::T { panic!() }
}
impl Leak for i32 {
type T = i32;
fn leak(self) -> i32 { self }
}
fn main() {
let _: u32 = hide(0_u32);
//~^ ERROR mismatched types
//~| expected type `u32`
//~| found type `impl Foo`
//~| expected u32, found anonymized type
let _: i32 = Leak::leak(hide(0_i32));
//~^ ERROR mismatched types
//~| expected type `i32`
//~| found type `<impl Foo as Leak>::T`
//~| expected i32, found associated type
let mut x = (hide(0_u32), hide(0_i32));
x = (x.1,
//~^ ERROR mismatched types
//~| expected u32, found i32
x.0);
//~^ ERROR mismatched types
//~| expected i32, found u32
}

View file

@ -0,0 +1,55 @@
error[E0308]: mismatched types
--> $DIR/equality.rs:25:5
|
25 | 0_u32
| ^^^^^ expected i32, found u32
|
= note: expected type `i32`
found type `u32`
error[E0277]: the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
--> $DIR/equality.rs:34:9
|
34 | n + sum_to(n - 1)
| ^^^^^^^^^^^^^^^^^ the trait `std::ops::Add<impl Foo>` is not implemented for `u32`
|
= note: no implementation for `u32 + impl Foo`
error[E0308]: mismatched types
--> $DIR/equality.rs:53:18
|
53 | let _: u32 = hide(0_u32);
| ^^^^^^^^^^^ expected u32, found anonymized type
|
= note: expected type `u32`
found type `impl Foo`
error[E0308]: mismatched types
--> $DIR/equality.rs:59:18
|
59 | let _: i32 = Leak::leak(hide(0_i32));
| ^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found associated type
|
= note: expected type `i32`
found type `<impl Foo as Leak>::T`
error[E0308]: mismatched types
--> $DIR/equality.rs:66:10
|
66 | x = (x.1,
| ^^^ expected u32, found i32
|
= note: expected type `impl Foo` (u32)
found type `impl Foo` (i32)
error[E0308]: mismatched types
--> $DIR/equality.rs:69:10
|
69 | x.0);
| ^^^ expected i32, found u32
|
= note: expected type `impl Foo` (i32)
found type `impl Foo` (u32)
error: aborting due to 6 previous errors

View file

@ -0,0 +1,18 @@
// Copyright 2017 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.
fn main() {
1 + Some(1);
2 as usize - Some(1);
3 * ();
4 / "";
5 < String::new();
6 == Ok(1);
}

View file

@ -0,0 +1,58 @@
error[E0277]: the trait bound `{integer}: std::ops::Add<std::option::Option<{integer}>>` is not satisfied
--> $DIR/binops.rs:12:5
|
12 | 1 + Some(1);
| ^^^^^^^^^^^ the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
|
= note: no implementation for `{integer} + std::option::Option<{integer}>`
error[E0277]: the trait bound `usize: std::ops::Sub<std::option::Option<{integer}>>` is not satisfied
--> $DIR/binops.rs:13:5
|
13 | 2 as usize - Some(1);
| ^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`
|
= note: no implementation for `usize - std::option::Option<{integer}>`
error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied
--> $DIR/binops.rs:14:5
|
14 | 3 * ();
| ^^^^^^ the trait `std::ops::Mul<()>` is not implemented for `{integer}`
|
= note: no implementation for `{integer} * ()`
error[E0277]: the trait bound `{integer}: std::ops::Div<&str>` is not satisfied
--> $DIR/binops.rs:15:5
|
15 | 4 / "";
| ^^^^^^ the trait `std::ops::Div<&str>` is not implemented for `{integer}`
|
= note: no implementation for `{integer} / &str`
error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<std::string::String>` is not satisfied
--> $DIR/binops.rs:16:5
|
16 | 5 < String::new();
| ^^^^^^^^^^^^^^^^^ the trait `std::cmp::PartialEq<std::string::String>` is not implemented for `{integer}`
|
= note: can't compare `{integer}` with `std::string::String`
error[E0277]: the trait bound `{integer}: std::cmp::PartialOrd<std::string::String>` is not satisfied
--> $DIR/binops.rs:16:5
|
16 | 5 < String::new();
| ^^^^^^^^^^^^^^^^^ the trait `std::cmp::PartialOrd<std::string::String>` is not implemented for `{integer}`
|
= note: can't compare `{integer}` with `std::string::String`
error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not satisfied
--> $DIR/binops.rs:17:5
|
17 | 6 == Ok(1);
| ^^^^^^^^^^ the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
|
= note: can't compare `{integer}` with `std::result::Result<{integer}, _>`
error: aborting due to 7 previous errors

View file

@ -9,11 +9,7 @@ error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied
27 | | y),
| |______________^ ...ending here: the trait `std::ops::Add<()>` is not implemented for `u32`
|
= help: the following implementations were found:
<u32 as std::ops::Add>
<&'a u32 as std::ops::Add<u32>>
<u32 as std::ops::Add<&'a u32>>
<&'b u32 as std::ops::Add<&'a u32>>
= note: no implementation for `u32 + ()`
error: aborting due to previous error