Suggest using ptr::null_mut when user supplied ptr::null to a function expecting ptr::null_mut

This commit is contained in:
许杰友 Jieyou Xu (Joe) 2023-06-05 15:17:49 +08:00
parent 8b35c0bb0f
commit 432ce39c8b
No known key found for this signature in database
GPG Key ID: C5FD5D32014FDB47
6 changed files with 86 additions and 0 deletions

View File

@ -87,6 +87,8 @@ hir_typeck_suggest_boxing_note = for more on the distinction between the stack a
hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new`
hir_typeck_suggest_ptr_null_mut = consider using `core::ptr::null_mut` instead
hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns
hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field

View File

@ -298,6 +298,17 @@ pub enum SuggestBoxing {
},
}
#[derive(Subdiagnostic)]
#[suggestion(
hir_typeck_suggest_ptr_null_mut,
applicability = "maybe-incorrect",
code = "core::ptr::null_mut()"
)]
pub struct SuggestPtrNullMut {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_no_associated_item, code = "E0599")]
pub struct NoAssociatedItem {

View File

@ -1,4 +1,5 @@
use crate::coercion::CoerceMany;
use crate::errors::SuggestPtrNullMut;
use crate::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx};
use crate::gather_locals::Declaration;
use crate::method::MethodCallee;
@ -814,6 +815,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}
self.suggest_ptr_null_mut(
expected_ty,
provided_ty,
provided_args[*provided_idx],
&mut err,
);
// Call out where the function is defined
self.label_fn_like(
&mut err,
@ -1271,6 +1279,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.emit();
}
fn suggest_ptr_null_mut(
&self,
expected_ty: Ty<'tcx>,
provided_ty: Ty<'tcx>,
arg: &hir::Expr<'tcx>,
err: &mut rustc_errors::DiagnosticBuilder<'tcx, ErrorGuaranteed>,
) {
if let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Mut, .. }) = expected_ty.kind()
&& let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Not, .. }) = provided_ty.kind()
&& let hir::ExprKind::Call(callee, _) = arg.kind
&& let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = callee.kind
&& let Res::Def(_, def_id) = path.res
&& self.tcx.get_diagnostic_item(sym::ptr_null) == Some(def_id)
{
// The user provided `ptr::null()`, but the function expects
// `ptr::null_mut()`.
err.subdiagnostic(SuggestPtrNullMut {
span: arg.span
});
}
}
// AST fragment checking
pub(in super::super) fn check_lit(
&self,

View File

@ -0,0 +1,11 @@
// run-rustfix
#[allow(unused_imports)]
use std::ptr;
fn expecting_null_mut(_: *mut u8) {}
fn main() {
expecting_null_mut(core::ptr::null_mut());
//~^ ERROR mismatched types
}

View File

@ -0,0 +1,11 @@
// run-rustfix
#[allow(unused_imports)]
use std::ptr;
fn expecting_null_mut(_: *mut u8) {}
fn main() {
expecting_null_mut(ptr::null());
//~^ ERROR mismatched types
}

View File

@ -0,0 +1,21 @@
error[E0308]: mismatched types
--> $DIR/ptr-null-mutability-suggestions.rs:9:24
|
LL | expecting_null_mut(ptr::null());
| ------------------ ^^^^^^^^^^^
| | |
| | types differ in mutability
| | help: consider using `core::ptr::null_mut` instead: `core::ptr::null_mut()`
| arguments to this function are incorrect
|
= note: expected raw pointer `*mut u8`
found raw pointer `*const _`
note: function defined here
--> $DIR/ptr-null-mutability-suggestions.rs:6:4
|
LL | fn expecting_null_mut(_: *mut u8) {}
| ^^^^^^^^^^^^^^^^^^ ----------
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.