diff options
| author | Jacob Pratt <jacob@jhpratt.dev> | 2024-11-17 22:30:48 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-17 22:30:48 -0500 |
| commit | c8741214873a48f7964a907952162dc20518095a (patch) | |
| tree | 4c5b5a59d0278234fbce35f1cf1ffad5a1122107 | |
| parent | e2993cd06e7b35422fcf172b0ff247873ddbb163 (diff) | |
| parent | 949cf61fdce2309920ebfa9f7e8363308fbdac08 (diff) | |
| download | rust-c8741214873a48f7964a907952162dc20518095a.tar.gz rust-c8741214873a48f7964a907952162dc20518095a.zip | |
Rollup merge of #132944 - linyihai:needing-parenthases-issue-132924, r=chenyukang
add parentheses when unboxing suggestion needed This PR tried to `add parentheses when unboxing suggestion needed` Fixes #132924
3 files changed, 101 insertions, 9 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 919e83724d7..c4c4c2f200b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -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}(")), @@ -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, @@ -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<'_>, diff --git a/tests/ui/coercion/unboxing-needing-parenthases-issue-132924.rs b/tests/ui/coercion/unboxing-needing-parenthases-issue-132924.rs new file mode 100644 index 00000000000..fc4258fc0af --- /dev/null +++ b/tests/ui/coercion/unboxing-needing-parenthases-issue-132924.rs @@ -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 +} diff --git a/tests/ui/coercion/unboxing-needing-parenthases-issue-132924.stderr b/tests/ui/coercion/unboxing-needing-parenthases-issue-132924.stderr new file mode 100644 index 00000000000..429b1b87357 --- /dev/null +++ b/tests/ui/coercion/unboxing-needing-parenthases-issue-132924.stderr @@ -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`. |
