Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP crater experiment: do not promote const fn calls implicitly ever #80243

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions compiler/rustc_mir/src/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,14 +692,9 @@ impl<'tcx> Validator<'_, 'tcx> {
) -> Result<(), Unpromotable> {
let fn_ty = callee.ty(self.body, self.tcx);

// When doing explicit promotion and inside const/static items, we promote all (eligible) function calls.
// When doing explicit promotion, we promote all (eligible) function calls.
// Everywhere else, we require `#[rustc_promotable]` on the callee.
let promote_all_const_fn = self.explicit
|| matches!(
self.const_kind,
Some(hir::ConstContext::Static(_) | hir::ConstContext::Const)
);
if !promote_all_const_fn {
if !self.explicit {
if let ty::FnDef(def_id, _) = *fn_ty.kind() {
// Never promote runtime `const fn` calls of
// functions without `#[rustc_promotable]`.
Expand Down
1 change: 1 addition & 0 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl<T: ?Sized> *const T {
/// Casts to a pointer of another type.
#[stable(feature = "ptr_cast", since = "1.38.0")]
#[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
#[rustc_promotable] // Operation cannot fail, so it may be promoted.
#[inline]
pub const fn cast<U>(self) -> *const U {
self as _
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
/// ```
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
#[rustc_promotable] // Operation cannot fail, so it may be promoted.
#[rustc_const_stable(feature = "const_ptr_null", since = "1.32.0")]
pub const fn null<T>() -> *const T {
0 as *const T
Expand All @@ -214,7 +214,7 @@ pub const fn null<T>() -> *const T {
/// ```
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
#[rustc_promotable] // Operation cannot fail, so it may be promoted.
#[rustc_const_stable(feature = "const_ptr_null", since = "1.32.0")]
pub const fn null_mut<T>() -> *mut T {
0 as *mut T
Expand Down
1 change: 1 addition & 0 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl<T: ?Sized> *mut T {
/// Casts to a pointer of another type.
#[stable(feature = "ptr_cast", since = "1.38.0")]
#[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
#[rustc_promotable] // Operation cannot fail, so it may be promoted.
#[inline]
pub const fn cast<U>(self) -> *mut U {
self as _
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ impl<T> [T] {
/// [`as_mut_ptr`]: #method.as_mut_ptr
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")]
#[rustc_promotable] // Operation cannot fail, so it may be promoted.
#[inline]
pub const fn as_ptr(&self) -> *const T {
self as *const [T] as *const T
Expand Down Expand Up @@ -432,6 +433,7 @@ impl<T> [T] {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
#[rustc_promotable] // Operation cannot fail, so it may be promoted.
#[inline]
pub const fn as_mut_ptr(&mut self) -> *mut T {
self as *mut [T] as *mut T
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/net/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ impl Ipv4Addr {
/// let addr = Ipv4Addr::new(127, 0, 0, 1);
/// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")]
#[rustc_promotable] // Operation cannot fail, so it may be promoted.
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
// `s_addr` is stored as BE on all machine and the array is in BE order.
Expand Down Expand Up @@ -1045,6 +1046,7 @@ impl Ipv6Addr {
/// ```
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
#[rustc_promotable] // Operation cannot fail, so it may be promoted.
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
let addr16 = [
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/ub-ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
//~^ ERROR it is undefined behavior to use this value

const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute(&[&0] as &[_]) };
//~^ ERROR it is undefined behavior to use this value

const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/ub-ref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref.rs:29:1
|
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain (non-pointer) bytes
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute(&[&0] as &[_]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain (non-pointer) bytes
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// run-pass

#![allow(unused)]
#![allow(unused, incomplete_features)]
#![feature(const_in_array_repeat_expressions)]
#![feature(inline_const)]

// Some type that is not copyable.
struct Bar;
Expand All @@ -16,8 +17,6 @@ const fn type_copy() -> u32 {

const _: [u32; 2] = [type_copy(); 2];

// This is allowed because all promotion contexts use the explicit rules for promotability when
// inside an explicit const context.
const _: [Option<Bar>; 2] = [type_no_copy(); 2];
const _: [Option<Bar>; 2] = [const { type_no_copy() }; 2];

fn main() {}