Tweak raw-pointer field access and array indexing suggestions

This commit is contained in:
Esteban Küber 2024-07-04 00:24:10 +00:00
parent 8ea1066fe6
commit a5e7da0cf6
5 changed files with 58 additions and 40 deletions

View File

@ -2551,10 +2551,10 @@ fn ban_nonexisting_field(
match *base_ty.peel_refs().kind() {
ty::Array(_, len) => {
self.maybe_suggest_array_indexing(&mut err, expr, base, ident, len);
self.maybe_suggest_array_indexing(&mut err, base, ident, len);
}
ty::RawPtr(..) => {
self.suggest_first_deref_field(&mut err, expr, base, ident);
self.suggest_first_deref_field(&mut err, base, ident);
}
ty::Param(param_ty) => {
err.span_label(ident.span, "unknown field");
@ -2721,7 +2721,6 @@ fn point_at_param_definition(&self, err: &mut Diag<'_>, param: ty::ParamTy) {
fn maybe_suggest_array_indexing(
&self,
err: &mut Diag<'_>,
expr: &hir::Expr<'_>,
base: &hir::Expr<'_>,
field: Ident,
len: ty::Const<'tcx>,
@ -2729,32 +2728,41 @@ fn maybe_suggest_array_indexing(
err.span_label(field.span, "unknown field");
if let (Some(len), Ok(user_index)) =
(len.try_eval_target_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
&& let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
{
let help = "instead of using tuple indexing, use array indexing";
let suggestion = format!("{base}[{field}]");
let applicability = if len < user_index {
Applicability::MachineApplicable
} else {
Applicability::MaybeIncorrect
};
err.span_suggestion(expr.span, help, suggestion, applicability);
err.multipart_suggestion(
help,
vec![
(base.span.between(field.span), "[".to_string()),
(field.span.shrink_to_hi(), "]".to_string()),
],
applicability,
);
}
}
fn suggest_first_deref_field(
&self,
err: &mut Diag<'_>,
expr: &hir::Expr<'_>,
base: &hir::Expr<'_>,
field: Ident,
) {
fn suggest_first_deref_field(&self, err: &mut Diag<'_>, base: &hir::Expr<'_>, field: Ident) {
err.span_label(field.span, "unknown field");
if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
let msg = format!("`{base}` is a raw pointer; try dereferencing it");
let suggestion = format!("(*{base}).{field}");
err.span_suggestion(expr.span, msg, suggestion, Applicability::MaybeIncorrect);
}
let val = if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
&& base.len() < 20
{
format!("`{base}`")
} else {
"the value".to_string()
};
err.multipart_suggestion(
format!("{val} is a raw pointer; try dereferencing it"),
vec![
(base.span.shrink_to_lo(), "(*".to_string()),
(base.span.shrink_to_hi(), ")".to_string()),
],
Applicability::MaybeIncorrect,
);
}
fn no_such_field_err(&self, field: Ident, expr_t: Ty<'tcx>, id: HirId) -> Diag<'_> {

View File

@ -2,19 +2,23 @@ error[E0609]: no field `x` on type `*mut A`
--> $DIR/issue-11004.rs:7:21
|
LL | let x : i32 = n.x;
| --^
| | |
| | unknown field
| help: `n` is a raw pointer; try dereferencing it: `(*n).x`
| ^ unknown field
|
help: `n` is a raw pointer; try dereferencing it
|
LL | let x : i32 = (*n).x;
| ++ +
error[E0609]: no field `y` on type `*mut A`
--> $DIR/issue-11004.rs:8:21
|
LL | let y : f64 = n.y;
| --^
| | |
| | unknown field
| help: `n` is a raw pointer; try dereferencing it: `(*n).y`
| ^ unknown field
|
help: `n` is a raw pointer; try dereferencing it
|
LL | let y : f64 = (*n).y;
| ++ +
error: aborting due to 2 previous errors

View File

@ -4,19 +4,21 @@ error[E0609]: no field `opts` on type `*const Session`
LL | (sess as *const Session).opts;
| ^^^^ unknown field
|
help: `(sess as *const Session)` is a raw pointer; try dereferencing it
help: the value is a raw pointer; try dereferencing it
|
LL | (*(sess as *const Session)).opts;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ++ +
error[E0609]: no field `0` on type `[u32; 1]`
--> $DIR/parenthesized-deref-suggestion.rs:10:21
|
LL | (x as [u32; 1]).0;
| ----------------^
| | |
| | unknown field
| help: instead of using tuple indexing, use array indexing: `(x as [u32; 1])[0]`
| ^ unknown field
|
help: instead of using tuple indexing, use array indexing
|
LL | (x as [u32; 1])[0];
| ~ +
error: aborting due to 2 previous errors

View File

@ -2,10 +2,12 @@ error[E0609]: no field `0` on type `[{integer}; 5]`
--> $DIR/issue-53712.rs:5:9
|
LL | arr.0;
| ----^
| | |
| | unknown field
| help: instead of using tuple indexing, use array indexing: `arr[0]`
| ^ unknown field
|
help: instead of using tuple indexing, use array indexing
|
LL | arr[0];
| ~ +
error: aborting due to 1 previous error

View File

@ -2,10 +2,12 @@ error[E0609]: no field `f` on type `*const Rec`
--> $DIR/unsafe-fn-autoderef.rs:19:14
|
LL | return p.f;
| --^
| | |
| | unknown field
| help: `p` is a raw pointer; try dereferencing it: `(*p).f`
| ^ unknown field
|
help: `p` is a raw pointer; try dereferencing it
|
LL | return (*p).f;
| ++ +
error: aborting due to 1 previous error