Skip to content

Commit ccac0d9

Browse files
committed
Suppress garbled suggestions from strict provenance lints in macros
1 parent 54333ff commit ccac0d9

4 files changed

Lines changed: 122 additions & 25 deletions

File tree

compiler/rustc_hir_typeck/src/cast.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,28 +1134,30 @@ impl<'a, 'tcx> CastCheck<'tcx> {
11341134
}
11351135

11361136
fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
1137-
let expr_prec = fcx.precedence(self.expr);
1138-
let needs_parens = expr_prec < ExprPrecedence::Unambiguous;
1139-
1140-
let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
1141-
let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span);
11421137
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
11431138
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
1144-
let expr_span = self.expr_span.shrink_to_lo();
1145-
let sugg = match (needs_parens, needs_cast) {
1146-
(true, true) => errors::LossyProvenancePtr2IntSuggestion::NeedsParensCast {
1147-
expr_span,
1148-
cast_span,
1149-
cast_ty,
1150-
},
1151-
(true, false) => {
1152-
errors::LossyProvenancePtr2IntSuggestion::NeedsParens { expr_span, cast_span }
1153-
}
1154-
(false, true) => {
1155-
errors::LossyProvenancePtr2IntSuggestion::NeedsCast { cast_span, cast_ty }
1139+
1140+
let sugg = self.span.can_be_used_for_suggestions().then(|| {
1141+
let expr_prec = fcx.precedence(self.expr);
1142+
let needs_parens = expr_prec < ExprPrecedence::Unambiguous;
1143+
let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
1144+
let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span);
1145+
let expr_span = self.expr_span.shrink_to_lo();
1146+
match (needs_parens, needs_cast) {
1147+
(true, true) => errors::LossyProvenancePtr2IntSuggestion::NeedsParensCast {
1148+
expr_span,
1149+
cast_span,
1150+
cast_ty,
1151+
},
1152+
(true, false) => {
1153+
errors::LossyProvenancePtr2IntSuggestion::NeedsParens { expr_span, cast_span }
1154+
}
1155+
(false, true) => {
1156+
errors::LossyProvenancePtr2IntSuggestion::NeedsCast { cast_span, cast_ty }
1157+
}
1158+
(false, false) => errors::LossyProvenancePtr2IntSuggestion::Other { cast_span },
11561159
}
1157-
(false, false) => errors::LossyProvenancePtr2IntSuggestion::Other { cast_span },
1158-
};
1160+
});
11591161

11601162
let lint = errors::LossyProvenancePtr2Int { expr_ty, cast_ty, sugg };
11611163
fcx.tcx.emit_node_span_lint(
@@ -1167,10 +1169,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
11671169
}
11681170

11691171
fn fuzzy_provenance_int2ptr_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
1170-
let sugg = errors::LossyProvenanceInt2PtrSuggestion {
1171-
lo: self.expr_span.shrink_to_lo(),
1172-
hi: self.expr_span.shrink_to_hi().to(self.cast_span),
1173-
};
1172+
let sugg = self.span.can_be_used_for_suggestions().then(|| {
1173+
errors::LossyProvenanceInt2PtrSuggestion {
1174+
lo: self.expr_span.shrink_to_lo(),
1175+
hi: self.expr_span.shrink_to_hi().to(self.cast_span),
1176+
}
1177+
});
11741178
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
11751179
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
11761180
let lint = errors::LossyProvenanceInt2Ptr { expr_ty, cast_ty, sugg };

compiler/rustc_hir_typeck/src/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ pub(crate) struct LossyProvenanceInt2Ptr<'tcx> {
386386
pub expr_ty: Ty<'tcx>,
387387
pub cast_ty: Ty<'tcx>,
388388
#[subdiagnostic]
389-
pub sugg: LossyProvenanceInt2PtrSuggestion,
389+
pub sugg: Option<LossyProvenanceInt2PtrSuggestion>,
390390
}
391391

