Account for ty::Error
when suggesting impl Trait
or Box<dyn Trait>
This commit is contained in:
parent
e0bbe7915e
commit
55dce720b2
3 changed files with 191 additions and 8 deletions
|
@ -606,11 +606,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap();
|
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 mut ret_types = visitor.0.iter().filter_map(|expr| tables.node_type_opt(expr.hir_id));
|
||||||
let (last_ty, all_returns_have_same_type) =
|
let (last_ty, all_returns_have_same_type) = ret_types.clone().fold(
|
||||||
ret_types.clone().fold((None, true), |(last_ty, mut same), returned_ty| {
|
(None, true),
|
||||||
same &= last_ty.map_or(true, |ty| ty == returned_ty);
|
|(last_ty, mut same): (std::option::Option<Ty<'_>>, bool), ty| {
|
||||||
(Some(returned_ty), same)
|
same &= last_ty.map_or(true, |last_ty| last_ty == ty) && ty.kind != ty::Error;
|
||||||
});
|
(Some(ty), same)
|
||||||
|
},
|
||||||
|
);
|
||||||
let all_returns_conform_to_trait =
|
let all_returns_conform_to_trait =
|
||||||
if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) {
|
if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) {
|
||||||
match ty_ret_ty.kind {
|
match ty_ret_ty.kind {
|
||||||
|
@ -625,7 +627,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => true,
|
_ => false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
|
|
@ -22,6 +22,32 @@ fn bal() -> dyn Trait { //~ ERROR E0746
|
||||||
}
|
}
|
||||||
42
|
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`
|
// Suggest using `impl Trait`
|
||||||
fn bat() -> dyn Trait { //~ ERROR E0746
|
fn bat() -> dyn Trait { //~ ERROR E0746
|
||||||
|
@ -30,5 +56,12 @@ fn bat() -> dyn Trait { //~ ERROR E0746
|
||||||
}
|
}
|
||||||
42
|
42
|
||||||
}
|
}
|
||||||
|
fn bay() -> dyn Trait { //~ ERROR E0746
|
||||||
|
if true {
|
||||||
|
0u32
|
||||||
|
} else {
|
||||||
|
42u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -95,8 +95,136 @@ LL | }
|
||||||
LL | Box::new(42)
|
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
|
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 {
|
LL | fn bat() -> dyn Trait {
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ 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 {
|
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.
|
Some errors have detailed explanations: E0277, E0308, E0746.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue