diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2024-01-22 20:53:41 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2024-01-22 20:53:41 +0000 |
| commit | ac56a2b564a3e15b8377e72294a3d565a1c8c659 (patch) | |
| tree | f42ae59254539e6d9319d666226c1c43740bb507 /compiler | |
| parent | 390ef9ba0297ae5ba5aacdf0be0d0c47be8d166a (diff) | |
| download | rust-ac56a2b564a3e15b8377e72294a3d565a1c8c659.tar.gz rust-ac56a2b564a3e15b8377e72294a3d565a1c8c659.zip | |
Suggest boxing if then expr if that solves divergent arms
When encountering
```rust
let _ = if true {
Struct
} else {
foo() // -> Box<dyn Trait>
};
```
if `Struct` implements `Trait`, suggest boxing the then arm tail expression.
Part of #102629.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index afb3c5c1e56..a0dfaf33a6e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -330,6 +330,38 @@ impl<T> Trait<T> for X { ); } } + (ty::Adt(_, _), ty::Adt(def, args)) + if let ObligationCauseCode::IfExpression(cause) = cause.code() + && let hir::Node::Block(blk) = self.tcx.hir_node(cause.then_id) + && let Some(then) = blk.expr + && def.is_box() + && let boxed_ty = args.type_at(0) + && let ty::Dynamic(t, _, _) = boxed_ty.kind() + && let Some(def_id) = t.principal_def_id() + && let mut impl_def_ids = vec![] + && let _ = + tcx.for_each_relevant_impl(def_id, values.expected, |did| { + impl_def_ids.push(did) + }) + && let [_] = &impl_def_ids[..] => + { + // We have divergent if/else arms where the expected value is a type that + // implements the trait of the found boxed trait object. + diag.multipart_suggestion( + format!( + "`{}` implements `{}` so you can box it to coerce to the trait \ + object `{}`", + values.expected, + tcx.item_name(def_id), + values.found, + ), + vec![ + (then.span.shrink_to_lo(), "Box::new(".to_string()), + (then.span.shrink_to_hi(), ")".to_string()), + ], + MachineApplicable, + ); + } _ => {} } debug!( |
