-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Typeck: Disallow scalar casts to bare_fn. #9788
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
Conversation
Bare functions are another example of a scalar but non-numeric type (like char) that should be handled separately in casts. This disallows expressions like `0 as extern "Rust" fn() -> int;`. It might be advantageous to allow casts between bare functions and raw pointers in unsafe code in the future, to pass function pointers between Rust and C. Closes #8728
I'm surprised this works currently, nice catch! I don't personally know exactly what would have caused this in the first place, but I know that @nikomatsakis was working with extern fns recently and may be able to shed some light on this. |
Hmm, I think the real problem is that bare fns and raw pointers should not be considered scalars. I suspect that the reason they are considered scalars, however, is to enable other kinds of casts (e.g., |
If Option<*T> is equivalent to *T, it definitely seems preferable to remove the ability to ability to cast integer types to unsafe pointers and use Option in FFI definitions instead. My changes allowed raw pointer to raw pointer casts, integer to raw pointer, and region pointer to raw pointer. The latter is important for creating static C string values from vectors, while the former is important for being able to convert pointers to constant Rust data into types that can be passed to external C libraries. |
The current code path treats quite a few of the scalars as exceptional cases: chars, C-like enums, nil, raw pointers, and now bare functions... A simpler code path that more closely matches the docs shouldn't involve scalars at all. Allow the following casts:
where Integer = ( ints, uints ) |
@nikomatsakis Do you agree with @geoffhill's assessment? Do we know how to fix this? |
Based on what @jdm said, I'd be inclined to push for fewer legal casts. We can always add more later. Therefore, I think we can even support fewer casts than what @geoffhill suggested. I think I would permit:
But I would not support:
To cover the last two cases, we can offer variations on I have to admit to some trepidation though. I don't want to make using |
I agree. I'm inclined to r+ this. Does anyone disagree? |
I like the casts that @nikomatsakis proposed, effectively separating the safe casts from casts only really needed for interfacing with C. Do I understand it right then that we also want to disallow bool => Number and char => Number casts? We should provide a function for the latter if that's the case. Also what about bare_fn => Raw Pointer? Seems the next step here is to remove the Integer <=> Raw Pointer and Raw Pointer <=> Raw Pointers casts. This will show us where the real use cases are, and we can provide |
On Wed, Oct 30, 2013 at 12:49:55PM -0700, Geoff Hill wrote:
I'd probably keep those.
This seems like it falls into the same category as raw pointer <=> raw pointer:
Sounds good to me! |
I'll note that raw pointer casts can be useful for statics where transmute isn't available. Granted, any time you have a cast in a static, you could instead call transmute when referencing it in a non-static expression. It does increase the spread of unsafe code, however. |
On Wed, Oct 30, 2013 at 09:31:49PM -0700, Josh Matthews wrote:
I guess we have to be sure to permit some way to go from a "foo" |
@pcwalton It sounds like no one disagrees and this is still mergeable -- any reason not to r+ it? |
Bare functions are another example of a scalar but non-numeric type (like char) that should be handled separately in casts. This disallows expressions like `0 as extern "Rust" fn() -> int;`. It might be advantageous to allow casts between bare functions and raw pointers in unsafe code in the future, to pass function pointers between Rust and C. Closes #8728
Bare functions are another example of a scalar but non-numeric
type (like char) that should be handled separately in casts.
This disallows expressions like
0 as extern "Rust" fn() -> int;
.It might be advantageous to allow casts between bare functions
and raw pointers in unsafe code in the future, to pass function
pointers between Rust and C.
Closes #8728