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:
commit
730e5ad04e
8 changed files with 164 additions and 17 deletions
72
src/test/ui/impl-trait/equality.rs
Normal file
72
src/test/ui/impl-trait/equality.rs
Normal 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
|
||||
}
|
||||
55
src/test/ui/impl-trait/equality.stderr
Normal file
55
src/test/ui/impl-trait/equality.stderr
Normal 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
|
||||
|
||||
18
src/test/ui/mismatched_types/binops.rs
Normal file
18
src/test/ui/mismatched_types/binops.rs
Normal 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);
|
||||
}
|
||||
58
src/test/ui/mismatched_types/binops.stderr
Normal file
58
src/test/ui/mismatched_types/binops.stderr
Normal 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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue