Skip to content

Commit

Permalink
add parentheses when unboxing suggestion needed
Browse files Browse the repository at this point in the history
  • Loading branch information
linyihai committed Nov 12, 2024
1 parent 81eef2d commit 53c5c5d
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 9 deletions.
33 changes: 24 additions & 9 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2648,15 +2648,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

let make_sugg = |expr: &Expr<'_>, span: Span, sugg: &str| {
let needs_parens = match expr.kind {
// parenthesize if needed (Issue #46756)
hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
// parenthesize borrows of range literals (Issue #54505)
_ if is_range_literal(expr) => true,
_ => false,
};

if needs_parens {
if self.is_need_parenthesize(expr) {
(
vec![
(span.shrink_to_lo(), format!("{prefix}{sugg}(")),
Expand Down Expand Up @@ -2869,6 +2861,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return None;
}

if checked_ty.is_box() && self.is_need_parenthesize(expr) {
return Some((
vec![
(span, format!("{suggestion}(")),
(expr.span.shrink_to_hi(), ")".to_string()),
],
message,
Applicability::MachineApplicable,
true,
false,
));
}

return Some((
vec![(span, suggestion)],
message,
Expand Down Expand Up @@ -2897,6 +2902,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false
}

fn is_need_parenthesize(&self, expr: &hir::Expr<'_>) -> bool {
match expr.kind {
// parenthesize if needed (Issue #46756)
hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
// parenthesize borrows of range literals (Issue #54505)
_ if is_range_literal(expr) => true,
_ => false,
}
}

pub(crate) fn suggest_cast(
&self,
err: &mut Diag<'_>,
Expand Down
14 changes: 14 additions & 0 deletions tests/ui/coercion/unboxing-needing-parenthases-issue-132924.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ check-fail
fn main() {
let x = Box::new(Some(1));

let test: Option<i32> = x;
//~^ ERROR mismatched types
let x = Box::new(Some(1));
let test: Option<i32> = { x as Box<Option<i32>> };
//~^ ERROR mismatched types

let x = Box::new(Some(1));
let test: Option<i32> = if true { x as Box<Option<i32>> } else { None };
//~^ ERROR mismatched types
}
44 changes: 44 additions & 0 deletions tests/ui/coercion/unboxing-needing-parenthases-issue-132924.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
error[E0308]: mismatched types
--> $DIR/unboxing-needing-parenthases-issue-132924.rs:5:29
|
LL | let test: Option<i32> = x;
| ----------- ^ expected `Option<i32>`, found `Box<Option<{integer}>>`
| |
| expected due to this
|
= note: expected enum `Option<i32>`
found struct `Box<Option<{integer}>>`
help: consider unboxing the value
|
LL | let test: Option<i32> = *x;
| +

error[E0308]: mismatched types
--> $DIR/unboxing-needing-parenthases-issue-132924.rs:8:31
|
LL | let test: Option<i32> = { x as Box<Option<i32>> };
| ^^^^^^^^^^^^^^^^^^^^^ expected `Option<i32>`, found `Box<Option<i32>>`
|
= note: expected enum `Option<_>`
found struct `Box<Option<_>>`
help: consider unboxing the value
|
LL | let test: Option<i32> = { *(x as Box<Option<i32>>) };
| ++ +

error[E0308]: mismatched types
--> $DIR/unboxing-needing-parenthases-issue-132924.rs:12:39
|
LL | let test: Option<i32> = if true { x as Box<Option<i32>> } else { None };
| ^^^^^^^^^^^^^^^^^^^^^ expected `Option<i32>`, found `Box<Option<i32>>`
|
= note: expected enum `Option<_>`
found struct `Box<Option<_>>`
help: consider unboxing the value
|
LL | let test: Option<i32> = if true { *(x as Box<Option<i32>>) } else { None };
| ++ +

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.

0 comments on commit 53c5c5d

Please sign in to comment.