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; Wednesday #22796

Merged
merged 62 commits into from
Feb 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
efd2a17
Deprecate std::sync::TaskPool
aturon Feb 17, 2015
64fe93e
std: Tidy up some `unsafe impl`s for `sync`
alexcrichton Feb 20, 2015
d443f98
Apply borrowck to fns that appear in const declarations.
nikomatsakis Feb 23, 2015
d0c589d
Hide unnecessary error checking from the user
tbu- Feb 23, 2015
79bf783
std: Handle a trailing slash in create_dir_all
alexcrichton Feb 23, 2015
537d694
std: Expose a `mode` accessor for Permissions on unix
alexcrichton Feb 23, 2015
948a17e
Stop parsing "-" as integer, fixes #22745
krdln Feb 24, 2015
fcf7023
Properly reimplement `unsafe-code` lint to honor changing lint attrib…
ipetkov Feb 24, 2015
23f5a8f
std::io::BufReader: remove leftover lifetime parameter on get_ref()
mzabaluev Feb 24, 2015
a9f6f4b
Add missing `fn`
krdln Feb 24, 2015
0afebe6
Replace deprecated getdtablesize() with sysconf(_SC_OPEN_MAX) for and…
ejjeong Feb 24, 2015
0bea550
style nitpicks
Feb 24, 2015
01385a2
iOS: Sync/Send fallout
vhbit Feb 24, 2015
54b1106
Revert a wrong replace of "fail" to "panic"
tbu- Feb 24, 2015
0fc1a7d
Improve readability of an error check in `set_non_blocking`
tbu- Feb 24, 2015
f31ea22
Mention try macro in error chapter
steveklabnik Feb 17, 2015
2807a1c
Use arrays instead of vectors in tests
petrochenkov Feb 24, 2015
c11807d
Fix broken tests
petrochenkov Feb 24, 2015
0e36a27
Rollup merge of #22623 - petrochenkov:optest, r=alexcrichton
Manishearth Feb 24, 2015
5af3d66
Rollup merge of #22739 - tbu-:pr_error_net, r=alexcrichton
Manishearth Feb 24, 2015
ad73cb0
Rollup merge of #22747 - krdln:fix-parsing-minus, r=alexcrichton
Manishearth Feb 24, 2015
4ff8b8a
Rollup merge of #22752 - ipetkov:unsafe-lint-fix, r=alexcrichton
Manishearth Feb 24, 2015
1913e79
Rollup merge of #22758 - ejjeong:aarch64-linux-android, r=alexcrichton
Manishearth Feb 24, 2015
216be12
Rollup merge of #22770 - vhbit:ios-rand-send, r=alexcrichton
Manishearth Feb 24, 2015
80ac3a8
Rollup merge of #22772 - tbu-:pr_panic_fail, r=alexcrichton
Manishearth Feb 24, 2015
a429bf6
Rollup merge of #22458 - steveklabnik:try_in_error_chapter, r=alexcri…
Manishearth Feb 24, 2015
c51c377
Rollup merge of #22539 - oli-obk:style_nitpicks, r=Manishearth
Manishearth Feb 24, 2015
2408698
Rollup merge of #22736 - nikomatsakis:issue-22382, r=eddyb
Manishearth Feb 24, 2015
b711b6a
Rollup merge of #22778 - mzabaluev:leftover-lifetime, r=alexcrichton
Manishearth Feb 24, 2015
ab45694
std: Stabilize some `ptr` functions
alexcrichton Feb 23, 2015
27f8708
std: Recomend threadpool on crates.io for TaskPool
alexcrichton Feb 24, 2015
14c7683
Fix "How to submit a bug report" link
rnestler Feb 24, 2015
408f7b5
Modify collection's `Debug` output to resemble in their content only
tbu- Feb 10, 2015
870ad3b
Change `Debug` implementation of `BTree*` as well
tbu- Feb 10, 2015
db6ae66
Make traits with assoc types invariant in their inputs.
nikomatsakis Feb 20, 2015
eb841fc
Resolve regions too when normalizing param env.
nikomatsakis Feb 20, 2015
206c254
Improve debug output from coherence.
nikomatsakis Feb 23, 2015
2d200c9
std: Move std::env to the new I/O APIs
alexcrichton Feb 23, 2015
65e1e6b
Add a section on recursive macros
kmcallister Feb 20, 2015
1804242
Add a second, more vexing section on recursive macros
kmcallister Feb 21, 2015
df08657
Tweak wording in the macros guide
kmcallister Feb 21, 2015
848a7e6
Enhance and move information about macro debugging
kmcallister Feb 21, 2015
5d7e283
Turn `unsafe_no_drop_flag` back into a gated-feature.
pnkfelix Feb 25, 2015
91e00f3
unbreak openbsd after nacl intergration
semarie Feb 25, 2015
9692f3b
Rollup merge of #22635 - kmcallister:macros-chapter, r=steveklabnik
Manishearth Feb 25, 2015
24fc50d
Rollup merge of #22783 - alexcrichton:deprecate-taskpool, r=alexcrichton
Manishearth Feb 25, 2015
267c587
Rollup merge of #22784 - rnestler:fix_doc_faq, r=dotdash
Manishearth Feb 25, 2015
3a49c3b
Rollup merge of #22785 - nikomatsakis:issue-21750-normalization-with-…
Manishearth Feb 25, 2015
1c97ac3
Rollup merge of #22792 - semarie:openbsd-unbreak-nacl, r=alexcrichton
Manishearth Feb 25, 2015
c950ee9
Rollup merge of #22157 - tbu-:pr_debug_collections, r=alexcrichton
Manishearth Feb 25, 2015
7b7cf84
Rollup merge of #22596 - alexcrichton:fix-some-impls, r=huonw
Manishearth Feb 25, 2015
b18584c
Rollup merge of #22727 - alexcrichton:prep-env, r=aturon
Manishearth Feb 25, 2015
6c6f231
Rollup merge of #22729 - alexcrichton:ptr-stabilization, r=aturon
Manishearth Feb 25, 2015
ecaf74a
Rollup merge of #22742 - alexcrichton:issue-22737, r=aturon
Manishearth Feb 25, 2015
1f2b3eb
Rollup merge of #22744 - alexcrichton:issue-22738, r=aturon
Manishearth Feb 25, 2015
f164254
Rollup merge of #22787 - pnkfelix:reenable-gate-for-unsafe_no_drop_fl…
Manishearth Feb 25, 2015
f8e4fcb
allow(deprecated) for TaskPool (fixup #22783)
Manishearth Feb 25, 2015
9f8a1cb
Use os::getcwd instead of env in rustbook (fixup #22727)
Manishearth Feb 25, 2015
e61a790
Fix type inference error (fixup #22739)
Manishearth Feb 25, 2015
2470fa1
Assert is internal now (fixup #22739)
Manishearth Feb 25, 2015
d54ed56
path -> PathBuf for osx/dragonfly (fixup #22727)
Manishearth Feb 25, 2015
357b41b
Path -> PathBuf for Windows test (fixup #22727)
Manishearth Feb 25, 2015
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/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ There are questions that are asked quite often, and so we've made FAQs for them:
* [Language Design FAQ](complement-design-faq.html)
* [Language FAQ](complement-lang-faq.html)
* [Project FAQ](complement-project-faq.html)
* [How to submit a bug report](complement-bugreport.html)
* [How to submit a bug report](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports)

# The standard library

Expand Down
17 changes: 12 additions & 5 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -731,15 +731,20 @@ Rust syntax is restricted in two ways:
pairs when they occur at the beginning of, or immediately after, a `$(...)*`;
requiring a distinctive token in front can solve the problem.

## Syntax extensions useful for the macro author
## Syntax extensions useful in macros

* `log_syntax!` : print out the arguments at compile time
* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging
* `stringify!` : turn the identifier argument into a string literal
* `concat!` : concatenates a comma-separated list of literals
* `concat_idents!` : create a new identifier by concatenating the arguments

The following attributes are used for quasiquoting in procedural macros:
## Syntax extensions for macro debugging

* `log_syntax!` : print out the arguments at compile time
* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging

## Quasiquoting

The following syntax extensions are used for quasiquoting Rust syntax trees,
usually in [procedural macros](book/plugins.html#syntax-extensions):

* `quote_expr!`
* `quote_item!`
Expand All @@ -748,6 +753,8 @@ The following attributes are used for quasiquoting in procedural macros:
* `quote_tokens!`
* `quote_ty!`

Documentation is very limited at the moment.

# Crates and source files

Rust is a *compiled* language. Its semantics obey a *phase distinction*
Expand Down
57 changes: 48 additions & 9 deletions src/doc/trpl/advanced-macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,19 +192,58 @@ To keep this system simple and correct, `#[macro_use] extern crate ...` may
only appear at the root of your crate, not inside `mod`. This ensures that
`$crate` is a single identifier.

# A final note
# The deep end

Macros, as currently implemented, are not for the faint of heart. Even
ordinary syntax errors can be more difficult to debug when they occur inside a
macro, and errors caused by parse problems in generated code can be very
tricky. Invoking the `log_syntax!` macro can help elucidate intermediate
states, invoking `trace_macros!(true)` will automatically print those
intermediate states out, and passing the flag `--pretty expanded` as a
command-line argument to the compiler will show the result of expansion.
The introductory chapter mentioned recursive macros, but it did not give the
full story. Recursive macros are useful for another reason: Each recursive
invocation gives you another opportunity to pattern-match the macro's
arguments.

As an extreme example, it is possible, though hardly advisable, to implement
the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
within Rust's macro system.

```rust
#![feature(trace_macros)]

macro_rules! bct {
// cmd 0: d ... => ...
(0, $($ps:tt),* ; $_d:tt)
=> (bct!($($ps),*, 0 ; ));
(0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
=> (bct!($($ps),*, 0 ; $($ds),*));

// cmd 1p: 1 ... => 1 ... p
(1, $p:tt, $($ps:tt),* ; 1)
=> (bct!($($ps),*, 1, $p ; 1, $p));
(1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
=> (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));

// cmd 1p: 0 ... => 0 ...
(1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
=> (bct!($($ps),*, 1, $p ; $($ds),*));

// halt on empty data string
( $($ps:tt),* ; )
=> (());
}

fn main() {
trace_macros!(true);
# /* just check the definition
bct!(0, 0, 1, 1, 1 ; 1, 0, 1);
# */
}
```

Exercise: use macros to reduce duplication in the above definition of the
`bct!` macro.

# Procedural macros

If Rust's macro system can't do what you need, you may want to write a
[compiler plugin](plugins.html) instead. Compared to `macro_rules!`
macros, this is significantly more work, the interfaces are much less stable,
and the warnings about debugging apply ten-fold. In exchange you get the
and bugs can be much harder to track down. In exchange you get the
flexibility of running arbitrary Rust code within the compiler. Syntax
extension plugins are sometimes called *procedural macros* for this reason.
72 changes: 72 additions & 0 deletions src/doc/trpl/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,78 @@ let input = io::stdin().read_line()
.ok()
.expect("Failed to read line");
```

`ok()` converts the `IoResult` into an `Option`, and `expect()` does the same
thing as `unwrap()`, but takes a message. This message is passed along to the
underlying `panic!`, providing a better error message if the code errors.

# Using `try!`

When writing code that calls many functions that return the `Result` type, the
error handling can be tedious. The `try!` macro hides some of the boilerplate
of propagating errors up the call stack.

It replaces this:

```rust
use std::fs::File;
use std::io;
use std::io::prelude::*;

struct Info {
name: String,
age: i32,
rating: i32,
}

fn write_info(info: &Info) -> io::Result<()> {
let mut file = File::open("my_best_friends.txt").unwrap();

if let Err(e) = writeln!(&mut file, "name: {}", info.name) {
return Err(e)
}
if let Err(e) = writeln!(&mut file, "age: {}", info.age) {
return Err(e)
}
if let Err(e) = writeln!(&mut file, "rating: {}", info.rating) {
return Err(e)
}

return Ok(());
}
```

With this:

```rust
use std::fs::File;
use std::io;
use std::io::prelude::*;

struct Info {
name: String,
age: i32,
rating: i32,
}

fn write_info(info: &Info) -> io::Result<()> {
let mut file = try!(File::open("my_best_friends.txt"));

try!(writeln!(&mut file, "name: {}", info.name));
try!(writeln!(&mut file, "age: {}", info.age));
try!(writeln!(&mut file, "rating: {}", info.rating));

return Ok(());
}
```

Wrapping an expression in `try!` will result in the unwrapped success (`Ok`)
value, unless the result is `Err`, in which case `Err` is returned early from
the enclosing function.

It's worth noting that you can only use `try!` from a function that returns a
`Result`, which means that you cannot use `try!` inside of `main()`, because
`main()` doesn't return anything.

`try!` makes use of [`FromError`](../std/error/#the-fromerror-trait) to determine
what to return in the error case.
89 changes: 78 additions & 11 deletions src/doc/trpl/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ macro_rules! vec {
};
}
# fn main() {
# assert_eq!(&[1,2,3], &vec![1,2,3]);
# assert_eq!([1,2,3], vec![1,2,3]);
# }
```

Expand Down Expand Up @@ -189,14 +189,12 @@ shorthand for a data type could be valid as either an expression or a pattern.

## Repetition

The repetition behavior can seem somewhat magical, especially when multiple
names are bound at multiple nested levels of repetition. The two rules to keep
in mind are:
The repetition operator follows two principal rules:

1. the behavior of `$(...)*` is to walk through one "layer" of repetitions, for
all of the `$name`s it contains, in lockstep, and
1. `$(...)*` walks through one "layer" of repetitions, for all of the `$name`s
it contains, in lockstep, and
2. each `$name` must be under at least as many `$(...)*`s as it was matched
against. If it is under more, it'll be duplicated, as appropriate.
against. If it is under more, it'll be duplicated, as appropriate.

This baroque macro illustrates the duplication of variables from outer
repetition levels.
Expand Down Expand Up @@ -226,6 +224,10 @@ That's most of the matcher syntax. These examples use `$(...)*`, which is a
more" match. Both forms optionally include a separator, which can be any token
except `+` or `*`.

This system is based on
"[Macro-by-Example](http://www.cs.indiana.edu/ftp/techreports/TR206.pdf)"
(PDF link).

# Hygiene

Some languages implement macros using simple text substitution, which leads to
Expand Down Expand Up @@ -273,19 +275,26 @@ macro, using [a GNU C extension] to emulate Rust's expression blocks.
})
```

This looks reasonable, but watch what happens in this example:
Here's a simple use case that goes terribly wrong:

```text
const char *state = "reticulating splines";
LOG(state);
LOG(state)
```

The program will likely segfault, after it tries to execute
This expands to

```text
printf("log(%d): %s\n", state, state);
const char *state = "reticulating splines";
int state = get_log_state();
if (state > 0) {
printf("log(%d): %s\n", state, state);
}
```

The second variable named `state` shadows the first one. This is a problem
because the print statement should refer to both of them.

The equivalent Rust macro has the desired behavior.

```rust
Expand Down Expand Up @@ -357,6 +366,64 @@ fn main() {

[items]: ../reference.html#items

# Recursive macros

A macro's expansion can include more macro invocations, including invocations
of the very same macro being expanded. These recursive macros are useful for
processing tree-structured input, as illustrated by this (simplistic) HTML
shorthand:

```rust
# #![allow(unused_must_use)]
macro_rules! write_html {
($w:expr, ) => (());

($w:expr, $e:tt) => (write!($w, "{}", $e));

($w:expr, $tag:ident [ $($inner:tt)* ] $($rest:tt)*) => {{
write!($w, "<{}>", stringify!($tag));
write_html!($w, $($inner)*);
write!($w, "</{}>", stringify!($tag));
write_html!($w, $($rest)*);
}};
}

fn main() {
# // FIXME(#21826)
use std::fmt::Write;
let mut out = String::new();

write_html!(&mut out,
html[
head[title["Macros guide"]]
body[h1["Macros are the best!"]]
]);

assert_eq!(out,
"<html><head><title>Macros guide</title></head>\
<body><h1>Macros are the best!</h1></body></html>");
}
```

# Debugging macro code

To see the results of expanding macros, run `rustc --pretty expanded`. The
output represents a whole crate, so you can also feed it back in to `rustc`,
which will sometimes produce better error messages than the original
compilation. Note that the `--pretty expanded` output may have a different
meaning if multiple variables of the same name (but different syntax contexts)
are in play in the same scope. In this case `--pretty expanded,hygiene` will
tell you about the syntax contexts.

`rustc` provides two syntax extensions that help with macro debugging. For now,
they are unstable and require feature gates.

* `log_syntax!(...)` will print its arguments to standard output, at compile
time, and "expand" to nothing.

* `trace_macros!(true)` will enable a compiler message every time a macro is
expanded. Use `trace_macros!(false)` later in expansion to turn it off.

# Further reading

The [advanced macros chapter][] goes into more detail about macro syntax. It
Expand Down
14 changes: 6 additions & 8 deletions src/doc/trpl/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,7 @@ a more involved macro example, see

## Tips and tricks

To see the results of expanding syntax extensions, run
`rustc --pretty expanded`. The output represents a whole crate, so you
can also feed it back in to `rustc`, which will sometimes produce better
error messages than the original compilation. Note that the
`--pretty expanded` output may have a different meaning if multiple
variables of the same name (but different syntax contexts) are in play
in the same scope. In this case `--pretty expanded,hygiene` will tell
you about the syntax contexts.
Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable.

You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into
higher-level syntax elements like expressions:
Expand Down Expand Up @@ -184,6 +177,11 @@ and return
[`DummyResult`](../syntax/ext/base/struct.DummyResult.html),
so that the compiler can continue and find further errors.

To print syntax fragments for debugging, you can use
[`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together
with
[`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions).

The example above produced an integer literal using
[`AstBuilder::expr_uint`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint).
As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of
Expand Down
1 change: 1 addition & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
#![feature(unboxed_closures)]
#![feature(unsafe_no_drop_flag)]
#![feature(core)]
#![feature(unique)]
#![cfg_attr(test, feature(test, alloc, rustc_private))]
#![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
feature(libc))]
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ impl<T: Ord> BinaryHeap<T> {
/// heap.push(3);
///
/// let vec = heap.into_sorted_vec();
/// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6, 7]);
/// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7]);
/// ```
pub fn into_sorted_vec(mut self) -> Vec<T> {
let mut end = self.len();
Expand Down
Loading