-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Change extern "ABI"
to extern<ABI>
or extern ABI
or extern(ABI)
#156
Conversation
I don't see the benefit to this. The supported ABIs for a function type are determined by the compiler, not by the library, and so having to use an enumeration (which would presumably be defined in the library using lang items to identify it to the compiler) for ABI just strikes me as odd. The only proposed benefit is the ability to abstract over the ABI of a function, but we could support this today merely by having the compiler provide automatic generation of function shims that expose a function from one ABI as if it were another. In fact, we basically already have this through closures; if you accept a closure value, function values will be implicitly wrapped in closures. I haven't tested to see how that handles ABI but I assume the compiler does that regardless of the function ABI. An unlisted drawback is that providing an enumeration like this is polluting the prelude with yet more stuff. We try to avoid putting values in the prelude (for the most part it's just traits), but for |
Just to be clear, this proposal is only about changing the syntax we currently use, not any kind of semantic change (exposing an enum, adding it to the Even if we never actually end up doing that, conceptually the ABI specifier is still much more like an enumeration member than a string. There is a limited list of options and you choose one of them; it's not free-form. Of course, making a breaking change just for this kind of conceptual consistency may not be worthwhile. I'm not particularly attached to this idea, and I have no idea whether it might have any practical benefit myself. I just figured I would write it up because it's interesting, and one of those rare RFCs which is small.
The list-of-variants would probably have to come from the compiler in some fashion. |
I definitely prefer using identifiers (rather than strings) for closed classes this; as you say, strings feel free-form. |
I prefer strings, because who's to say that one day someone won't write a compiler plugin that does extern "Nimrod" or extern "Clay"? |
@o11c being an identifier doesn't prohibit other names, i.e. the parser etc. could handle |
How does this interact with macro hygiene? |
I missed that this was not proposing an enum for all possible ABIs. Even if we could create such an enum sometime in the future, I highly doubt that we ever would, as adding names to the prelude is both gross and backwards-incompatible. So really this is just strictly a syntactic change. |
+1 identifiers seem much more appropriate than string literals. |
I'm in favor of this change, since like @huonw says, strings feel free-form when they're clearly not. +1 EDIT: I think I prefer the // what's system?
let fptr: extern system fn() -> int = new_int;
// clearer IMO
let fptr: extern<system> fn() -> int = new_int; |
I think If it's not, then there'd be no point in changing from one misleading intuition to another misleading intuition. Either |
I consider the association with type arguments to be good intuition. A close analogy within the type system seems to be Still, |
-1. Looks weird syntax, where ABI is neither keywords nor library defined names. extern "C" is the syntax that C++ uses. It's OK, especially for FFI. |
How does extern rust-call fn call(...); compare to extern "rust-call" fn call(...); ? Requiring ABI names to be identifiers may limit what compiler plugins one could provide. Also, it may create the illusion of collision with or shadowing of other identifiers in scope. |
FWIW I'm leaning toward extern(rust-call) fn call(...); syntax iff the |
Why not |
extern "ABI"
to extern<ABI>
or extern ABI
extern "ABI"
to extern<ABI>
or extern ABI
or extern(ABI)
So the choices are: #[link(name = "c")]
extern "C"
{
fn printf(arg: *const u8, ...) -> i32;
}
#[link(name = "c")]
extern C
{
fn printf(arg: *const u8, ...) -> i32;
}
#[link(name = "c")]
extern(C)
{
fn printf(arg: *const u8, ...) -> i32;
}
#[link(name = "c")]
extern<C>
{
fn printf(arg: *const u8, ...) -> i32;
} Unless the types It's similar to what's already provided in |
I like A counter to the argument against extensibility could be that type parameter is an uninhabited |
Although the syntax is not attractive, it's not 'common', there's existing precedent, and the string syntax makes it clear these are implementation- and platform-specific and not keywords or 'normal' identifiers. We'll keep this as-is. Thank you. |
impl Error for Oneshot
Pretty