Skip to content

Commit

Permalink
Rollup merge of #132944 - linyihai:needing-parenthases-issue-132924, …
Browse files Browse the repository at this point in the history
…r=chenyukang

add parentheses when unboxing suggestion needed

This PR tried to `add parentheses when unboxing suggestion needed`

Fixes #132924
  • Loading branch information
jhpratt authored Nov 18, 2024
2 parents e2993cd + 949cf61 commit c874121
Show file tree
Hide file tree
Showing 3 changed files with 101 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.needs_parentheses(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 self.needs_parentheses(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 needs_parentheses(&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
18 changes: 18 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,18 @@
//@ 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

let x = std::rc::Rc::new(Some(1));
let test: Option<i32> = x as std::rc::Rc<Option<i32>>;
//~^ ERROR mismatched types
}
59 changes: 59 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,59 @@
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[E0308]: mismatched types
--> $DIR/unboxing-needing-parenthases-issue-132924.rs:16:29
|
LL | let test: Option<i32> = x as std::rc::Rc<Option<i32>>;
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<i32>`, found `Rc<Option<i32>>`
| |
| expected due to this
|
= note: expected enum `Option<_>`
found struct `Rc<Option<_>>`
help: consider dereferencing the type
|
LL | let test: Option<i32> = *(x as std::rc::Rc<Option<i32>>);
| ++ +

error: aborting due to 4 previous errors

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

0 comments on commit c874121

Please sign in to comment.