diff --git a/active/0000-new-intrinsics.md b/active/0000-new-intrinsics.md new file mode 100644 index 00000000000..5b99aa14eb2 --- /dev/null +++ b/active/0000-new-intrinsics.md @@ -0,0 +1,79 @@ +- Start Date: 2014-03-14 +- RFC PR #: (leave this empty) +- Rust Issue #: (leave this empty) + +# Summary + +They way our intrinsics work forces them to be wrapped in order to +behave like normal functions. As a result, rustc is forced to inline a +great number of tiny intrinsic wrappers, which is bad for both +compile-time performance and runtime performance without +optimizations. This proposal changes the way intrinsics are surfaced +in the language so that they behave the same as normal Rust functions +by removing the "rust-intrinsic" foreign ABI and reusing the "Rust" +ABI. + +# Motivation + +A number of commonly-used intrinsics, including `transmute`, `forget`, +`init`, `uninit`, and `move_val_init`, are accessed through wrappers +whose only purpose is to present the intrinsics as normal functions. +As a result, rustc is forced to inline a great number of tiny +intrinsic wrappers, which is bad for both compile-time performance and +runtime performance without optimizations. + +Intrinsics have a differently-named ABI from Rust functions +("rust-intrinsic" vs. "Rust") though the actual ABI implementation is +identical. As a result one can't take the value of an intrinsic as a +function: + +``` +// error: the type of transmute is `extern "rust-intrinsic" fn ...` +let transmute: fn(int) -> uint = intrinsics::transmute; +``` + +This incongruity means that we can't just expose the intrinsics +directly as part of the public API. + +# Detailed design + +`extern "Rust" fn` is already equivalent to `fn`, so if intrinsics +have the "Rust" ABI then the problem is solved. + +Under this scheme intrinsics will be declared as `extern "Rust"` functions +and identified as intrinsics with the `#[lang = "..."]` attribute: + +``` +extern "Rust" { + #[lang = "transmute"] + fn transmute(T) -> U; +} +``` + +The compiler will type check and translate intrinsics the same as today. +Additionally, when trans sees a "Rust" extern tagged as an intrinsic +it will not emit a function declaration to LLVM bitcode. + +Because intrinsics will be lang items, they can no longer be redeclared +arbitrary number of times. This will require a small amount of existing +library code to be refactored, and all intrinsics to be exposed through public +abstractions. + +Currently, "Rust" foreign functions may not be generic; this change +will require a special case that allows intrinsics to be generic. + +# Alternatives + +1. Instead of making intrinsics lang items we could create a slightly +different mechanism, like an `#[intrinsic]` attribute, that would +continue letting intrinsics to be redeclared. + +2. While using lang items to identify intrinsics, intrinsic lang items +*could* be allowed to be redeclared. + +3. We could also make "rust-intrinsic" coerce or otherwise be the same +as "Rust" externs and normal Rust functions. + +# Unresolved questions + +None. \ No newline at end of file