Skip to content
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

Rollup of PRs in the queue; Thursday #24703

Merged
merged 7 commits into from
Apr 23, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/doc/trpl/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -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)
69 changes: 68 additions & 1 deletion src/doc/trpl/attributes.md
Original file line number Diff line number Diff line change
@@ -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
92 changes: 91 additions & 1 deletion src/doc/trpl/conditional-compilation.md
Original file line number Diff line number Diff line change
@@ -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.
75 changes: 74 additions & 1 deletion src/doc/trpl/type-aliases.md
Original file line number Diff line number Diff line change
@@ -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
57 changes: 56 additions & 1 deletion src/doc/trpl/unsized-types.md
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 3 additions & 1 deletion src/test/run-pass/ifmt.rs
Original file line number Diff line number Diff line change
@@ -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