about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-22 23:25:32 +0000
committerbors <bors@rust-lang.org>2015-04-22 23:25:32 +0000
commit90cc83015eafb21293fd0cb8fb81f172236325df (patch)
treef2b2bc6e032b098ebcca4ae1c2c2dfcc001fe79d
parent5c9636975cdc289e98ef8f33400969371c4ce1bf (diff)
parentb0319e9094c9f4d5d273ab4a40324bd9ded97b5c (diff)
downloadrust-90cc83015eafb21293fd0cb8fb81f172236325df.tar.gz
rust-90cc83015eafb21293fd0cb8fb81f172236325df.zip
Auto merge of #24703 - Manishearth:rollup, r=Manishearth
r? @Manishearth
-rw-r--r--src/doc/trpl/SUMMARY.md2
-rw-r--r--src/doc/trpl/attributes.md69
-rw-r--r--src/doc/trpl/conditional-compilation.md92
-rw-r--r--src/doc/trpl/type-aliases.md75
-rw-r--r--src/doc/trpl/unsized-types.md57
-rw-r--r--src/test/run-pass/ifmt.rs4
6 files changed, 293 insertions, 6 deletions
diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md
index e3c636df2e4..0edadeb628e 100644
--- a/src/doc/trpl/SUMMARY.md
+++ b/src/doc/trpl/SUMMARY.md
@@ -9,6 +9,7 @@
     * [The Stack and the Heap](the-stack-and-the-heap.md)
     * [Debug and Display](debug-and-display.md)
     * [Testing](testing.md)
+    * [Conditional Compilation](conditional-compilation.md)
     * [Documentation](documentation.md)
     * [Iterators](iterators.md)
     * [Concurrency](concurrency.md)
@@ -46,7 +47,6 @@
     * [`const` and `static`](const-and-static.md)
     * [Tuple Structs](tuple-structs.md)
     * [Attributes](attributes.md)
-    * [Conditional Compilation](conditional-compilation.md)
     * [`type` aliases](type-aliases.md)
     * [Casting between types](casting-between-types.md)
     * [Associated Types](associated-types.md)
diff --git a/src/doc/trpl/attributes.md b/src/doc/trpl/attributes.md
index e699bd85f6e..54195a5063b 100644
--- a/src/doc/trpl/attributes.md
+++ b/src/doc/trpl/attributes.md
@@ -1,3 +1,70 @@
 % Attributes
 
-Coming Soon!
+Declarations can be annotated with ‘attributes’ in Rust. They look like this:
+
+```rust
+#[test]
+# fn foo() {}
+```
+
+or like this:
+
+```rust
+# mod foo {
+#![test]
+# }
+```
+
+The difference between the two is the `!`, which changes what the attribute
+applies to:
+
+```rust,ignore
+#[foo]
+struct Foo;
+
+mod bar {
+    #![bar]
+}
+```
+
+The `#[foo]` attribute applies to the next item, which is the `struct`
+declaration. The `#![bar]` attribute applies to the item enclosing it, which is
+the `mod` declaration. Otherwise, they’re the same. Both change the meaning of
+the item they’re attached to somehow.
+
+For example, consider a function like this:
+
+```rust
+#[test]
+fn check() {
+    assert_eq!(2, 1 + 1);
+}
+```
+
+It is marked with `#[test]`. This means it’s special: when you run
+[tests][tests], this function will execute. When you compile as usual, it won’t
+even be included. This function is now a test function.
+
+[tests]: testing.html
+
+Attributes may also have additional data:
+
+```rust
+#[inline(always)]
+fn super_fast_fn() {
+# }
+```
+
+Or even keys and values:
+
+```rust
+#[cfg(target_os = "macos")]
+mod macos_only {
+# }
+```
+
+Rust attributes are used for a number of different things. There is a full list
+of attributes [in the reference][reference]. Currently, you are not allowed to
+create your own attributes, the Rust compiler defines them.
+
+[reference]: reference.html#attributes
diff --git a/src/doc/trpl/conditional-compilation.md b/src/doc/trpl/conditional-compilation.md
index 40367fa844d..73eb0101692 100644
--- a/src/doc/trpl/conditional-compilation.md
+++ b/src/doc/trpl/conditional-compilation.md
@@ -1,3 +1,93 @@
 % Conditional Compilation
 
-Coming Soon!
+Rust has a special attribute, `#[cfg]`, which allows you to compile code
+based on a flag passed to the compiler. It has two forms:
+
+```rust
+#[cfg(foo)]
+# fn foo() {}
+
+#[cfg(bar = "baz")]
+# fn bar() {}
+```
+
+They also have some helpers:
+
+```rust
+#[cfg(any(unix, windows))]
+# fn foo() {}
+
+#[cfg(all(unix, target_pointer_width = "32"))]
+# fn bar() {}
+
+#[cfg(not(foo))]
+# fn not_foo() {}
+```
+
+These can nest arbitrarily:
+
+```rust
+#[cfg(any(not(unix), all(target_os="macos", target_arch = "powerpc")))]
+# fn foo() {}
+```
+
+As for how to enable or disable these switches, if you’re using Cargo,
+they get set in the [`[features]` section][features] of your `Cargo.toml`:
+
+[features]: http://doc.crates.io/manifest.html#the-[features]-section
+
+```toml
+[features]
+# no features by default
+default = []
+
+# The “secure-password” feature depends on the bcrypt package.
+secure-password = ["bcrypt"]
+```
+
+When you do this, Cargo passes along a flag to `rustc`:
+
+```text
+--cfg feature="${feature_name}"
+```
+
+The sum of these `cfg` flags will determine which ones get activated, and
+therefore, which code gets compiled. Let’s take this code:
+
+```rust
+#[cfg(feature = "foo")]
+mod foo {
+}
+```
+
+If we compile it with `cargo build --features "foo"`, it will send the `--cfg
+feature="foo"` flag to `rustc`, and the output will have the `mod foo` in it.
+If we compile it with a regular `cargo build`, no extra flags get passed on,
+and so, no `foo` module will exist.
+
+# cfg_attr
+
+You can also set another attribute based on a `cfg` variable with `cfg_attr`:
+
+```rust
+#[cfg_attr(a, b)]
+# fn foo() {}
+```
+
+Will be the same as `#[b]` if `a` is set by `cfg` attribute, and nothing otherwise.
+
+# cfg!
+
+The `cfg!` [syntax extension][compilerplugins] lets you use these kinds of flags
+elsewhere in your code, too:
+
+```rust
+if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
+    println!("Think Different!");
+}
+```
+
+[compilerplugins]: compiler-plugins.html
+
+These will be replaced by a `true` or `false` at compile-time, depending on the
+configuration settings.
diff --git a/src/doc/trpl/type-aliases.md b/src/doc/trpl/type-aliases.md
index fffa0ae1383..d175da35f5e 100644
--- a/src/doc/trpl/type-aliases.md
+++ b/src/doc/trpl/type-aliases.md
@@ -1,3 +1,76 @@
 % `type` Aliases
 
