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 0d20a84

Browse files
committed
rework ptr-to-ref conversion suggestion for method calls
1 parent 4aecfa9 commit 0d20a84

File tree

3 files changed

+110
-15
lines changed

3 files changed

+110
-15
lines changed

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

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

544572
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: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,70 @@
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: you might want to use the unsafe method `<*const T>::as_ref` to get an optional reference to the value behind the pointer
10+
= note: read the documentation for `<*const T>::as_ref` and ensure you satisfy its safety preconditions before calling it to avoid undefined behavior: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
911
= note: the following trait bounds were not satisfied:
1012
`*const u8: std::fmt::Display`
1113
which is required by `*const u8: ToString`
1214

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

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

0 commit comments

Comments
(0)

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