]> git.lizzy.rs Git - rust.git/commitdiff
clean up some things
authorSteve Klabnik <steve@steveklabnik.com>
Wed, 15 Feb 2017 22:55:02 +0000 (17:55 -0500)
committerSteve Klabnik <steve@steveklabnik.com>
Tue, 21 Feb 2017 19:01:23 +0000 (14:01 -0500)
I double checked that everything is here and in the correct order; this fixes things up

src/doc/reference/src/items.md
src/doc/reference/src/memory-model.md
src/doc/reference/src/tokens.md
src/doc/reference/src/unsafety.md

index 0b4421de2a9653d63d105d59d418cc9369e55964..9f667e7a3c46d1e4824e4a83e6fd1956f9325755 100644 (file)
@@ -630,7 +630,7 @@ unsafe fn bump_levels_unsafe2() -> u32 {
 Mutable statics have the same restrictions as normal statics, except that the
 type of the value is not required to ascribe to `Sync`.
 
-### `'static` lifetime elision
+#### `'static` lifetime elision
 
 [Unstable] Both constant and static declarations of reference types have
 *implicit* `'static` lifetimes unless an explicit lifetime is specified. As
@@ -676,3 +676,372 @@ const RESOLVED_MULTIPLE: Fn(&Foo, &Bar, &Baz) -> usize = ..
 // `Fn(&'static Foo, &'static Bar) -> &'static Baz`.
 const RESOLVED_STATIC: Fn(&Foo, &Bar) -> &Baz = ..
 ```
+
+### Traits
+
+A _trait_ describes an abstract interface that types can
+implement. This interface consists of associated items, which come in
+three varieties:
+
+- functions
+- constants
+- types
+
+Associated functions whose first parameter is named `self` are called
+methods and may be invoked using `.` notation (e.g., `x.foo()`).
+
+All traits define an implicit type parameter `Self` that refers to
+"the type that is implementing this interface". Traits may also
+contain additional type parameters. These type parameters (including
+`Self`) may be constrained by other traits and so forth as usual.
+
+Trait bounds on `Self` are considered "supertraits". These are
+required to be acyclic.  Supertraits are somewhat different from other
+constraints in that they affect what methods are available in the
+vtable when the trait is used as a [trait object](#trait-objects).
+
+Traits are implemented for specific types through separate
+[implementations](#implementations).
+
+Consider the following trait:
+
+```
+# type Surface = i32;
+# type BoundingBox = i32;
+trait Shape {
+    fn draw(&self, Surface);
+    fn bounding_box(&self) -> BoundingBox;
+}
+```
+
+This defines a trait with two methods. All values that have
+[implementations](#implementations) of this trait in scope can have their
+`draw` and `bounding_box` methods called, using `value.bounding_box()`
+[syntax](#method-call-expressions).
+
+Traits can include default implementations of methods, as in:
+
+```
+trait Foo {
+    fn bar(&self);
+    fn baz(&self) { println!("We called baz."); }
+}
+```
+
+Here the `baz` method has a default implementation, so types that implement
+`Foo` need only implement `bar`. It is also possible for implementing types
+to override a method that has a default implementation.
+
+Type parameters can be specified for a trait to make it generic. These appear
+after the trait name, using the same syntax used in [generic
+functions](#generic-functions).
+
+```
+trait Seq<T> {
+    fn len(&self) -> u32;
+    fn elt_at(&self, n: u32) -> T;
+    fn iter<F>(&self, F) where F: Fn(T);
+}
+```
+
+It is also possible to define associated types for a trait. Consider the
+following example of a `Container` trait. Notice how the type is available
+for use in the method signatures:
+
+```
+trait Container {
+    type E;
+    fn empty() -> Self;
+    fn insert(&mut self, Self::E);
+}
+```
+
+In order for a type to implement this trait, it must not only provide
+implementations for every method, but it must specify the type `E`. Here's
+an implementation of `Container` for the standard library type `Vec`:
+
+```
+# trait Container {
+#     type E;
+#     fn empty() -> Self;
+#     fn insert(&mut self, Self::E);
+# }
+impl<T> Container for Vec<T> {
+    type E = T;
+    fn empty() -> Vec<T> { Vec::new() }
+    fn insert(&mut self, x: T) { self.push(x); }
+}
+```
+
+Generic functions may use traits as _bounds_ on their type parameters. This
+will have two effects:
+
+- Only types that have the trait may instantiate the parameter.
+- Within the generic function, the methods of the trait can be
+  called on values that have the parameter's type.
+
+For example:
+
+```
+# type Surface = i32;
+# trait Shape { fn draw(&self, Surface); }
+fn draw_twice<T: Shape>(surface: Surface, sh: T) {
+    sh.draw(surface);
+    sh.draw(surface);
+}
+```
+
+Traits also define a [trait object](#trait-objects) with the same
+name as the trait. Values of this type are created by coercing from a
+pointer of some specific type to a pointer of trait type. For example,
+`&T` could be coerced to `&Shape` if `T: Shape` holds (and similarly
+for `Box<T>`). This coercion can either be implicit or
+[explicit](#type-cast-expressions). Here is an example of an explicit
+coercion:
+
+```
+trait Shape { }
+impl Shape for i32 { }
+let mycircle = 0i32;
+let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;
+```
+
+The resulting value is a box containing the value that was cast, along with
+information that identifies the methods of the implementation that was used.
+Values with a trait type can have [methods called](#method-call-expressions) on
+them, for any method in the trait, and can be used to instantiate type
+parameters that are bounded by the trait.
+
+Trait methods may be static, which means that they lack a `self` argument.
+This means that they can only be called with function call syntax (`f(x)`) and
+not method call syntax (`obj.f()`). The way to refer to the name of a static
+method is to qualify it with the trait name, treating the trait name like a
+module. For example:
+
+```
+trait Num {
+    fn from_i32(n: i32) -> Self;
+}
+impl Num for f64 {
+    fn from_i32(n: i32) -> f64 { n as f64 }
+}
+let x: f64 = Num::from_i32(42);
+```
+
+Traits may inherit from other traits. Consider the following example:
+
+```
+trait Shape { fn area(&self) -> f64; }
+trait Circle : Shape { fn radius(&self) -> f64; }
+```
+
+The syntax `Circle : Shape` means that types that implement `Circle` must also
+have an implementation for `Shape`. Multiple supertraits are separated by `+`,
+`trait Circle : Shape + PartialEq { }`. In an implementation of `Circle` for a
+given type `T`, methods can refer to `Shape` methods, since the typechecker
+checks that any type with an implementation of `Circle` also has an
+implementation of `Shape`:
+
+```rust
+struct Foo;
+
+trait Shape { fn area(&self) -> f64; }
+trait Circle : Shape { fn radius(&self) -> f64; }
+impl Shape for Foo {
+    fn area(&self) -> f64 {
+        0.0
+    }
+}
+impl Circle for Foo {
+    fn radius(&self) -> f64 {
+        println!("calling area: {}", self.area());
+
+        0.0
+    }
+}
+
+let c = Foo;
+c.radius();
+```
+
+In type-parameterized functions, methods of the supertrait may be called on
+values of subtrait-bound type parameters. Referring to the previous example of
+`trait Circle : Shape`:
+
+```
+# trait Shape { fn area(&self) -> f64; }
+# trait Circle : Shape { fn radius(&self) -> f64; }
+fn radius_times_area<T: Circle>(c: T) -> f64 {
+    // `c` is both a Circle and a Shape
+    c.radius() * c.area()
+}
+```
+
+Likewise, supertrait methods may also be called on trait objects.
+
+```{.ignore}
+# trait Shape { fn area(&self) -> f64; }
+# trait Circle : Shape { fn radius(&self) -> f64; }
+# impl Shape for i32 { fn area(&self) -> f64 { 0.0 } }
+# impl Circle for i32 { fn radius(&self) -> f64 { 0.0 } }
+# let mycircle = 0i32;
+let mycircle = Box::new(mycircle) as Box<Circle>;
+let nonsense = mycircle.radius() * mycircle.area();
+```
+
+### Implementations
+
+An _implementation_ is an item that implements a [trait](#traits) for a
+specific type.
+
+Implementations are defined with the keyword `impl`.
+
+```
+# #[derive(Copy, Clone)]
+# struct Point {x: f64, y: f64};
+# type Surface = i32;
+# struct BoundingBox {x: f64, y: f64, width: f64, height: f64};
+# trait Shape { fn draw(&self, Surface); fn bounding_box(&self) -> BoundingBox; }
+# fn do_draw_circle(s: Surface, c: Circle) { }
+struct Circle {
+    radius: f64,
+    center: Point,
+}
+
+impl Copy for Circle {}
+
+impl Clone for Circle {
+    fn clone(&self) -> Circle { *self }
+}
+
+impl Shape for Circle {
+    fn draw(&self, s: Surface) { do_draw_circle(s, *self); }
+    fn bounding_box(&self) -> BoundingBox {
+        let r = self.radius;
+        BoundingBox {
+            x: self.center.x - r,
+            y: self.center.y - r,
+            width: 2.0 * r,
+            height: 2.0 * r,
+        }
+    }
+}
+```
+
+It is possible to define an implementation without referring to a trait. The
+methods in such an implementation can only be used as direct calls on the values
+of the type that the implementation targets. In such an implementation, the
+trait type and `for` after `impl` are omitted. Such implementations are limited
+to nominal types (enums, structs, trait objects), and the implementation must
+appear in the same crate as the `self` type:
+
+```
+struct Point {x: i32, y: i32}
+
+impl Point {
+    fn log(&self) {
+        println!("Point is at ({}, {})", self.x, self.y);
+    }
+}
+
+let my_point = Point {x: 10, y:11};
+my_point.log();
+```
+
+When a trait _is_ specified in an `impl`, all methods declared as part of the
+trait must be implemented, with matching types and type parameter counts.
+
+An implementation can take type parameters, which can be different from the
+type parameters taken by the trait it implements. Implementation parameters
+are written after the `impl` keyword.
+
+```
+# trait Seq<T> { fn dummy(&self, _: T) { } }
+impl<T> Seq<T> for Vec<T> {
+    /* ... */
+}
+impl Seq<bool> for u32 {
+    /* Treat the integer as a sequence of bits */
+}
+```
+
+### External blocks
+
+External blocks form the basis for Rust's foreign function interface.
+Declarations in an external block describe symbols in external, non-Rust
+libraries.
+
+Functions within external blocks are declared in the same way as other Rust
+functions, with the exception that they may not have a body and are instead
+terminated by a semicolon.
+
+Functions within external blocks may be called by Rust code, just like
+functions defined in Rust. The Rust compiler automatically translates between
+the Rust ABI and the foreign ABI.
+
+Functions within external blocks may be variadic by specifying `...` after one
+or more named arguments in the argument list:
+
+```ignore
+extern {
+    fn foo(x: i32, ...);
+}
+```
+
+A number of [attributes](#ffi-attributes) control the behavior of external blocks.
+
+By default external blocks assume that the library they are calling uses the
+standard C ABI on the specific platform. Other ABIs may be specified using an
+`abi` string, as shown here:
+
+```ignore
+// Interface to the Windows API
+extern "stdcall" { }
+```
+
+There are three ABI strings which are cross-platform, and which all compilers
+are guaranteed to support:
+
+* `extern "Rust"` -- The default ABI when you write a normal `fn foo()` in any
+  Rust code.
+* `extern "C"` -- This is the same as `extern fn foo()`; whatever the default
+  your C compiler supports.
+* `extern "system"` -- Usually the same as `extern "C"`, except on Win32, in
+  which case it's `"stdcall"`, or what you should use to link to the Windows API
+  itself
+
+There are also some platform-specific ABI strings:
+
+* `extern "cdecl"` -- The default for x86\_32 C code.
+* `extern "stdcall"` -- The default for the Win32 API on x86\_32.
+* `extern "win64"` -- The default for C code on x86\_64 Windows.
+* `extern "sysv64"` -- The default for C code on non-Windows x86\_64.
+* `extern "aapcs"` -- The default for ARM.
+* `extern "fastcall"` -- The `fastcall` ABI -- corresponds to MSVC's
+  `__fastcall` and GCC and clang's `__attribute__((fastcall))`
+* `extern "vectorcall"` -- The `vectorcall` ABI -- corresponds to MSVC's
+  `__vectorcall` and clang's `__attribute__((vectorcall))`
+
+Finally, there are some rustc-specific ABI strings:
+
+* `extern "rust-intrinsic"` -- The ABI of rustc intrinsics.
+* `extern "rust-call"` -- The ABI of the Fn::call trait functions.
+* `extern "platform-intrinsic"` -- Specific platform intrinsics -- like, for
+  example, `sqrt` -- have this ABI. You should never have to deal with it.
+
+The `link` attribute allows the name of the library to be specified. When
+specified the compiler will attempt to link against the native library of the
+specified name.
+
+```{.ignore}
+#[link(name = "crypto")]
+extern { }
+```
+
+The type of a function declared in an extern block is `extern "abi" fn(A1, ...,
+An) -> R`, where `A1...An` are the declared types of its arguments and `R` is
+the declared return type.
+
+It is valid to add the `link` attribute on an empty extern block. You can use
+this to satisfy the linking requirements of extern blocks elsewhere in your code
+(including upstream crates) instead of adding the attribute to each extern block.
index 2798b0d165f7fdda4fa08d130b401987b07ac3f8..aa57ae6ae9bead48da8e96697c73058d78958387 100644 (file)
@@ -8,17 +8,3 @@ discipline, exist in the standard library.
 
 Allocations in the stack consist of *variables*, and allocations in the heap
 consist of *boxes*.
-
-## Memory allocation and lifetime
-
-The _items_ of a program are those functions, modules and types that have their
-value calculated at compile-time and stored uniquely in the memory image of the
-rust process. Items are neither dynamically allocated nor freed.
-
-The _heap_ is a general term that describes boxes.  The lifetime of an
-allocation in the heap depends on the lifetime of the box values pointing to
-it. Since box values may themselves be passed in and out of frames, or stored
-in the heap, heap allocations may outlive the frame they are allocated within.
-An allocation in the heap is guaranteed to reside at a single location in the
-heap for the whole lifetime of the allocation - it will never be relocated as
-a result of moving a box value.
index ae4007b0c99c5d3e65114c4c52c342ef18600117..5a45a2a150b8feaa390d0af6630bb35d62be0d4d 100644 (file)
@@ -303,3 +303,14 @@ The representation semantics of floating-point numbers are described in
 ### Boolean literals
 
 The two values of the boolean type are written `true` and `false`.
+
+## Symbols
+
+Symbols are a general class of printable [tokens](#tokens) that play structural
+roles in a variety of grammar productions. They are a
+set of remaining miscellaneous printable tokens that do not
+otherwise appear as [unary operators](#unary-operator-expressions), [binary
+operators](#binary-operator-expressions), or [keywords][keywords].
+They are catalogued in [the Symbols section][symbols] of the Grammar document.
+
+[symbols]: grammar.html#symbols
index f4a9a1d12925abb0bafeda36f49049d0c0c881f4..72ae1c725edf3ee71047cf640aaf2a41ed92d449 100644 (file)
@@ -9,32 +9,3 @@ Rust:
 - Dereferencing a [raw pointer](#pointer-types).
 - Reading or writing a [mutable static variable](#mutable-statics).
 - Calling an unsafe function (including an intrinsic or foreign function).
-
-## Unsafe functions
-
-Unsafe functions are functions that are not safe in all contexts and/or for all
-possible inputs. Such a function must be prefixed with the keyword `unsafe` and
-can only be called from an `unsafe` block or another `unsafe` function.
-
-## Unsafe blocks
-
-A block of code can be prefixed with the `unsafe` keyword, to permit calling
-`unsafe` functions or dereferencing raw pointers within a safe function.
-
-When a programmer has sufficient conviction that a sequence of potentially
-unsafe operations is actually safe, they can encapsulate that sequence (taken
-as a whole) within an `unsafe` block. The compiler will consider uses of such
-code safe, in the surrounding context.
-
-Unsafe blocks are used to wrap foreign libraries, make direct use of hardware
-or implement features not directly present in the language. For example, Rust
-provides the language features necessary to implement memory-safe concurrency
-in the language but the implementation of threads and message passing is in the
-standard library.
-
-Rust's type system is a conservative approximation of the dynamic safety
-requirements, so in some cases there is a performance cost to using safe code.
-For example, a doubly-linked list is not a tree structure and can only be
-represented with reference-counted pointers in safe code. By using `unsafe`
-blocks to represent the reverse links as raw pointers, it can be implemented
-with only boxes.