Skip to content
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

[WIP] Enable va_arg for raw pointers to unsized types #61126

Open
wants to merge 1 commit into
base: master
from

Conversation

@ahomescu
Copy link
Contributor

commented May 24, 2019

This patch implements VaArgSafe for raw pointers to unsized types, which lets users call VaList::arg for such pointers. Everything else in libcore uses T: ?Sized for raw pointers, so VaList should too, and we already ran into a case where we could use this for C2Rust.

r? @joshtriplett
cc @dlrobertson

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

commented May 24, 2019

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @joshtriplett (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@dlrobertson

This comment has been minimized.

Copy link
Contributor

commented May 24, 2019

Good catch. Could you add a ui test for this?

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented May 24, 2019

Could you add a ui test for this?

Would src/test/ui/c-variadic be the place for that? Edit: most of the files in that directory seem to check for errors.

@ahomescu ahomescu force-pushed the immunant:vaargsafe_unsized_pointers branch from 431c65a to 29f4ad4 May 24, 2019

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented May 24, 2019

I added a "pointer to foreign type" test to checkrust.rs.

@whataloadofwhat

This comment has been minimized.

Copy link
Contributor

commented May 25, 2019

Wouldn't this would make ap.arg::<*const [u8]>() legal? Isn't that bad?

@joshtriplett

This comment has been minimized.

Copy link
Member

commented May 25, 2019

@whataloadofwhat

This comment has been minimized.

Copy link
Contributor

commented May 25, 2019

*const [u8] isn't just a pointer though, it's a pointer and a length.

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented May 25, 2019

Wouldn't this would make ap.arg::<*const [u8]>() legal? Isn't that bad?

Right, *const [u8] is a fat pointer, which shouldn't be legal for arg. I'm not sure how to implement this additional restriction, if it can even be done.

Pointers-to-slices and pointers-to-traits are currently the only 2 kinds of fat pointers in Rust, afaik.

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented Jun 3, 2019

My latest update is that I have an idea how to fix this using auto traits (basically making VaArgSafe an auto trait), but I have to do some experiments to see if it works.

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented Jun 4, 2019

After looking into auto traits for a bit, I came to the conclusion that VaArgSafe should probably be an auto trait, with the following consequences:

  • Support for negative implementations, which would let us disable it for slices and/or pointers to slices, e.g., impl<T> !VaArgSafe for *const [T]
  • Implicit support for calling VaList::arg on structures. I originally thought C doesn't support this either, but it turns out that both gcc and clang do support this.
  • Support for calling VaList::arg on unions, enums, Rust tuples, closures and other Rust-specific data types. These ideally wouldn't be allowed, but I haven't been able to figure out how to disable them.

The other kind of fat pointers in Rust are pointers-to-traits, i.e., *const dyn Foo, and I'm not sure how to disable the auto trait for those.

@ahomescu ahomescu changed the title Enable va_arg for raw pointers to unsized types [WIP] Enable va_arg for raw pointers to unsized types Jun 4, 2019

@ahomescu ahomescu force-pushed the immunant:vaargsafe_unsized_pointers branch from 29f4ad4 to 0fb85ef Jun 4, 2019

@dlrobertson

This comment has been minimized.

Copy link
Contributor

commented Jul 10, 2019

@ahomescu does this enable the use of VaList::arg with aggregate types? Also how would this work with #62207?

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented Jul 10, 2019

does this enable the use of VaList::arg with aggregate types?

It actually does, recursively (if all members of the aggregate implement the trait, then the aggregate does too). However, it still doesn't the original problem of allowing fat pointers.

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented Jul 10, 2019

Also how would this work with #62207?

Adding a function to VaArgSafe precludes making it an auto-trait, but maybe we could solve that by splitting it into 2 traits: the auto VaArgSafe and the actual VaArgImpl.

@dlrobertson

This comment has been minimized.

Copy link
Contributor

commented Jul 10, 2019

Adding a function to VaArgSafe precludes making it an auto-trait, but maybe we could solve that by splitting it into 2 traits: the auto VaArgSafe and the actual VaArgImpl.

that seems reasonable

It actually does, recursively

AFAIK I hit some strange errors on windows with aggregate types. If we use auto trait we'd want to start testing aggregate types, not sure if it works now or not.

@rholderfield

This comment has been minimized.

Copy link

commented Jul 25, 2019

ping from triage... @ahomescu thank you for your time, can you please provide a status?

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented Jul 26, 2019

@rholderfield This is blocked until I figure out a way to disable the VaArgSafe trait for pointers to DSTs, e.g., *const [u8] mentioned above by @whataloadofwhat. AFAIK, the language doesn't currently have a way to disable marker traits for fat pointers and references.

The change from a regular trait to an auto trait also enables VaArgSafe automatically for structures. If that's desirable, then the PR could go in as is, and we solve the DST issue later.
I'll defer to @joshtriplett and @dlrobertson on this.

@ahomescu

This comment has been minimized.

Copy link
Contributor Author

commented Aug 2, 2019

This RFC could help us, since it would let us implement VaArgSafe only on ?Sized + Thin pointers.

@hdhoang

This comment has been minimized.

Copy link
Contributor

commented Aug 9, 2019

ping from triage @joshtriplett and @dlrobertson, could you comment on the author's concern above?

@JohnCSimon

This comment has been minimized.

Copy link

commented Aug 17, 2019

pinging agan from triage @joshtriplett and @dlrobertson @ahomescu

could you comment on the author's concern above?

@dlrobertson

This comment has been minimized.

Copy link
Contributor

commented Aug 17, 2019

This RFC could help us, since it would let us implement VaArgSafe only on ?Sized + Thin pointers.

Yeah RFC 2580 would be perfect for resolving this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
9 participants
You can’t perform that action at this time.