|
30 | 30 |
|
31 | 31 | use super::FnCtxt;
|
32 | 32 |
|
| 33 | +use crate::errors; |
33 | 34 | use crate::type_error_struct;
|
34 | 35 | use hir::ExprKind;
|
35 | 36 | use rustc_errors::{
|
@@ -1007,50 +1008,35 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
1007 | 1008 | }
|
1008 | 1009 |
|
1009 | 1010 | fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
|
1010 |
| - fcx.tcx.struct_span_lint_hir( |
| 1011 | + let expr_prec = self.expr.precedence().order(); |
| 1012 | + let needs_parens = expr_prec < rustc_ast::util::parser::PREC_POSTFIX; |
| 1013 | + |
| 1014 | + let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize)); |
| 1015 | + let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span); |
| 1016 | + let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); |
| 1017 | + let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); |
| 1018 | + let expr_span = self.expr_span.shrink_to_lo(); |
| 1019 | + let sugg = match (needs_parens, needs_cast) { |
| 1020 | + (true, true) => errors::LossyProvenancePtr2IntSuggestion::NeedsParensCast { |
| 1021 | + expr_span, |
| 1022 | + cast_span, |
| 1023 | + cast_ty, |
| 1024 | + }, |
| 1025 | + (true, false) => { |
| 1026 | + errors::LossyProvenancePtr2IntSuggestion::NeedsParens { expr_span, cast_span } |
| 1027 | + } |
| 1028 | + (false, true) => { |
| 1029 | + errors::LossyProvenancePtr2IntSuggestion::NeedsCast { cast_span, cast_ty } |
| 1030 | + } |
| 1031 | + (false, false) => errors::LossyProvenancePtr2IntSuggestion::Other { cast_span }, |
| 1032 | + }; |
| 1033 | + |
| 1034 | + let lint = errors::LossyProvenancePtr2Int { expr_ty, cast_ty, sugg }; |
| 1035 | + fcx.tcx.emit_spanned_lint( |
1011 | 1036 | lint::builtin::LOSSY_PROVENANCE_CASTS,
|
1012 | 1037 | self.expr.hir_id,
|
1013 | 1038 | self.span,
|
1014 |
| - DelayDm(|| format!( |
1015 |
| - "under strict provenance it is considered bad style to cast pointer `{}` to integer `{}`", |
1016 |
| - self.expr_ty, self.cast_ty |
1017 |
| - )), |
1018 |
| - |lint| { |
1019 |
| - let msg = "use `.addr()` to obtain the address of a pointer"; |
1020 |
| - |
1021 |
| - let expr_prec = self.expr.precedence().order(); |
1022 |
| - let needs_parens = expr_prec < rustc_ast::util::parser::PREC_POSTFIX; |
1023 |
| - |
1024 |
| - let scalar_cast = match t_c { |
1025 |
| - ty::cast::IntTy::U(ty::UintTy::Usize) => String::new(), |
1026 |
| - _ => format!(" as {}", self.cast_ty), |
1027 |
| - }; |
1028 |
| - |
1029 |
| - let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span); |
1030 |
| - |
1031 |
| - if needs_parens { |
1032 |
| - let suggestions = vec![ |
1033 |
| - (self.expr_span.shrink_to_lo(), String::from("(")), |
1034 |
| - (cast_span, format!(").addr(){scalar_cast}")), |
1035 |
| - ]; |
1036 |
| - |
1037 |
| - lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); |
1038 |
| - } else { |
1039 |
| - lint.span_suggestion( |
1040 |
| - cast_span, |
1041 |
| - msg, |
1042 |
| - format!(".addr(){scalar_cast}"), |
1043 |
| - Applicability::MaybeIncorrect, |
1044 |
| - ); |
1045 |
| - } |
1046 |
| - |
1047 |
| - lint.help( |
1048 |
| - "if you can't comply with strict provenance and need to expose the pointer \ |
1049 |
| - provenance you can use `.expose_addr()` instead" |
1050 |
| - ); |
1051 |
| - |
1052 |
| - lint |
1053 |
| - }, |
| 1039 | + lint, |
1054 | 1040 | );
|
1055 | 1041 | }
|
1056 | 1042 |
|
|
0 commit comments