Skip to content

Commit 7483211

Browse files
authored
Rollup merge of #91364 - FabianWolff:issue-91210-ptr-field, r=oli-obk
Improve error message for incorrect field accesses through raw pointers Fixes #91210.
2 parents fd6e66f + 821b92b commit 7483211

File tree

4 files changed

+72
-1
lines changed

4 files changed

+72
-1
lines changed

compiler/rustc_typeck/src/check/expr.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use rustc_span::hygiene::DesugaringKind;
4646
use rustc_span::lev_distance::find_best_match_for_name;
4747
use rustc_span::source_map::Span;
4848
use rustc_span::symbol::{kw, sym, Ident, Symbol};
49+
use rustc_span::{BytePos, Pos};
4950
use rustc_trait_selection::traits::{self, ObligationCauseCode};
5051

5152
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -2063,7 +2064,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20632064
Some(span),
20642065
);
20652066
} else {
2066-
err.help("methods are immutable and cannot be assigned to");
2067+
let mut found = false;
2068+
2069+
if let ty::RawPtr(ty_and_mut) = expr_t.kind() {
2070+
if let ty::Adt(adt_def, _) = ty_and_mut.ty.kind() {
2071+
if adt_def.variants.len() == 1
2072+
&& adt_def
2073+
.variants
2074+
.iter()
2075+
.next()
2076+
.unwrap()
2077+
.fields
2078+
.iter()
2079+
.any(|f| f.ident == field)
2080+
{
2081+
if let Some(dot_loc) = expr_snippet.rfind('.') {
2082+
found = true;
2083+
err.span_suggestion(
2084+
expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)),
2085+
"to access the field, dereference first",
2086+
format!("(*{})", &expr_snippet[0..dot_loc]),
2087+
Applicability::MaybeIncorrect,
2088+
);
2089+
}
2090+
}
2091+
}
2092+
}
2093+
2094+
if !found {
2095+
err.help("methods are immutable and cannot be assigned to");
2096+
}
20672097
}
20682098

20692099
err.emit();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Regression test for issue #91210.
2+
3+
// run-rustfix
4+
5+
#![allow(unused)]
6+
7+
struct Foo { read: i32 }
8+
9+
unsafe fn blah(x: *mut Foo) {
10+
(*x).read = 4;
11+
//~^ ERROR: attempted to take value of method
12+
//~| HELP: to access the field, dereference first
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Regression test for issue #91210.
2+
3+
// run-rustfix
4+
5+
#![allow(unused)]
6+
7+
struct Foo { read: i32 }
8+
9+
unsafe fn blah(x: *mut Foo) {
10+
x.read = 4;
11+
//~^ ERROR: attempted to take value of method
12+
//~| HELP: to access the field, dereference first
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0615]: attempted to take value of method `read` on type `*mut Foo`
2+
--> $DIR/issue-91210-ptr-method.rs:10:7
3+
|
4+
LL | x.read = 4;
5+
| - ^^^^ method, not a field
6+
| |
7+
| help: to access the field, dereference first: `(*x)`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0615`.

0 commit comments

Comments
 (0)