Skip to content

Implement the special repr(C)-non-clike-enum layout - #46123

Merged
bors merged 4 commits into
rust-lang:masterfrom
Gankra:c-repr
Nov 28, 2017
Merged

Implement the special repr(C)-non-clike-enum layout#46123
bors merged 4 commits into
rust-lang:masterfrom
Gankra:c-repr

Conversation

@Gankra

@Gankra Gankra commented Nov 20, 2017

Copy link
Copy Markdown
Contributor

This is the second half of rust-lang/rfcs#2195

which specifies that

#[repr(C, u8)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
enum MyEnum {
    A(u32),                 // Single primitive value
    B { x: u8, y: i16 },    // Composite, and the offset of `y` depends on tag being internal
    C,                      // Empty
    D(Option<u32>),         // Contains an enum
    E(Duration),            // Contains a struct
}

Has the same layout as

#[repr(C)]
struct MyEnumRepr {
    tag: MyEnumTag,
    payload: MyEnumPayload,
}

#[repr(C)]
#[allow(non_snake_case)]
union MyEnumPayload {
    A: MyEnumVariantA,
    B: MyEnumVariantB,
    D: MyEnumVariantD,
    E: MyEnumVariantE,
}

#[repr(u8)] #[derive(Copy, Clone)] enum MyEnumTag { A, B, C, D, E }
#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantA(u32);
#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantB {x: u8, y: i16 }
#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantD(Option<u32>);
#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantE(Duration);

@rust-highfive

Copy link
Copy Markdown
Contributor

r? @petrochenkov

(rust_highfive has picked a reviewer for you, use r? to override)

@Gankra

Gankra commented Nov 20, 2017

Copy link
Copy Markdown
Contributor Author

r? @eddyb

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not using this, are you?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind.

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 20, 2017
@Gankra

Gankra commented Nov 20, 2017

Copy link
Copy Markdown
Contributor Author

Changed impl to reflect discussion in IRC. Also fixed a test that was asserting the old behaviour.

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this to Prefixed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, forgot!

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer naming this optimize, making it mutable, and &=-ing it below instead.

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant was that you wouldn't need special discriminant vs union semantics, just applying a size&align prefix.

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this to prefix_align, I guess.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it's not how aligned the prefix should be, it's how aligned the suffix should be.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the alignment imposed by the prefix, the logic looking at it need not know why it's chosen the way it is.

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&variants

@Gankra

Gankra commented Nov 20, 2017

Copy link
Copy Markdown
Contributor Author

Comments addressed

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change the comment to say "with a prefix of an arbitrary size & alignment (e.g. enum tag)" instead of "but part of an enum"?

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefix_size instead of discr_size should do nicely.

Comment thread src/librustc/ty/layout.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment could be expanded to describe how increasing the prefix alignment produces the same variant layouts as if they were separately computed as structs and then had some space inserted in the front.

@eddyb

eddyb commented Nov 20, 2017

Copy link
Copy Markdown
Contributor

cc @rust-lang/compiler @rust-lang/lang LGTM, should this wait on the RFC / have a FCP?

@Gankra

Gankra commented Nov 20, 2017

Copy link
Copy Markdown
Contributor Author

Comments addressed.

@kennytm kennytm added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Nov 23, 2017
@kennytm kennytm added the T-lang Relevant to the language team label Nov 23, 2017
@carols10cents

carols10cents commented Nov 27, 2017

Copy link
Copy Markdown
Member

eddyb (Eduard-Mihai Burtescu) approved these changes 7 days ago

soooo do I hear an r+ @eddyb? or an fcp merge? :)

@eddyb

eddyb commented Nov 27, 2017

Copy link
Copy Markdown
Contributor

@carols10cents But nobody answered...

@nikomatsakis

Copy link
Copy Markdown
Contributor

hould this wait on the RFC / have a FCP?

I do expect the RFC to be accepted, but I don't believe we have to block on it. I believe the current behavior is undefined, so we are within our rights to adjust it.

FCP might be reasonable, though I think not really necessary, I don't feel like major controversy is expected here.

@eddyb

eddyb commented Nov 28, 2017

Copy link
Copy Markdown
Contributor

@bors r+

@bors

bors commented Nov 28, 2017

Copy link
Copy Markdown
Collaborator

📌 Commit 904ccbc has been approved by eddyb

@bors

bors commented Nov 28, 2017

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 904ccbc9c2b1f8f24664a7ef89071738954f0028 with merge 2e0fd271c40ec90c0d6fa5b99929b81f12413d63...

@bors

bors commented Nov 28, 2017

Copy link
Copy Markdown
Collaborator

💔 Test failed - status-travis

@Gankra

Gankra commented Nov 28, 2017

Copy link
Copy Markdown
Contributor Author

uhhh so apparently

#[repr(u64)]
enum E6 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

is 16 bytes on i586-gnu-i686-musl, but u64 is only aligned to 4 bytes?

wat

[00:50:11] thread 'main' panicked at 'assertion failed: `(left == right)`
[00:50:11]   left: `16`,
[00:50:11]  right: `12`', /checkout/src/test/run-pass/multiple-reprs.rs:78:4
    assert_eq!(size_of::<E6>(), align_size(12, align_of::<u64>()));

@Gankra

Gankra commented Nov 28, 2017

Copy link
Copy Markdown
Contributor Author

nevermind, I'm dumb. 6 + 8 != 12. On 64-bit that error didn't matter.

@eddyb

eddyb commented Nov 28, 2017

Copy link
Copy Markdown
Contributor

@bors r+

@bors

bors commented Nov 28, 2017

Copy link
Copy Markdown
Collaborator

📌 Commit 0e63d27 has been approved by eddyb

@bors

bors commented Nov 28, 2017

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 0e63d27 with merge 436ac89...

bors added a commit that referenced this pull request Nov 28, 2017
Implement the special repr(C)-non-clike-enum layout

This is the second half of rust-lang/rfcs#2195

which specifies that

```rust
#[repr(C, u8)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
enum MyEnum {
    A(u32),                 // Single primitive value
    B { x: u8, y: i16 },    // Composite, and the offset of `y` depends on tag being internal
    C,                      // Empty
    D(Option<u32>),         // Contains an enum
    E(Duration),            // Contains a struct
}
```

Has the same layout as

```rust
#[repr(C)]
struct MyEnumRepr {
    tag: MyEnumTag,
    payload: MyEnumPayload,
}

#[repr(C)]
#[allow(non_snake_case)]
union MyEnumPayload {
    A: MyEnumVariantA,
    B: MyEnumVariantB,
    D: MyEnumVariantD,
    E: MyEnumVariantE,
}

#[repr(u8)] #[derive(Copy, Clone)] enum MyEnumTag { A, B, C, D, E }
#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantA(u32);
#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantB {x: u8, y: i16 }
#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantD(Option<u32>);
#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantE(Duration);

```
@bors

bors commented Nov 28, 2017

Copy link
Copy Markdown
Collaborator

☀️ Test successful - status-appveyor, status-travis
Approved by: eddyb
Pushing 436ac89 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants