See https://github.com/rust-lang/rfcs/pull/16 and https://github.com/rust-lang/rust/issues/15701
- Added syntax support for attributes on expressions and all syntax nodes in statement position.
- Extended `#[cfg]` folder to allow removal of statements, and
of expressions in optional positions like expression lists and trailing
block expressions.
- Extended lint checker to recognize lint levels on expressions and
locals.
- As per RFC, attributes are not yet accepted on `if` expressions.
Examples:
```rust
let x = y;
{
...
}
assert_eq!((1, #[cfg(unset)] 2, 3), (1, 3));
let FOO = 0;
```
Implementation wise, there are a few rough corners and open questions:
- The parser work ended up a bit ugly.
- The pretty printer change was based mostly on guessing.
- Similar to the `if` case, there are some places in the grammar where a new `Expr` node starts,
but where it seemed weird to accept attributes and hence the parser doesn't. This includes:
- const expressions in patterns
- in the middle of an postfix operator chain (that is, after `.`, before indexing, before calls)
- on range expressions, since `#[attr] x .. y` parses as `(#[attr] x) .. y`, which is inconsistent with
`#[attr] .. y` which would parse as `#[attr] (.. y)`
- Attributes are added as additional `Option<Box<Vec<Attribute>>>` fields in expressions and locals.
- Memory impact has not been measured yet.
- A cfg-away trailing expression in a block does not currently promote the previous `StmtExpr` in a block to a new trailing expr. That is to say, this won't work:
```rust
let x = {
#[cfg(foo)]
Foo { data: x }
#[cfg(not(foo))]
Foo { data: y }
};
```
- One-element tuples can have their inner expression removed to become Unit, but just Parenthesis can't. Eg, `(#[cfg(unset)] x,) == ()` but `(#[cfg(unset)] x) == error`. This seemed reasonable to me since tuples and unit are type constructors, but could probably be argued either way.
- Attributes on macro nodes are currently unconditionally dropped during macro expansion, which seemed fine since macro disappear at that point?
- Attributes on `ast::ExprParens` will be prepend-ed to the inner expression in the hir folder.
- The work on pretty printer tests for this did trigger, but not fix errors regarding macros:
- expression `foo![]` prints as `foo!()`
- expression `foo!{}` prints as `foo!()`
- statement `foo![];` prints as `foo!();`
- statement `foo!{};` prints as `foo!();`
- statement `foo!{}` triggers a `None` unwrap ICE.
Replace the old link pointing to an out-of-date gist with a
link to the lazy_static crate on crates.io.
We also don't need to state the author, as the crates.io page
shows the authors and owners.
I think this fixes#30137. I basically just repeated some details that were scattered around other places in this document, and emphasized that you probably don't want an `extern crate` or `mod` statement to end up inside a function.
The documentation shows this:
[dependencies]
rand="0.3.0"
and says it allows any version compatible with 0.3.0, but then it says, "If we wanted to use only 0.3.0 exactly, we could use `=0.3.0`." That is very easy to misunderstand, so hopefully this PR will help others not to be as confused as me. :-)
I think this fixes#30137. I basically just repeated some details that were scattered around other places in this document, and emphasized that you probably don't want an `extern crate` or `mod` statement to end up inside a function.
* `const`: Add reference to raw pointers
* Change `expr!(...)` etc. examples to use `ident` instead.
*Technically*, it should be `pat`, but that's not how it works in
practice.
* `|`: add reference to closure syntax.
* Closure syntax entry.
* Indexing and slicing entries.
The `f` argument will reference the actual value in the `d` box, not the box in the `bar`'s stack frame.
I am just learning Rust, so I don't know how to explain this well, but just from `f`'s type it is clear that it will be a pointer to an `i32`, not a pointer to a pointer. Some `println!("{:p}", ...)`'s can easily confirm this.
I would actually suggest to remove/simplify this part of the example. This is a subtle issue that can easily confuse people at the early stages of familiarizing with the language. (As I got confused by it. :))
At this point of the book, reader have likely use `cargo new --bin`,
likely 2 times, once if they are lazy. This remind them of the `cargo`
syntax.
I was myself unsure whether it was `cargo create`, `cargo new`, and
whether it would initialize in current working directory or needed a
target.
--
Otherwise thanks, I've been writing rust for a few hours, and likes it so far.
At this point of the book, reader have likely use `cargo new --bin`,
likely 2 times, once if they are lazy. This remind them of the `cargo`
syntax.
I was myself unsure whether it was `cargo create`, `cargo new`, and
whether it would initialize in current working directory or needed a
target.