Skip to content

[WIP] Remove various transmutes #47005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed

Conversation

nvzqz
Copy link
Contributor

@nvzqz nvzqz commented Dec 25, 2017

This PR removes various transmutes that can either be replaced with casts or safe code.

@rust-highfive
Copy link
Contributor

r? @petrochenkov

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

@petrochenkov
Copy link
Contributor

I don't know what is the official policy and half of the changed cases looks better with transmute to me.
r? @bluss

@rust-highfive rust-highfive assigned bluss and unassigned petrochenkov Dec 26, 2017
@kennytm kennytm added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Dec 27, 2017
@@ -592,7 +591,8 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<Ty<'tcx>> {}
impl<T> Slice<T> {
pub fn empty<'a>() -> &'a Slice<T> {
unsafe {
mem::transmute(slice::from_raw_parts(0x1 as *const T, 0))
let slice = slice::from_raw_parts(0x1 as *const T, 0);
&*(slice as *const _ as *const _)
Copy link
Member

Choose a reason for hiding this comment

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

This one in particular I don't know why transmute isn't the best way. We need some way to do the &[X] -> &NewType([X]) cast.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This still performs the same cast, just without transmuting the fat pointer. Can you explain further why transmute would be preferred here?

@bluss
Copy link
Member

bluss commented Dec 31, 2017

Yes, we want to set a good example and not use transmute, though I agree many of them look better with transmute; with transmute, we also have some size checking that the pointer casts don't have.
But we don't have any pointee size check in either case.

So it's almost like we want better primitives that are transmute-like. Previous removal of them was in #14069 but there are frankly not many there that are worth bringing back, except transmute_lifetime, and whatever new ones we need.

@shepmaster
Copy link
Member

Happy new year from triage, @nvzqz! A reminder that this is awaiting your feedback!

@bors
Copy link
Collaborator

bors commented Jan 6, 2018

☔ The latest upstream changes (presumably #47225) made this pull request unmergeable. Please resolve the merge conflicts.

@nvzqz
Copy link
Contributor Author

nvzqz commented Jan 7, 2018

@bluss I'm of the opinion that mem::transmute should be reserved for certain cases, such as ones that warrant a size check. The nomicon states that it's very easy to cause UB via transmutes, and I think that the Rust standard library/ies should be somewhat of a role model in how it uses them.

I agree that some of these look better as transmutes but unless there's necessary size checks, alternatives should be considered.

Proof I don't hate mem::transmute. 😜

@shepmaster Happy new year ❤️


Edit: This is still a WIP. I'll update the title when I feel that this PR finishes accomplishing what I intend for it to. I've just been busy in my personal life.

@bluss
Copy link
Member

bluss commented Jan 7, 2018

@nvzqz Sure, I'm also partial to that. I don't really dislike these changes, but I hope we can find something even better for Rust than these myriads of double as casts.

@@ -213,7 +213,9 @@ impl SocketAddr {

fn address<'a>(&'a self) -> AddressKind<'a> {
let len = self.len as usize - sun_path_offset();
let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
let path: &[libc::c_char] = unsafe {
&*(&self.addr.sun_path as *const _ as *const _)
Copy link
Member

@bluss bluss Jan 7, 2018

Choose a reason for hiding this comment

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

This one is actually wrong — the original is tricky. self.addr.sun_path is an array and the transmute with explicit type is using the coercion from array to slice.

I am not actually sure if it's wrong. But I'll have to double check how this works with coercion here.

Reinterpreting &[u8] <-> &[c_char] seems like it should be a function.

Copy link
Member

Choose a reason for hiding this comment

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

And the old target type was &[u8], in this code it is instead &[c_char]. They should switch places. Convert from c_char to u8.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see what you mean. Thanks a lot @bluss, you're awesome 👍🏻. Thanks for everything you do for this project. I'm make the appropriate changes tomorrow.

@nvzqz nvzqz force-pushed the remove-transmute branch from dde1d39 to dd49ccd Compare January 7, 2018 20:13
@nvzqz nvzqz force-pushed the remove-transmute branch from dd49ccd to 90a17e9 Compare January 7, 2018 22:08
@shepmaster shepmaster added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 13, 2018
@shepmaster
Copy link
Member

Heads up from triage, @bluss! Looks like there are new commits to be reviewed!

@@ -114,43 +113,49 @@ impl Deref for Interned<String> {
type Target = str;
fn deref(&self) -> &'static str {
let l = INTERNER.strs.lock().unwrap();
unsafe { mem::transmute::<&str, &'static str>(l.get(*self)) }
let s: &str = l.get(*self).as_ref();
Copy link
Member

Choose a reason for hiding this comment

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

What's as_ref called on? If it's &String then you should remove .as_ref() and let it coerce.

Copy link
Member

Choose a reason for hiding this comment

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

Same for all the other 5 cases in this file.

@@ -592,7 +591,8 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<Ty<'tcx>> {}
impl<T> Slice<T> {
pub fn empty<'a>() -> &'a Slice<T> {
unsafe {
mem::transmute(slice::from_raw_parts(0x1 as *const T, 0))
let slice = slice::from_raw_parts(0x1 as *const T, 0);
&*(slice as *const [T] as *const Slice<T>)
Copy link
Member

Choose a reason for hiding this comment

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

This should be &*(mem::align_of::<T>() as *const [T; 0] as *const [T] as *const Slice<T>).

@shepmaster shepmaster added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 20, 2018
@shepmaster
Copy link
Member

Ping from triage @nvzqz ! We haven't heard from you in over a week; do you think you'll be able to respond to the feedback soon?

@shepmaster
Copy link
Member

Thanks for the PR, @nvzqz ! Since we haven't heard from you in a few weeks, I'm going to go ahead and close this PR for now. Please feel free to reopen when you are able to address the last bit of feedback.

@shepmaster shepmaster closed this Feb 3, 2018
@shepmaster shepmaster added S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants