about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs53
-rw-r--r--src/test/ui/typeck/issue-91210-ptr-method.stderr9
2 files changed, 28 insertions, 34 deletions
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index e20c6a2d99a..fc54eedcffe 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -50,7 +50,6 @@ use rustc_span::hygiene::DesugaringKind;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::source_map::{Span, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, Pos};
 use rustc_target::spec::abi::Abi::RustIntrinsic;
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCauseCode};
@@ -2391,37 +2390,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 expr,
                 Some(span),
             );
+        } else if let ty::RawPtr(ty_and_mut) = expr_t.kind()
+            && let ty::Adt(adt_def, _) = ty_and_mut.ty.kind()
+            && let ExprKind::Field(base_expr, _) = expr.kind
+            && adt_def.variants().len() == 1
+            && adt_def
+                .variants()
+                .iter()
+                .next()
+                .unwrap()
+                .fields
+                .iter()
+                .any(|f| f.ident(self.tcx) == field)
+        {
+            err.multipart_suggestion(
+                "to access the field, dereference first",
+                vec![
+                    (base_expr.span.shrink_to_lo(), "(*".to_string()),
+                    (base_expr.span.shrink_to_hi(), ")".to_string()),
+                ],
+                Applicability::MaybeIncorrect,
+            );
         } else {
-            let mut found = false;
-
-            if let ty::RawPtr(ty_and_mut) = expr_t.kind()
-                && 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(self.tcx) == 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.help("methods are immutable and cannot be assigned to");
         }
 
         err.emit();
diff --git a/src/test/ui/typeck/issue-91210-ptr-method.stderr b/src/test/ui/typeck/issue-91210-ptr-method.stderr
index 503a32373d5..7a0cfb2cf51 100644
--- a/src/test/ui/typeck/issue-91210-ptr-method.stderr
+++ b/src/test/ui/typeck/issue-91210-ptr-method.stderr
@@ -2,9 +2,12 @@ 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)`
+   |       ^^^^ method, not a field
+   |
+help: to access the field, dereference first
+   |
+LL |     (*x).read = 4;
+   |     ++ +
 
 error: aborting due to previous error