Skip to content

Commit a5e7da0

Browse files
committed
Tweak raw-pointer field access and array indexing suggestions
1 parent 8ea1066 commit a5e7da0

File tree

5 files changed

+58
-40
lines changed

5 files changed

+58
-40
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+26-18
Original file line numberDiff line numberDiff line change
@@ -2551,10 +2551,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25512551

25522552
match *base_ty.peel_refs().kind() {
25532553
ty::Array(_, len) => {
2554-
self.maybe_suggest_array_indexing(&mut err, expr, base, ident, len);
2554+
self.maybe_suggest_array_indexing(&mut err, base, ident, len);
25552555
}
25562556
ty::RawPtr(..) => {
2557-
self.suggest_first_deref_field(&mut err, expr, base, ident);
2557+
self.suggest_first_deref_field(&mut err, base, ident);
25582558
}
25592559
ty::Param(param_ty) => {
25602560
err.span_label(ident.span, "unknown field");
@@ -2721,40 +2721,48 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27212721
fn maybe_suggest_array_indexing(
27222722
&self,
27232723
err: &mut Diag<'_>,
2724-
expr: &hir::Expr<'_>,
27252724
base: &hir::Expr<'_>,
27262725
field: Ident,
27272726
len: ty::Const<'tcx>,
27282727
) {
27292728
err.span_label(field.span, "unknown field");
27302729
if let (Some(len), Ok(user_index)) =
27312730
(len.try_eval_target_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
2732-
&& let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
27332731
{
27342732
let help = "instead of using tuple indexing, use array indexing";
2735-
let suggestion = format!("{base}[{field}]");
27362733
let applicability = if len < user_index {
27372734
Applicability::MachineApplicable
27382735
} else {
27392736
Applicability::MaybeIncorrect
27402737
};
2741-
err.span_suggestion(expr.span, help, suggestion, applicability);
2738+
err.multipart_suggestion(
2739+
help,
2740+
vec![
2741+
(base.span.between(field.span), "[".to_string()),
2742+
(field.span.shrink_to_hi(), "]".to_string()),
2743+
],
2744+
applicability,
2745+
);
27422746
}
27432747
}
27442748

2745-
fn suggest_first_deref_field(
2746-
&self,
2747-
err: &mut Diag<'_>,
2748-
expr: &hir::Expr<'_>,
2749-
base: &hir::Expr<'_>,
2750-
field: Ident,
2751-
) {
2749+
fn suggest_first_deref_field(&self, err: &mut Diag<'_>, base: &hir::Expr<'_>, field: Ident) {
27522750
err.span_label(field.span, "unknown field");
2753-
if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
2754-
let msg = format!("`{base}` is a raw pointer; try dereferencing it");
2755-
let suggestion = format!("(*{base}).{field}");
2756-
err.span_suggestion(expr.span, msg, suggestion, Applicability::MaybeIncorrect);
2757-
}
2751+
let val = if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
2752+
&& base.len() < 20
2753+
{
2754+
format!("`{base}`")
2755+
} else {
2756+
"the value".to_string()
2757+
};
2758+
err.multipart_suggestion(
2759+
format!("{val} is a raw pointer; try dereferencing it"),
2760+
vec![
2761+
(base.span.shrink_to_lo(), "(*".to_string()),
2762+
(base.span.shrink_to_hi(), ")".to_string()),
2763+
],
2764+
Applicability::MaybeIncorrect,
2765+
);
27582766
}
27592767

27602768
fn no_such_field_err(&self, field: Ident, expr_t: Ty<'tcx>, id: HirId) -> Diag<'_> {

tests/ui/issues/issue-11004.stderr

+12-8
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,23 @@ error[E0609]: no field `x` on type `*mut A`
22
--> $DIR/issue-11004.rs:7:21
33
|
44
LL | let x : i32 = n.x;
5-
| --^
6-
| | |
7-
| | unknown field
8-
| help: `n` is a raw pointer; try dereferencing it: `(*n).x`
5+
| ^ unknown field
6+
|
7+
help: `n` is a raw pointer; try dereferencing it
8+
|
9+
LL | let x : i32 = (*n).x;
10+
| ++ +
911

1012
error[E0609]: no field `y` on type `*mut A`
1113
--> $DIR/issue-11004.rs:8:21
1214
|
1315
LL | let y : f64 = n.y;
14-
| --^
15-
| | |
16-
| | unknown field
17-
| help: `n` is a raw pointer; try dereferencing it: `(*n).y`
16+
| ^ unknown field
17+
|
18+
help: `n` is a raw pointer; try dereferencing it
19+
|
20+
LL | let y : f64 = (*n).y;
21+
| ++ +
1822

1923
error: aborting due to 2 previous errors
2024

tests/ui/suggestions/parenthesized-deref-suggestion.stderr

+8-6
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@ error[E0609]: no field `opts` on type `*const Session`
44
LL | (sess as *const Session).opts;
55
| ^^^^ unknown field
66
|
7-
help: `(sess as *const Session)` is a raw pointer; try dereferencing it
7+
help: the value is a raw pointer; try dereferencing it
88
|
99
LL | (*(sess as *const Session)).opts;
10-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10+
| ++ +
1111

1212
error[E0609]: no field `0` on type `[u32; 1]`
1313
--> $DIR/parenthesized-deref-suggestion.rs:10:21
1414
|
1515
LL | (x as [u32; 1]).0;
16-
| ----------------^
17-
| | |
18-
| | unknown field
19-
| help: instead of using tuple indexing, use array indexing: `(x as [u32; 1])[0]`
16+
| ^ unknown field
17+
|
18+
help: instead of using tuple indexing, use array indexing
19+
|
20+
LL | (x as [u32; 1])[0];
21+
| ~ +
2022

2123
error: aborting due to 2 previous errors
2224

tests/ui/typeck/issue-53712.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0609]: no field `0` on type `[{integer}; 5]`
22
--> $DIR/issue-53712.rs:5:9
33
|
44
LL | arr.0;
5-
| ----^
6-
| | |
7-
| | unknown field
8-
| help: instead of using tuple indexing, use array indexing: `arr[0]`
5+
| ^ unknown field
6+
|
7+
help: instead of using tuple indexing, use array indexing
8+
|
9+
LL | arr[0];
10+
| ~ +
911

1012
error: aborting due to 1 previous error
1113

tests/ui/unsafe/unsafe-fn-autoderef.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0609]: no field `f` on type `*const Rec`
22
--> $DIR/unsafe-fn-autoderef.rs:19:14
33
|
44
LL | return p.f;
5-
| --^
6-
| | |
7-
| | unknown field
8-
| help: `p` is a raw pointer; try dereferencing it: `(*p).f`
5+
| ^ unknown field
6+
|
7+
help: `p` is a raw pointer; try dereferencing it
8+
|
9+
LL | return (*p).f;
10+
| ++ +
911

1012
error: aborting due to 1 previous error
1113

0 commit comments

Comments
 (0)