Account for ty::Error
when suggesting impl Trait
or Box<dyn Trait>
This commit is contained in:
parent
e0bbe7915e
commit
55dce720b2
@ -606,11 +606,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap();
|
||||
|
||||
let mut ret_types = visitor.0.iter().filter_map(|expr| tables.node_type_opt(expr.hir_id));
|
||||
let (last_ty, all_returns_have_same_type) =
|
||||
ret_types.clone().fold((None, true), |(last_ty, mut same), returned_ty| {
|
||||
same &= last_ty.map_or(true, |ty| ty == returned_ty);
|
||||
(Some(returned_ty), same)
|
||||
});
|
||||
let (last_ty, all_returns_have_same_type) = ret_types.clone().fold(
|
||||
(None, true),
|
||||
|(last_ty, mut same): (std::option::Option<Ty<'_>>, bool), ty| {
|
||||
same &= last_ty.map_or(true, |last_ty| last_ty == ty) && ty.kind != ty::Error;
|
||||
(Some(ty), same)
|
||||
},
|
||||
);
|
||||
let all_returns_conform_to_trait =
|
||||
if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) {
|
||||
match ty_ret_ty.kind {
|
||||
@ -625,7 +627,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
})
|
||||
})
|
||||
}
|
||||
_ => true,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
true
|
||||
|
@ -22,6 +22,32 @@ fn bal() -> dyn Trait { //~ ERROR E0746
|
||||
}
|
||||
42
|
||||
}
|
||||
fn bam() -> Box<dyn Trait> {
|
||||
if true {
|
||||
return Struct; //~ ERROR mismatched types
|
||||
}
|
||||
42 //~ ERROR mismatched types
|
||||
}
|
||||
fn baq() -> Box<dyn Trait> {
|
||||
if true {
|
||||
return 0; //~ ERROR mismatched types
|
||||
}
|
||||
42 //~ ERROR mismatched types
|
||||
}
|
||||
fn baz() -> Box<dyn Trait> {
|
||||
if true {
|
||||
Struct //~ ERROR mismatched types
|
||||
} else {
|
||||
42 //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
fn baw() -> Box<dyn Trait> {
|
||||
if true {
|
||||
0 //~ ERROR mismatched types
|
||||
} else {
|
||||
42 //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
// Suggest using `impl Trait`
|
||||
fn bat() -> dyn Trait { //~ ERROR E0746
|
||||
@ -30,5 +56,12 @@ fn bat() -> dyn Trait { //~ ERROR E0746
|
||||
}
|
||||
42
|
||||
}
|
||||
fn bay() -> dyn Trait { //~ ERROR E0746
|
||||
if true {
|
||||
0u32
|
||||
} else {
|
||||
42u32
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -95,8 +95,136 @@ LL | }
|
||||
LL | Box::new(42)
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:16
|
||||
|
|
||||
LL | fn bam() -> Box<dyn Trait> {
|
||||
| -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type
|
||||
LL | if true {
|
||||
LL | return Struct;
|
||||
| ^^^^^^
|
||||
| |
|
||||
| expected struct `std::boxed::Box`, found struct `Struct`
|
||||
| help: store this in the heap by calling `Box::new`: `Box::new(Struct)`
|
||||
|
|
||||
= note: expected struct `std::boxed::Box<(dyn Trait + 'static)>`
|
||||
found struct `Struct`
|
||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:5
|
||||
|
|
||||
LL | fn bam() -> Box<dyn Trait> {
|
||||
| -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type
|
||||
...
|
||||
LL | 42
|
||||
| ^^
|
||||
| |
|
||||
| expected struct `std::boxed::Box`, found integer
|
||||
| help: store this in the heap by calling `Box::new`: `Box::new(42)`
|
||||
|
|
||||
= note: expected struct `std::boxed::Box<(dyn Trait + 'static)>`
|
||||
found type `{integer}`
|
||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:33:16
|
||||
|
|
||||
LL | fn baq() -> Box<dyn Trait> {
|
||||
| -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type
|
||||
LL | if true {
|
||||
LL | return 0;
|
||||
| ^
|
||||
| |
|
||||
| expected struct `std::boxed::Box`, found integer
|
||||
| help: store this in the heap by calling `Box::new`: `Box::new(0)`
|
||||
|
|
||||
= note: expected struct `std::boxed::Box<(dyn Trait + 'static)>`
|
||||
found type `{integer}`
|
||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:35:5
|
||||
|
|
||||
LL | fn baq() -> Box<dyn Trait> {
|
||||
| -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type
|
||||
...
|
||||
LL | 42
|
||||
| ^^
|
||||
| |
|
||||
| expected struct `std::boxed::Box`, found integer
|
||||
| help: store this in the heap by calling `Box::new`: `Box::new(42)`
|
||||
|
|
||||
= note: expected struct `std::boxed::Box<(dyn Trait + 'static)>`
|
||||
found type `{integer}`
|
||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:39:9
|
||||
|
|
||||
LL | fn baz() -> Box<dyn Trait> {
|
||||
| -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type
|
||||
LL | if true {
|
||||
LL | Struct
|
||||
| ^^^^^^
|
||||
| |
|
||||
| expected struct `std::boxed::Box`, found struct `Struct`
|
||||
| help: store this in the heap by calling `Box::new`: `Box::new(Struct)`
|
||||
|
|
||||
= note: expected struct `std::boxed::Box<(dyn Trait + 'static)>`
|
||||
found struct `Struct`
|
||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:41:9
|
||||
|
|
||||
LL | fn baz() -> Box<dyn Trait> {
|
||||
| -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type
|
||||
...
|
||||
LL | 42
|
||||
| ^^
|
||||
| |
|
||||
| expected struct `std::boxed::Box`, found integer
|
||||
| help: store this in the heap by calling `Box::new`: `Box::new(42)`
|
||||
|
|
||||
= note: expected struct `std::boxed::Box<(dyn Trait + 'static)>`
|
||||
found type `{integer}`
|
||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9
|
||||
|
|
||||
LL | fn baw() -> Box<dyn Trait> {
|
||||
| -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type
|
||||
LL | if true {
|
||||
LL | 0
|
||||
| ^
|
||||
| |
|
||||
| expected struct `std::boxed::Box`, found integer
|
||||
| help: store this in the heap by calling `Box::new`: `Box::new(0)`
|
||||
|
|
||||
= note: expected struct `std::boxed::Box<(dyn Trait + 'static)>`
|
||||
found type `{integer}`
|
||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9
|
||||
|
|
||||
LL | fn baw() -> Box<dyn Trait> {
|
||||
| -------------- expected `std::boxed::Box<(dyn Trait + 'static)>` because of return type
|
||||
...
|
||||
LL | 42
|
||||
| ^^
|
||||
| |
|
||||
| expected struct `std::boxed::Box`, found integer
|
||||
| help: store this in the heap by calling `Box::new`: `Box::new(42)`
|
||||
|
|
||||
= note: expected struct `std::boxed::Box<(dyn Trait + 'static)>`
|
||||
found type `{integer}`
|
||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||
|
||||
error[E0746]: return type cannot have an unboxed trait object
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:13
|
||||
|
|
||||
LL | fn bat() -> dyn Trait {
|
||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||
@ -107,7 +235,27 @@ help: return `impl Trait` instead, as all return paths are of type `{integer}`,
|
||||
LL | fn bat() -> impl Trait {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error[E0746]: return type cannot have an unboxed trait object
|
||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:59:13
|
||||
|
|
||||
LL | fn bay() -> dyn Trait {
|
||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
|
||||
= note: if all the returned values were of the same type you could use `impl Trait` as the return type
|
||||
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
|
||||
= note: you can create a new `enum` with a variant for each returned type
|
||||
help: return a boxed trait object instead
|
||||
|
|
||||
LL | fn bay() -> Box<dyn Trait> {
|
||||
LL | Box::new(if true {
|
||||
LL | 0u32
|
||||
LL | } else {
|
||||
LL | 42u32
|
||||
LL | })
|
||||
|
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308, E0746.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
Loading…
Reference in New Issue
Block a user