Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC: Deprecate type aliases in std::os::*::raw #1415
Conversation
alexcrichton
self-assigned this
Dec 18, 2015
alexcrichton
added
the
T-libs
label
Dec 18, 2015
This was referenced Dec 18, 2015
cuviper
reviewed
Dec 18, 2015
| platform specific modules. All type aliases can be switched over to `u64` and | ||
| the `stat` structure could simply be redefined to `stat64` on Linux (minus | ||
| keeping the same name). This would, however, explicitly mean that | ||
| **std::os::raw is no longer FFI compatible with C**. |
This comment has been minimized.
This comment has been minimized.
cuviper
Dec 18, 2015
Member
Right, but as your motivation says, the current FFI compatibility is a bit of an illusion anyway, thanks to LFS -DFILE_OFFSET_BITS.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Dec 18, 2015
Author
Member
Yeah that's a good point! There's sort of a case to be made with "well they're FFI compatible if you pass no flags to the compiler", but that's shaky at best at this point.
cuviper
reviewed
Dec 18, 2015
|
|
||
| * Is the policy of almost always returning `u64` too strict? Should types like | ||
| `mode_t` be allowed as `i32` explicitly? Should the sign at least attempt to | ||
| always be preserved? |
This comment has been minimized.
This comment has been minimized.
cuviper
Dec 18, 2015
Member
I'd aim for lossless casts only. Widening should always be safe, but it would be bad to lose the sign on something like time_t. For another example, dev_t is u64 on Linux and i32 on OSX -- there's no universal upcast for these (i128?), so it will have to have platform-specific signedness. (Consider using integer From/Into instead of manual as casts to keep things safe.)
This comment has been minimized.
This comment has been minimized.
alexcrichton
Dec 18, 2015
Author
Member
Yeah I'd definitely want to only go below 64 bits if we're 100% absolutely positive that they're not necessary. For example anything related to timestamps, sizes, amounts, etc, will be 64 bits. I also think it's fine that even if dev_t is i32 on OSX if we return it as u64 that seems fine to me (it'll just require some fiddling to get the real value back out).
I guess I'm mostly wondering here that if all current platforms agree that a type should be signed, should we return it as i64? I think the answer should be yes, but it makes it somewhat more difficult to select what the best type to return is.
This comment has been minimized.
This comment has been minimized.
cuviper
Dec 19, 2015
Member
It's a tricky question, and I think it has to be considered case-by-case. Take file size, for instance -- I can't think of any reasonable scenario where this would be negative, so Metadata::len() -> u64 makes sense. But every platform uses a signed type for stat.st_size, usually signed off_t, so seek offsets can be negative. Rust's Seek and SeekFrom already reflects this signed/unsigned conceptual split. So what should MetadataExt::size() return?
This comment has been minimized.
This comment has been minimized.
alexcrichton
Dec 19, 2015
Author
Member
Hm that is a good question! I had no idea everything was signed everywhere.
In some sense it doesn't matter too much so long as we ship the bits in some form out of the standard library in a lossless fashion, even if it's just painful to recover on the other end. I do think, though, that for MetadataExt::size it should definitely return u64 (like the standard library already does)
This comment has been minimized.
This comment has been minimized.
briansmith
Feb 1, 2016
For example anything related to timestamps, sizes, amounts, etc, will be 64 bits.
I think it is worth thinking about this in the context of very (small) embedded devices where it is desirable for variables to hold these types of values to be small in memory, and which might trade off support for large things in favor of smaller memory requirements.
I think timestamps are the only thing that should be assumed to be larger than 32-bits.
tbu-
reviewed
Dec 23, 2015
| suffice. This will improve consistency across platforms as well as avoid | ||
| truncation problems such as those Android is experiencing. Furthermore this | ||
| frees std from dealing with any odd FFI compatibility issues, punting that to | ||
| the libc crate itself it the values are handed back into C. |
This comment has been minimized.
This comment has been minimized.
tbu-
Dec 23, 2015
Contributor
What should happen if you pass a large integer to such a u64 parameter on a platform that internally has u32 as a type? Should the Rust code panic? Should it silently truncate the value?
This comment has been minimized.
This comment has been minimized.
cuviper
Dec 23, 2015
Member
Most of the types in question are only return values, AFAICS, except for mode_t which I think is fine to leave as its smaller native type. Any specific parameters you're concerned about?
This comment has been minimized.
This comment has been minimized.
tbu-
Dec 26, 2015
Contributor
Well, what should you do if you want to use those integers? Currently, you could pass them to the relevant C APIs directly, but after this change you have to do some kind of cast.
This comment has been minimized.
This comment has been minimized.
cuviper
Dec 28, 2015
Member
It's stuck between a rock and a hard place. We can't both support large files in libstd and still support passing those values directly to non-LFS C APIs. As the RFC says, the new advice is to use types from the libc crate for FFI, and it's up to you to make sure all your LFS ducks are in a row.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jan 11, 2016
Author
Member
@tbu- yeah the burden would be on consumers of libstd to cast appropriately and panic if out-of-bounds. I would expect that 95% of the time the types would always fit, but for the cases like LFS that @cuviper mentions it could be that the two applications are compiled differently (e.g. linking to C which isn't using LFS and hence can't handle file sizes > 4GB on 32-bit Linux).
This comment has been minimized.
This comment has been minimized.
remram44
commented
Dec 26, 2015
This comment has been minimized.
This comment has been minimized.
|
|
alexcrichton
added
the
final-comment-period
label
Jan 29, 2016
This comment has been minimized.
This comment has been minimized.
|
The libs team discussed this today and the conclusion was that there is not a clear enough path moving forward that doesn't involve theoretical breakage. We decided to leave this in FCP while I gather some statistics and flesh out a more concrete plan. |
This comment has been minimized.
This comment has been minimized.
|
Ok, I've done some analysis of what this change might have. The numbers here were gathered against these changes to the standard library, which I believe fully implement this RFC (enabling us to move to LFS on Linux at the same time). A crater report reports four regressions, three of which were spurious. I have submitted a PR for the other regression. Specifically, this regression involved code that looked like: libc::foo(..., value as std::os::raw::off_t)In other words, the regression came from the reliance that the types in std agreed with those in libc, which this RFC would be breaking. I then compiled Servo against a standard library with the patches above applied. With the Finally, I did a manual survey of all code on crates.io for usage of
The following usage was all observed but would not break from the change in this RFC (confirmed from the crater run)
My conclusion from this is that we can likely take the path set forth in this RFC (aka merge the two commits above at the same time). In summary, they:
The breaking changes are specifically breaking if you assume std/libc or std/gcc agree on the types, which from the above analysis looks like is limited to just a few crates (both of which have PRs to be updated). |
alexcrichton
referenced this pull request
Feb 10, 2016
Closed
std `c_void` and libc `c_void` are different types #31536
This comment has been minimized.
This comment has been minimized.
|
We discussed this during libs team triage today, and the conclusion was that given the limited fall out we should push forward with this. Thanks again for the discussion everyone! |
alexcrichton
referenced this pull request
Feb 11, 2016
Closed
Tracking issue for deprecating std::os::*::raw types #31549
alexcrichton
merged commit d95caf2
into
rust-lang:master
Feb 11, 2016
This comment has been minimized.
This comment has been minimized.
|
|
alexcrichton commentedDec 18, 2015
Deprecate type aliases and structs in
std::os::$platform::rawin favor oftrait-based accessors which return Rust types rather than the equivalent C type
aliases.