Skip to content

Commit

Permalink
Rollup merge of #91364 - FabianWolff:issue-91210-ptr-field, r=oli-obk
Browse files Browse the repository at this point in the history
Improve error message for incorrect field accesses through raw pointers

Fixes #91210.
  • Loading branch information
matthiaskrgr authored Dec 2, 2021
2 parents fd6e66f + 821b92b commit 7483211
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 1 deletion.
32 changes: 31 additions & 1 deletion compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use rustc_span::hygiene::DesugaringKind;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::Span;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Pos};
use rustc_trait_selection::traits::{self, ObligationCauseCode};

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -2063,7 +2064,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(span),
);
} else {
err.help("methods are immutable and cannot be assigned to");
let mut found = false;

if let ty::RawPtr(ty_and_mut) = expr_t.kind() {
if let ty::Adt(adt_def, _) = ty_and_mut.ty.kind() {
if adt_def.variants.len() == 1
&& adt_def
.variants
.iter()
.next()
.unwrap()
.fields
.iter()
.any(|f| f.ident == field)
{
if let Some(dot_loc) = expr_snippet.rfind('.') {
found = true;
err.span_suggestion(
expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)),
"to access the field, dereference first",
format!("(*{})", &expr_snippet[0..dot_loc]),
Applicability::MaybeIncorrect,
);
}
}
}
}

if !found {
err.help("methods are immutable and cannot be assigned to");
}
}

err.emit();
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/typeck/issue-91210-ptr-method.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Regression test for issue #91210.

// run-rustfix

#![allow(unused)]

struct Foo { read: i32 }

unsafe fn blah(x: *mut Foo) {
(*x).read = 4;
//~^ ERROR: attempted to take value of method
//~| HELP: to access the field, dereference first
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/typeck/issue-91210-ptr-method.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Regression test for issue #91210.

// run-rustfix

#![allow(unused)]

struct Foo { read: i32 }

unsafe fn blah(x: *mut Foo) {
x.read = 4;
//~^ ERROR: attempted to take value of method
//~| HELP: to access the field, dereference first
}

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/typeck/issue-91210-ptr-method.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0615]: attempted to take value of method `read` on type `*mut Foo`
--> $DIR/issue-91210-ptr-method.rs:10:7
|
LL | x.read = 4;
| - ^^^^ method, not a field
| |
| help: to access the field, dereference first: `(*x)`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0615`.

0 comments on commit 7483211

Please sign in to comment.