Skip to content

Conversation

@manhatsu
Copy link
Contributor

Added new guideline on unions by @rcseacord.

This is the same content as #270 but moved to the feature branch.

@netlify
Copy link

netlify bot commented Dec 16, 2025

Deploy Preview for scrc-coding-guidelines ready!

Name Link
🔨 Latest commit 945d8f0
🔍 Latest deploy log https://app.netlify.com/projects/scrc-coding-guidelines/deploys/694c9afa434667000815c7f1
😎 Deploy Preview https://deploy-preview-300--scrc-coding-guidelines.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@rcseacord
Copy link
Collaborator

@PLeVasseur @felix91gr I did a final cleanup and this rule LGTM. Please review & approve

@rcseacord rcseacord self-assigned this Dec 16, 2025
Copy link
Contributor

@iglesias iglesias left a comment

Choose a reason for hiding this comment

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

I left a couple of comments. Otherwise it was all clear. One is a question about a line I wasn't sure about and the other just a typo fix suggestion.

@felix91gr
Copy link
Collaborator

@PLeVasseur @felix91gr I did a final cleanup and this rule LGTM. Please review & approve

Alright, it goes into the queue.

@PLeVasseur
Copy link
Collaborator

PLeVasseur commented Dec 17, 2025

@PLeVasseur @felix91gr I did a final cleanup and this rule LGTM. Please review & approve

Alright, it goes into the queue.

Hey @felix91gr -- did you take a look at this one yet? I'd like it to be reviewed before we queue it up