-Coming soon
+The `type` keyword lets you declare an alias of another type:
+
+```rust
+type Name = String;
+```
+
+You can then use this type as if it were a real type:
+
+```rust
+type Name = String;
+
+let x: Name = "Hello".to_string();
+```
+
+Note, however, that this is an _alias_, not a new type entirely. In other
+words, because Rust is strongly typed, you’d expect a comparison between two
+different types to fail:
+
+```rust,ignore
+let x: i32 = 5;
+let y: i64 = 5;
+
+if x == y {
+   // ...
+}
+```
+
+this gives
+
+```text
+error: mismatched types:
+ expected `i32`,
+    found `i64`
+(expected i32,
+    found i64) [E0308]
+     if x == y {
+             ^
+```
+
+But, if we had an alias:
+
+```rust
+type Num = i32;
+
+let x: i32 = 5;
+let y: Num = 5;
+
+if x == y {
+   // ...
+}
+```
+
+This compiles without error. Values of a `Num` type are the same as a value of
+type `i32`, in every way.
+
+You can also use type aliases with generics:
+
+```rust
+use std::result;
+
+enum ConcreteError {
+    Foo,
+    Bar,
+}
+
+type Result<T> = result::Result<T, ConcreteError>;
+```
+
+This creates a specialized version of the `Result` type, which always has a
+`ConcreteError` for the `E` part of `Result<T, E>`. This is commonly used
+in the standard library to create custom errors for each subsection. For
+example, [io::Result][ioresult].
+
+[ioresult]: ../std/io/type.Result.html
diff --git a/src/doc/trpl/unsized-types.md b/src/doc/trpl/unsized-types.md
index f307f23f011..756abeff06d 100644
--- a/src/doc/trpl/unsized-types.md
+++ b/src/doc/trpl/unsized-types.md
@@ -1,3 +1,58 @@
 % Unsized Types
 
-Coming Soon!
+Most types have a particular size, in bytes, that is knowable at compile time.
+For example, an `i32` is thirty-two bits big, or four bytes. However, there are
+some types which are useful to express, but do not have a defined size. These are
+called ‘unsized’ or ‘dynamically sized’ types. One example is `[T]`. This type
+represents a certain number of `T` in sequence. But we don’t know how many
+there are, so the size is not known.
+
+Rust understands a few of these types, but they have some restrictions. There
+are three:
+
+1. We can only manipulate an instance of an unsized type via a pointer. An
+   `&[T]` works just fine, but a `[T]` does not.
+2. Variables and arguments cannot have dynamically sized types.
+3. Only the last field in a `struct` may have a dynamically sized type; the
+   other fields must not. Enum variants must not have dynamically sized types as
+   data.
+
+So why bother? Well, because `[T]` can only be used behind a pointer, if we
+didn’t have language support for unsized types, it would be impossible to write
+this:
+
+```rust,ignore
+impl Foo for str {
+```
+
+or
+
+```rust,ignore
+impl<T> Foo for [T] {
+```
+
+Instead, you would have to write:
+
+```rust,ignore
+impl Foo for &str {
+```
+
+Meaning, this implementation would only work for [references][ref], and not
+other types of pointers. With this `impl`, all pointers, including (at some
+point, there are some bugs to fix first) user-defined custom smart pointers,
+can use this `impl`.
+
+# ?Sized
+
+If you want to write a function that accepts a dynamically sized type, you
+can use the special bound, `?Sized`:
+
+```rust
+struct Foo<T: ?Sized> {
+    f: T,
+}
+```
+
+This `?`, read as “T may be `Sized`”,  means that this bound is special: it
+lets us match more kinds, not less. It’s almost like every `T` implicitly has
+`T: Sized`, and the `?` undoes this default.
diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs
index 7ae1347f2c7..240b6286c8c 100644
--- a/src/test/run-pass/ifmt.rs
+++ b/src/test/run-pass/ifmt.rs
@@ -195,9 +195,11 @@ fn test_write() {
         write!(w, "{}", "hello");
         writeln!(w, "{}", "line");
         writeln!(w, "{foo}", foo="bar");
+        w.write_char('☃');
+        w.write_str("str");
     }
 
-    t!(buf, "34helloline\nbar\n");
+    t!(buf, "34helloline\nbar\n☃str");
 }
 
 // Just make sure that the macros are defined, there's not really a lot that we