Skip to content

Commit 6dfdea9

Browse files
Make the THIR unsafeck use the thir_body query
1 parent 6f64eb1 commit 6dfdea9

File tree

5 files changed

+53
-54
lines changed

5 files changed

+53
-54
lines changed

compiler/rustc_mir_build/src/build/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
4646
let body_owner_kind = tcx.hir().body_owner_kind(id);
4747
let typeck_results = tcx.typeck_opt_const_arg(def);
4848

49+
if tcx.sess.opts.debugging_opts.thir_unsafeck {
50+
// Ensure unsafeck is ran before we steal the THIR.
51+
match def {
52+
ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => {
53+
tcx.ensure().thir_check_unsafety_for_const_arg((did, const_param_did))
54+
}
55+
ty::WithOptConstParam { did, const_param_did: None } => {
56+
tcx.ensure().thir_check_unsafety(did)
57+
}
58+
}
59+
}
60+
4961
// Figure out what primary body this item has.
5062
let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) {
5163
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. }) => {

compiler/rustc_mir_build/src/check_unsafety.rs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::thir::visit::{self, Visitor};
2-
use crate::thir::*;
32

43
use rustc_errors::struct_span_err;
54
use rustc_hir as hir;
5+
use rustc_middle::thir::*;
66
use rustc_middle::ty::{self, TyCtxt};
77
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
88
use rustc_session::lint::Level;
@@ -328,26 +328,23 @@ impl UnsafeOpKind {
328328

329329
// FIXME: checking unsafety for closures should be handled by their parent body,
330330
// as they inherit their "safety context" from their declaration site.
331-
pub fn check_unsafety<'tcx>(
332-
tcx: TyCtxt<'tcx>,
333-
thir: &Thir<'tcx>,
334-
expr: ExprId,
335-
def_id: LocalDefId,
336-
hir_id: hir::HirId,
337-
) {
331+
pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) {
332+
let (thir, expr) = tcx.thir_body(def);
333+
let thir = &thir.borrow();
334+
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
338335
let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| {
339336
if fn_sig.header.unsafety == hir::Unsafety::Unsafe {
340337
BodyUnsafety::Unsafe(fn_sig.span)
341338
} else {
342339
BodyUnsafety::Safe
343340
}
344341
});
345-
let body_target_features = &tcx.codegen_fn_attrs(def_id).target_features;
342+
let body_target_features = &tcx.codegen_fn_attrs(def.did).target_features;
346343
let safety_context =
347344
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
348345
let is_const = match tcx.hir().body_owner_kind(hir_id) {
349346
hir::BodyOwnerKind::Closure => false,
350-
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def_id.to_def_id()),
347+
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def.did.to_def_id()),
351348
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
352349
};
353350
let mut visitor = UnsafetyVisitor {
@@ -362,28 +359,17 @@ pub fn check_unsafety<'tcx>(
362359
visitor.visit_expr(&thir[expr]);
363360
}
364361

365-
crate fn thir_check_unsafety_inner<'tcx>(
366-
tcx: TyCtxt<'tcx>,
367-
def: ty::WithOptConstParam<LocalDefId>,
368-
) {
369-
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
370-
let body_id = tcx.hir().body_owned_by(hir_id);
371-
let body = tcx.hir().body(body_id);
372-
let (thir, expr) = cx::build_thir(tcx, def, &body.value);
373-
check_unsafety(tcx, &thir, expr, def.did, hir_id);
374-
}
375-
376362
crate fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
377363
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
378364
tcx.thir_check_unsafety_for_const_arg(def)
379365
} else {
380-
thir_check_unsafety_inner(tcx, ty::WithOptConstParam::unknown(def_id))
366+
check_unsafety(tcx, ty::WithOptConstParam::unknown(def_id))
381367
}
382368
}
383369

