From bfb027a50da1cd398159f09a7ce0acbf87b33eac Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 16 Dec 2024 20:24:34 +0100 Subject: [PATCH 1/3] rustc_borrowck: suggest_ampmut(): Just rename some variables By making the variable names more descriptive it becomes easier to understand the code. Especially with the more complicated code in the next commit. --- .../src/diagnostics/mutability_errors.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 4fb7b22f2896e..ed249555ae4f4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1474,16 +1474,16 @@ fn suggest_ampmut<'tcx>( // let x: &i32 = &'a 5; // ^^ lifetime annotation not allowed // - if let Some(assignment_rhs_span) = opt_assignment_rhs_span - && let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) - && let Some(stripped) = src.strip_prefix('&') + if let Some(rhs_span) = opt_assignment_rhs_span + && let Ok(rhs_str) = tcx.sess.source_map().span_to_snippet(rhs_span) + && let Some(rhs_str_no_amp) = rhs_str.strip_prefix('&') { - let is_raw_ref = stripped.trim_start().starts_with("raw "); + let is_raw_ref = rhs_str_no_amp.trim_start().starts_with("raw "); // We don't support raw refs yet if is_raw_ref { return None; } - let is_mut = if let Some(rest) = stripped.trim_start().strip_prefix("mut") { + let is_mut = if let Some(rest) = rhs_str_no_amp.trim_start().strip_prefix("mut") { match rest.chars().next() { // e.g. `&mut x` Some(c) if c.is_whitespace() => true, @@ -1500,7 +1500,7 @@ fn suggest_ampmut<'tcx>( // if the reference is already mutable then there is nothing we can do // here. if !is_mut { - let span = assignment_rhs_span; + let span = rhs_span; // shrink the span to just after the `&` in `&variable` let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo(); From 47b559d00e8723b407dd44b0d1e004bd43bab8c8 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 16 Dec 2024 20:31:06 +0100 Subject: [PATCH 2/3] rustc_borrowck: suggest_ampmut(): Inline unneeded local var Since the previos commit renamed `assignment_rhs_span` to just `rhs_span` there is no need for a variable just to shorten the expression on the next line. Inline the variable. --- compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index ed249555ae4f4..73b76cd16d140 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1500,9 +1500,8 @@ fn suggest_ampmut<'tcx>( // if the reference is already mutable then there is nothing we can do // here. if !is_mut { - let span = rhs_span; // shrink the span to just after the `&` in `&variable` - let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo(); + let span = rhs_span.with_lo(rhs_span.lo() + BytePos(1)).shrink_to_lo(); // FIXME(Ezrashaw): returning is bad because we still might want to // update the annotated type, see #106857. From 70a0dc1f7e964e249c4bc7c08bfeb0e96ba5deb7 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 16 Dec 2024 20:39:31 +0100 Subject: [PATCH 3/3] rustc_borrowck: Suggest changing `&raw const` to `&raw mut` if applicable --- .../src/diagnostics/mutability_errors.rs | 19 +++++++++++++++---- ...estion-for-raw-pointer-issue-127562.stderr | 5 +++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 73b76cd16d140..4938875f7c46d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1478,11 +1478,22 @@ fn suggest_ampmut<'tcx>( && let Ok(rhs_str) = tcx.sess.source_map().span_to_snippet(rhs_span) && let Some(rhs_str_no_amp) = rhs_str.strip_prefix('&') { - let is_raw_ref = rhs_str_no_amp.trim_start().starts_with("raw "); - // We don't support raw refs yet - if is_raw_ref { - return None; + // Suggest changing `&raw const` to `&raw mut` if applicable. + if rhs_str_no_amp.trim_start().strip_prefix("raw const").is_some() { + let const_idx = rhs_str.find("const").unwrap() as u32; + let const_span = rhs_span + .with_lo(rhs_span.lo() + BytePos(const_idx)) + .with_hi(rhs_span.lo() + BytePos(const_idx + "const".len() as u32)); + + return Some(AmpMutSugg { + has_sugg: true, + span: const_span, + suggestion: "mut".to_owned(), + additional: None, + }); } + + // Figure out if rhs already is `&mut`. let is_mut = if let Some(rest) = rhs_str_no_amp.trim_start().strip_prefix("mut") { match rest.chars().next() { // e.g. `&mut x` diff --git a/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr b/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr index c27dcc19827d6..dbe834b6b78e1 100644 --- a/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr +++ b/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr @@ -3,6 +3,11 @@ error[E0594]: cannot assign to `*ptr`, which is behind a `*const` pointer | LL | unsafe { *ptr = 3; } | ^^^^^^^^ `ptr` is a `*const` pointer, so the data it refers to cannot be written + | +help: consider changing this to be a mutable pointer + | +LL | let ptr = &raw mut val; + | ~~~ error: aborting due to 1 previous error