Remove the const_raw_ptr_comparison feature gate.
We can never supply a meaningful implementation of this. Instead, the follow up commits will create two intrinsics that approximate comparisons: * `ptr_maybe_eq` * `ptr_maybe_ne` The fact that `ptr_maybe_eq(a, b)` is not necessarily the same value as `!ptr_maybe_ne(a, b)` is a symptom of this entire problem.
This commit is contained in:
parent
72417d84fb
commit
9245ba8304
27 changed files with 165 additions and 190 deletions
|
@ -401,9 +401,6 @@ declare_features! (
|
|||
/// Allows dereferencing raw pointers during const eval.
|
||||
(active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
|
||||
|
||||
/// Allows comparing raw pointers during const eval.
|
||||
(active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
|
||||
|
||||
/// Allows `#[doc(alias = "...")]`.
|
||||
(active, doc_alias, "1.27.0", Some(50146), None),
|
||||
|
||||
|
|
|
@ -113,6 +113,11 @@ declare_features! (
|
|||
Some("removed in favor of `#![feature(marker_trait_attr)]`")),
|
||||
/// Allows `#[no_debug]`.
|
||||
(removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")),
|
||||
|
||||
/// Allows comparing raw pointers during const eval.
|
||||
(removed, const_compare_raw_pointers, "1.46.0", Some(53020), None,
|
||||
Some("cannot be allowed in const eval in any meaningful way")),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: removed features
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
|
@ -284,18 +284,24 @@ impl NonConstOp for Panic {
|
|||
#[derive(Debug)]
|
||||
pub struct RawPtrComparison;
|
||||
impl NonConstOp for RawPtrComparison {
|
||||
fn feature_gate() -> Option<Symbol> {
|
||||
Some(sym::const_compare_raw_pointers)
|
||||
}
|
||||
|
||||
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_compare_raw_pointers,
|
||||
let mut err = ccx.tcx.sess.struct_span_err(
|
||||
span,
|
||||
&format!("comparing raw pointers inside {}", ccx.const_kind()),
|
||||
)
|
||||
.emit();
|
||||
"pointers cannot be compared in a meaningful way during const eval.",
|
||||
);
|
||||
err.note(
|
||||
"It is conceptually impossible for const eval to know in all cases whether two \
|
||||
pointers are equal. While sometimes it is clear (the address of a static item \
|
||||
is never equal to the address of another static item), comparing an integer \
|
||||
address with any allocation's address is impossible to do at compile-time.",
|
||||
);
|
||||
err.note(
|
||||
"That said, there's the `ptr_maybe_eq` intrinsic which returns `true` for all \
|
||||
comparisons where CTFE isn't sure whether two addresses are equal. The mirror \
|
||||
intrinsic `ptr_maybe_ne` returns `true` for all comparisons where CTFE isn't \
|
||||
sure whether two addresses are inequal.",
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -171,21 +171,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
// 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.body, self.tcx).kind {
|
||||
self.require_unsafe(
|
||||
"pointer operation",
|
||||
"operations on pointers in constants",
|
||||
UnsafetyViolationKind::General,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
self.super_rvalue(rvalue, location);
|
||||
|
|
|
@ -10,8 +10,7 @@ use rustc_middle::hir::map::Map;
|
|||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
|
@ -303,25 +302,22 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty),
|
||||
GenericParamKind::Const { ty: ref hir_ty, .. } => {
|
||||
let ty = icx.to_ty(hir_ty);
|
||||
if !tcx.features().const_compare_raw_pointers {
|
||||
let err = match ty.peel_refs().kind {
|
||||
ty::FnPtr(_) => Some("function pointers"),
|
||||
ty::RawPtr(_) => Some("raw pointers"),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(unsupported_type) = err {
|
||||
feature_err(
|
||||
&tcx.sess.parse_sess,
|
||||
sym::const_compare_raw_pointers,
|
||||
let err = match ty.peel_refs().kind {
|
||||
ty::FnPtr(_) => Some("function pointers"),
|
||||
ty::RawPtr(_) => Some("raw pointers"),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(unsupported_type) = err {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
hir_ty.span,
|
||||
&format!(
|
||||
"using {} as const generic parameters is unstable",
|
||||
"using {} as const generic parameters is forbidden",
|
||||
unsupported_type
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
};
|
||||
}
|
||||
};
|
||||
if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty)
|
||||
.is_some()
|
||||
{
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(const_generics, const_compare_raw_pointers)]
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
fn function() -> u32 {
|
||||
17
|
||||
}
|
||||
|
||||
struct Wrapper<const F: fn() -> u32>;
|
||||
struct Wrapper<const F: fn() -> u32>; //~ ERROR: using function pointers as const generic parameters
|
||||
|
||||
impl<const F: fn() -> u32> Wrapper<F> {
|
||||
//~^ ERROR: using function pointers as const generic parameters
|
||||
fn call() -> u32 {
|
||||
F()
|
||||
}
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/fn-const-param-call.rs:3:12
|
||||
--> $DIR/fn-const-param-call.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics, const_compare_raw_pointers)]
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/fn-const-param-call.rs:8:25
|
||||
|
|
||||
LL | struct Wrapper<const F: fn() -> u32>;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/fn-const-param-call.rs:10:15
|
||||
|
|
||||
LL | impl<const F: fn() -> u32> Wrapper<F> {
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#![feature(const_generics, const_compare_raw_pointers)]
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
struct Checked<const F: fn(usize) -> bool>;
|
||||
//~^ ERROR: using function pointers as const generic parameters
|
||||
|
||||
fn not_one(val: usize) -> bool { val != 1 }
|
||||
fn not_two(val: usize) -> bool { val != 2 }
|
||||
|
@ -13,14 +14,14 @@ fn generic<T>(val: usize) -> bool { val != 1 }
|
|||
fn main() {
|
||||
let _: Option<Checked<not_one>> = None;
|
||||
let _: Checked<not_one> = Checked::<not_one>;
|
||||
let _: Checked<not_one> = Checked::<not_two>; //~ mismatched types
|
||||
let _: Checked<not_one> = Checked::<not_two>;
|
||||
|
||||
let _ = Checked::<generic_arg>;
|
||||
let _ = Checked::<{generic_arg::<usize>}>;
|
||||
let _ = Checked::<{generic_arg::<u32>}>; //~ mismatched types
|
||||
let _ = Checked::<{generic_arg::<u32>}>;
|
||||
|
||||
let _ = Checked::<generic>; //~ type annotations needed
|
||||
let _ = Checked::<generic>;
|
||||
let _ = Checked::<{generic::<u16>}>;
|
||||
let _: Checked<{generic::<u16>}> = Checked::<{generic::<u16>}>;
|
||||
let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>; //~ mismatched types
|
||||
let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>;
|
||||
}
|
||||
|
|
|
@ -1,46 +1,17 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/fn-const-param-infer.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics, const_compare_raw_pointers)]
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-const-param-infer.rs:16:31
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/fn-const-param-infer.rs:4:25
|
||||
|
|
||||
LL | let _: Checked<not_one> = Checked::<not_two>;
|
||||
| ^^^^^^^^^^^^^^^^^^ expected `{not_one as fn(usize) -> bool}`, found `{not_two as fn(usize) -> bool}`
|
||||
|
|
||||
= note: expected type `{not_one as fn(usize) -> bool}`
|
||||
found type `{not_two as fn(usize) -> bool}`
|
||||
LL | struct Checked<const F: fn(usize) -> bool>;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-const-param-infer.rs:20:24
|
||||
|
|
||||
LL | let _ = Checked::<{generic_arg::<u32>}>;
|
||||
| ^^^^^^^^^^^^^^^^^^ expected `usize`, found `u32`
|
||||
|
|
||||
= note: expected fn pointer `fn(usize) -> _`
|
||||
found fn item `fn(u32) -> _ {generic_arg::<u32>}`
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/fn-const-param-infer.rs:22:23
|
||||
|
|
||||
LL | let _ = Checked::<generic>;
|
||||
| ^^^^^^^ cannot infer type for type parameter `T` declared on the function `generic`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-const-param-infer.rs:25:40
|
||||
|
|
||||
LL | let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{generic::<u32> as fn(usize) -> bool}`, found `{generic::<u16> as fn(usize) -> bool}`
|
||||
|
|
||||
= note: expected type `{generic::<u32> as fn(usize) -> bool}`
|
||||
found type `{generic::<u16> as fn(usize) -> bool}`
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0282, E0308.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, const_compare_raw_pointers)]
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
const A: u32 = 3;
|
||||
|
||||
struct Const<const P: *const u32>;
|
||||
struct Const<const P: *const u32>; //~ ERROR: using raw pointers as const generic parameters
|
||||
|
||||
impl<const P: *const u32> Const<P> {
|
||||
impl<const P: *const u32> Const<P> { //~ ERROR: using raw pointers as const generic parameters
|
||||
fn get() -> u32 {
|
||||
unsafe {
|
||||
*P
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/raw-ptr-const-param-deref.rs:2:12
|
||||
--> $DIR/raw-ptr-const-param-deref.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics, const_compare_raw_pointers)]
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
error: using raw pointers as const generic parameters is forbidden
|
||||
--> $DIR/raw-ptr-const-param-deref.rs:6:23
|
||||
|
|
||||
LL | struct Const<const P: *const u32>;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: using raw pointers as const generic parameters is forbidden
|
||||
--> $DIR/raw-ptr-const-param-deref.rs:8:15
|
||||
|
|
||||
LL | impl<const P: *const u32> Const<P> {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#![feature(const_generics, const_compare_raw_pointers)]
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
struct Const<const P: *const u32>;
|
||||
struct Const<const P: *const u32>; //~ ERROR: using raw pointers as const generic parameters
|
||||
|
||||
fn main() {
|
||||
let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>; //~ mismatched types
|
||||
let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>;
|
||||
let _: Const<{ 10 as *const _ }> = Const::<{ 10 as *const _ }>;
|
||||
}
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/raw-ptr-const-param.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics, const_compare_raw_pointers)]
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/raw-ptr-const-param.rs:7:40
|
||||
error: using raw pointers as const generic parameters is forbidden
|
||||
--> $DIR/raw-ptr-const-param.rs:4:23
|
||||
|
|
||||
LL | let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{0xf as *const u32}`, found `{0xa as *const u32}`
|
||||
|
|
||||
= note: expected type `{0xf as *const u32}`
|
||||
found type `{0xa as *const u32}`
|
||||
LL | struct Const<const P: *const u32>;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
#![feature(const_raw_ptr_to_usize_cast, const_compare_raw_pointers, const_raw_ptr_deref)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
// unconst and bad, will thus error in miri
|
||||
const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this
|
||||
const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR cannot be compared
|
||||
// unconst and bad, will thus error in miri
|
||||
const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR any use of this
|
||||
// unconst and fine
|
||||
const Y: usize = unsafe { 42usize as *const i32 as usize + 1 };
|
||||
// unconst and bad, will thus error in miri
|
||||
const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; //~ ERROR any use of this
|
||||
// unconst and fine
|
||||
const Z: i32 = unsafe { *(&1 as *const i32) };
|
||||
// unconst and bad, will thus error in miri
|
||||
const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR any use of this value will cause
|
||||
const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR any use of this value will cause
|
||||
const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR cannot be compared
|
||||
|
|
|
@ -1,44 +1,20 @@
|
|||
error: any use of this value will cause an error
|
||||
--> $DIR/const_raw_ptr_ops.rs:6:26
|
||||
error: pointers cannot be compared in a meaningful way during const eval.
|
||||
--> $DIR/const_raw_ptr_ops.rs:4:26
|
||||
|
|
||||
LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 };
|
||||
| -------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= note: It is conceptually impossible for const eval to know in all cases whether two pointers are equal. While sometimes it is clear (the address of a static item is never equal to the address of another static item), comparing an integer address with any allocation's address is impossible to do at compile-time.
|
||||
= note: That said, there's the `ptr_maybe_eq` intrinsic which returns `true` for all comparisons where CTFE isn't sure whether two addresses are equal. The mirror intrinsic `ptr_maybe_ne` returns `true` for all comparisons where CTFE isn't sure whether two addresses are inequal.
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_raw_ptr_ops.rs:8:27
|
||||
error: pointers cannot be compared in a meaningful way during const eval.
|
||||
--> $DIR/const_raw_ptr_ops.rs:6:27
|
||||
|
|
||||
LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 };
|
||||
| --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_raw_ptr_ops.rs:12:28
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
LL | const Y2: usize = unsafe { &1 as *const i32 as usize + 1 };
|
||||
| ---------------------------^^^^^^^^^^^^^^^^^^^^^^^^^-------
|
||||
| |
|
||||
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||
= note: It is conceptually impossible for const eval to know in all cases whether two pointers are equal. While sometimes it is clear (the address of a static item is never equal to the address of another static item), comparing an integer address with any allocation's address is impossible to do at compile-time.
|
||||
= note: That said, there's the `ptr_maybe_eq` intrinsic which returns `true` for all comparisons where CTFE isn't sure whether two addresses are equal. The mirror intrinsic `ptr_maybe_ne` returns `true` for all comparisons where CTFE isn't sure whether two addresses are inequal.
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_raw_ptr_ops.rs:16:26
|
||||
|
|
||||
LL | const Z2: i32 = unsafe { *(42 as *const i32) };
|
||||
| -------------------------^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| unable to turn bytes into a pointer
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_raw_ptr_ops.rs:17:26
|
||||
|
|
||||
LL | const Z3: i32 = unsafe { *(44 as *const i32) };
|
||||
| -------------------------^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| unable to turn bytes into a pointer
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
13
src/test/ui/consts/const-eval/const_raw_ptr_ops2.rs
Normal file
13
src/test/ui/consts/const-eval/const_raw_ptr_ops2.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
#![feature(const_raw_ptr_to_usize_cast, const_raw_ptr_deref)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
// unconst and fine
|
||||
const Y: usize = unsafe { 42usize as *const i32 as usize + 1 };
|
||||
// unconst and bad, will thus error in miri
|
||||
const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; //~ ERROR any use of this
|
||||
// unconst and fine
|
||||
const Z: i32 = unsafe { *(&1 as *const i32) };
|
||||
// unconst and bad, will thus error in miri
|
||||
const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR any use of this value will cause
|
||||
const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR any use of this value will cause
|
28
src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr
Normal file
28
src/test/ui/consts/const-eval/const_raw_ptr_ops2.stderr
Normal file
|
@ -0,0 +1,28 @@
|
|||
error: any use of this value will cause an error
|
||||
--> $DIR/const_raw_ptr_ops2.rs:8:28
|
||||
|
|
||||
LL | const Y2: usize = unsafe { &1 as *const i32 as usize + 1 };
|
||||
| ---------------------------^^^^^^^^^^^^^^^^^^^^^^^^^-------
|
||||
| |
|
||||
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_raw_ptr_ops2.rs:12:26
|
||||
|
|
||||
LL | const Z2: i32 = unsafe { *(42 as *const i32) };
|
||||
| -------------------------^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| unable to turn bytes into a pointer
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_raw_ptr_ops2.rs:13:26
|
||||
|
|
||||
LL | const Z3: i32 = unsafe { *(44 as *const i32) };
|
||||
| -------------------------^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| unable to turn bytes into a pointer
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(const_raw_ptr_to_usize_cast, const_compare_raw_pointers, const_raw_ptr_deref)]
|
||||
#![feature(const_raw_ptr_to_usize_cast, const_raw_ptr_deref)]
|
||||
|
||||
fn main() {
|
||||
let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
|
||||
|
|
|
@ -12,7 +12,7 @@ LL | let _v = x + 0;
|
|||
|
||||
warning: skipping const checks
|
||||
|
|
||||
help: skipping check for `const_compare_raw_pointers` feature
|
||||
help: skipping check that does not even have a feature gate
|
||||
--> $DIR/ptr_arith.rs:9:14
|
||||
|
|
||||
LL | let _v = x == x;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
// gate-test-const_compare_raw_pointers
|
||||
|
||||
static FOO: i32 = 42;
|
||||
static BAR: i32 = 42;
|
||||
|
||||
static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) };
|
||||
//~^ ERROR comparing raw pointers inside static
|
||||
//~^ ERROR pointers cannot be compared in a meaningful way during const eval
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
error[E0658]: comparing raw pointers inside static
|
||||
--> $DIR/E0395.rs:6:29
|
||||
error: pointers cannot be compared in a meaningful way during const eval.
|
||||
--> $DIR/E0395.rs:4:29
|
||||
|
|
||||
LL | static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
||||
= help: add `#![feature(const_compare_raw_pointers)]` to the crate attributes to enable
|
||||
= note: It is conceptually impossible for const eval to know in all cases whether two pointers are equal. While sometimes it is clear (the address of a static item is never equal to the address of another static item), comparing an integer address with any allocation's address is impossible to do at compile-time.
|
||||
= note: That said, there's the `ptr_maybe_eq` intrinsic which returns `true` for all comparisons where CTFE isn't sure whether two addresses are equal. The mirror intrinsic `ptr_maybe_ne` returns `true` for all comparisons where CTFE isn't sure whether two addresses are inequal.
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
struct ConstFn<const F: fn()>;
|
||||
//~^ ERROR const generics are unstable
|
||||
//~^^ ERROR using function pointers as const generic parameters is unstable
|
||||
//~^^ ERROR using function pointers as const generic parameters is forbidden
|
||||
|
||||
struct ConstPtr<const P: *const u32>;
|
||||
//~^ ERROR const generics are unstable
|
||||
//~^^ ERROR using raw pointers as const generic parameters is unstable
|
||||
//~^^ ERROR using raw pointers as const generic parameters is forbidden
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -16,23 +16,17 @@ LL | struct ConstPtr<const P: *const u32>;
|
|||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
= help: add `#![feature(const_generics)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: using function pointers as const generic parameters is unstable
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/feature-gate-const_generics-ptr.rs:1:25
|
||||
|
|
||||
LL | struct ConstFn<const F: fn()>;
|
||||
| ^^^^
|
||||
|
|
||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
||||
= help: add `#![feature(const_compare_raw_pointers)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: using raw pointers as const generic parameters is unstable
|
||||
error: using raw pointers as const generic parameters is forbidden
|
||||
--> $DIR/feature-gate-const_generics-ptr.rs:5:26
|
||||
|
|
||||
LL | struct ConstPtr<const P: *const u32>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
||||
= help: add `#![feature(const_compare_raw_pointers)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn id<T>(t: T) -> T { t }
|
||||
fn main() {
|
||||
const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
||||
//~^ ERROR comparing raw pointers inside constant
|
||||
//~^ ERROR pointers cannot be compared in a meaningful way during const eval
|
||||
println!("{}", A);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
error[E0658]: comparing raw pointers inside constant
|
||||
error: pointers cannot be compared in a meaningful way during const eval.
|
||||
--> $DIR/issue-25826.rs:3:30
|
||||
|
|
||||
LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
|
||||
= help: add `#![feature(const_compare_raw_pointers)]` to the crate attributes to enable
|
||||
= note: It is conceptually impossible for const eval to know in all cases whether two pointers are equal. While sometimes it is clear (the address of a static item is never equal to the address of another static item), comparing an integer address with any allocation's address is impossible to do at compile-time.
|
||||
= note: That said, there's the `ptr_maybe_eq` intrinsic which returns `true` for all comparisons where CTFE isn't sure whether two addresses are equal. The mirror intrinsic `ptr_maybe_ne` returns `true` for all comparisons where CTFE isn't sure whether two addresses are inequal.
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#![stable(feature = "foo", since = "1.33.0")]
|
||||
#![feature(staged_api)]
|
||||
#![feature(const_compare_raw_pointers)]
|
||||
#![feature(const_raw_ptr_deref)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
#[stable(feature = "foo", since = "1.33.0")]
|
||||
#[rustc_const_unstable(feature = "const_foo", issue = "none")]
|
||||
const fn unstable(a: *const i32, b: *const i32) -> bool {
|
||||
a == b
|
||||
//~^ pointer operation is unsafe
|
||||
const fn unstable(a: *const i32, b: i32) -> bool {
|
||||
*a == b
|
||||
//~^ dereference of raw pointer is unsafe
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0133]: pointer operation is unsafe and requires unsafe function or block
|
||||
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-unstable-const-fn.rs:9:5
|
||||
|
|
||||
LL | a == b
|
||||
| ^^^^^^ pointer operation
|
||||
LL | *a == b
|
||||
| ^^ dereference of raw pointer
|
||||
|
|
||||
= note: operations on pointers in constants
|
||||
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue