rework ptr-to-ref conversion suggestion for method calls
This commit is contained in:
parent
277e61854e
commit
3a2a3ae0b3
@ -529,16 +529,44 @@ pub fn report_no_match_method_error(
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
if let ty::RawPtr(_, _) = &rcvr_ty.kind() {
|
||||
err.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",
|
||||
);
|
||||
err.note(
|
||||
"using `<*const T>::as_ref()` on a pointer which is unaligned or points \
|
||||
to invalid or uninitialized memory is undefined behavior",
|
||||
|
||||
// on pointers, check if the method would exist on a reference
|
||||
if let SelfSource::MethodCall(rcvr_expr) = source
|
||||
&& let ty::RawPtr(ty, ptr_mutbl) = *rcvr_ty.kind()
|
||||
&& let Ok(pick) = self.lookup_probe_for_diagnostic(
|
||||
item_name,
|
||||
Ty::new_ref(tcx, ty::Region::new_error_misc(tcx), ty, ptr_mutbl),
|
||||
self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)),
|
||||
ProbeScope::TraitsInScope,
|
||||
None,
|
||||
)
|
||||
&& let ty::Ref(_, _, sugg_mutbl) = *pick.self_ty.kind()
|
||||
&& (sugg_mutbl.is_not() || ptr_mutbl.is_mut())
|
||||
{
|
||||
let (method, method_anchor) = match sugg_mutbl {
|
||||
Mutability::Not => {
|
||||
let method_anchor = match ptr_mutbl {
|
||||
Mutability::Not => "as_ref",
|
||||
Mutability::Mut => "as_ref-1",
|
||||
};
|
||||
("as_ref", method_anchor)
|
||||
}
|
||||
Mutability::Mut => ("as_mut", "as_mut"),
|
||||
};
|
||||
err.span_note(
|
||||
tcx.def_span(pick.item.def_id),
|
||||
format!("the method `{item_name}` exists on the type `{ty}`", ty = pick.self_ty),
|
||||
);
|
||||
let mut_str = ptr_mutbl.ptr_str();
|
||||
err.note(format!(
|
||||
"you might want to use the unsafe method `<*{mut_str} T>::{method}` to get \
|
||||
an optional reference to the value behind the pointer"
|
||||
));
|
||||
err.note(format!(
|
||||
"read the documentation for `<*{mut_str} T>::{method}` and ensure you satisfy its \
|
||||
safety preconditions before calling it to avoid undefined behavior: \
|
||||
https://doc.rust-lang.org/std/primitive.pointer.html#method.{method_anchor}"
|
||||
));
|
||||
}
|
||||
|
||||
let mut ty_span = match rcvr_ty.kind() {
|
||||
|
@ -1,5 +1,17 @@
|
||||
fn main() {
|
||||
let x = 8u8;
|
||||
let mut x = 8u8;
|
||||
let z: *const u8 = &x;
|
||||
println!("{}", z.to_string()); //~ ERROR E0599
|
||||
// issue #21596
|
||||
println!("{}", z.to_string()); //~ ERROR E0599
|
||||
|
||||
let t: *mut u8 = &mut x;
|
||||
println!("{}", t.to_string()); //~ ERROR E0599
|
||||
t.make_ascii_lowercase(); //~ ERROR E0599
|
||||
|
||||
// suggest `as_mut` simply because the name is similar
|
||||
let _ = t.as_mut_ref(); //~ ERROR E0599
|
||||
let _ = t.as_ref_mut(); //~ ERROR E0599
|
||||
|
||||
// no ptr-to-ref suggestion
|
||||
z.make_ascii_lowercase(); //~ ERROR E0599
|
||||
}
|
||||
|
@ -1,15 +1,70 @@
|
||||
error[E0599]: `*const u8` doesn't implement `std::fmt::Display`
|
||||
--> $DIR/issue-21596.rs:4:22
|
||||
--> $DIR/suggest-convert-ptr-to-ref.rs:5:22
|
||||
|
|
||||
LL | println!("{}", z.to_string());
|
||||
| ^^^^^^^^^ `*const u8` cannot be formatted with the default formatter
|
||||
|
|
||||
= 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
|
||||
= note: using `<*const T>::as_ref()` on a pointer which is unaligned or points to invalid or uninitialized memory is undefined behavior
|
||||
note: the method `to_string` exists on the type `&u8`
|
||||
--> $SRC_DIR/alloc/src/string.rs:LL:COL
|
||||
= note: you might want to use the unsafe method `<*const T>::as_ref` to get an optional reference to the value behind the pointer
|
||||
= 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
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`*const u8: std::fmt::Display`
|
||||
which is required by `*const u8: ToString`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0599]: `*mut u8` doesn't implement `std::fmt::Display`
|
||||
--> $DIR/suggest-convert-ptr-to-ref.rs:8:22
|
||||
|
|
||||
LL | println!("{}", t.to_string());
|
||||
| ^^^^^^^^^ `*mut u8` cannot be formatted with the default formatter
|
||||
|
|
||||
note: the method `to_string` exists on the type `&&mut u8`
|
||||
--> $SRC_DIR/alloc/src/string.rs:LL:COL
|
||||
= note: you might want to use the unsafe method `<*mut T>::as_ref` to get an optional reference to the value behind the pointer
|
||||
= 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
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`*mut u8: std::fmt::Display`
|
||||
which is required by `*mut u8: ToString`
|
||||
|
||||
error[E0599]: no method named `make_ascii_lowercase` found for raw pointer `*mut u8` in the current scope
|
||||
--> $DIR/suggest-convert-ptr-to-ref.rs:9:7
|
||||
|
|
||||
LL | t.make_ascii_lowercase();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ method not found in `*mut u8`
|
||||
|
|
||||
note: the method `make_ascii_lowercase` exists on the type `&mut u8`
|
||||
--> $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
= note: you might want to use the unsafe method `<*mut T>::as_mut` to get an optional reference to the value behind the pointer
|
||||
= 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
|
||||
|
||||
error[E0599]: no method named `as_mut_ref` found for raw pointer `*mut u8` in the current scope
|
||||
--> $DIR/suggest-convert-ptr-to-ref.rs:12:15
|
||||
|
|
||||
LL | let _ = t.as_mut_ref();
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: there is a method `as_mut` with a similar name
|
||||
|
|
||||
LL | let _ = t.as_mut();
|
||||
| ~~~~~~
|
||||
|
||||
error[E0599]: no method named `as_ref_mut` found for raw pointer `*mut u8` in the current scope
|
||||
--> $DIR/suggest-convert-ptr-to-ref.rs:13:15
|
||||
|
|
||||
LL | let _ = t.as_ref_mut();
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: there is a method `as_mut` with a similar name
|
||||
|
|
||||
LL | let _ = t.as_mut();
|
||||
| ~~~~~~
|
||||
|
||||
error[E0599]: no method named `make_ascii_lowercase` found for raw pointer `*const u8` in the current scope
|
||||
--> $DIR/suggest-convert-ptr-to-ref.rs:16:7
|
||||
|
|
||||
LL | z.make_ascii_lowercase();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ method not found in `*const u8`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
||||
|
Loading…
Reference in New Issue
Block a user