Skip to content

Commit fc43bd6

Browse files
committed
revive suggestions for boxed trait objects instead of impl Trait
1 parent 24cf45a commit fc43bd6

5 files changed

+99
-2
lines changed

compiler/rustc_typeck/src/check/_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_errors::{Applicability, MultiSpan};
44
use rustc_hir::{self as hir, ExprKind};
55
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
66
use rustc_infer::traits::Obligation;
7-
use rustc_middle::ty::{self, ToPredicate, Ty, TypeVisitable};
7+
use rustc_middle::ty::{self, ToPredicate, Ty};
88
use rustc_span::Span;
99
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
1010
use rustc_trait_selection::traits::{
@@ -479,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
479479
match orig_expected {
480480
Expectation::ExpectHasType(expected)
481481
if self.in_tail_expr
482-
&& self.ret_coercion.as_ref()?.borrow().merged_ty().has_opaque_types()
482+
&& self.return_type_has_opaque
483483
&& self.can_coerce(outer_ty, expected) =>
484484
{
485485
let obligations = self.fulfillment_cx.borrow().pending_obligations();

src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr

+29
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ LL | | 1u32
5252
LL | | }
5353
| |_____- `if` and `else` have incompatible types
5454
|
55+
help: you could change the return type to be a boxed trait object
56+
|
57+
LL | fn qux() -> Box<dyn std::fmt::Display> {
58+
| ~~~~~~~ +
59+
help: if you change the return type to expect trait objects, box the returned expressions
60+
|
61+
LL ~ Box::new(0i32)
62+
LL | } else {
63+
LL ~ Box::new(1u32)
64+
|
5565
help: change the type of the numeric literal from `u32` to `i32`
5666
|
5767
LL | 1i32
@@ -114,6 +124,15 @@ LL | | _ => 2u32,
114124
LL | | }
115125
| |_____- `match` arms have incompatible types
116126
|
127+
help: you could change the return type to be a boxed trait object
128+
|
129+
LL | fn dog() -> Box<dyn std::fmt::Display> {
130+
| ~~~~~~~ +
131+
help: if you change the return type to expect trait objects, box the returned expressions
132+
|
133+
LL ~ 0 => Box::new(0i32),
134+
LL ~ 1 => Box::new(1u32),
135+
|
117136
help: change the type of the numeric literal from `u32` to `i32`
118137
|
119138
LL | 1 => 1i32,
@@ -131,6 +150,16 @@ LL | | 1u32
131150
LL | | }
132151
| |_____- `if` and `else` have incompatible types
133152
|
153+
help: you could change the return type to be a boxed trait object
154+
|
155+
LL | fn apt() -> Box<dyn std::fmt::Display> {
156+
| ~~~~~~~ +
157+
help: if you change the return type to expect trait objects, box the returned expressions
158+
|
159+
LL ~ Box::new(0i32)
160+
LL | } else {
161+
LL ~ Box::new(1u32)
162+
|
134163
help: change the type of the numeric literal from `u32` to `i32`
135164
|
136165
LL | 1i32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// run-rustfix
2+
3+
#![allow(dead_code)]
4+
5+
struct S;
6+
struct Y;
7+
8+
trait Trait {}
9+
10+
impl Trait for S {}
11+
impl Trait for Y {}
12+
13+
fn baz() -> Box<dyn Trait> {
14+
if true {
15+
Box::new(S)
16+
} else {
17+
Box::new(Y) //~ ERROR `if` and `else` have incompatible types
18+
}
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// run-rustfix
2+
3+
#![allow(dead_code)]
4+
5+
struct S;
6+
struct Y;
7+
8+
trait Trait {}
9+
10+
impl Trait for S {}
11+
impl Trait for Y {}
12+
13+
fn baz() -> impl Trait {
14+
if true {
15+
S
16+
} else {
17+
Y //~ ERROR `if` and `else` have incompatible types
18+
}
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error[E0308]: `if` and `else` have incompatible types
2+
--> $DIR/suggest-boxed-trait-objects-instead-of-impl-trait.rs:17:9
3+
|
4+
LL | / if true {
5+
LL | | S
6+
| | - expected because of this
7+
LL | | } else {
8+
LL | | Y
9+
| | ^ expected struct `S`, found struct `Y`
10+
LL | | }
11+
| |_____- `if` and `else` have incompatible types
12+
|
13+
help: you could change the return type to be a boxed trait object
14+
|
15+
LL | fn baz() -> Box<dyn Trait> {
16+
| ~~~~~~~ +
17+
help: if you change the return type to expect trait objects, box the returned expressions
18+
|
19+
LL ~ Box::new(S)
20+
LL | } else {
21+
LL ~ Box::new(Y)
22+
|
23+
24+
error: aborting due to previous error
25+
26+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)