Migrate 'lossy ptr2int cast' diagnostic
This commit is contained in:
parent
de68911f4a
commit
bf693d1743
3 changed files with 77 additions and 42 deletions
|
|
@ -69,6 +69,11 @@ hir_typeck_lang_start_incorrect_param = parameter {$param_num} of the `start` la
|
|||
hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang item is incorrect
|
||||
.suggestion = change the type from `{$found_ty}` to `{$expected_ty}`
|
||||
|
||||
hir_typeck_lossy_provenance_ptr2int =
|
||||
under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}`
|
||||
.suggestion = use `.addr()` to obtain the address of a pointer
|
||||
.help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
|
||||
|
||||
hir_typeck_method_call_on_unknown_raw_pointee =
|
||||
cannot call a method on a raw pointer with an unknown pointee type
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
use super::FnCtxt;
|
||||
|
||||
use crate::errors;
|
||||
use crate::type_error_struct;
|
||||
use hir::ExprKind;
|
||||
use rustc_errors::{
|
||||
|
|
@ -1007,50 +1008,35 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
}
|
||||
|
||||
fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
|
||||
fcx.tcx.struct_span_lint_hir(
|
||||
let expr_prec = self.expr.precedence().order();
|
||||
let needs_parens = expr_prec < rustc_ast::util::parser::PREC_POSTFIX;
|
||||
|
||||
let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
|
||||
let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span);
|
||||
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
|
||||
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
|
||||
let expr_span = self.expr_span.shrink_to_lo();
|
||||
let sugg = match (needs_parens, needs_cast) {
|
||||
(true, true) => errors::LossyProvenancePtr2IntSuggestion::NeedsParensCast {
|
||||
expr_span,
|
||||
cast_span,
|
||||
cast_ty,
|
||||
},
|
||||
(true, false) => {
|
||||
errors::LossyProvenancePtr2IntSuggestion::NeedsParens { expr_span, cast_span }
|
||||
}
|
||||
(false, true) => {
|
||||
errors::LossyProvenancePtr2IntSuggestion::NeedsCast { cast_span, cast_ty }
|
||||
}
|
||||
(false, false) => errors::LossyProvenancePtr2IntSuggestion::Other { cast_span },
|
||||
};
|
||||
|
||||
let lint = errors::LossyProvenancePtr2Int { expr_ty, cast_ty, sugg };
|
||||
fcx.tcx.emit_spanned_lint(
|
||||
lint::builtin::LOSSY_PROVENANCE_CASTS,
|
||||
self.expr.hir_id,
|
||||
self.span,
|
||||
DelayDm(|| format!(
|
||||
"under strict provenance it is considered bad style to cast pointer `{}` to integer `{}`",
|
||||
self.expr_ty, self.cast_ty
|
||||
)),
|
||||
|lint| {
|
||||
let msg = "use `.addr()` to obtain the address of a pointer";
|
||||
|
||||
let expr_prec = self.expr.precedence().order();
|
||||
let needs_parens = expr_prec < rustc_ast::util::parser::PREC_POSTFIX;
|
||||
|
||||
let scalar_cast = match t_c {
|
||||
ty::cast::IntTy::U(ty::UintTy::Usize) => String::new(),
|
||||
_ => format!(" as {}", self.cast_ty),
|
||||
};
|
||||
|
||||
let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span);
|
||||
|
||||
if needs_parens {
|
||||
let suggestions = vec![
|
||||
(self.expr_span.shrink_to_lo(), String::from("(")),
|
||||
(cast_span, format!(").addr(){scalar_cast}")),
|
||||
];
|
||||
|
||||
lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
|
||||
} else {
|
||||
lint.span_suggestion(
|
||||
cast_span,
|
||||
msg,
|
||||
format!(".addr(){scalar_cast}"),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
|
||||
lint.help(
|
||||
"if you can't comply with strict provenance and need to expose the pointer \
|
||||
provenance you can use `.expose_addr()` instead"
|
||||
);
|
||||
|
||||
lint
|
||||
},
|
||||
lint,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use rustc_errors::{
|
|||
AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg, MultiSpan,
|
||||
SubdiagnosticMessage,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::{
|
||||
edition::{Edition, LATEST_STABLE_EDITION},
|
||||
|
|
@ -269,6 +269,50 @@ pub struct LangStartIncorrectRetTy<'tcx> {
|
|||
pub found_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(hir_typeck_lossy_provenance_ptr2int)]
|
||||
#[help]
|
||||
pub struct LossyProvenancePtr2Int<'tcx> {
|
||||
pub expr_ty: Ty<'tcx>,
|
||||
pub cast_ty: Ty<'tcx>,
|
||||
#[subdiagnostic]
|
||||
pub sugg: LossyProvenancePtr2IntSuggestion<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum LossyProvenancePtr2IntSuggestion<'tcx> {
|
||||
#[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
|
||||
NeedsParensCast {
|
||||
#[suggestion_part(code = "(")]
|
||||
expr_span: Span,
|
||||
#[suggestion_part(code = ").addr() as {cast_ty}")]
|
||||
cast_span: Span,
|
||||
cast_ty: Ty<'tcx>,
|
||||
},
|
||||
#[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
|
||||
NeedsParens {
|
||||
#[suggestion_part(code = "(")]
|
||||
expr_span: Span,
|
||||
#[suggestion_part(code = ").addr()")]
|
||||
cast_span: Span,
|
||||
},
|
||||
#[suggestion(
|
||||
hir_typeck_suggestion,
|
||||
code = ".addr() as {cast_ty}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
NeedsCast {
|
||||
#[primary_span]
|
||||
cast_span: Span,
|
||||
cast_ty: Ty<'tcx>,
|
||||
},
|
||||
#[suggestion(hir_typeck_suggestion, code = ".addr()", applicability = "maybe-incorrect")]
|
||||
Other {
|
||||
#[primary_span]
|
||||
cast_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum HelpUseLatestEdition {
|
||||
#[help(hir_typeck_help_set_edition_cargo)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue