Skip to content

Commit f411576

Browse files
committed
Intrinsic checks are just needed for qualify_min_const_fn
1 parent b779694 commit f411576

File tree

6 files changed

+53
-30
lines changed

6 files changed

+53
-30
lines changed

src/librustc/ty/constness.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use ty::TyCtxt;
55
use syntax_pos::symbol::Symbol;
66
use hir::map::blocks::FnLikeNode;
77
use syntax::attr;
8-
use rustc_target::spec::abi;
98

109
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
1110
/// Whether the `def_id` counts as const fn in your current crate, considering all active
@@ -40,18 +39,6 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
4039

4140
/// Returns true if this function must conform to `min_const_fn`
4241
pub fn is_min_const_fn(self, def_id: DefId) -> bool {
43-
// some intrinsics are waved through if called inside the
44-
// standard library. Users never need to call them directly
45-
if let abi::Abi::RustIntrinsic = self.fn_sig(def_id).abi() {
46-
match &self.item_name(def_id).as_str()[..] {
47-
| "size_of"
48-
| "min_align_of"
49-
| "needs_drop"
50-
=> return true,
51-
_ => {},
52-
}
53-
}
54-
5542
// Bail out if the signature doesn't contain `const`
5643
if !self.is_const_fn_raw(def_id) {
5744
return false;
@@ -60,7 +47,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
6047
if self.features().staged_api {
6148
// in order for a libstd function to be considered min_const_fn
6249
// it needs to be stable and have no `rustc_const_unstable` attribute
63-
self.is_const_fn_raw(def_id) && match self.lookup_stability(def_id) {
50+
match self.lookup_stability(def_id) {
6451
// stable functions with unstable const fn aren't `min_const_fn`
6552
Some(&attr::Stability { const_stability: Some(_), .. }) => false,
6653
// unstable functions don't need to conform

src/librustc_mir/build/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
115115
// As specified in #55607, a `const unsafe fn` differs
116116
// from an `unsafe fn` in that its body is still considered
117117
// safe code by default.
118-
assert!(!implicit_argument.is_none());
118+
assert!(implicit_argument.is_none());
119119
Safety::Safe
120120
},
121121
hir::Unsafety::Unsafe => Safety::FnUnsafe,

src/librustc_mir/transform/check_unsafety.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
514514

515515
let param_env = tcx.param_env(def_id);
516516
let mut checker = UnsafetyChecker::new(
517-
tcx.is_const_fn(def_id) && tcx.is_min_const_fn(def_id),
517+
tcx.is_min_const_fn(def_id),
518518
mir, source_scope_local_data, tcx, param_env);
519519
checker.visit_mir(mir);
520520

@@ -617,13 +617,19 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
617617
// Report an error.
618618
match kind {
619619
UnsafetyViolationKind::General if tcx.is_min_const_fn(def_id) => {
620-
tcx.sess.struct_span_err(
620+
let mut err = tcx.sess.struct_span_err(
621621
source_info.span,
622622
&format!("{} is unsafe and unsafe operations \
623-
are not allowed in const fn", description))
624-
.span_label(source_info.span, &description.as_str()[..])
625-
.note(&details.as_str()[..])
626-
.emit();
623+
are not allowed in const fn", description));
624+
err.span_label(source_info.span, &description.as_str()[..])
625+
.note(&details.as_str()[..]);
626+
if tcx.fn_sig(def_id).unsafety() == hir::Unsafety::Unsafe {
627+
err.note(
628+
"unsafe action within a `const unsafe fn` still require an `unsafe` \
629+
block in contrast to regular `unsafe fn`."
630+
);
631+
}
632+
err.emit();
627633
}
628634
UnsafetyViolationKind::GeneralAndConstFn |
629635
UnsafetyViolationKind::General => {

src/librustc_mir/transform/qualify_min_const_fn.rs

+31-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc::hir::def_id::DefId;
22
use rustc::hir;
33
use rustc::mir::*;
44
use rustc::ty::{self, Predicate, TyCtxt};
5+
use rustc_target::spec::abi;
56
use std::borrow::Cow;
67
use syntax_pos::Span;
78

@@ -338,19 +339,40 @@ fn check_terminator(
338339
} => {
339340
let fn_ty = func.ty(mir, tcx);
340341
if let ty::FnDef(def_id, _) = fn_ty.sty {
341-
if tcx.is_min_const_fn(def_id) {
342-
check_operand(tcx, mir, func, span)?;
343342

344-
for arg in args {
345-
check_operand(tcx, mir, arg, span)?;
346-
}
347-
Ok(())
348-
} else {
349-
Err((
343+
// some intrinsics are waved through if called inside the
344+
// standard library. Users never need to call them directly
345+
match tcx.fn_sig(def_id).abi() {
346+
abi::Abi::RustIntrinsic => match &tcx.item_name(def_id).as_str()[..] {
347+
| "size_of"
348+
| "min_align_of"
349+
| "needs_drop"
350+
=> {},
351+
_ => return Err((
352+
span,
353+
"can only call a curated list of intrinsics in `min_const_fn`".into(),
354+
)),
355+
},
356+
abi::Abi::Rust if tcx.is_min_const_fn(def_id) => {},
357+
abi::Abi::Rust => return Err((
350358
span,
351359
"can only call other `min_const_fn` within a `min_const_fn`".into(),
352-
))
360+
)),
361+
abi => return Err((
362+
span,
363+
format!(
364+
"cannot call functions with `{}` abi in `min_const_fn`",
365+
abi,
366+
).into(),
367+
)),
368+
}
369+
370+
check_operand(tcx, mir, func, span)?;
371+
372+
for arg in args {
373+
check_operand(tcx, mir, arg, span)?;
353374
}
375+
Ok(())
354376
} else {
355377
Err((span, "can only call other const fns within const fn".into()))
356378
}

src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ LL | const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x } //~ ERROR no
4545
| ^^ dereference of raw pointer
4646
|
4747
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
48+
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
4849

4950
error: access to union field is unsafe and unsafe operations are not allowed in const fn
5051
--> $DIR/min_const_fn_unsafe.rs:38:5
@@ -53,6 +54,7 @@ LL | Foo { x: () }.y //~ ERROR not allowed in const fn
5354
| ^^^^^^^^^^^^^^^ access to union field
5455
|
5556
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
57+
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
5658

5759
error: aborting due to 7 previous errors
5860

src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ LL | foo4() //~ ERROR not allowed in const fn
3737
| ^^^^^^ call to unsafe function
3838
|
3939
= note: consult the function's documentation for information on how to avoid undefined behavior
40+
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
4041

4142
error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
4243
--> $DIR/min_const_fn_unsafe_feature_gate.rs:42:5
@@ -45,6 +46,7 @@ LL | foo5::<String>() //~ ERROR not allowed in const fn
4546
| ^^^^^^^^^^^^^^^^ call to unsafe function
4647
|
4748
= note: consult the function's documentation for information on how to avoid undefined behavior
49+
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
4850

4951
error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
5052
--> $DIR/min_const_fn_unsafe_feature_gate.rs:45:5
@@ -53,6 +55,7 @@ LL | foo6::<Vec<std::cell::Cell<u32>>>() //~ ERROR not allowed in const fn
5355
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
5456
|
5557
= note: consult the function's documentation for information on how to avoid undefined behavior
58+
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
5659

5760
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
5861
--> $DIR/min_const_fn_unsafe_feature_gate.rs:47:51
@@ -61,6 +64,7 @@ LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowe
6164
| ^^ dereference of raw pointer
6265
|
6366
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
67+
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
6468

6569
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
6670
--> $DIR/min_const_fn_unsafe_feature_gate.rs:50:60
@@ -69,6 +73,7 @@ LL | const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x } //~ ERROR
6973
| ^^^ dereference of raw pointer
7074
|
7175
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
76+
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
7277

7378
error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
7479
--> $DIR/min_const_fn_unsafe_feature_gate.rs:53:62
@@ -85,6 +90,7 @@ LL | Foo { x: () }.y //~ ERROR not allowed in const fn
8590
| ^^^^^^^^^^^^^^^ access to union field
8691
|
8792
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
93+
= note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
8894

8995
error: aborting due to 11 previous errors
9096

0 commit comments

Comments
 (0)