use syntax_pos::symbol::Symbol;
use hir::map::blocks::FnLikeNode;
use syntax::attr;
-use rustc_target::spec::abi;
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
/// Whether the `def_id` counts as const fn in your current crate, considering all active
/// Returns true if this function must conform to `min_const_fn`
pub fn is_min_const_fn(self, def_id: DefId) -> bool {
- // some intrinsics are waved through if called inside the
- // standard library. Users never need to call them directly
- if let abi::Abi::RustIntrinsic = self.fn_sig(def_id).abi() {
- match &self.item_name(def_id).as_str()[..] {
- | "size_of"
- | "min_align_of"
- | "needs_drop"
- => return true,
- _ => {},
- }
- }
-
// Bail out if the signature doesn't contain `const`
if !self.is_const_fn_raw(def_id) {
return false;
if self.features().staged_api {
// in order for a libstd function to be considered min_const_fn
// it needs to be stable and have no `rustc_const_unstable` attribute
- self.is_const_fn_raw(def_id) && match self.lookup_stability(def_id) {
+ match self.lookup_stability(def_id) {
// stable functions with unstable const fn aren't `min_const_fn`
Some(&attr::Stability { const_stability: Some(_), .. }) => false,
// unstable functions don't need to conform
// 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());
+ assert!(implicit_argument.is_none());
Safety::Safe
},
hir::Unsafety::Unsafe => Safety::FnUnsafe,
let param_env = tcx.param_env(def_id);
let mut checker = UnsafetyChecker::new(
- tcx.is_const_fn(def_id) && tcx.is_min_const_fn(def_id),
+ tcx.is_min_const_fn(def_id),
mir, source_scope_local_data, tcx, param_env);
checker.visit_mir(mir);
// Report an error.
match kind {
UnsafetyViolationKind::General if tcx.is_min_const_fn(def_id) => {
- tcx.sess.struct_span_err(
+ let mut err = tcx.sess.struct_span_err(
source_info.span,
&format!("{} is unsafe and unsafe operations \
- are not allowed in const fn", description))
- .span_label(source_info.span, &description.as_str()[..])
- .note(&details.as_str()[..])
- .emit();
+ are not allowed in const fn", description));
+ err.span_label(source_info.span, &description.as_str()[..])
+ .note(&details.as_str()[..]);
+ if tcx.fn_sig(def_id).unsafety() == hir::Unsafety::Unsafe {
+ err.note(
+ "unsafe action within a `const unsafe fn` still require an `unsafe` \
+ block in contrast to regular `unsafe fn`."
+ );
+ }
+ err.emit();
}
UnsafetyViolationKind::GeneralAndConstFn |
UnsafetyViolationKind::General => {
use rustc::hir;
use rustc::mir::*;
use rustc::ty::{self, Predicate, TyCtxt};
+use rustc_target::spec::abi;
use std::borrow::Cow;
use syntax_pos::Span;
} => {
let fn_ty = func.ty(mir, tcx);
if let ty::FnDef(def_id, _) = fn_ty.sty {
- if tcx.is_min_const_fn(def_id) {
- check_operand(tcx, mir, func, span)?;
- for arg in args {
- check_operand(tcx, mir, arg, span)?;
- }
- Ok(())
- } else {
- Err((
+ // some intrinsics are waved through if called inside the
+ // standard library. Users never need to call them directly
+ match tcx.fn_sig(def_id).abi() {
+ abi::Abi::RustIntrinsic => match &tcx.item_name(def_id).as_str()[..] {
+ | "size_of"
+ | "min_align_of"
+ | "needs_drop"
+ => {},
+ _ => return Err((
+ span,
+ "can only call a curated list of intrinsics in `min_const_fn`".into(),
+ )),
+ },
+ abi::Abi::Rust if tcx.is_min_const_fn(def_id) => {},
+ abi::Abi::Rust => return Err((
span,
"can only call other `min_const_fn` within a `min_const_fn`".into(),
- ))
+ )),
+ abi => return Err((
+ span,
+ format!(
+ "cannot call functions with `{}` abi in `min_const_fn`",
+ abi,
+ ).into(),
+ )),
+ }
+
+ check_operand(tcx, mir, func, span)?;
+
+ for arg in args {
+ check_operand(tcx, mir, arg, span)?;
}
+ Ok(())
} else {
Err((span, "can only call other const fns within const fn".into()))
}
| ^^ dereference of raw pointer
|
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+ = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
error: access to union field is unsafe and unsafe operations are not allowed in const fn
--> $DIR/min_const_fn_unsafe.rs:38:5
| ^^^^^^^^^^^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+ = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
error: aborting due to 7 previous errors
| ^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
+ = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
--> $DIR/min_const_fn_unsafe_feature_gate.rs:42:5
| ^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
+ = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
--> $DIR/min_const_fn_unsafe_feature_gate.rs:45:5
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
+ = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
--> $DIR/min_const_fn_unsafe_feature_gate.rs:47:51
| ^^ dereference of raw pointer
|
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+ = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
--> $DIR/min_const_fn_unsafe_feature_gate.rs:50:60
| ^^^ dereference of raw pointer
|
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+ = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
--> $DIR/min_const_fn_unsafe_feature_gate.rs:53:62
| ^^^^^^^^^^^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+ = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
error: aborting due to 11 previous errors