mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-28 20:16:58 +03:00
Suggest naming types before using explicit type names
`missing_transmute_annotations` will suggest naming the origin and destination types if they do not have explicit names already. Co-authored-by: Alejandra González <blyxyas@gmail.com>
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::{HasSession, SpanRangeExt as _};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{GenericArg, HirId, LetStmt, Node, Path, TyKind};
|
||||
use rustc_hir::{Expr, GenericArg, HirId, LetStmt, Node, Path, TyKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;
|
||||
|
||||
@@ -38,6 +42,7 @@ fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool {
|
||||
pub(super) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
path: &Path<'tcx>,
|
||||
arg: &Expr<'tcx>,
|
||||
from_ty: Ty<'tcx>,
|
||||
to_ty: Ty<'tcx>,
|
||||
expr_hir_id: HirId,
|
||||
@@ -68,14 +73,48 @@ pub(super) fn check<'tcx>(
|
||||
} else if is_function_block(cx, expr_hir_id) {
|
||||
return false;
|
||||
}
|
||||
span_lint_and_sugg(
|
||||
let span = last.ident.span.with_hi(path.span.hi());
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
MISSING_TRANSMUTE_ANNOTATIONS,
|
||||
last.ident.span.with_hi(path.span.hi()),
|
||||
span,
|
||||
"transmute used without annotations",
|
||||
"consider adding missing annotations",
|
||||
format!("{}::<{from_ty}, {to_ty}>", last.ident),
|
||||
Applicability::MaybeIncorrect,
|
||||
|diag| {
|
||||
let from_ty_no_name = ty_cannot_be_named(from_ty);
|
||||
let to_ty_no_name = ty_cannot_be_named(to_ty);
|
||||
if from_ty_no_name || to_ty_no_name {
|
||||
let to_name = match (from_ty_no_name, to_ty_no_name) {
|
||||
(true, false) => maybe_name_by_expr(cx, arg.span, "the origin type"),
|
||||
(false, true) => "the destination type".into(),
|
||||
_ => "the source and destination types".into(),
|
||||
};
|
||||
diag.help(format!(
|
||||
"consider giving {to_name} a name, and adding missing type annotations"
|
||||
));
|
||||
} else {
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
"consider adding missing annotations",
|
||||
format!("{}::<{from_ty}, {to_ty}>", last.ident),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
true
|
||||
}
|
||||
|
||||
fn ty_cannot_be_named(ty: Ty<'_>) -> bool {
|
||||
matches!(
|
||||
ty.kind(),
|
||||
ty::Alias(ty::AliasTyKind::Opaque | ty::AliasTyKind::Inherent, _)
|
||||
)
|
||||
}
|
||||
|
||||
fn maybe_name_by_expr<'a>(sess: &impl HasSession, span: Span, default: &'a str) -> Cow<'a, str> {
|
||||
span.with_source_text(sess, |name| {
|
||||
(name.len() + 9 < default.len()).then_some(format!("`{name}`'s type").into())
|
||||
})
|
||||
.flatten()
|
||||
.unwrap_or(default.into())
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
|
||||
| transmuting_null::check(cx, e, arg, to_ty)
|
||||
| transmute_null_to_fn::check(cx, e, arg, to_ty)
|
||||
| transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, self.msrv)
|
||||
| missing_transmute_annotations::check(cx, path, from_ty, to_ty, e.hir_id)
|
||||
| missing_transmute_annotations::check(cx, path, arg, from_ty, to_ty, e.hir_id)
|
||||
| transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
|
||||
| transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, self.msrv)
|
||||
| transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//@no-rustfix
|
||||
|
||||
fn issue14984() {
|
||||
async fn e() {}
|
||||
async fn x() -> u32 {
|
||||
0
|
||||
}
|
||||
async fn y() -> f32 {
|
||||
0.0
|
||||
};
|
||||
let mut yy = unsafe { std::ptr::read(&y()) };
|
||||
yy = unsafe { std::mem::transmute(std::ptr::read(&x())) };
|
||||
//~^ missing_transmute_annotations
|
||||
|
||||
let mut zz = 0u8;
|
||||
zz = unsafe { std::mem::transmute(std::ptr::read(&x())) };
|
||||
//~^ missing_transmute_annotations
|
||||
|
||||
yy = unsafe { std::mem::transmute(zz) };
|
||||
//~^ missing_transmute_annotations
|
||||
|
||||
fn a() -> impl Sized {
|
||||
0u32
|
||||
}
|
||||
|
||||
let mut b: f32 = 0.0;
|
||||
b = unsafe { std::mem::transmute(a()) };
|
||||
//~^ missing_transmute_annotations
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
error: transmute used without annotations
|
||||
--> tests/ui/missing_transmute_annotations_unfixable.rs:12:29
|
||||
|
|
||||
LL | yy = unsafe { std::mem::transmute(std::ptr::read(&x())) };
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: consider giving the source and destination types a name, and adding missing type annotations
|
||||
= note: `-D clippy::missing-transmute-annotations` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]`
|
||||
|
||||
error: transmute used without annotations
|
||||
--> tests/ui/missing_transmute_annotations_unfixable.rs:16:29
|
||||
|
|
||||
LL | zz = unsafe { std::mem::transmute(std::ptr::read(&x())) };
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: consider giving the origin type a name, and adding missing type annotations
|
||||
|
||||
error: transmute used without annotations
|
||||
--> tests/ui/missing_transmute_annotations_unfixable.rs:19:29
|
||||
|
|
||||
LL | yy = unsafe { std::mem::transmute(zz) };
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: consider giving the destination type a name, and adding missing type annotations
|
||||
|
||||
error: transmute used without annotations
|
||||
--> tests/ui/missing_transmute_annotations_unfixable.rs:27:28
|
||||
|
|
||||
LL | b = unsafe { std::mem::transmute(a()) };
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: consider giving `a()`'s type a name, and adding missing type annotations
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Reference in New Issue
Block a user