392392
#[derive(Diagnostic)]
@@ -427,7 +427,7 @@ pub(crate) struct LossyProvenancePtr2Int<'tcx> {
427427
pub expr_ty: Ty<'tcx>,
428428
pub cast_ty: Ty<'tcx>,
429429
#[subdiagnostic]
430-
pub sugg: LossyProvenancePtr2IntSuggestion<'tcx>,
430+
pub sugg: Option<LossyProvenancePtr2IntSuggestion<'tcx>>,
431431
}
432432

433433
#[derive(Subdiagnostic)]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#![feature(strict_provenance_lints)]
2+
#![deny(lossy_provenance_casts)]
3+
#![deny(fuzzy_provenance_casts)]
4+
5+
macro_rules! cast {
6+
($e:expr, $t:ty) => {
7+
$e as $t
8+
//~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
9+
//~| ERROR strict provenance disallows casting integer `usize` to pointer `*const u8`
10+
};
11+
}
12+
13+
macro_rules! p2i {
14+
($e:expr) => { $e as usize };
15+
//~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
16+
}
17+
18+
macro_rules! i2p {
19+
($e:expr) => { $e as *const () };
20+
//~^ ERROR strict provenance disallows casting integer `usize` to pointer `*const ()`
21+
}
22+
23+
fn main() {
24+
let ptr = &0u8 as *const u8;
25+
let _addr = cast!(ptr, usize);
26+
27+
let _ptr = cast!(0usize, *const u8);
28+
29+
let x = 1u8;
30+
p2i!(&raw const x);
31+
32+
i2p!(0x42);
33+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
2+
--> $DIR/lint-strict-provenance-macro-casts.rs:7:9
3+
|
4+
LL | $e as $t
5+
| ^^^^^^^^
6+
...
7+
LL | let _addr = cast!(ptr, usize);
8+
| ----------------- in this macro invocation
9+
|
10+
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
11+
note: the lint level is defined here
12+
--> $DIR/lint-strict-provenance-macro-casts.rs:2:9
13+
|
14+
LL | #![deny(lossy_provenance_casts)]
15+
| ^^^^^^^^^^^^^^^^^^^^^^
16+
= note: this error originates in the macro `cast` (in Nightly builds, run with -Z macro-backtrace for more info)
17+
18+
error: strict provenance disallows casting integer `usize` to pointer `*const u8`
19+
--> $DIR/lint-strict-provenance-macro-casts.rs:7:9
20+
|
21+
LL | $e as $t
22+
| ^^^^^^^^
23+
...
24+
LL | let _ptr = cast!(0usize, *const u8);
25+
| ------------------------ in this macro invocation
26+
|
27+
= help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
28+
note: the lint level is defined here
29+
--> $DIR/lint-strict-provenance-macro-casts.rs:3:9
30+
|
31+
LL | #![deny(fuzzy_provenance_casts)]
32+
| ^^^^^^^^^^^^^^^^^^^^^^
33+
= note: this error originates in the macro `cast` (in Nightly builds, run with -Z macro-backtrace for more info)
34+
35+
error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
36+
--> $DIR/lint-strict-provenance-macro-casts.rs:14:20
37+
|
38+
LL | ($e:expr) => { $e as usize };
39+
| ^^^^^^^^^^^
40+
...
41+
LL | p2i!(&raw const x);
42+
| ------------------ in this macro invocation
43+
|
44+
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
45+
= note: this error originates in the macro `p2i` (in Nightly builds, run with -Z macro-backtrace for more info)
46+
47+
error: strict provenance disallows casting integer `usize` to pointer `*const ()`
48+
--> $DIR/lint-strict-provenance-macro-casts.rs:19:20
49+
|
50+
LL | ($e:expr) => { $e as *const () };
51+
| ^^^^^^^^^^^^^^^
52+
...
53+
LL | i2p!(0x42);
54+
| ---------- in this macro invocation
55+
|
56+
= help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
57+
= note: this error originates in the macro `i2p` (in Nightly builds, run with -Z macro-backtrace for more info)
58+
59+
error: aborting due to 4 previous errors
60+

0 commit comments

Comments
 (0)