384370
crate fn thir_check_unsafety_for_const_arg<'tcx>(
385371
tcx: TyCtxt<'tcx>,
386372
(did, param_did): (LocalDefId, DefId),
387373
) {
388-
thir_check_unsafety_inner(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
374+
check_unsafety(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
389375
}

compiler/rustc_mir_build/src/thir/visit.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::thir::*;
1+
use rustc_middle::thir::*;
2+
use rustc_middle::ty::Const;
23

34
pub trait Visitor<'a, 'tcx: 'a>: Sized {
45
fn thir(&self) -> &'a Thir<'tcx>;

src/test/ui/feature-gates/feature-gate-const_fn_transmute.thir.stderr

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ LL | const unsafe fn unsafe_transmute_fn_core_intrinsic() -> u32 { core::intrins
5858
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
5959
= note: `transmute` is only allowed in constants and statics for now
6060

61+
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
62+
--> $DIR/feature-gate-const_fn_transmute.rs:29:39
63+
|
64+
LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
65+
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
66+
|
67+
= note: consult the function's documentation for information on how to avoid undefined behavior
68+
6169
error[E0658]: `transmute` is not allowed in constant functions
6270
--> $DIR/feature-gate-const_fn_transmute.rs:29:39
6371
|
@@ -68,49 +76,41 @@ LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
6876
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
6977
= note: `transmute` is only allowed in constants and statics for now
7078

71-
error[E0658]: `transmute` is not allowed in constant functions
79+
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
7280
--> $DIR/feature-gate-const_fn_transmute.rs:33:49
7381
|
7482
LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
75-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
83+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
7684
|
77-
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
78-
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
79-
= note: `transmute` is only allowed in constants and statics for now
85+
= note: consult the function's documentation for information on how to avoid undefined behavior
8086

8187
error[E0658]: `transmute` is not allowed in constant functions
82-
--> $DIR/feature-gate-const_fn_transmute.rs:37:54
88+
--> $DIR/feature-gate-const_fn_transmute.rs:33:49
8389
|
84-
LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
85-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90+
LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
91+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8692
|
8793
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
8894
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
8995
= note: `transmute` is only allowed in constants and statics for now
9096

9197
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
92-
--> $DIR/feature-gate-const_fn_transmute.rs:29:39
93-
|
94-
LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
95-
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
96-
|
97-
= note: consult the function's documentation for information on how to avoid undefined behavior
98-
99-
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
100-
--> $DIR/feature-gate-const_fn_transmute.rs:33:49
98+
--> $DIR/feature-gate-const_fn_transmute.rs:37:54
10199
|
102-
LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
103-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
100+
LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
101+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
104102
|
105103
= note: consult the function's documentation for information on how to avoid undefined behavior
106104

107-
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
105+
error[E0658]: `transmute` is not allowed in constant functions
108106
--> $DIR/feature-gate-const_fn_transmute.rs:37:54
109107
|
110108
LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
111-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
109+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
112110
|
113-
= note: consult the function's documentation for information on how to avoid undefined behavior
111+
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
112+
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
113+
= note: `transmute` is only allowed in constants and statics for now
114114

115115
error: aborting due to 12 previous errors
116116

src/test/ui/issues/issue-16538.thir.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
error[E0133]: use of extern static is unsafe and requires unsafe function or block
2+
--> $DIR/issue-16538.rs:14:34
3+
|
4+
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
5+
| ^^^^ use of extern static
6+
|
7+
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
8+
19
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
210
--> $DIR/issue-16538.rs:14:27
311
|
@@ -13,14 +21,6 @@ LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
1321
= help: the trait `Sync` is not implemented for `*const usize`
1422
= note: shared static variables must have a type that implements `Sync`
1523

16-
error[E0133]: use of extern static is unsafe and requires unsafe function or block
17-
--> $DIR/issue-16538.rs:14:34
18-
|
19-
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
20-
| ^^^^ use of extern static
21-
|
22-
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
23-
2424
error: aborting due to 3 previous errors
2525

2626
Some errors have detailed explanations: E0015, E0133, E0277.

0 commit comments

Comments
 (0)