Skip to content

convention issue: structs with all pub fields are a hazard and should be avoided in libstd #22045

Closed
@pnkfelix

Description

@pnkfelix

Tuple structs are convenient at times, but they present issues for forward compatibility, especially (but not only) when they carry all pub fields

Example: std::ptr::Unique is currently defined as follows:

#[unstable(feature = "core", reason = "recently added to this module")]
pub struct Unique<T: ?Sized>(pub *mut T);

This is unfortunate, since assuming rust-lang/rfcs#738 is accepted (namely the PhantomData part, which I need for rust-lang/rfcs#769), we really should add PhantomData<T> as a member of Unique<T>.

So, why did we use tuple structs instead of a struct with private named fields?

I suspect it was for the convenience of the person authoring the library when it was first made. But these details end up leaking out to the users of these modules, and there does not seem to be much reason for it. The main use of a tuple-struct in a case like this is for composability with pattern matching, but I do not think that use outweighs the cost of being stuck with an API that hinders future changes to the internals of the stdlib.


Another related case where this comes up: we currently define std::boxed::Box as a tuple struct. Now, its only field is non-pub. However, the use of a tuple struct here puts Box itself into the value namespace, and thus the name Box in the value namespace of the prelude is essentially unavailable for any useful purpose. I think this is a bug in that API design; see my comment here: rust-lang/rfcs#809 (comment)

UPDATE: I have been convinced that tuple structs with a non-pub field are not a real hazard (see reasoning in my comment below).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions