Skip to content

Commit 08cbb7d

Browse files
Rollup merge of #88757 - andrewhickman:master, r=jackh726
Suggest wapping expr in parentheses on invalid unary negation Fixes #88701
2 parents 746eb1d + 43b79d8 commit 08cbb7d

File tree

4 files changed

+80
-37
lines changed

4 files changed

+80
-37
lines changed

compiler/rustc_typeck/src/check/op.rs

+46-35
Original file line numberDiff line numberDiff line change
@@ -680,42 +680,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
680680
ex.span,
681681
format!("cannot apply unary operator `{}`", op.as_str()),
682682
);
683-
match actual.kind() {
684-
Uint(_) if op == hir::UnOp::Neg => {
685-
err.note("unsigned values cannot be negated");
686-
687-
if let hir::ExprKind::Unary(
688-
_,
689-
hir::Expr {
690-
kind:
691-
hir::ExprKind::Lit(Spanned {
692-
node: ast::LitKind::Int(1, _),
693-
..
694-
}),
695-
..
696-
},
697-
) = ex.kind
698-
{
699-
err.span_suggestion(
700-
ex.span,
701-
&format!(
702-
"you may have meant the maximum value of `{}`",
703-
actual
704-
),
705-
format!("{}::MAX", actual),
706-
Applicability::MaybeIncorrect,
707-
);
683+
684+
let sp = self.tcx.sess.source_map().start_point(ex.span);
685+
if let Some(sp) =
686+
self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
687+
{
688+
// If the previous expression was a block expression, suggest parentheses
689+
// (turning this into a binary subtraction operation instead.)
690+
// for example, `{2} - 2` -> `({2}) - 2` (see src\test\ui\parser\expr-as-stmt.rs)
691+
self.tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
692+
} else {
693+
match actual.kind() {
694+
Uint(_) if op == hir::UnOp::Neg => {
695+
err.note("unsigned values cannot be negated");
696+
697+
if let hir::ExprKind::Unary(
698+
_,
699+
hir::Expr {
700+
kind:
701+
hir::ExprKind::Lit(Spanned {
702+
node: ast::LitKind::Int(1, _),
703+
..
704+
}),
705+
..
706+
},
707+
) = ex.kind
708+
{
709+
err.span_suggestion(
710+
ex.span,
711+
&format!(
712+
"you may have meant the maximum value of `{}`",
713+
actual
714+
),
715+
format!("{}::MAX", actual),
716+
Applicability::MaybeIncorrect,
717+
);
718+
}
719+
}
720+
Str | Never | Char | Tuple(_) | Array(_, _) => {}
721+
Ref(_, ref lty, _) if *lty.kind() == Str => {}
722+
_ => {
723+
let missing_trait = match op {
724+
hir::UnOp::Neg => "std::ops::Neg",
725+
hir::UnOp::Not => "std::ops::Not",
726+
hir::UnOp::Deref => "std::ops::UnDerf",
727+
};
728+
suggest_impl_missing(&mut err, operand_ty, &missing_trait);
708729
}
709-
}
710-
Str | Never | Char | Tuple(_) | Array(_, _) => {}
711-
Ref(_, ref lty, _) if *lty.kind() == Str => {}
712-
_ => {
713-
let missing_trait = match op {
714-
hir::UnOp::Neg => "std::ops::Neg",
715-
hir::UnOp::Not => "std::ops::Not",
716-
hir::UnOp::Deref => "std::ops::UnDerf",
717-
};
718-
suggest_impl_missing(&mut err, operand_ty, &missing_trait);
719730
}
720731
}
721732
err.emit();

src/test/ui/parser/expr-as-stmt.fixed

+5
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,9 @@ fn moo(x: u32) -> bool {
3232
}) > 0 //~ ERROR expected expression
3333
}
3434

35+
fn qux() -> u32 {
36+
({2}) - 2 //~ ERROR cannot apply unary operator `-` to type `u32`
37+
//~^ ERROR mismatched types
38+
}
39+
3540
fn main() {}

src/test/ui/parser/expr-as-stmt.rs

+5
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,9 @@ fn moo(x: u32) -> bool {
3232
} > 0 //~ ERROR expected expression
3333
}
3434

35+
fn qux() -> u32 {
36+
{2} - 2 //~ ERROR cannot apply unary operator `-` to type `u32`
37+
//~^ ERROR mismatched types
38+
}
39+
3540
fn main() {}

src/test/ui/parser/expr-as-stmt.stderr

+24-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,29 @@ help: parentheses are required to parse this as an expression
9999
LL | ({ 3 }) * 3
100100
| + +
101101

102-
error: aborting due to 9 previous errors
102+
error[E0308]: mismatched types
103+
--> $DIR/expr-as-stmt.rs:36:6
104+
|
105+
LL | {2} - 2
106+
| ^ expected `()`, found integer
107+
|
108+
help: you might have meant to return this value
109+
|
110+
LL | {return 2;} - 2
111+
| ++++++ +
112+
113+
error[E0600]: cannot apply unary operator `-` to type `u32`
114+
--> $DIR/expr-as-stmt.rs:36:9
115+
|
116+
LL | {2} - 2
117+
| ^^^ cannot apply unary operator `-`
118+
|
119+
help: parentheses are required to parse this as an expression
120+
|
121+
LL | ({2}) - 2
122+
| + +
123+
124+
error: aborting due to 11 previous errors
103125

104-
Some errors have detailed explanations: E0308, E0614.
126+
Some errors have detailed explanations: E0308, E0600, E0614.
105127
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)