mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-18 18:04:13 +00:00
Declare some unconst operations as unsafe in const fn
This commit is contained in:
parent
64afc6b517
commit
aedc3a51df
@ -4,6 +4,7 @@ use rustc_data_structures::sync::Lrc;
|
|||||||
|
|
||||||
use rustc::ty::query::Providers;
|
use rustc::ty::query::Providers;
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
|
use rustc::ty::cast::CastTy;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::Node;
|
use rustc::hir::Node;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
@ -20,6 +21,7 @@ use util;
|
|||||||
|
|
||||||
pub struct UnsafetyChecker<'a, 'tcx: 'a> {
|
pub struct UnsafetyChecker<'a, 'tcx: 'a> {
|
||||||
mir: &'a Mir<'tcx>,
|
mir: &'a Mir<'tcx>,
|
||||||
|
const_context: bool,
|
||||||
min_const_fn: bool,
|
min_const_fn: bool,
|
||||||
source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
|
source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
|
||||||
violations: Vec<UnsafetyViolation>,
|
violations: Vec<UnsafetyViolation>,
|
||||||
@ -33,14 +35,20 @@ pub struct UnsafetyChecker<'a, 'tcx: 'a> {
|
|||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
impl<'a, 'gcx, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
|
const_context: bool,
|
||||||
min_const_fn: bool,
|
min_const_fn: bool,
|
||||||
mir: &'a Mir<'tcx>,
|
mir: &'a Mir<'tcx>,
|
||||||
source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
|
source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
// sanity check
|
||||||
|
if min_const_fn {
|
||||||
|
assert!(const_context);
|
||||||
|
}
|
||||||
Self {
|
Self {
|
||||||
mir,
|
mir,
|
||||||
|
const_context,
|
||||||
min_const_fn,
|
min_const_fn,
|
||||||
source_scope_local_data,
|
source_scope_local_data,
|
||||||
violations: vec![],
|
violations: vec![],
|
||||||
@ -124,29 +132,70 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||||||
rvalue: &Rvalue<'tcx>,
|
rvalue: &Rvalue<'tcx>,
|
||||||
location: Location)
|
location: Location)
|
||||||
{
|
{
|
||||||
if let &Rvalue::Aggregate(box ref aggregate, _) = rvalue {
|
match rvalue {
|
||||||
match aggregate {
|
Rvalue::Aggregate(box ref aggregate, _) => {
|
||||||
&AggregateKind::Array(..) |
|
match aggregate {
|
||||||
&AggregateKind::Tuple => {}
|
&AggregateKind::Array(..) |
|
||||||
&AggregateKind::Adt(ref def, ..) => {
|
&AggregateKind::Tuple => {}
|
||||||
match self.tcx.layout_scalar_valid_range(def.did) {
|
&AggregateKind::Adt(ref def, ..) => {
|
||||||
(Bound::Unbounded, Bound::Unbounded) => {},
|
match self.tcx.layout_scalar_valid_range(def.did) {
|
||||||
_ => self.require_unsafe(
|
(Bound::Unbounded, Bound::Unbounded) => {},
|
||||||
"initializing type with `rustc_layout_scalar_valid_range` attr",
|
_ => self.require_unsafe(
|
||||||
"initializing a layout restricted type's field with a value outside \
|
"initializing type with `rustc_layout_scalar_valid_range` attr",
|
||||||
the valid range is undefined behavior",
|
"initializing a layout restricted type's field with a value \
|
||||||
UnsafetyViolationKind::GeneralAndConstFn,
|
outside the valid range is undefined behavior",
|
||||||
),
|
UnsafetyViolationKind::GeneralAndConstFn,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&AggregateKind::Closure(def_id, _) |
|
||||||
|
&AggregateKind::Generator(def_id, _, _) => {
|
||||||
|
let UnsafetyCheckResult {
|
||||||
|
violations, unsafe_blocks
|
||||||
|
} = self.tcx.unsafety_check_result(def_id);
|
||||||
|
self.register_violations(&violations, &unsafe_blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&AggregateKind::Closure(def_id, _) |
|
},
|
||||||
&AggregateKind::Generator(def_id, _, _) => {
|
// casting pointers to ints is unsafe in const fn because the const evaluator cannot
|
||||||
let UnsafetyCheckResult {
|
// possibly know what the result of various operations like `address / 2` would be
|
||||||
violations, unsafe_blocks
|
// pointers during const evaluation have no integral address, only an abstract one
|
||||||
} = self.tcx.unsafety_check_result(def_id);
|
Rvalue::Cast(CastKind::Misc, ref operand, cast_ty)
|
||||||
self.register_violations(&violations, &unsafe_blocks);
|
if self.const_context && self.tcx.features().const_raw_ptr_to_usize_cast => {
|
||||||
|
let operand_ty = operand.ty(self.mir, self.tcx);
|
||||||
|
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
|
||||||
|
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||||
|
match (cast_in, cast_out) {
|
||||||
|
(CastTy::Ptr(_), CastTy::Int(_)) |
|
||||||
|
(CastTy::FnPtr, CastTy::Int(_)) => {
|
||||||
|
self.register_violations(&[UnsafetyViolation {
|
||||||
|
source_info: self.source_info,
|
||||||
|
description: Symbol::intern("cast of pointer to int").as_interned_str(),
|
||||||
|
details: Symbol::intern("casting pointers to integers in constants")
|
||||||
|
.as_interned_str(),
|
||||||
|
kind: UnsafetyViolationKind::General,
|
||||||
|
}], &[]);
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// raw pointer and fn pointer operations are unsafe as it is not clear whether one
|
||||||
|
// pointer would be "less" or "equal" to another, because we cannot know where llvm
|
||||||
|
// or the linker will place various statics in memory. Without this information the
|
||||||
|
// result of a comparison of addresses would differ between runtime and compile-time.
|
||||||
|
Rvalue::BinaryOp(_, ref lhs, _)
|
||||||
|
if self.const_context && self.tcx.features().const_compare_raw_pointers => {
|
||||||
|
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.mir, self.tcx).sty {
|
||||||
|
self.register_violations(&[UnsafetyViolation {
|
||||||
|
source_info: self.source_info,
|
||||||
|
description: Symbol::intern("pointer operation").as_interned_str(),
|
||||||
|
details: Symbol::intern("operations on pointers in constants")
|
||||||
|
.as_interned_str(),
|
||||||
|
kind: UnsafetyViolationKind::General,
|
||||||
|
}], &[]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
self.super_rvalue(rvalue, location);
|
self.super_rvalue(rvalue, location);
|
||||||
}
|
}
|
||||||
@ -484,8 +533,16 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
|
|||||||
};
|
};
|
||||||
|
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
|
|
||||||
|
let id = tcx.hir().as_local_node_id(def_id).unwrap();
|
||||||
|
let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) {
|
||||||
|
hir::BodyOwnerKind::Closure => (false, false),
|
||||||
|
hir::BodyOwnerKind::Fn => (tcx.is_const_fn(def_id), tcx.is_min_const_fn(def_id)),
|
||||||
|
hir::BodyOwnerKind::Const |
|
||||||
|
hir::BodyOwnerKind::Static(_) => (true, false),
|
||||||
|
};
|
||||||
let mut checker = UnsafetyChecker::new(
|
let mut checker = UnsafetyChecker::new(
|
||||||
tcx.is_min_const_fn(def_id),
|
const_context, min_const_fn,
|
||||||
mir, source_scope_local_data, tcx, param_env);
|
mir, source_scope_local_data, tcx, param_env);
|
||||||
checker.visit_mir(mir);
|
checker.visit_mir(mir);
|
||||||
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
// gate-test-const_raw_ptr_to_usize_cast
|
// gate-test-const_raw_ptr_to_usize_cast
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
const X: u32 = main as u32; //~ ERROR casting pointers to integers in constants is unstable
|
const X: u32 = unsafe {
|
||||||
|
main as u32 //~ ERROR casting pointers to integers in constants is unstable
|
||||||
|
};
|
||||||
const Y: u32 = 0;
|
const Y: u32 = 0;
|
||||||
const Z: u32 = &Y as *const u32 as u32; //~ ERROR is unstable
|
const Z: u32 = unsafe {
|
||||||
|
&Y as *const u32 as u32 //~ ERROR is unstable
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
|
error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
|
||||||
--> $DIR/cast-ptr-to-int-const.rs:4:20
|
--> $DIR/cast-ptr-to-int-const.rs:5:9
|
||||||
|
|
|
|
||||||
LL | const X: u32 = main as u32; //~ ERROR casting pointers to integers in constants is unstable
|
LL | main as u32 //~ ERROR casting pointers to integers in constants is unstable
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
|
= help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
|
error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
|
||||||
--> $DIR/cast-ptr-to-int-const.rs:6:20
|
--> $DIR/cast-ptr-to-int-const.rs:9:9
|
||||||
|
|
|
|
||||||
LL | const Z: u32 = &Y as *const u32 as u32; //~ ERROR is unstable
|
LL | &Y as *const u32 as u32 //~ ERROR is unstable
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
|
= help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
|
||||||
|
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
// unconst and bad, will thus error in miri
|
// unconst and bad, will thus error in miri
|
||||||
const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR any use of this value will cause
|
const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this
|
||||||
// unconst and fine
|
// unconst and fine
|
||||||
const X2: bool = 42 as *const i32 == 43 as *const i32;
|
const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 };
|
||||||
// unconst and fine
|
// unconst and fine
|
||||||
const Y: usize = 42usize as *const i32 as usize + 1;
|
const Y: usize = unsafe { 42usize as *const i32 as usize + 1 };
|
||||||
// unconst and bad, will thus error in miri
|
// unconst and bad, will thus error in miri
|
||||||
const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR any use of this value will cause
|
const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; //~ ERROR any use of this
|
||||||
// unconst and fine
|
// unconst and fine
|
||||||
const Z: i32 = unsafe { *(&1 as *const i32) };
|
const Z: i32 = unsafe { *(&1 as *const i32) };
|
||||||
// unconst and bad, will thus error in miri
|
// unconst and bad, will thus error in miri
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const_raw_ptr_ops.rs:6:1
|
--> $DIR/const_raw_ptr_ops.rs:6:1
|
||||||
|
|
|
|
||||||
LL | const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR any use of this value will cause
|
LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this
|
||||||
| ^^^^^^^^^^^^^^^^------------------------------------^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
|
||||||
| |
|
| |
|
||||||
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
||||||
|
|
|
|
||||||
= note: #[deny(const_err)] on by default
|
= note: #[deny(const_err)] on by default
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const_raw_ptr_ops.rs:12:1
|
--> $DIR/const_raw_ptr_ops.rs:12:1
|
||||||
|
|
|
|
||||||
LL | const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR any use of this value will cause
|
LL | const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; //~ ERROR any use of this
|
||||||
| ^^^^^^^^^^^^^^^^^^-----------------------------^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------^^^
|
||||||
| |
|
| |
|
||||||
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const_raw_ptr_ops.rs:16:1
|
--> $DIR/const_raw_ptr_ops.rs:16:1
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const fn cmp(x: fn(), y: fn()) -> bool { //~ ERROR function pointers in const fn are unstable
|
const fn cmp(x: fn(), y: fn()) -> bool { //~ ERROR function pointers in const fn are unstable
|
||||||
x == y
|
unsafe { x == y }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -95,97 +95,109 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
|
|||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: casting pointers to ints is unstable in const fn
|
error: casting pointers to ints is unstable in const fn
|
||||||
--> $DIR/min_const_fn.rs:94:42
|
--> $DIR/min_const_fn.rs:94:63
|
||||||
|
|
|
||||||
|
LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: casting pointers to ints is unstable in const fn
|
||||||
|
--> $DIR/min_const_fn.rs:96:42
|
||||||
|
|
|
|
||||||
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: casting pointers to ints is unstable in const fn
|
||||||
|
--> $DIR/min_const_fn.rs:98:63
|
||||||
|
|
|
||||||
|
LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
--> $DIR/min_const_fn.rs:96:38
|
--> $DIR/min_const_fn.rs:100:38
|
||||||
|
|
|
|
||||||
LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
|
LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
--> $DIR/min_const_fn.rs:98:29
|
--> $DIR/min_const_fn.rs:102:29
|
||||||
|
|
|
|
||||||
LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
--> $DIR/min_const_fn.rs:100:44
|
--> $DIR/min_const_fn.rs:104:44
|
||||||
|
|
|
|
||||||
LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
|
LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
--> $DIR/min_const_fn.rs:102:44
|
--> $DIR/min_const_fn.rs:106:44
|
||||||
|
|
|
|
||||||
LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
|
LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: mutable references in const fn are unstable
|
error: mutable references in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:104:14
|
--> $DIR/min_const_fn.rs:108:14
|
||||||
|
|
|
|
||||||
LL | const fn inc(x: &mut i32) { *x += 1 }
|
LL | const fn inc(x: &mut i32) { *x += 1 }
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:109:6
|
--> $DIR/min_const_fn.rs:113:6
|
||||||
|
|
|
|
||||||
LL | impl<T: std::fmt::Debug> Foo<T> {
|
LL | impl<T: std::fmt::Debug> Foo<T> {
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:114:6
|
--> $DIR/min_const_fn.rs:118:6
|
||||||
|
|
|
|
||||||
LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
|
LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:119:6
|
--> $DIR/min_const_fn.rs:123:6
|
||||||
|
|
|
|
||||||
LL | impl<T: Sync + Sized> Foo<T> {
|
LL | impl<T: Sync + Sized> Foo<T> {
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: `impl Trait` in const fn is unstable
|
error: `impl Trait` in const fn is unstable
|
||||||
--> $DIR/min_const_fn.rs:125:24
|
--> $DIR/min_const_fn.rs:129:24
|
||||||
|
|
|
|
||||||
LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { AlanTuring(0) }
|
LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { AlanTuring(0) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:127:34
|
--> $DIR/min_const_fn.rs:131:34
|
||||||
|
|
|
|
||||||
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:129:22
|
--> $DIR/min_const_fn.rs:133:22
|
||||||
|
|
|
|
||||||
LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `impl Trait` in const fn is unstable
|
error: `impl Trait` in const fn is unstable
|
||||||
--> $DIR/min_const_fn.rs:130:23
|
--> $DIR/min_const_fn.rs:134:23
|
||||||
|
|
|
|
||||||
LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable
|
LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:131:23
|
--> $DIR/min_const_fn.rs:135:23
|
||||||
|
|
|
|
||||||
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:132:32
|
--> $DIR/min_const_fn.rs:136:32
|
||||||
|
|
|
|
||||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning[E0515]: cannot return reference to temporary value
|
warning[E0515]: cannot return reference to temporary value
|
||||||
--> $DIR/min_const_fn.rs:132:63
|
--> $DIR/min_const_fn.rs:136:63
|
||||||
|
|
|
|
||||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||||
| ^--
|
| ^--
|
||||||
@ -197,24 +209,24 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
|||||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:137:41
|
--> $DIR/min_const_fn.rs:141:41
|
||||||
|
|
|
|
||||||
LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 }
|
LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: function pointers in const fn are unstable
|
error: function pointers in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:140:21
|
--> $DIR/min_const_fn.rs:144:21
|
||||||
|
|
|
|
||||||
LL | const fn no_fn_ptrs(_x: fn()) {}
|
LL | const fn no_fn_ptrs(_x: fn()) {}
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: function pointers in const fn are unstable
|
error: function pointers in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:142:27
|
--> $DIR/min_const_fn.rs:146:27
|
||||||
|
|
|
|
||||||
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 34 previous errors
|
error: aborting due to 36 previous errors
|
||||||
|
|
||||||
Some errors occurred: E0493, E0515.
|
Some errors occurred: E0493, E0515.
|
||||||
For more information about an error, try `rustc --explain E0493`.
|
For more information about an error, try `rustc --explain E0493`.
|
||||||
|
@ -90,9 +90,13 @@ static BAR: u32 = 42;
|
|||||||
const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn
|
const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn
|
||||||
const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items
|
const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items
|
||||||
const fn foo30(x: *const u32) -> usize { x as usize }
|
const fn foo30(x: *const u32) -> usize { x as usize }
|
||||||
//~^ ERROR casting pointers to int
|
//~^ ERROR casting pointers to ints is unstable
|
||||||
|
const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
|
||||||
|
//~^ ERROR casting pointers to ints is unstable
|
||||||
const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
||||||
//~^ ERROR casting pointers to int
|
//~^ ERROR casting pointers to ints is unstable
|
||||||
|
const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
|
||||||
|
//~^ ERROR casting pointers to ints is unstable
|
||||||
const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
|
const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
|
||||||
//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
|
//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
||||||
|
@ -95,113 +95,125 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
|
|||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: casting pointers to ints is unstable in const fn
|
error: casting pointers to ints is unstable in const fn
|
||||||
--> $DIR/min_const_fn.rs:94:42
|
--> $DIR/min_const_fn.rs:94:63
|
||||||
|
|
|
||||||
|
LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: casting pointers to ints is unstable in const fn
|
||||||
|
--> $DIR/min_const_fn.rs:96:42
|
||||||
|
|
|
|
||||||
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: casting pointers to ints is unstable in const fn
|
||||||
|
--> $DIR/min_const_fn.rs:98:63
|
||||||
|
|
|
||||||
|
LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
--> $DIR/min_const_fn.rs:96:38
|
--> $DIR/min_const_fn.rs:100:38
|
||||||
|
|
|
|
||||||
LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
|
LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
--> $DIR/min_const_fn.rs:98:29
|
--> $DIR/min_const_fn.rs:102:29
|
||||||
|
|
|
|
||||||
LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
--> $DIR/min_const_fn.rs:100:44
|
--> $DIR/min_const_fn.rs:104:44
|
||||||
|
|
|
|
||||||
LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
|
LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||||
--> $DIR/min_const_fn.rs:102:44
|
--> $DIR/min_const_fn.rs:106:44
|
||||||
|
|
|
|
||||||
LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
|
LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: mutable references in const fn are unstable
|
error: mutable references in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:104:14
|
--> $DIR/min_const_fn.rs:108:14
|
||||||
|
|
|
|
||||||
LL | const fn inc(x: &mut i32) { *x += 1 }
|
LL | const fn inc(x: &mut i32) { *x += 1 }
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:109:6
|
--> $DIR/min_const_fn.rs:113:6
|
||||||
|
|
|
|
||||||
LL | impl<T: std::fmt::Debug> Foo<T> {
|
LL | impl<T: std::fmt::Debug> Foo<T> {
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:114:6
|
--> $DIR/min_const_fn.rs:118:6
|
||||||
|
|
|
|
||||||
LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
|
LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:119:6
|
--> $DIR/min_const_fn.rs:123:6
|
||||||
|
|
|
|
||||||
LL | impl<T: Sync + Sized> Foo<T> {
|
LL | impl<T: Sync + Sized> Foo<T> {
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: `impl Trait` in const fn is unstable
|
error: `impl Trait` in const fn is unstable
|
||||||
--> $DIR/min_const_fn.rs:125:24
|
--> $DIR/min_const_fn.rs:129:24
|
||||||
|
|
|
|
||||||
LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { AlanTuring(0) }
|
LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { AlanTuring(0) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:127:34
|
--> $DIR/min_const_fn.rs:131:34
|
||||||
|
|
|
|
||||||
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:129:22
|
--> $DIR/min_const_fn.rs:133:22
|
||||||
|
|
|
|
||||||
LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `impl Trait` in const fn is unstable
|
error: `impl Trait` in const fn is unstable
|
||||||
--> $DIR/min_const_fn.rs:130:23
|
--> $DIR/min_const_fn.rs:134:23
|
||||||
|
|
|
|
||||||
LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable
|
LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:131:23
|
--> $DIR/min_const_fn.rs:135:23
|
||||||
|
|
|
|
||||||
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:132:32
|
--> $DIR/min_const_fn.rs:136:32
|
||||||
|
|
|
|
||||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||||
--> $DIR/min_const_fn.rs:137:41
|
--> $DIR/min_const_fn.rs:141:41
|
||||||
|
|
|
|
||||||
LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 }
|
LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: function pointers in const fn are unstable
|
error: function pointers in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:140:21
|
--> $DIR/min_const_fn.rs:144:21
|
||||||
|
|
|
|
||||||
LL | const fn no_fn_ptrs(_x: fn()) {}
|
LL | const fn no_fn_ptrs(_x: fn()) {}
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: function pointers in const fn are unstable
|
error: function pointers in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:142:27
|
--> $DIR/min_const_fn.rs:146:27
|
||||||
|
|
|
|
||||||
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 34 previous errors
|
error: aborting due to 36 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0493`.
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
static FOO: i32 = 42;
|
static FOO: i32 = 42;
|
||||||
static BAR: i32 = 42;
|
static BAR: i32 = 42;
|
||||||
|
|
||||||
static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020
|
static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020
|
||||||
fn main() {
|
fn main() {
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error[E0658]: comparing raw pointers inside static (see issue #53020)
|
error[E0658]: comparing raw pointers inside static (see issue #53020)
|
||||||
--> $DIR/E0395.rs:6:22
|
--> $DIR/E0395.rs:6:29
|
||||||
|
|
|
|
||||||
LL | static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020
|
LL | static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable
|
= help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
static X: usize = 0 as *const usize as usize;
|
static X: usize = unsafe { 0 as *const usize as usize };
|
||||||
//~^ ERROR: casting pointers to integers in statics is unstable
|
//~^ ERROR: casting pointers to integers in statics is unstable
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error[E0658]: casting pointers to integers in statics is unstable (see issue #51910)
|
error[E0658]: casting pointers to integers in statics is unstable (see issue #51910)
|
||||||
--> $DIR/issue-17458.rs:1:19
|
--> $DIR/issue-17458.rs:1:28
|
||||||
|
|
|
|
||||||
LL | static X: usize = 0 as *const usize as usize;
|
LL | static X: usize = unsafe { 0 as *const usize as usize };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
|
= help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
const X: u32 = 1;
|
const X: u32 = 1;
|
||||||
const Y: usize = &X as *const u32 as usize; //~ ERROR is unstable
|
const Y: usize = unsafe { &X as *const u32 as usize }; //~ ERROR is unstable
|
||||||
println!("{}", Y);
|
println!("{}", Y);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
|
error[E0658]: casting pointers to integers in constants is unstable (see issue #51910)
|
||||||
--> $DIR/issue-18294.rs:3:22
|
--> $DIR/issue-18294.rs:3:31
|
||||||
|
|
|
|
||||||
LL | const Y: usize = &X as *const u32 as usize; //~ ERROR is unstable
|
LL | const Y: usize = unsafe { &X as *const u32 as usize }; //~ ERROR is unstable
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
|
= help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
fn id<T>(t: T) -> T { t }
|
fn id<T>(t: T) -> T { t }
|
||||||
fn main() {
|
fn main() {
|
||||||
const A: bool = id::<u8> as *const () < id::<u16> as *const ();
|
const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
||||||
//~^ ERROR comparing raw pointers inside constant
|
//~^ ERROR comparing raw pointers inside constant
|
||||||
println!("{}", A);
|
println!("{}", A);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error[E0658]: comparing raw pointers inside constant (see issue #53020)
|
error[E0658]: comparing raw pointers inside constant (see issue #53020)
|
||||||
--> $DIR/issue-25826.rs:3:21
|
--> $DIR/issue-25826.rs:3:30
|
||||||
|
|
|
|
||||||
LL | const A: bool = id::<u8> as *const () < id::<u16> as *const ();
|
LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable
|
= help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user