mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Rollup merge of #155428 - lapla-cogito:issue_139089, r=mejrs
Fix ICE in borrowck mutability suggestion with multi-byte ref sigil Fixes rust-lang/rust#139089 Similarly to rust-lang/rust#155068, this is another instance where span arithmetic did not account for multi-byte characters. (Note that the ampersand in the test is full-width) This change also results in correcting some inappropriate suggestions.
This commit is contained in:
@@ -1410,9 +1410,20 @@ fn suggest_make_local_mut(&self, err: &mut Diag<'_>, local: Local, name: Symbol)
|
||||
(span, " mut".to_owned(), true)
|
||||
// If there is already a binding, we modify it to be `mut`.
|
||||
} else if binding_exists {
|
||||
// Shrink the span to just after the `&` in `&variable`.
|
||||
let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
|
||||
(span, "mut ".to_owned(), true)
|
||||
// Replace the sigil with the mutable version. We may be dealing
|
||||
// with parser recovery here and cannot assume the user actually
|
||||
// typed `&` or `*const`, so we compute the prefix from the snippet.
|
||||
let Ok(src) = self.infcx.tcx.sess.source_map().span_to_snippet(span) else {
|
||||
return;
|
||||
};
|
||||
let (prefix_len, replacement) = if local_decl.ty.is_ref() {
|
||||
(src.chars().next().map_or(0, char::len_utf8), "&mut ")
|
||||
} else {
|
||||
(src.find("const").map_or(1, |i| i + "const".len()), "*mut ")
|
||||
};
|
||||
let ws_len = src[prefix_len..].len() - src[prefix_len..].trim_start().len();
|
||||
let span = span.with_hi(span.lo() + BytePos((prefix_len + ws_len) as u32));
|
||||
(span, replacement.to_owned(), true)
|
||||
} else {
|
||||
// Otherwise, suggest that the user annotates the binding; We provide the
|
||||
// type of the local.
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
//@ known-bug: #139089
|
||||
pub fn foo3(x: &Vec<u8>) { x.push(0); }
|
||||
@@ -74,8 +74,9 @@ LL | *x = (1,);
|
||||
|
|
||||
help: consider changing this to be a mutable pointer
|
||||
|
|
||||
LL | unsafe fn named_ptr(x: *mut const (i32,)) {
|
||||
| +++
|
||||
LL - unsafe fn named_ptr(x: *const (i32,)) {
|
||||
LL + unsafe fn named_ptr(x: *mut (i32,)) {
|
||||
|
|
||||
|
||||
error[E0594]: cannot assign to `x.0`, which is behind a `*const` pointer
|
||||
--> $DIR/mutability-errors.rs:24:5
|
||||
@@ -85,8 +86,9 @@ LL | (*x).0 = 1;
|
||||
|
|
||||
help: consider changing this to be a mutable pointer
|
||||
|
|
||||
LL | unsafe fn named_ptr(x: *mut const (i32,)) {
|
||||
| +++
|
||||
LL - unsafe fn named_ptr(x: *const (i32,)) {
|
||||
LL + unsafe fn named_ptr(x: *mut (i32,)) {
|
||||
|
|
||||
|
||||
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
|
||||
--> $DIR/mutability-errors.rs:25:5
|
||||
@@ -96,8 +98,9 @@ LL | &mut *x;
|
||||
|
|
||||
help: consider changing this to be a mutable pointer
|
||||
|
|
||||
LL | unsafe fn named_ptr(x: *mut const (i32,)) {
|
||||
| +++
|
||||
LL - unsafe fn named_ptr(x: *const (i32,)) {
|
||||
LL + unsafe fn named_ptr(x: *mut (i32,)) {
|
||||
|
|
||||
|
||||
error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `*const` pointer
|
||||
--> $DIR/mutability-errors.rs:26:5
|
||||
@@ -107,8 +110,9 @@ LL | &mut (*x).0;
|
||||
|
|
||||
help: consider changing this to be a mutable pointer
|
||||
|
|
||||
LL | unsafe fn named_ptr(x: *mut const (i32,)) {
|
||||
| +++
|
||||
LL - unsafe fn named_ptr(x: *const (i32,)) {
|
||||
LL + unsafe fn named_ptr(x: *mut (i32,)) {
|
||||
|
|
||||
|
||||
error[E0594]: cannot assign to data in a `*const` pointer
|
||||
--> $DIR/mutability-errors.rs:30:5
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/139089
|
||||
|
||||
fn foo(x: &Vec<u8>) {
|
||||
//~^ ERROR unknown start of token
|
||||
x.push(0);
|
||||
//~^ ERROR cannot borrow `*x` as mutable
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,27 @@
|
||||
error: unknown start of token: \u{ff06}
|
||||
--> $DIR/mutability-suggestion-fullwidth-ampersand.rs:3:11
|
||||
|
|
||||
LL | fn foo(x: &Vec<u8>) {
|
||||
| ^^
|
||||
|
|
||||
help: Unicode character '&' (Fullwidth Ampersand) looks like '&' (Ampersand), but it is not
|
||||
|
|
||||
LL - fn foo(x: &Vec<u8>) {
|
||||
LL + fn foo(x: &Vec<u8>) {
|
||||
|
|
||||
|
||||
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
|
||||
--> $DIR/mutability-suggestion-fullwidth-ampersand.rs:5:5
|
||||
|
|
||||
LL | x.push(0);
|
||||
| ^ `x` is a `&` reference, so it cannot be borrowed as mutable
|
||||
|
|
||||
help: consider changing this to be a mutable reference
|
||||
|
|
||||
LL - fn foo(x: &Vec<u8>) {
|
||||
LL + fn foo(x: &mut Vec<u8>) {
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0596`.
|
||||
Reference in New Issue
Block a user