_ => None,
};
- // FIXME: safety in closures
let safety = match fn_sig.unsafety {
hir::Unsafety::Normal => Safety::Safe,
+ hir::Unsafety::Unsafe if tcx.is_min_const_fn(fn_def_id) => {
+ // As specified in #55607, a `const unsafe fn` differs
+ // from an `unsafe fn` in that its body is still considered
+ // safe code by default.
+ assert!(!implicit_argument.is_none());
+ Safety::Safe
+ },
hir::Unsafety::Unsafe => Safety::FnUnsafe,
};
- let safety = match fn_sig.unsafety {
- hir::Unsafety::Normal => Safety::Safe,
- hir::Unsafety::Unsafe => {
- if tcx.is_min_const_fn(fn_def_id) => {
- // As specified in #55607, a `const unsafe fn` differs
- // from an `unsafe fn` in that its body is still considered
- // safe code by default.
- assert!(!implicit_argument.is_none());
- Safety::Safe
- } else {
- Safety::Unsafe
- }
- }
- };
-
let body = tcx.hir.body(body_id);
let explicit_arguments =
body.arguments
}
// only some unsafety is allowed in const fn
if self.min_const_fn {
+ let min_const_unsafe_fn = self.tcx.features().min_const_unsafe_fn;
for violation in violations {
match violation.kind {
- // these are allowed
- UnsafetyViolationKind::GatedConstFnCall => {
+ UnsafetyViolationKind::GatedConstFnCall if min_const_unsafe_fn => {
+ // these function calls to unsafe functions are allowed
// if `#![feature(min_const_unsafe_fn)]` is active
- if !self.tcx.sess.features_untracked().min_const_unsafe_fn {
- if !self.violations.contains(&violation) {
- self.violations.push(violation.clone())
- }
+ },
+ UnsafetyViolationKind::GatedConstFnCall => {
+ // without the feature gate, we report errors
+ if !self.violations.contains(&violation) {
+ self.violations.push(violation.clone())
}
}
// these unsafe things are stable in const fn
UnsafetyViolationKind::GeneralAndConstFn => {},
+ // these things are forbidden in const fns
UnsafetyViolationKind::General |
UnsafetyViolationKind::BorrowPacked(_) |
UnsafetyViolationKind::ExternStatic(_) => {