Skip to content

Constants and statics are not required to be Sized. #34390

Closed
@eddyb

Description

@eddyb

This looks unintentional, and has been broken in all cases, until a few releases ago, AFAICT.
Should this be covered by WF rules? cc @rust-lang/lang @ubsan @solson

Unsized constants cause an ICE, in both old trans and MIR trans:

// rustc_trans/consts.rs:445: const expr(35: &S) of type &str has size 8 instead of 16
// rustc_trans/mir/constant.rs:175: loading from `str`
//     ((i8*:i8* getelementptr inbounds ([3 x i8], [3 x i8]* @str7144, i32 0, i32 0)))
//     in constant
const S: str = *"foo";
fn main() { println!("{}", &S); }

Unsized statics appear to work, but only in old trans:

use std::fmt::Debug;
static FOO: Debug+Sync = *(&1 as &(Debug+Sync));
static S: str = *"foo";
fn main() { println!("{:?} {}", &FOO, &S); }

I believe this is possible because a constant DST lvalue in old trans is merely the fat pointer.
It seems useful to allow an unsized static, but IMO it should require a sized RHS instead, i.e.:

static A: [i32] = [1, 2, 3];
fn main() { let x = A[0]; ... }
// as sugar for:
static A_SIZED: [i32; 3] = [1, 2, 3];
static A: &'static [i32] = &A_SIZED;
fn main() { let x = (*A)[0]; ... }

And, of course, this should all go through the RFC process, to figure out all the finer details.

Metadata

Metadata

Assignees

Labels

I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-langRelevant to the language team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions