mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Rollup merge of #152834 - lapla-cogito:issue_152831, r=jackh726
Fix incorrect `let` to `const` suggestion for pattern bindings
When a variable from a pattern binding was referenced inside a `const {}` block, the compiler incorrectly suggested replacing `let` with `const`. This was reported in rust-lang/rust#152831 for `if let`, but also applies to `while let` and `let ... else`.
This commit is contained in:
@@ -979,23 +979,47 @@ pub(crate) fn into_struct_error(
|
||||
.source_map()
|
||||
.span_extend_to_prev_str(ident.span, current, true, false);
|
||||
|
||||
let ((with, with_label), without) = match sp {
|
||||
let (with, with_label, without) = match sp {
|
||||
Some(sp) if !self.tcx.sess.source_map().is_multiline(sp) => {
|
||||
let sp = sp
|
||||
.with_lo(BytePos(sp.lo().0 - (current.len() as u32)))
|
||||
.until(ident.span);
|
||||
(
|
||||
(Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion {
|
||||
span: sp,
|
||||
suggestion,
|
||||
current,
|
||||
type_span,
|
||||
}), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})),
|
||||
None,
|
||||
)
|
||||
|
||||
// Only suggest replacing the binding keyword if this is a simple
|
||||
// binding.
|
||||
//
|
||||
// Note: this approach still incorrectly suggests for irrefutable
|
||||
// patterns like `if let x = 1 { const { x } }`, since the text
|
||||
// between `let` and the identifier is just whitespace.
|
||||
// See tests/ui/consts/non-const-value-in-const-irrefutable-pat-binding.rs
|
||||
let is_simple_binding =
|
||||
self.tcx.sess.source_map().span_to_snippet(sp).is_ok_and(|snippet| {
|
||||
let after_keyword = snippet[current.len()..].trim();
|
||||
after_keyword.is_empty() || after_keyword == "mut"
|
||||
});
|
||||
|
||||
if is_simple_binding {
|
||||
(
|
||||
Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion {
|
||||
span: sp,
|
||||
suggestion,
|
||||
current,
|
||||
type_span,
|
||||
}),
|
||||
Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion { span }),
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
None,
|
||||
Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion { span }),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => (
|
||||
(None, None),
|
||||
None,
|
||||
None,
|
||||
Some(errs::AttemptToUseNonConstantValueInConstantWithoutSuggestion {
|
||||
ident_span: ident.span,
|
||||
suggestion,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Irrefutable `if let` pattern bindings still produce an incorrect suggestion
|
||||
// to replace `let` with `const`.
|
||||
// See https://github.com/rust-lang/rust/pull/152834#discussion_r3068766148
|
||||
|
||||
//@ known-bug: #152831
|
||||
|
||||
fn irrefutable_if_let_binding() {
|
||||
if let x = 1 {
|
||||
const { x }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,15 @@
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/non-const-value-in-const-irrefutable-pat-binding.rs:9:17
|
||||
|
|
||||
LL | const { x }
|
||||
| ^ non-constant value
|
||||
|
|
||||
help: consider using `const` instead of `let`
|
||||
|
|
||||
LL - if let x = 1 {
|
||||
LL + if const x: /* Type */ = 1 {
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0435`.
|
||||
@@ -0,0 +1,24 @@
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/152831
|
||||
|
||||
fn if_let_binding() {
|
||||
if let Some(v) = Some(1) {
|
||||
const { v }
|
||||
//~^ ERROR: attempt to use a non-constant value in a constant
|
||||
}
|
||||
}
|
||||
|
||||
fn while_let_binding() {
|
||||
while let Some(v) = Some(1) {
|
||||
const { v }
|
||||
//~^ ERROR: attempt to use a non-constant value in a constant
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fn let_else_binding() {
|
||||
let Some(v) = Some(1) else { return };
|
||||
const { v }
|
||||
//~^ ERROR: attempt to use a non-constant value in a constant
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,21 @@
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/non-const-value-in-const-pat-binding.rs:5:17
|
||||
|
|
||||
LL | const { v }
|
||||
| ^ non-constant value
|
||||
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/non-const-value-in-const-pat-binding.rs:12:17
|
||||
|
|
||||
LL | const { v }
|
||||
| ^ non-constant value
|
||||
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/non-const-value-in-const-pat-binding.rs:20:13
|
||||
|
|
||||
LL | const { v }
|
||||
| ^ non-constant value
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0435`.
|
||||
Reference in New Issue
Block a user