(I'll try to make time to review some of @rcseacord's latest ones tomorrow, this included, if it's not been reviewed by you yet)

@felix91gr
Copy link
Collaborator

I'd like it to be reviewed before we queue it up

@PLeVasseur ah, sorry! I forgot we have a Merge Queue as well. I meant it as my own task queue, my bad. I haven't reviewed it yet

Copy link
Collaborator

@PLeVasseur PLeVasseur left a comment

Choose a reason for hiding this comment

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

Hey thanks for pulling this together @manhatsu and @rcseacord

Given that adding the bibliography bit touches quite a few other things, I'd suggest backing that out of this PR if you'd like the guideline to be reviewed on its merits and merged sooner than later.

I've opened issue #306 to track the work towards the work for a bibliography.

@manhatsu manhatsu force-pushed the doc/union-field-validation branch from 0431525 to 696e633 Compare December 19, 2025 02:27
@manhatsu
Copy link
Contributor Author

There is a duplication of URL in these two documents:
expressions/gui_Bib7x9KmPq2nL.rst.inc and types-and-traits/gui_0cuTYG8RVYjg.rst.inc.
bibliography.md says I should consider this, but how can I actually solve this?
I think it's fine if both have the source entry...

@manhatsu manhatsu requested a review from PLeVasseur December 19, 2025 02:41
@PLeVasseur
Copy link
Collaborator

There is a duplication of URL in these two documents: expressions/gui_Bib7x9KmPq2nL.rst.inc and types-and-traits/gui_0cuTYG8RVYjg.rst.inc. bibliography.md says I should consider this, but how can I actually solve this? I think it's fine if both have the source entry...

Yeah, you're right. I didn't have this implemented correctly. Duplicate URLs should be fine, what I wanted to have was for the same URL to force consistent referencing to be used.

I've pushed #335 which should fix this.

Please take a look at the following and rebase:
https://github.com/rustfoundation/safety-critical-rust-coding-guidelines/blob/main/docs/bibliography.md

@PLeVasseur PLeVasseur force-pushed the doc/union-field-validation branch from 696e633 to 99551c2 Compare December 23, 2025 22:35
@PLeVasseur
Copy link
Collaborator

I rebased this on main. It's building and working now.

Copy link
Collaborator

@PLeVasseur PLeVasseur left a comment

Choose a reason for hiding this comment

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

This is somewhat a procedural review to get this in-line with current best practices as outlined in CONTRIBUTING.md.

I haven't reviewed the contents of the guideline yet.

Please update and I can then take a look through content.

@manhatsu manhatsu requested a review from PLeVasseur December 24, 2025 00:16
@PLeVasseur
Copy link
Collaborator

@guidelines-bot /claim

@github-actions github-actions bot requested review from PLeVasseur and removed request for PLeVasseur and felix91gr December 24, 2025 14:07
@github-actions
Copy link
Contributor

@PLeVasseur has claimed this review (previously: @PLeVasseur, @felix91gr).

Copy link
Collaborator

@PLeVasseur PLeVasseur left a comment

Choose a reason for hiding this comment

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

Okay, have now reviewed the contents.

Overall this looks really good.

Please take a look at the comments and suggestions I left.


.. rust-example::

union IntOrBool {
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about this? The goal is to show this in a situation / light that mimics code we might see used.

  1. We make the union #[repr(C)] as most of the time we'll be doing this to interact over FFI
  2. We put // SAFETY: comments above usages of unsafe; still kept in there that we're therefore compliant
  3. We use assert_eq!() instead of println!() so that we can test for equivalence
#[repr(C)]
#[derive(Copy, Clone)]
union IntOrBoolData {
    i: u8,
    b: bool,
}

/// Tracks which field of the union is currently active.
#[derive(Clone, Copy, PartialEq, Eq)]
enum ActiveField {
    Int,
    Bool,
}

/// A union wrapper that tracks the active field at runtime.
pub struct IntOrBool {
    data: IntOrBoolData,
    active: ActiveField,
}

impl IntOrBool {
    pub fn from_int(value: u8) -> Self {
        Self {
            data: IntOrBoolData { i: value },
            active: ActiveField::Int,
        }
    }

    pub fn from_bool(value: bool) -> Self {
        Self {
            data: IntOrBoolData { b: value },
            active: ActiveField::Bool,
        }
    }

    pub fn set_int(&mut self, value: u8) {
        self.data.i = value;
        self.active = ActiveField::Int;
    }

    pub fn set_bool(&mut self, value: bool) {
        self.data.b = value;
        self.active = ActiveField::Bool;
    }

    /// Returns the integer value if that field is active.
    pub fn as_int(&self) -> Option<u8> {
        match self.active {
            // SAFETY: We only read `i` when we know it was last written as `i`, thus compliant
            ActiveField::Int => Some(unsafe { self.data.i }),
            ActiveField::Bool => None,
        }
    }

    /// Returns the boolean value if that field is active.
    pub fn as_bool(&self) -> Option<bool> {
        match self.active {
            // SAFETY: We only read `b` when we know it was last written as `b`, thus compliant
            ActiveField::Bool => Some(unsafe { self.data.b }),
            ActiveField::Int => None,
        }
    }
}

fn main() {
    let mut value = IntOrBool::from_bool(true);
    assert_eq!(value.as_bool(), Some(true));
    assert_eq!(value.as_int(), None);

    value.set_int(42);
    assert_eq!(value.as_bool(), None);
    assert_eq!(value.as_int(), Some(42));
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this program have to do something so it's not all optimized away? Maybe return value?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess it doesn't matter. It's hard to make this code do something meaningful. A good optimizer is just going to return a constant value.

Copy link
Collaborator

Choose a reason for hiding this comment

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

resolved by d70df8d

Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this program have to do something so it's not all optimized away?

Assertions are never optimized away, by design. So whatever this program asserts, it will always be tested.

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK, there are also debug assertions that are removed from the release build.


.. rust-example::

union IntOrBool {
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about this?

  1. We make the union #[repr(C)] as most of the time we'll be doing this to interact over FFI
  2. We put // SAFETY: comments above usages of unsafe; still kept in there that we're therefore compliant
  3. We use assert_eq!() instead of println!() so that we can test for equivalence
#[repr(C)]
union IntOrBool {
    i: u8,
    b: bool,
}
fn main() {
    let u = IntOrBool { b: true };
    
    // SAFETY: Read the same field that was written, thus compliant
    assert_eq!(unsafe { u.b }, true); // compliant
}

rcseacord and others added 6 commits December 24, 2025 11:44
updated example based on comment from @PLeVasseur
update example based on comment from @PLeVasseur
Updated comments for clarity and compliance in examples.
function with main doesn't have a main apparently
Copy link
Collaborator

@PLeVasseur PLeVasseur left a comment

Choose a reason for hiding this comment

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

Nice, thanks for the revisions.

LGTM

@PLeVasseur PLeVasseur added this pull request to the merge queue Dec 31, 2025
Merged via the queue into rustfoundation:main with commit a9d650f Dec 31, 2025
13 checks passed
@PLeVasseur PLeVasseur deleted the doc/union-field-validation branch December 31, 2025 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants