summaryrefslogtreecommitdiffstats
path: root/src/test/ui/explain.stdout
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/explain.stdout')
-rw-r--r--src/test/ui/explain.stdout71
1 files changed, 0 insertions, 71 deletions
diff --git a/src/test/ui/explain.stdout b/src/test/ui/explain.stdout
deleted file mode 100644
index ef1d866c3..000000000
--- a/src/test/ui/explain.stdout
+++ /dev/null
@@ -1,71 +0,0 @@
-Per [RFC 401][rfc401], if you have a function declaration `foo`:
-
-```
-struct S;
-
-// For the purposes of this explanation, all of these
-// different kinds of `fn` declarations are equivalent:
-
-fn foo(x: S) { /* ... */ }
-extern "C" {
- fn foo(x: S);
-}
-impl S {
- fn foo(self) { /* ... */ }
-}
-```
-
-the type of `foo` is **not** `fn(S)`, as one might expect.
-Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`.
-However, `typeof(foo)` can be _coerced_ to a function pointer `fn(S)`,
-so you rarely notice this:
-
-```
-let x: fn(S) = foo; // OK, coerces
-```
-
-The reason that this matter is that the type `fn(S)` is not specific to
-any particular function: it's a function _pointer_. So calling `x()` results
-in a virtual call, whereas `foo()` is statically dispatched, because the type
-of `foo` tells us precisely what function is being called.
-
-As noted above, coercions mean that most code doesn't have to be
-concerned with this distinction. However, you can tell the difference
-when using **transmute** to convert a fn item into a fn pointer.
-
-This is sometimes done as part of an FFI:
-
-```
-extern "C" fn foo(userdata: Box<i32>) {
- /* ... */
-}
-
-unsafe {
- let f: extern "C" fn(*mut i32) = transmute(foo);
- callback(f);
-}
-```
-
-Here, transmute is being used to convert the types of the fn arguments.
-This pattern is incorrect because the type of `foo` is a function **item**
-(`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
-is a function pointer, which is not zero-sized.
-This pattern should be rewritten. There are a few possible ways to do this:
-
-- change the original fn declaration to match the expected signature,
- and do the cast in the fn body (the preferred option)
-- cast the fn item of a fn pointer before calling transmute, as shown here:
-
- ```
- let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
- let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
- ```
-
-The same applies to transmutes to `*mut fn()`, which were observed in practice.
-Note though that use of this type is generally incorrect.
-The intention is typically to describe a function pointer, but just `fn()`
-alone suffices for that. `*mut fn()` is a pointer to a fn pointer.
-(Since these values are typically just passed to C code, however, this rarely
-makes a difference in practice.)
-
-[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md