Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b5e7a1c

Browse files
committed
rework ptr-to-ref conversion suggestion for method calls
1 parent 9250906 commit b5e7a1c

File tree

3 files changed

+103
-15
lines changed

3 files changed

+103
-15
lines changed

‎compiler/rustc_hir_typeck/src/method/suggest.rs‎

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -530,16 +530,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
530530
Applicability::MachineApplicable,
531531
);
532532
}
533-
if let ty::RawPtr(_, _) = &rcvr_ty.kind() {
534-
err.note(
535-
"try using `<*const T>::as_ref()` to get a reference to the \
536-
type behind the pointer: https://doc.rust-lang.org/std/\
537-
primitive.pointer.html#method.as_ref",
538-
);
539-
err.note(
540-
"using `<*const T>::as_ref()` on a pointer which is unaligned or points \
541-
to invalid or uninitialized memory is undefined behavior",
533+
534+
// on pointers, check if the method would exist on a reference
535+
if let SelfSource::MethodCall(rcvr_expr) = source
536+
&& let ty::RawPtr(ty, ptr_mutbl) = *rcvr_ty.kind()
537+
&& let Ok(pick) = self.lookup_probe_for_diagnostic(
538+
item_name,
539+
Ty::new_ref(tcx, ty::Region::new_error_misc(tcx), ty, ptr_mutbl),
540+
self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)),
541+
ProbeScope::TraitsInScope,
542+
None,
543+
)
544+
&& let ty::Ref(_, _, sugg_mutbl) = *pick.self_ty.kind()
545+
&& (sugg_mutbl.is_not() || ptr_mutbl.is_mut())
546+
{
547+
let (method, method_anchor) = match sugg_mutbl {
548+
Mutability::Not => {
549+
let method_anchor = match ptr_mutbl {
550+
Mutability::Not => "as_ref",
551+
Mutability::Mut => "as_ref-1",
552+
};
553+
("as_ref", method_anchor)
554+
}
555+
Mutability::Mut => ("as_mut", "as_mut"),
556+
};
557+
err.span_note(
558+
tcx.def_span(pick.item.def_id),
559+
format!("the method `{item_name}` exists on the type `{ty}`", ty = pick.self_ty),
542560
);
561+
err.note(format!(
562+
"try using the unsafe method `<*{mut_str} T>::{method}` to get \
563+
an optional reference to the value behind the pointer: \
564+
https://doc.rust-lang.org/std/primitive.pointer.html#method.{method_anchor}",
565+
mut_str = ptr_mutbl.ptr_str()
566+
));
543567
}
544568

545569
let mut ty_span = match rcvr_ty.kind() {
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
fn main() {
2-
let x = 8u8;
2+
let mutx = 8u8;
33
let z: *const u8 = &x;
4-
println!("{}", z.to_string()); //~ ERROR E0599
4+
// issue #21596
5+
println!("{}", z.to_string()); //~ ERROR E0599
6+
7+
let t: *mut u8 = &mut x;
8+
println!("{}", t.to_string()); //~ ERROR E0599
9+
t.make_ascii_lowercase(); //~ ERROR E0599
10+
11+
// suggest `as_mut` simply because the name is similar
12+
let _ = t.as_mut_ref(); //~ ERROR E0599
13+
let _ = t.as_ref_mut(); //~ ERROR E0599
14+
15+
// no ptr-to-ref suggestion
16+
z.make_ascii_lowercase(); //~ ERROR E0599
517
}
Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,67 @@
11
error[E0599]: `*const u8` doesn't implement `std::fmt::Display`
2-
--> $DIR/issue-21596.rs:4:22
2+
--> $DIR/suggest-convert-ptr-to-ref.rs:5:22
33
|
44
LL | println!("{}", z.to_string());
55
| ^^^^^^^^^ `*const u8` cannot be formatted with the default formatter
66
|
7-
= note: try using `<*const T>::as_ref()` to get a reference to the type behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
8-
= note: using `<*const T>::as_ref()` on a pointer which is unaligned or points to invalid or uninitialized memory is undefined behavior
7+
note: the method `to_string` exists on the type `&u8`
8+
--> $SRC_DIR/alloc/src/string.rs:LL:COL
9+
= note: try using the unsafe method `<*const T>::as_ref` to get an optional reference to the value behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
910
= note: the following trait bounds were not satisfied:
1011
`*const u8: std::fmt::Display`
1112
which is required by `*const u8: ToString`
1213

13-
error: aborting due to 1 previous error
14+
error[E0599]: `*mut u8` doesn't implement `std::fmt::Display`
15+
--> $DIR/suggest-convert-ptr-to-ref.rs:8:22
16+
|
17+
LL | println!("{}", t.to_string());
18+
| ^^^^^^^^^ `*mut u8` cannot be formatted with the default formatter
19+
|
20+
note: the method `to_string` exists on the type `&&mut u8`
21+
--> $SRC_DIR/alloc/src/string.rs:LL:COL
22+
= note: try using the unsafe method `<*mut T>::as_ref` to get an optional reference to the value behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref-1
23+
= note: the following trait bounds were not satisfied:
24+
`*mut u8: std::fmt::Display`
25+
which is required by `*mut u8: ToString`
26+
27+
error[E0599]: no method named `make_ascii_lowercase` found for raw pointer `*mut u8` in the current scope
28+
--> $DIR/suggest-convert-ptr-to-ref.rs:9:7
29+
|
30+
LL | t.make_ascii_lowercase();
31+
| ^^^^^^^^^^^^^^^^^^^^ method not found in `*mut u8`
32+
|
33+
note: the method `make_ascii_lowercase` exists on the type `&mut u8`
34+
--> $SRC_DIR/core/src/num/mod.rs:LL:COL
35+
= note: try using the unsafe method `<*mut T>::as_mut` to get an optional reference to the value behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_mut
36+
37+
error[E0599]: no method named `as_mut_ref` found for raw pointer `*mut u8` in the current scope
38+
--> $DIR/suggest-convert-ptr-to-ref.rs:12:15
39+
|
40+
LL | let _ = t.as_mut_ref();
41+
| ^^^^^^^^^^
42+
|
43+
help: there is a method `as_mut` with a similar name
44+
|
45+
LL | let _ = t.as_mut();
46+
| ~~~~~~
47+
48+
error[E0599]: no method named `as_ref_mut` found for raw pointer `*mut u8` in the current scope
49+
--> $DIR/suggest-convert-ptr-to-ref.rs:13:15
50+
|
51+
LL | let _ = t.as_ref_mut();
52+
| ^^^^^^^^^^
53+
|
54+
help: there is a method `as_mut` with a similar name
55+
|
56+
LL | let _ = t.as_mut();
57+
| ~~~~~~
58+
59+
error[E0599]: no method named `make_ascii_lowercase` found for raw pointer `*const u8` in the current scope
60+
--> $DIR/suggest-convert-ptr-to-ref.rs:16:7
61+
|
62+
LL | z.make_ascii_lowercase();
63+
| ^^^^^^^^^^^^^^^^^^^^ method not found in `*const u8`
64+
65+
error: aborting due to 6 previous errors
1466

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

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /