Skip to content

Commit 9082078

Browse files
committed
unsafety checking: no longer care about is_min_const_fn
Rejecting the forbidden unsafe ops is done by const checking, not by unsafety checking
1 parent 5da10c0 commit 9082078

File tree

2 files changed

+18
-53
lines changed

2 files changed

+18
-53
lines changed

compiler/rustc_middle/src/mir/query.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ use super::{Field, SourceInfo};
1919

2020
#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
2121
pub enum UnsafetyViolationKind {
22-
/// Only permitted in regular `fn`s, prohibited in `const fn`s.
22+
/// Unsafe operation outside `unsafe`
2323
General,
24-
/// Permitted both in `const fn`s and regular `fn`s.
25-
GeneralAndConstFn,
2624
/// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
2725
/// Has to be handled as a lint for backwards compatibility.
2826
UnsafeFn,

compiler/rustc_mir/src/transform/check_unsafety.rs

Lines changed: 17 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,10 @@ use rustc_session::lint::Level;
1515

1616
use std::ops::Bound;
1717

18-
use crate::const_eval::is_min_const_fn;
19-
2018
pub struct UnsafetyChecker<'a, 'tcx> {
2119
body: &'a Body<'tcx>,
2220
body_did: LocalDefId,
2321
const_context: bool,
24-
min_const_fn: bool,
2522
violations: Vec<UnsafetyViolation>,
2623
source_info: SourceInfo,
2724
tcx: TyCtxt<'tcx>,
@@ -34,21 +31,15 @@ pub struct UnsafetyChecker<'a, 'tcx> {
3431
impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
3532
fn new(
3633
const_context: bool,
37-
min_const_fn: bool,
3834
body: &'a Body<'tcx>,
3935
body_did: LocalDefId,
4036
tcx: TyCtxt<'tcx>,
4137
param_env: ty::ParamEnv<'tcx>,
4238
) -> Self {
43-
// sanity check
44-
if min_const_fn {
45-
assert!(const_context);
46-
}
4739
Self {
4840
body,
4941
body_did,
5042
const_context,
51-
min_const_fn,
5243
violations: vec![],
5344
source_info: SourceInfo::outermost(body.span),
5445
tcx,
@@ -84,7 +75,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
8475
let sig = func_ty.fn_sig(self.tcx);
8576
if let hir::Unsafety::Unsafe = sig.unsafety() {
8677
self.require_unsafe(
87-
UnsafetyViolationKind::GeneralAndConstFn,
78+
UnsafetyViolationKind::General,
8879
UnsafetyViolationDetails::CallToUnsafeFunction,
8980
)
9081
}
@@ -134,7 +125,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
134125
match self.tcx.layout_scalar_valid_range(def.did) {
135126
(Bound::Unbounded, Bound::Unbounded) => {}
136127
_ => self.require_unsafe(
137-
UnsafetyViolationKind::GeneralAndConstFn,
128+
UnsafetyViolationKind::General,
138129
UnsafetyViolationDetails::InitializingTypeWith,
139130
),
140131
}
@@ -213,7 +204,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
213204
let base_ty = base.ty(self.body, self.tcx).ty;
214205
if base_ty.is_unsafe_ptr() {
215206
self.require_unsafe(
216-
UnsafetyViolationKind::GeneralAndConstFn,
207+
UnsafetyViolationKind::General,
217208
UnsafetyViolationDetails::DerefOfRawPointer,
218209
)
219210
}
@@ -258,15 +249,15 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
258249
);
259250
if !nodrop {
260251
self.require_unsafe(
261-
UnsafetyViolationKind::GeneralAndConstFn,
252+
UnsafetyViolationKind::General,
262253
UnsafetyViolationDetails::AssignToDroppingUnionField,
263254
);
264255
} else {
265256
// write to non-drop union field, safe
266257
}
267258
} else {
268259
self.require_unsafe(
269-
UnsafetyViolationKind::GeneralAndConstFn,
260+
UnsafetyViolationKind::General,
270261
UnsafetyViolationDetails::AccessToUnionField,
271262
)
272263
}
@@ -277,6 +268,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
277268

278269
impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
279270
fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViolationDetails) {
271+
// Violations can turn out to be `UnsafeFn` during analysis, but they should not start out as such.
272+
assert_ne!(kind, UnsafetyViolationKind::UnsafeFn);
273+
280274
let source_info = self.source_info;
281275
let lint_root = self.body.source_scopes[self.source_info.scope]
282276
.local_data
@@ -304,8 +298,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
304298
Safety::Safe => {
305299
for violation in violations {
306300
match violation.kind {
307-
UnsafetyViolationKind::GeneralAndConstFn
308-
| UnsafetyViolationKind::General => {}
301+
UnsafetyViolationKind::General => {}
309302
UnsafetyViolationKind::UnsafeFn => {
310303
bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context")
311304
}
@@ -334,29 +327,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
334327
if !violations.is_empty() {
335328
self.used_unsafe.insert(hir_id);
336329
}
337-
// only some unsafety is allowed in const fn
338-
if self.min_const_fn {
339-
for violation in violations {
340-
match violation.kind {
341-
// these unsafe things are stable in const fn
342-
UnsafetyViolationKind::GeneralAndConstFn => {}
343-
// these things are forbidden in const fns
344-
UnsafetyViolationKind::General => {
345-
let mut violation = *violation;
346-
// const fns don't need to be backwards compatible and can
347-
// emit these violations as a hard error instead of a backwards
348-
// compat lint
349-
violation.kind = UnsafetyViolationKind::General;
350-
if !self.violations.contains(&violation) {
351-
self.violations.push(violation)
352-
}
353-
}
354-
UnsafetyViolationKind::UnsafeFn => bug!(
355-
"`UnsafetyViolationKind::UnsafeFn` in an `ExplicitUnsafe` context"
356-
),
357-
}
358-
}
359-
}
360330
true
361331
}
362332
};
@@ -394,7 +364,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
394364
} else {
395365
continue;
396366
};
397-
self.require_unsafe(UnsafetyViolationKind::GeneralAndConstFn, details);
367+
self.require_unsafe(UnsafetyViolationKind::General, details);
398368
}
399369
}
400370
}
@@ -412,7 +382,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
412382
// Is `callee_features` a subset of `calling_features`?
413383
if !callee_features.iter().all(|feature| self_features.contains(feature)) {
414384
self.require_unsafe(
415-
UnsafetyViolationKind::GeneralAndConstFn,
385+
UnsafetyViolationKind::General,
416386
UnsafetyViolationDetails::CallToFunctionWith,
417387
)
418388
}
@@ -494,15 +464,12 @@ fn unsafety_check_result<'tcx>(
494464
let param_env = tcx.param_env(def.did);
495465

496466
let id = tcx.hir().local_def_id_to_hir_id(def.did);
497-
let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) {
498-
hir::BodyOwnerKind::Closure => (false, false),
499-
hir::BodyOwnerKind::Fn => {
500-
(tcx.is_const_fn_raw(def.did.to_def_id()), is_min_const_fn(tcx, def.did.to_def_id()))
501-
}
502-
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false),
467+
let const_context = match tcx.hir().body_owner_kind(id) {
468+
hir::BodyOwnerKind::Closure => false,
469+
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def.did.to_def_id()),
470+
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
503471
};
504-
let mut checker =
505-
UnsafetyChecker::new(const_context, min_const_fn, body, def.did, tcx, param_env);
472+
let mut checker = UnsafetyChecker::new(const_context, body, def.did, tcx, param_env);
506473
checker.visit_body(&body);
507474

508475
check_unused_unsafe(tcx, def.did, &checker.used_unsafe, &mut checker.inherited_blocks);
@@ -577,7 +544,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
577544
if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" };
578545

579546
match kind {
580-
UnsafetyViolationKind::GeneralAndConstFn | UnsafetyViolationKind::General => {
547+
UnsafetyViolationKind::General => {
581548
// once
582549
struct_span_err!(
583550
tcx.sess,

0 commit comments

Comments
 (0)