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

Tracking issue for RFC 2582, &raw [mut | const] $place (raw_ref_op) #64490

Closed
2 of 3 tasks
Centril opened this issue Sep 15, 2019 · 80 comments · Fixed by #127679 or rust-lang/reference#1567
Closed
2 of 3 tasks
Labels
B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-raw_ref_op `#![feature(raw_ref_op)]` requires-nightly This issue requires a nightly compiler in some way. S-tracking-needs-summary Status: It's hard to tell what's been done and what hasn't! Someone should do some investigation. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@Centril
Copy link
Contributor

Centril commented Sep 15, 2019

This is a tracking issue for the RFC "an operator to take a raw reference" (rust-lang/rfcs#2582), feature(raw_ref_op).

Steps:

Unresolved questions:

(None left here, since the lint was moved to #127724)

Implementation history:

@Centril Centril added B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. T-lang Relevant to the language team, which will review and decide on the PR/issue. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. requires-nightly This issue requires a nightly compiler in some way. F-raw_ref_op `#![feature(raw_ref_op)]` labels Sep 15, 2019
@matthewjasper
Copy link
Contributor

I'll try to get a PR open for this soon.

@Centril
Copy link
Contributor Author

Centril commented Sep 15, 2019

I would suggest splitting the implementation work up into phases to make each part thoroughly reviewed and tested. However, think of this list as a bunch of tasks that need to be done at some point.

  1. Implement &raw [mut | const] $expr in the parser and AST.
    • Ensure the unused_parens lint works alright.
    • Handle interactions in librustc_resolve.
  2. Push things down from AST => HIR
    • Handle lowering
    • Handle type checking
  3. Push things down from HIR => HAIR
  4. Push things down from HAIR => MIR -- here, the actual MIR operation is introduced.
  5. Introduce lints for statically detectable UB as per the RFC.
  6. Make safe_packed_borrows a hard error when the feature gate is active, and make this the case as well for unsafe equivalents.

...but it seems @matthewjasper already has a PR heh.

@Aaron1011
Copy link
Member

Make safe_packed_borrows a hard error when the feature gate is active, and make this the case as well for unsafe equivalents.

I'm not sure that this is a good idea. This would make it impossible to gradually migrate a codebase over to using raw references - once the feature gate is enabled, all references to packed structs must be fixed at once in order to get the crate building again.

@moshg
Copy link

moshg commented Sep 15, 2019

I wonder why not &raw $expr but &raw const $expr. Is there a discussion about this?

@mjbshaw
Copy link
Contributor

mjbshaw commented Sep 15, 2019

@moshg Yes, this was discussed. See here (and the following comments) for an initial discussion. And here (and the following comments) for a signoff from grammar-wg. And here for an example that &raw (expr) can be ambiguous.

I think it might be worth amending the RFC to state why &raw const $expr was chosen over &raw $expr.

@Ixrec
Copy link
Contributor

Ixrec commented Sep 15, 2019

The RFC thread noted a couple times (including in the FCP comment) that &raw expr without the const conflicts with existing syntax and would break real code. rust-lang/rfcs#2582 (comment) goes into some detail. My understanding is that it is still possible to migrate to &raw expr with breaking changes in an edition, and I didn't see much explicit discussion of that, but I think everyone agrees that there's enough urgency here that we definitely prefer making &raw const expr a thing over blocking any solution on waiting for another edition.

@moshg
Copy link

moshg commented Sep 16, 2019

@mjbshaw @lxrec
Thank you for your explanations! I've understood why &raw $expr is breaking change.

@RalfJung
Copy link
Member

I think it might be worth amending the RFC to state why &raw const $expr was chosen over &raw $expr.

rust-lang/rfcs#2764

@red75prime
Copy link

red75prime commented Oct 9, 2019

@RalfJung I'm addressing the points you've made in rust-lang/rfcs#2582 (comment)

promotion being confusing here seems mostly orthogonal to raw-vs-ref, doesn't it?

While it would be helpful to have at least a warning for a promotion in &mut <rvalue> case, disabling it is a backward incompatible change to the language. In &raw mut <rvalue> case it can be done from the beginning.

If no promotion happens with raw ptrs, what would you expect to happen instead?

I would expect &raw mut <rvalue> to result in compilation error, as &<rvalue> does in C.

I would expect &raw mut (1+2) to be promoted the same way &mut (1+2) is; not doing that seems even more confusing and very error-prone

I have an impression that silently allowing such promotions is more error prone, as it violates the principle of least surprise.

trait AddTwo {
    fn add_two(&mut self);
}

impl AddTwo for u32 {
    fn add_two(&mut self) { *self += 2; }
}

const N: u32 = 0;
// somewhere else
assert_eq!(N, 0);
// N += 2; // doesn't compile
N.add_two(); // compiles with no warnings
assert_eq!(N, 2); // fails

@oli-obk
Copy link
Contributor

oli-obk commented Oct 9, 2019

promotion being confusing here seems mostly orthogonal to raw-vs-ref, doesn't it?

yes, promotion has nothing to do with it as far as I can tell.

I would expect &raw mut to result in compilation error, as & does in C.

I agree. We should error on any &raw place where place

  1. has no Deref projections (*) or Index ([i]) projections
  2. and has a temporary local as base

since we still want to permit &raw *foo() I would assume. Or more concretely &raw foo().bar when foo() returns a reference.

If "erroring if not" has too many negations (i confused myself in the process of writing this), here's a version of what I think we should permit (and only that):

We should permit &raw place only if place

  1. has Deref projections or Index projections
  2. or has a static or local variable as the base

@RalfJung
Copy link
Member

RalfJung commented Oct 9, 2019

While it would be helpful to have at least a warning for a promotion in &mut case, disabling it is a backward incompatible change to the language. In &raw mut case it can be done from the beginning.

Note that not promoting here means this becomes a very short-lived temporary and the code has UB (or fails to compile, when only safe references are used)! Is that really what you want? ptr as T is not a place like ptr is and cannot be used as such; in particular it cannot be mutated.

I have an impression that silently allowing such promotions is more error prone, as it violates the principle of least surprise.

I have a hard time imagining that silently causing UB is less of a surprise than promoting...

N.add_two(); // compiles with no warnings

You are conflating some things here; what you are seeing here are implicit deref coercions. Promotion is not involved in this example.

We should permit &raw place only if place

Oh I see, you want to cause some static errors. Yeah I can imagine that there are reasonable things we could do here.

@red75prime
Copy link

red75prime commented Oct 9, 2019

You are conflating some things here; what you are seeing here are implicit deref coercions. Promotion is not involved in this example.

There's a bit of misunderstanding. I used a wrong term. When I said "rvalue promotion", I had "creation of a temporary memory location for an rvalue" in mind, not "promotion of a temporary to 'static".

@RalfJung
Copy link
Member

RalfJung commented Oct 9, 2019

@red75prime oh I see. Well currently, with promotion, we do not create a temporary memory location, but just a global one. But I suppose your desired behavior is more like what @oli-obk described, where we have static compiler errors?

I am not sure to what extend we can reliably produce those though. But MIR construction should know when it builds temporaries, so couldn't it refuse to do that when &raw is involved? Cc @matthewjasper

@HadrienG2
Copy link

Is there any plan to eventually add &raw pointer support to pattern matching? It could enable getting rid of various forms of deliberate UB in abomonation.

@RalfJung
Copy link
Member

@HeroicKatora actually wrote an RFC for that, though it was originally meant as an alternative to &raw: rust-lang/rfcs#2666

@HeroicKatora
Copy link
Contributor

I'd be fine with it being interpreted as complementary, and can rewrite portions of it as necessary :)

@mjbshaw
Copy link
Contributor

mjbshaw commented Oct 20, 2019

I can't recall if this was discussed in the RFC (and failed to find any comments on it), but can <place> be a pointer (to allow pointer-to-field computations)? Example:

struct Struct {
    field: f32,
}

let base_ptr = core::mem::MaybeUninit::<Struct>::uninit().as_ptr();
let field_ptr = &raw const base_ptr.field; // Is this allowed by this RFC?

Currently field_ptr has to be initialized with unsafe { &(*base_ptr).field as *const _ }. Using unsafe { &raw const(*base_ptr).field } is a bit better, but avoiding the *base_ptr dereference entirely would be ideal.

I assume the RFC doesn't permit this (since base_ptr.field isn't a place), but I just wanted to confirm (to be clear: I'm not trying to advocate for this RFC to do that if it doesn't already; I would like to draft a separate RFC exploring ways to avoid the *base_ptr dereference).

@RalfJung
Copy link
Member

I can't recall if this was discussed in the RFC (and failed to find any comments on it), but can be a pointer (to allow pointer-to-field computations)?

That question is ill-typed. A pointer is a kind of value, which is a class of things separate from places.

let field_ptr = &raw const base_ptr.field; // Is this allowed by this RFC?

No, because there is no deref coercion for raw ptrs. But &raw const (*base_ptr).field is allowed, because (*base_ptr).field is a place.

avoiding the *base_ptr dereference entirely would be ideal.

That has nothing to do with places though, that's just a deref coercion. When you write similar things with references, they work because the compiler adds the * for you -- and not because of anything having to do with places.

since base_ptr.field isn't a place

It's not even well-typed.

I would like to draft a separate RFC exploring ways to avoid the *base_ptr dereference).

Agreed, the current syntax is bad -- but mostly because of the parenthesis and the use of a prefix operator. I think we should have posfix-deref, e.g. base_ptr.*.field. That has been discussed before... somewhere...

@mjbshaw
Copy link
Contributor

mjbshaw commented Oct 20, 2019

That question is ill-typed. A pointer is a kind of value, which is a class of things separate from places.

You're right. Sorry for my poor choice of words.

let field_ptr = &raw const base_ptr.field; // Is this allowed by this RFC?

No

Thanks for answering my question. I'll follow up to your other points in a new thread on internals.rust-lang.org.

@eddyb
Copy link
Member

eddyb commented Oct 20, 2019

Small nit: a deref coercion is &T to &U via deref(s). Dot access has its own implicit deref.

@RalfJung
Copy link
Member

RalfJung commented Sep 20, 2020

I thought this was what the RFC proposes, so it looks like I deeply misunderstand it :/

There is, as far as I can see, not a single instance of the deref operator * in the RFC (except for "future possibilities", where they are implicit though through auto-deref). So no, this is not what the RFC proposes. The "offsetof woes" paragraph in "Future possibilities" mentions such a change could be desirable in the future, but the rest of the RFC is specifically about creating pointers, not about dereferencing them.

@A1-Triard
Copy link

@RalfJung , OK, You have convinced me. I will use memoffset crate.

@withoutboats
Copy link
Contributor

withoutboats commented Sep 21, 2020

The RFC seems to be written on the premise that problematic part of this code is the reference-creating operator &, and proposes a new operator that can be used instead. However that does not match my mental model at all. My understanding of raw pointers in current stable Rust is that the dereference operator * is the only source of unsafety / potential UB.

That's not correct; the use case that the RFC immediately addresses has to do with packed structs and not dereferencing raw pointers.

#[repr(packed)]
struct A(u8, i32);

let x: A = A(0, 0);
let r: &A = &x;

// IMMEDIATE UB
let ub: &i32 = &x.1;

This code contains UB, as I understand it, because it creates an unaligned reference to an i32. This despite the fact that it contains no raw pointers at all. Eventually we'd like to make this a compiler error.

The raw ref macros like you get an *mut i32 without constructing an &i32; that avoids the UB, because you never create an unaligned reference. The problem today is that there's no reasonable to create a raw pointer without first creating a reference, which must be aligned.

@QuineDot
Copy link

QuineDot commented Nov 3, 2021

For what it's worth, I too got the wrong impression from this paragraph and the two that follow.

If one wants to avoid creating a reference to uninitialized data (which might or might not become part of the invariant that must be always upheld), it is also currently not possible to create a raw pointer to a field of an uninitialized struct: again, &mut uninit.field as *mut _ would create an intermediate reference to uninitialized data.

@RalfJung
Copy link
Member

RalfJung commented Nov 3, 2021

What was that wrong impression that you got?

@joshtriplett joshtriplett added the S-tracking-needs-summary Status: It's hard to tell what's been done and what hasn't! Someone should do some investigation. label Jun 22, 2022
@joshtriplett
Copy link
Member

It looks like the new raw ref syntax has been implemented. Are there any blocking concerns that would prevent us from stabilizing this?

@RalfJung
Copy link
Member

AFAIK the lint specified in the RFC has never been implemented. But I guess that is not a blocker for the syntax.

We introduced the addr_of! macro instead of stabilizing the &raw [mut|const] syntax immediately due to concerns around extending the surface syntax and avoiding syntax bikeshed and grammar concerns. No idea if anything changed on that front -- Cc @rust-lang/wg-grammar

@CAD97
Copy link
Contributor

CAD97 commented Jun 23, 2022

It's also my recollection that there were no blocking concerns on the grammar or parsing side.

There were three questions I recall without a definitive answer:

  • &raw $place versus &raw const $place, and whether the syntax should be evoking *const T or &T.
    • From a grammar side, &raw (expr) still requires making raw a contextual keyword here. But the question is whether const is just a concession to parsing that we'd prefer to remove, or if it's desirable as evocative of *const T.
  • &raw const $place giving a read-only pointer even when used on a writable place is contentious.
  • It's unclear what &raw const (*ptr).field requires from ptr — is it gepi or gep, and the related generality/optimization toggles.
    • The problem here is that dereferencing into "place mode" is potentially the wrong abstraction.

Additionally, there is one big "shiny future" possibility: &raw const T (or just &raw T, or &'unsafe T, or any other number of possibilities) for a "better raw pointer" type. The problems and footguns with working with the existing *[const|mut] T and ptr::NonNull<T> are well documented and I won't rehash them here. If in a shiny future we get a built-in nicer raw pointer type, &raw [const|mut] T is currently the most promising syntax for creating a raw pointer (and that's why it's used here), and it'd be a shame to have worse syntax for the better thing, and better syntax for the worse thing.

(But seriously, go read every single thing @Gankra has written about pointers.)

To be clear: I'm not arguing we shouldn't improve what we have because we might be able to do it better in the future. Rather, there are existing proposals that show we really should consider

If we had a time machine, what would we want Rust pointers to look like?

and how close can we realistically get to that ideal?

I think we can get close enough that Rust is a contender for the best language to write C in. This isn't the case currently because of how easy it is to incidentally introduce reference semantics into pointer code (along with other papercuts), but I have faith that we can make it there.

So I guess the conclusion of this is: &raw hasn't stabilized yet because while it is agreeably the best implementation of this solution to this problem, we're still not necessarily in agreement that this is the correct problem to be solving.

Given a magical grant of bandwidth, this is what I personally think should be the path forward:

  • Collect a T-lang design notes document for "pointer pain points"
  • From the pain points, T-lang decides on which path we want to pursue: new pointer type(s) or old pointer types
  • If old pointer types:
    • Stabilize &raw $place syntax 🎉
  • If new pointer type(s)
    • If &raw T:
      • &raw $place makes them and not * [const|mut] T
    • If a new keyword/sigil/etc:
      • Too much of an unknown to predict
    • If a named type (e.g. ptr::NonNull<T>)
      • Determine if place-to-new-pointer is an important operation that wants the & {?} $place syntax space
      • If not: stabilize &raw $place syntax to make today's Rust significantly better 🎉

(And to try to predict the future: I predict that a far-future pointer-perfect Rust has refinement typing for pointers and that ptr::NonNull and ptr::WellFormed are aliases for the namable refined pointer types that can cross function boundaries. Prefix deref is deprecated in favor of .read()/.write()/.as_ref()/.as_mut() and . for safe field offsetting, ~ for unsafe GEPi field offsetting. container_of! is still, as usual, a controversial nightmare.)

gwilymk added a commit to agbrs/agb that referenced this issue Mar 23, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [syn](https://github.com/dtolnay/syn) | dependencies | major | `1`
-> `2` |

---

### Release Notes

<details>
<summary>dtolnay/syn</summary>

### [`v2.0.8`](https://github.com/dtolnay/syn/releases/tag/2.0.8)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.7...2.0.8)

- Treat `try` keyword as 2015-edition identifier in definition of try
macro ([#&#8203;1422](https://github.com/dtolnay/syn/issues/1422))

### [`v2.0.7`](https://github.com/dtolnay/syn/releases/tag/2.0.7)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.6...2.0.7)

-   Fix parsing of `mut self` inside of Type::BareFn

### [`v2.0.6`](https://github.com/dtolnay/syn/releases/tag/2.0.6)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.5...2.0.6)

- Improve error message on missing ';' between statements
([#&#8203;1419](https://github.com/dtolnay/syn/issues/1419))
- Keep non-brace macro invocations in trailing expr position as
Expr::Macro
([#&#8203;1420](https://github.com/dtolnay/syn/issues/1420))

### [`v2.0.5`](https://github.com/dtolnay/syn/releases/tag/2.0.5)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.4...2.0.5)

- Expose `ExprMacro` data structure even when `features="full"` is not
used ([#&#8203;1417](https://github.com/dtolnay/syn/issues/1417))

### [`v2.0.4`](https://github.com/dtolnay/syn/releases/tag/2.0.4)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.3...2.0.4)

- Improve error reporting when parsing identifiers and paths
([#&#8203;1415](https://github.com/dtolnay/syn/issues/1415),
[#&#8203;1416](https://github.com/dtolnay/syn/issues/1416))

### [`v2.0.3`](https://github.com/dtolnay/syn/releases/tag/2.0.3)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.2...2.0.3)

- Expose `ExprGroup` data structure even when `features="full"` is not
used ([#&#8203;1412](https://github.com/dtolnay/syn/issues/1412))

### [`v2.0.2`](https://github.com/dtolnay/syn/releases/tag/2.0.2)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.1...2.0.2)

-   Documentation improvements

### [`v2.0.1`](https://github.com/dtolnay/syn/releases/tag/2.0.1)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.0...2.0.1)

- Add methods on syn::Meta for reporting error on an incorrect kind of
attribute ([#&#8203;1409](https://github.com/dtolnay/syn/issues/1409))

### [`v2.0.0`](https://github.com/dtolnay/syn/releases/tag/2.0.0)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.109...2.0.0)

This release contains a batch of syntax tree improvements to incorporate
ongoing Rust language development from the past 3.5 years since syn 1.

It never seems like an ideal time to finalize a syntax tree design,
considering the frankly alarming number of syntax-disrupting language
features currently in flight: keyword generics, restrictions,
capabilities and contexts, conditional constness, new varieties of
literals, dyn revamp such as explicitly dyn-safe traits and dyn-star,
expression syntax in various phases of being added or being torn out
(const blocks, try blocks, raw references), auto traits and negative
impls, generalizations to higher rank trait bounds, async closures and
static async trait methods, postfix keywords, pattern types, return type
notation, unsafe attributes, …

The plan continues to be the same as laid out originally in the 1.0.0
release announcement:

> Be aware that the underlying Rust language will continue to evolve.
Syn is able to accommodate most kinds of Rust grammar changes via the
nonexhaustive enums and `Verbatim` variants in the syntax tree, but we
will plan to put out new major versions on a 12 to 24 month cadence to
incorporate ongoing language changes as needed.

If anything, the takeaway from the 3.5 year longevity of syn 1 is that
this period was tamer from a language development perspective than
anticipated, but that is unlikely to last and I think around 24 months
is still the correct cadence to expect between releases going forward.

<br>

<p align="center"><a href="https://docs.rs/syn/2/syn/">[API
documentation for 2.0]</a></p>

### Breaking changes

-   Minimum required Rust version is raised from rustc 1.31 to 1.56.

##### Expressions

- Support for `box expr` syntax has been deleted, as it has been deleted
recently from rustc.

- Support for type ascription syntax `expr: Type` in expression position
has been deleted.

- Support for unstable `&raw const expr` raw-pointer reference syntax
has been deleted.

- The representation of generic arguments has been unified between
method calls and non-method paths into a single `GenericArgument` type,
which supersedes the previous `GenericMethodArgument` and
`MethodTurbofish`.

- Generic arguments now distinguish between associated types
(`AssocType`) and associated constant values (`AssocConst`). Previously
these would be parsed ambiguously as `Binding`.

- The binary assignment operators in `BinOp` have been renamed to align
with the naming used by the standard library's `core::ops` module's
traits. For example `BinOp::AddEq` is now called `BinOp::AddAssign`.

- `Expr::Struct` struct construction expressions now support structs
which are a variant of an enum associated type of a trait, as in `<Type
as Trait>::Assoc::Variant { ... }`, which has recently been added to
Rust.

- `Expr::Range` now follows the `start` and `end` naming used by the
standard library's `RangeBounds` trait, rather than `from`/`to` or
`lo`/`hi`.

- `Expr::AssignOp` has been merged into `Expr::Binary`, which now
represents both non-assignment and assignment binary operators.

- Stricter parsing of ranges. None of the following are valid
expressions, but were previously accepted by syn: `..=`, `lo..=`, `...`,
`...hi`, `lo...`, `lo...hi`.

- `Expr::Closure` now includes a representation for `for<...>`
lifetimes.

##### Statements

- Variants `Stmt::Expr` (tail-position expression without trailing
semicolon) and `Stmt::Semi` (non-tail expression with trailing
semicolon) have been combined into `Stmt::Expr` with the optional
semicolon represented by `Option<Token![;]>`.

- The syntax tree for `Stmt::Local` has been extended to handle
`let`/`else` syntax.

- Macros in statement position are now uniformly parsed as
`Stmt::Macro`. Previously these would be disambiguated to `Stmt::Item`,
although it was ambiguous whether a macro in statement position would
expand to an item (like `thread_local! { ... }`) vs an expression (like
`println! { ... }`).

##### Patterns

- Pattern parsing for all the different syntactic positions in which
patterns are allowed has been split into `Pat::parse_single` (for
function- and closure-argument position, where top-level `|` is not
allowed), `Pat::parse_multi` (where `|` is allowed) and
`Pat::parse_multi_with_leading_vert` (for the pattern of match arms,
which allow an optional leading `|`). Previously only a single `parse`
behavior was supported and behaved like the new `parse_single`.

- The `Pat` syntax tree now shares more common data structures with the
`Expr` syntax tree where possible, such as for literals, paths, macros,
and ranges in pattern position.

- Parsing of struct field patterns does a better job rejecting bogus
syntax such as `Struct { 0 asdf }` and `Struct { ref mut 0: asdf }`,
which were previously incorrectly accepted.

- `Pat::Range` now supports one-sided ranges by representing the start
and end bound of the range by `Option<Expr>`.

- `Pat::Struct` keeps track of attributes on the optional `..` "rest"
part of the pattern, as in `let Struct { x, #[cfg(any())] .. } = _;`.

- Parsing unary negation now enforces that only literal patterns can be
unarily negated. For example `-self::CONST` and `-const { 0i32 }` are
not valid syntax in pattern position.

- `Pat::TupleStruct` no longer wraps a value of type `PatTuple` but
represents that information in its fields directly.

- A single parenthesized pattern without trailing comma inside the
parentheses is no longer considered a `Pat::Tuple`, it will be parsed as
`Pat::Paren`.

- One-sided range patterns are no longer allowed inside of slice
patterns. `[lo..]` and `[..=hi]` are not considered valid pattern syntax
by Rust.

##### Items

- Typed `self` in a method signature, such as `self: Pin<&mut Self>`,
will now be parsed as `FnArg::Receiver`. This means `self`, whether with
or without an explicit type, is always treated as a `Receiver`.
Previously only the `&self` and `&mut self` shorthand receivers were
parsed as `Receiver`.

- `TraitItem::Method` and `ImplItem::Method` have been renamed to
`TraitItem::Fn` and `ImplItem::Fn`, as they do not necessarily represent
methods if the function signature contains no `self`.

- `Item::Macro2` has been deleted as "macros 2.0" syntax is no longer
considered on track for stabilization.

- Various item kinds now hold `Generics` which didn't used to have them.

- The variadic argument of an extern function signature can now be given
an optional parameter name.

-   `WherePredicate::Eq` is no longer supported.

- `Visibility::Crate` is no longer supported. This syntax has been
removed from rustc.

- Public visibility is now represented by a single `Token![pub]` token
rather than the old `VisPublic` struct.

- `LifetimeDef` is now called `LifetimeParam`. This name makes more
sense in the context of the `GenericParam` enum (which also includes
`TypeParam` and `ConstParam`), and is the name that the Rust Reference
uses.

- Modules and extern blocks (`Item::Mod` and `Item::ForeignMod`) can now
be marked `unsafe`.

##### Attributes

- The syntax tree for `Attribute` has been redesigned. The new API
better accommodates attributes which mix structured and unstructured
content at different levels of nesting.

-   `AttributeArgs` has been removed. Use `Punctuated<Meta, Token![,]>`.

- For parsing attribute contents, `parse_meta()` is superseded by a new
parsing library called `syn::meta`, and the `parse_nested_meta` method
on `Attribute`.

##### Tokens

- In string literals, the handling of non-ASCII whitespace after
trailing `\` now matches what is implemented by rustc. Space, horizontal
tab, line feed, and carriage return are the only 4 whitespace characters
which are supposed to be stripped from the beginning of the next line.

- The delimiter tokens `syn::token::Paren`, `Bracket`, and `Brace` now
store 2 spans (the open and close punctuation separately) rather than
just 1. Use `.join()` to obtain a single `Span` spanning the whole
group.

- Keyword construction now requires a single span; an array of 1 span is
no longer accepted. Use `Token![trait](span)` instead of
`Token![trait]([span])`.

- Some token types have been renamed to conform with terminology used by
the [Rust
Reference](https://doc.rust-lang.org/1.68.0/reference/tokens.html#punctuation).
These are `Add`->`Plus`, `Bang`->`Not`, `Colon2`->`PathSep`,
`Div`->`Slash`, `Dot2`->`DotDot`, `Dot3`->`DotDotDot`, `Rem`->`Percent`,
and `Sub`->`Minus`.

##### More

- Several enums have been made `#[non_exhaustive]` in anticipation of
upcoming language changes. This includes `WherePredicate`, `Lit`, and
`GenericArgument`.

- The `impl Extend<Pair<T, P>> for Punctuated<T, P>` now requires `P:
Default` and will push a default punctuation between the pre-existing
elements and the new ones, if there is not already a trailing
punctuation. Previously it would panic in this situation.

- `ParseStream::parse_terminated` now takes a peek-style punctuation
argument instead of turbofish. Replace `input.parse_terminated::<_,
Token![,]>(Thing::parse)` with `input.parse_terminated(Thing::parse,
Token![,])`.

###
[`v1.0.109`](https://github.com/dtolnay/syn/compare/1.0.108...1.0.109)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.108...1.0.109)

### [`v1.0.108`](https://github.com/dtolnay/syn/releases/tag/1.0.108)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.107...1.0.108)

- Fix handling of unusual whitespace after escaped newlines in
`LitStr::value`
([#&#8203;1381](https://github.com/dtolnay/syn/issues/1381), thanks
[@&#8203;ModProg](https://github.com/ModProg))

### [`v1.0.107`](https://github.com/dtolnay/syn/releases/tag/1.0.107)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.106...1.0.107)

-   Opt out of `-Zrustdoc-scrape-examples` on docs.rs for now

### [`v1.0.106`](https://github.com/dtolnay/syn/releases/tag/1.0.106)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.105...1.0.106)

-   Documentation improvements

### [`v1.0.105`](https://github.com/dtolnay/syn/releases/tag/1.0.105)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.104...1.0.105)

- Improve parse errors related to `dyn` and `impl` type syntax
([#&#8203;1245](https://github.com/dtolnay/syn/issues/1245))

### [`v1.0.104`](https://github.com/dtolnay/syn/releases/tag/1.0.104)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.103...1.0.104)

-   Add `PathArguments::is_none()`

### [`v1.0.103`](https://github.com/dtolnay/syn/releases/tag/1.0.103)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.102...1.0.103)

- Implement `PartialOrd` for `Cursor`
([#&#8203;1236](https://github.com/dtolnay/syn/issues/1236),
[#&#8203;1237](https://github.com/dtolnay/syn/issues/1237), thanks
[@&#8203;CAD97](https://github.com/CAD97))

### [`v1.0.102`](https://github.com/dtolnay/syn/releases/tag/1.0.102)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.101...1.0.102)

- More efficient internal representation for `TokenBuffer`
([#&#8203;1223](https://github.com/dtolnay/syn/issues/1223), thanks
[@&#8203;CAD97](https://github.com/CAD97))
- Fix parsing of a left shift after macro metavariable in type position
([#&#8203;1229](https://github.com/dtolnay/syn/issues/1229))

### [`v1.0.101`](https://github.com/dtolnay/syn/releases/tag/1.0.101)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.100...1.0.101)

- Eliminate a bunch of redundant work done by LitStr::parse
([#&#8203;1221](https://github.com/dtolnay/syn/issues/1221))

### [`v1.0.100`](https://github.com/dtolnay/syn/releases/tag/1.0.100)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.99...1.0.100)

- Parse closures with explicit empty lifetime parameter list `for<> ||
-> T {…}` ([#&#8203;1212](https://github.com/dtolnay/syn/issues/1212),
[https://github.com/rust-lang/rust/issues/97362](https://github.com/rust-lang/rust/issues/97362))
- Parse `dyn*` provisional syntax
([#&#8203;1213](https://github.com/dtolnay/syn/issues/1213),
[https://github.com/rust-lang/rust/issues/91611](https://github.com/rust-lang/rust/issues/91611))
- Parse attributes on the "rest" pattern of a struct in pattern
position, `Struct { #[attr] .. }`
([#&#8203;1214](https://github.com/dtolnay/syn/issues/1214))
- Parse `static async` and `static async move` closures
([#&#8203;1215](https://github.com/dtolnay/syn/issues/1215),
[https://github.com/rust-lang/rust/issues/62290](https://github.com/rust-lang/rust/issues/62290))

### [`v1.0.99`](https://github.com/dtolnay/syn/releases/tag/1.0.99)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.98...1.0.99)

-   Add categories and keywords to crates.io metadata

### [`v1.0.98`](https://github.com/dtolnay/syn/releases/tag/1.0.98)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.97...1.0.98)

-   Format example code with rustfmt

### [`v1.0.97`](https://github.com/dtolnay/syn/releases/tag/1.0.97)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.96...1.0.97)

-   Update examples

### [`v1.0.96`](https://github.com/dtolnay/syn/releases/tag/1.0.96)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.95...1.0.96)

- Add a `punct_mut()` method on `syn::punctuated::Pair` to return
`Option<&mut P>`
([#&#8203;1183](https://github.com/dtolnay/syn/issues/1183))

### [`v1.0.95`](https://github.com/dtolnay/syn/releases/tag/1.0.95)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.94...1.0.95)

- Replace unicode-xid with unicode-ident crate:
https://github.com/dtolnay/unicode-ident

### [`v1.0.94`](https://github.com/dtolnay/syn/releases/tag/1.0.94)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.93...1.0.94)

-   Resolve some unused_macro_rules warnings

### [`v1.0.93`](https://github.com/dtolnay/syn/releases/tag/1.0.93)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.92...1.0.93)

- Fix compile error when `Some` means something unusual in the
expression namespace of the scope where `custom_keyword` is invoked
([#&#8203;1171](https://github.com/dtolnay/syn/issues/1171), thanks
[@&#8203;zakarumych](https://github.com/zakarumych))

### [`v1.0.92`](https://github.com/dtolnay/syn/releases/tag/1.0.92)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.91...1.0.92)

- Make compatible with Miri's tag-raw-pointers mode
([#&#8203;1166](https://github.com/dtolnay/syn/issues/1166), thanks
[@&#8203;saethlin](https://github.com/saethlin))

### [`v1.0.91`](https://github.com/dtolnay/syn/releases/tag/1.0.91)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.90...1.0.91)

-   impl ToTokens for RangeLimits
-   impl Parse for ExprAwait
-   impl Parse for GenericMethodArgument
-   impl Parse for MethodTurbofish

### [`v1.0.90`](https://github.com/dtolnay/syn/releases/tag/1.0.90)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.89...1.0.90)

- Update recommended exhaustive matching idiom to use
`non_exhaustive_omitted_patterns` lint:

    ```rust
    match expr {
        Expr::Array(e) => {…}
        Expr::Assign(e) => {…}
        ...
        Expr::Yield(e) => {…}

        #[cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
        _ => {/* some sane fallback */}
    }
    ```

### [`v1.0.89`](https://github.com/dtolnay/syn/releases/tag/1.0.89)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.88...1.0.89)

- Remove support for inner attributes on non-block expressions
([#&#8203;1146](https://github.com/dtolnay/syn/issues/1146),
[https://github.com/rust-lang/rust/pull/83312](https://github.com/rust-lang/rust/pull/83312))
- Fix panic on comma after `mut self` in a bare fn type
([#&#8203;1148](https://github.com/dtolnay/syn/issues/1148))

### [`v1.0.88`](https://github.com/dtolnay/syn/releases/tag/1.0.88)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.87...1.0.88)

- Parse `..` pattern in pattern of `let`
([#&#8203;1136](https://github.com/dtolnay/syn/issues/1136))
- Parse `for<…>` lifetime introducer on closures
([#&#8203;1135](https://github.com/dtolnay/syn/issues/1135))
- Reject postfix operators after cast
([#&#8203;1117](https://github.com/dtolnay/syn/issues/1117))
- Implement extra-traits for `Nothing`
([#&#8203;1144](https://github.com/dtolnay/syn/issues/1144))

### [`v1.0.87`](https://github.com/dtolnay/syn/releases/tag/1.0.87)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.86...1.0.87)

- Parse trait bounds containing associated constant constraint
([#&#8203;1138](https://github.com/dtolnay/syn/issues/1138))
- Change syntax of where-clauses on generic associated types
([#&#8203;1071](https://github.com/dtolnay/syn/issues/1071),
[https://github.com/rust-lang/rust/issues/89122](https://github.com/rust-lang/rust/issues/89122))

### [`v1.0.86`](https://github.com/dtolnay/syn/releases/tag/1.0.86)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.85...1.0.86)

-   Add support for parsing if- and while-let-chains (RFC 2497)

### [`v1.0.85`](https://github.com/dtolnay/syn/releases/tag/1.0.85)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.84...1.0.85)

- Add `token()` method to each variant of syn::Lit to expose the
underlying token representation with original formatting

### [`v1.0.84`](https://github.com/dtolnay/syn/releases/tag/1.0.84)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.83...1.0.84)

- Add
[`parse_quote_spanned!`](https://docs.rs/syn/1.0.84/syn/macro.parse_quote_spanned.html)
macro which is a combination `parse_quote!` + `quote_spanned!`

### [`v1.0.83`](https://github.com/dtolnay/syn/releases/tag/1.0.83)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.82...1.0.83)

- Fix panic parsing trait impl with qself in trait type: `impl
<Thing<>>::Trait for Type {}`
([#&#8203;1109](https://github.com/dtolnay/syn/issues/1109))
- Preserve attributes on let-else stmt: `#[attr] let pat = val else {
return }` ([#&#8203;1110](https://github.com/dtolnay/syn/issues/1110))

### [`v1.0.82`](https://github.com/dtolnay/syn/releases/tag/1.0.82)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.81...1.0.82)

- Support parenthesized generic argument syntax with `::` disambiguator:
`Fn::() -> !`
([#&#8203;1096](https://github.com/dtolnay/syn/issues/1096))

### [`v1.0.81`](https://github.com/dtolnay/syn/releases/tag/1.0.81)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.80...1.0.81)

- Support arbitrary precision negative literal tokens on rustc 1.56+
([#&#8203;1087](https://github.com/dtolnay/syn/issues/1087),
[#&#8203;1088](https://github.com/dtolnay/syn/issues/1088))

### [`v1.0.80`](https://github.com/dtolnay/syn/releases/tag/1.0.80)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.79...1.0.80)

- Parse unstable `~const` syntax in where-clauses
([#&#8203;1083](https://github.com/dtolnay/syn/issues/1083), tracking
issue
[https://github.com/rust-lang/rust/issues/67792](https://github.com/rust-lang/rust/issues/67792))

### [`v1.0.79`](https://github.com/dtolnay/syn/releases/tag/1.0.79)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.78...1.0.79)

- Support trailing `+` in `dyn Trait` syntax, including bare (non-`dyn`)
pre-2018 trait object syntax
([#&#8203;1075](https://github.com/dtolnay/syn/issues/1075),
[#&#8203;1077](https://github.com/dtolnay/syn/issues/1077),
[#&#8203;1078](https://github.com/dtolnay/syn/issues/1078),
[#&#8203;1079](https://github.com/dtolnay/syn/issues/1079),
[#&#8203;1080](https://github.com/dtolnay/syn/issues/1080),
[#&#8203;1081](https://github.com/dtolnay/syn/issues/1081))

### [`v1.0.78`](https://github.com/dtolnay/syn/releases/tag/1.0.78)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.77...1.0.78)

- Parse trailing `+` in the bounds of `impl Trait` type
([#&#8203;1073](https://github.com/dtolnay/syn/issues/1073))

### [`v1.0.77`](https://github.com/dtolnay/syn/releases/tag/1.0.77)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.76...1.0.77)

- Match Rust 1.57+'s parsing of dot and question mark after a curly
braced macro invocation
([#&#8203;1068](https://github.com/dtolnay/syn/issues/1068))

### [`v1.0.76`](https://github.com/dtolnay/syn/releases/tag/1.0.76)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.75...1.0.76)

- Parse unstable `let`–`else` syntax
([#&#8203;1050](https://github.com/dtolnay/syn/issues/1050),
[#&#8203;1057](https://github.com/dtolnay/syn/issues/1057))
- Parse qualified braced variant expressions and patterns: `<E>::V {..}`
([#&#8203;1058](https://github.com/dtolnay/syn/issues/1058),
[#&#8203;1059](https://github.com/dtolnay/syn/issues/1059))
- Fix precedence of outer attributes in front of an assignment
expression in statement position
([#&#8203;1060](https://github.com/dtolnay/syn/issues/1060))

### [`v1.0.75`](https://github.com/dtolnay/syn/releases/tag/1.0.75)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.74...1.0.75)

-   Improve spans on a method without body inside an impl block
- Documentation improvements
([#&#8203;922](https://github.com/dtolnay/syn/issues/922), thanks
[@&#8203;Tamschi](https://github.com/Tamschi))

### [`v1.0.74`](https://github.com/dtolnay/syn/releases/tag/1.0.74)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.73...1.0.74)

- Reject `for<'a> dyn Trait<'a>` syntax; the correct representation is
`dyn for<'a> Trait<'a>`
([#&#8203;1042](https://github.com/dtolnay/syn/issues/1042))

### [`v1.0.73`](https://github.com/dtolnay/syn/releases/tag/1.0.73)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.72...1.0.73)

- Add From\<Ident>, From\<Index>, From\<usize> for Member
([#&#8203;1038](https://github.com/dtolnay/syn/issues/1038), thanks
[@&#8203;m-ou-se](https://github.com/m-ou-se))

### [`v1.0.72`](https://github.com/dtolnay/syn/releases/tag/1.0.72)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.71...1.0.72)

- Parse const generics which use value of a previous const generic
parameter as a default value
([#&#8203;1027](https://github.com/dtolnay/syn/issues/1027))

### [`v1.0.71`](https://github.com/dtolnay/syn/releases/tag/1.0.71)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.70...1.0.71)

- Fix panic deserializing an ItemImpl with a non-path in trait position
([#&#8203;1023](https://github.com/dtolnay/syn/issues/1023))
- Parse visibility on impl blocks
([#&#8203;1024](https://github.com/dtolnay/syn/issues/1024))
- Fix parsing a type parameter default on the first generic parameter of
an impl block
([#&#8203;1025](https://github.com/dtolnay/syn/issues/1025), thanks
[@&#8203;taiki-e](https://github.com/taiki-e))

### [`v1.0.70`](https://github.com/dtolnay/syn/releases/tag/1.0.70)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.69...1.0.70)

- Fix precedence of closure body vs ExprRange rhs: `|| .. .method()`
([#&#8203;1019](https://github.com/dtolnay/syn/issues/1019))
- Parse inner attributes inside of structs and enums
([#&#8203;1022](https://github.com/dtolnay/syn/issues/1022))

### [`v1.0.69`](https://github.com/dtolnay/syn/releases/tag/1.0.69)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.68...1.0.69)

- Improve Parse impls of ExprBox, ExprUnary, ExprLet, ExprClosure,
ExprReference, ExprBreak, ExprContinue, ExprReturn, ExprYield to respect
precedence for parsing a subexpression beginning with the respective
keyword/punctuation
([#&#8203;1007](https://github.com/dtolnay/syn/issues/1007),
[#&#8203;1008](https://github.com/dtolnay/syn/issues/1008),
[#&#8203;1009](https://github.com/dtolnay/syn/issues/1009),
[#&#8203;1010](https://github.com/dtolnay/syn/issues/1010),
[#&#8203;1011](https://github.com/dtolnay/syn/issues/1011),
[#&#8203;1012](https://github.com/dtolnay/syn/issues/1012),
[#&#8203;1013](https://github.com/dtolnay/syn/issues/1013),
[#&#8203;1014](https://github.com/dtolnay/syn/issues/1014),
[#&#8203;1015](https://github.com/dtolnay/syn/issues/1015))

### [`v1.0.68`](https://github.com/dtolnay/syn/releases/tag/1.0.68)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.67...1.0.68)

- Preserve span of `LexError` on conversion to `syn::Error`
([#&#8203;1006](https://github.com/dtolnay/syn/issues/1006))

### [`v1.0.67`](https://github.com/dtolnay/syn/releases/tag/1.0.67)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.66...1.0.67)

- Accept outer attributes in the Parse impl of ExprBlock
([#&#8203;1004](https://github.com/dtolnay/syn/issues/1004))

### [`v1.0.66`](https://github.com/dtolnay/syn/releases/tag/1.0.66)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.65...1.0.66)

- Parse equality constraints on generic associated types
([#&#8203;979](https://github.com/dtolnay/syn/issues/979))
- Parse default value exprs in const generic declarations
([#&#8203;980](https://github.com/dtolnay/syn/issues/980))
- Fix infinite loop parsing malformed type ascription expression in
non-`full` mode
([#&#8203;978](https://github.com/dtolnay/syn/issues/978))
- Improve Parse impls of ExprArray, ExprAsync, ExprBlock, ExprMacro,
ExprParen, ExprRepeat, ExprStruct, ExprTryBlock, ExprUnsafe to succeed
parsing even in the presence of trailing binary operators
([#&#8203;991](https://github.com/dtolnay/syn/issues/991),
[#&#8203;992](https://github.com/dtolnay/syn/issues/992),
[#&#8203;993](https://github.com/dtolnay/syn/issues/993),
[#&#8203;994](https://github.com/dtolnay/syn/issues/994),
[#&#8203;995](https://github.com/dtolnay/syn/issues/995),
[#&#8203;996](https://github.com/dtolnay/syn/issues/996),
[#&#8203;997](https://github.com/dtolnay/syn/issues/997),
[#&#8203;998](https://github.com/dtolnay/syn/issues/998),
[#&#8203;999](https://github.com/dtolnay/syn/issues/999))

### [`v1.0.65`](https://github.com/dtolnay/syn/releases/tag/1.0.65)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.64...1.0.65)

- Parse visibility on macro_rules
([#&#8203;981](https://github.com/dtolnay/syn/issues/981), tracking
issue
[rust-lang/rust#&#8203;78855](https://github.com/rust-lang/rust/issues/78855))
- Parse leading vert in or-patterns
([#&#8203;982](https://github.com/dtolnay/syn/issues/982), matching
the Rust grammar change in
[rust-lang/rust#&#8203;81869](https://github.com/rust-lang/rust/issues/81869))
- Parse static with omitted type
([#&#8203;983](https://github.com/dtolnay/syn/issues/983))
- Parse placeholder type in type parameter position
([#&#8203;984](https://github.com/dtolnay/syn/issues/984))

### [`v1.0.64`](https://github.com/dtolnay/syn/releases/tag/1.0.64)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.63...1.0.64)

- Avoid `clippy::expl_impl_clone_on_copy` pedantic lint in downstream
custom token types
([#&#8203;976](https://github.com/dtolnay/syn/issues/976))

### [`v1.0.63`](https://github.com/dtolnay/syn/releases/tag/1.0.63)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.62...1.0.63)

- Fix parsing associated types with empty trait bound list after colon
([#&#8203;974](https://github.com/dtolnay/syn/issues/974))

### [`v1.0.62`](https://github.com/dtolnay/syn/releases/tag/1.0.62)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.61...1.0.62)

- Republish to work around docs.rs bug
[https://github.com/rust-lang/docs.rs/issues/1300](https://github.com/rust-lang/docs.rs/issues/1300)

### [`v1.0.61`](https://github.com/dtolnay/syn/releases/tag/1.0.61)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.60...1.0.61)

- Improve assertion failures on invalid use of `Punctuated` API
([#&#8203;970](https://github.com/dtolnay/syn/issues/970), thanks
[@&#8203;osa1](https://github.com/osa1))
- Add `Lifetime::span` and `Lifetime::set_span` accessors
([#&#8203;971](https://github.com/dtolnay/syn/issues/971))

### [`v1.0.60`](https://github.com/dtolnay/syn/releases/tag/1.0.60)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.59...1.0.60)

- Provide an idiom for testing exhaustiveness of pattern matches on
`Expr`, `Type`, `Pat`, `Item`, `ForeignItem`, `TraitItem`, and
`ImplItem` ([#&#8203;694](https://github.com/dtolnay/syn/issues/694))

    ```rust
    match expr {
        Expr::Array(e) => {...}
        Expr::Assign(e) => {...}
        ...
        Expr::Yield(e) => {...}

        #[cfg(test)]
        Expr::__TestExhaustive(_) => unimplemented!(),
        #[cfg(not(test))]
        _ => { /* some sane fallback */ }
    }
    ```

The above is the only supported idiom for exhaustive matching of those
enum. Do not write anything differently as it is not supported.

The conditional compilation on match-arms lets us fail your tests but
not break your library when adding a variant. You will be notified by a
test failure when a variant is added, so that you can add code to handle
it, but your library will continue to compile and work for downstream
users in the interim.

### [`v1.0.59`](https://github.com/dtolnay/syn/releases/tag/1.0.59)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.58...1.0.59)

- Parse empty supertrait lists consistently with rustc
([#&#8203;952](https://github.com/dtolnay/syn/issues/952))
- Fix loss of span information on comma tokens inside of Type::Tuple
during parse
([#&#8203;959](https://github.com/dtolnay/syn/issues/959))

### [`v1.0.58`](https://github.com/dtolnay/syn/releases/tag/1.0.58)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.57...1.0.58)

- Allow literals to parse as a const generic path argument even without
"full" feature enabled
([#&#8203;951](https://github.com/dtolnay/syn/issues/951))

    ```rust
    pub struct Struct {
        array: Array<10>,  // used to require `features = "full"`
    }
    ```

### [`v1.0.57`](https://github.com/dtolnay/syn/releases/tag/1.0.57)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.56...1.0.57)

- Make Punctuated::new available as a `const fn`
([#&#8203;949](https://github.com/dtolnay/syn/issues/949))

### [`v1.0.56`](https://github.com/dtolnay/syn/releases/tag/1.0.56)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.55...1.0.56)

- Add
[`Error::into_compile_error`](https://docs.rs/syn/1.0.56/syn/struct.Error.html#method.into_compile_error)

### [`v1.0.55`](https://github.com/dtolnay/syn/releases/tag/1.0.55)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.54...1.0.55)

- Preserve None-delimited group around macro metavariable when parsing
`T<$ty>` ([#&#8203;944](https://github.com/dtolnay/syn/issues/944),
[#&#8203;945](https://github.com/dtolnay/syn/issues/945))

### [`v1.0.54`](https://github.com/dtolnay/syn/releases/tag/1.0.54)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.53...1.0.54)

- Fix parsing of `impl` items with macro metavariable in the trait path:
`impl $trait for Type {...}`
([#&#8203;942](https://github.com/dtolnay/syn/issues/942))

### [`v1.0.53`](https://github.com/dtolnay/syn/releases/tag/1.0.53)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.52...1.0.53)

- Parse `impl !Trait {...}` syntax
([#&#8203;936](https://github.com/dtolnay/syn/issues/936))

### [`v1.0.52`](https://github.com/dtolnay/syn/releases/tag/1.0.52)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.51...1.0.52)

- Parse `unsafe extern` block syntax
([#&#8203;918](https://github.com/dtolnay/syn/issues/918))
- Parse `unsafe mod` syntax
([#&#8203;919](https://github.com/dtolnay/syn/issues/919))
- Parse `const {...}` block syntax
([#&#8203;921](https://github.com/dtolnay/syn/issues/921))
- Parse destructuring assignment syntax
([#&#8203;933](https://github.com/dtolnay/syn/issues/933))

### [`v1.0.51`](https://github.com/dtolnay/syn/releases/tag/1.0.51)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.50...1.0.51)

- Allow parsing signatures in which const generic params appear in front
of lifetime params
([#&#8203;920](https://github.com/dtolnay/syn/issues/920))

### [`v1.0.50`](https://github.com/dtolnay/syn/releases/tag/1.0.50)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.48...1.0.50)

- Apply `doc(cfg(...))` on feature gated APIs for docs.rs-rendered
documentation
([#&#8203;925](https://github.com/dtolnay/syn/issues/925))

### [`v1.0.48`](https://github.com/dtolnay/syn/releases/tag/1.0.48)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.47...1.0.48)

-   Rebuild for https://astexplorer.net

### [`v1.0.47`](https://github.com/dtolnay/syn/releases/tag/1.0.47)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.46...1.0.47)

-   Documentation improvements

### [`v1.0.46`](https://github.com/dtolnay/syn/releases/tag/1.0.46)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.45...1.0.46)

- Fix parsing structured attributes that contain nested absolute paths,
such as `#[derive(::serde::Serialize)]`
([#&#8203;909](https://github.com/dtolnay/syn/issues/909))

### [`v1.0.45`](https://github.com/dtolnay/syn/releases/tag/1.0.45)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.44...1.0.45)

- Provide more detailed error messages when parsing specific literal
kind ([#&#8203;908](https://github.com/dtolnay/syn/issues/908))

### [`v1.0.44`](https://github.com/dtolnay/syn/releases/tag/1.0.44)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.43...1.0.44)

- Fix some parsing of patterns inside of None-delimited groups
([#&#8203;907](https://github.com/dtolnay/syn/issues/907))

### [`v1.0.43`](https://github.com/dtolnay/syn/releases/tag/1.0.43)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.42...1.0.43)

-   Add Parse impl for syn::Signature

### [`v1.0.42`](https://github.com/dtolnay/syn/releases/tag/1.0.42)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.41...1.0.42)

- Fix several bugs involving unusual suffixes on integer and floating
point literal tokens
([#&#8203;898](https://github.com/dtolnay/syn/issues/898),
[#&#8203;899](https://github.com/dtolnay/syn/issues/899),
[#&#8203;900](https://github.com/dtolnay/syn/issues/900))

### [`v1.0.41`](https://github.com/dtolnay/syn/releases/tag/1.0.41)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.40...1.0.41)

- Fix panic on printing an incomplete (having fewer path segments than
originally parsed with) qualified path (ExprPath, PatPath, TypePath
containing QSelf)
([#&#8203;891](https://github.com/dtolnay/syn/issues/891), thanks
[@&#8203;taiki-e](https://github.com/taiki-e))
- Fix panic triggered by syntactically invalid overflowing negative
float literal after `.` in a field access position, e.g. `let _ =
obj.-0.9E999999`
([#&#8203;895](https://github.com/dtolnay/syn/issues/895), thanks
[@&#8203;sameer](https://github.com/sameer))
- Enable using `parse_macro_input!` with a Parser function rather than
type having a Parse impl
([#&#8203;896](https://github.com/dtolnay/syn/issues/896), thanks
[@&#8203;sbrocket](https://github.com/sbrocket))

### [`v1.0.40`](https://github.com/dtolnay/syn/releases/tag/1.0.40)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.39...1.0.40)

- Fix panic on parsing float literals having both an exponent and a
suffix beginning with 'e' or 'E', such as `9e99e999`
([#&#8203;893](https://github.com/dtolnay/syn/issues/893))

### [`v1.0.39`](https://github.com/dtolnay/syn/releases/tag/1.0.39)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.38...1.0.39)

- Improve compile time by pre-expanding derives
([#&#8203;885](https://github.com/dtolnay/syn/issues/885))
- Parse const generic parameters in any order relative to type
parameters ([#&#8203;886](https://github.com/dtolnay/syn/issues/886))

### [`v1.0.38`](https://github.com/dtolnay/syn/releases/tag/1.0.38)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.37...1.0.38)

- Accept traits with parenthesized path arguments in impls
([#&#8203;880](https://github.com/dtolnay/syn/issues/880), thanks
[@&#8203;alecmocatta](https://github.com/alecmocatta))

### [`v1.0.37`](https://github.com/dtolnay/syn/releases/tag/1.0.37)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.36...1.0.37)

- Handle shebang in a way that matches rustc 1.46+
([#&#8203;876](https://github.com/dtolnay/syn/issues/876),
[https://github.com/rust-lang/rust/pull/71487](https://github.com/rust-lang/rust/pull/71487),
[https://github.com/rust-lang/rust/pull/73596](https://github.com/rust-lang/rust/pull/73596))

    ```rust
    #!//am/i/a/comment

    fn main() {} // ^ shebang
    ```

    ```rust
    #!//am/i/a/comment

    [allow(dead_code)] // ^ not a shebang
    fn main() {}
    ```

- Accept <code>tuple.0.  0</code> as a tuple indexing expression
([#&#8203;877](https://github.com/dtolnay/syn/issues/877))

### [`v1.0.36`](https://github.com/dtolnay/syn/releases/tag/1.0.36)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.35...1.0.36)

- Add Lit::span, Lit::set_span
([#&#8203;874](https://github.com/dtolnay/syn/issues/874))

### [`v1.0.35`](https://github.com/dtolnay/syn/releases/tag/1.0.35)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.34...1.0.35)

- Fix parsing of Expr::Field in non-full mode
([#&#8203;870](https://github.com/dtolnay/syn/issues/870))

### [`v1.0.34`](https://github.com/dtolnay/syn/releases/tag/1.0.34)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.33...1.0.34)

-   Documentation improvements

### [`v1.0.33`](https://github.com/dtolnay/syn/releases/tag/1.0.33)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.32...1.0.33)

- Parse `tuple.0.0` as an indexing expression
([https://github.com/rust-lang/rust/pull/71322](https://github.com/rust-lang/rust/pull/71322))
- Add `Parse` impls for optional of proc-macro2 types:
`Option<TokenTree>`, `Option<Punct>`, `Option<Literal>`, `Option<Group>`

### [`v1.0.32`](https://github.com/dtolnay/syn/releases/tag/1.0.32)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.31...1.0.32)

- Fix parsing $:item macro_rules metavariables containing outer
attributes ([#&#8203;852](https://github.com/dtolnay/syn/issues/852))

### [`v1.0.31`](https://github.com/dtolnay/syn/releases/tag/1.0.31)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.30...1.0.31)

- Add
[`Expr::parse_without_eager_brace`](https://docs.rs/syn/1.0.31/syn/enum.Expr.html#method.parse_without_eager_brace)
to parse expressions in ambiguous syntactic position.

Rust grammar has an ambiguity where braces sometimes turn a path
expression into a struct initialization and sometimes do not. In the
following code, the expression `S {}` is one expression. Presumably
there is an empty struct `struct S {}` defined somewhere which it is
instantiating.

    ```rust
    let _ = *S {};

    // parsed by rustc as: `*(S {})`
    ```

We would want to parse the above using `Expr::parse` after the `=`
token.

    But in the following, `S {}` is *not* a struct init expression.

    ```rust
    if *S {} {}

    // parsed by rustc as:
    //
    //    if (*S) {
    //        /* empty block */
    //    }
    //    {
    //        /* another empty block */
    //    }
    ```

For that reason we would want to parse if-conditions using
`Expr::parse_without_eager_brace` after the `if` token. Same for similar
syntactic positions such as the condition expr after a `while` token or
the expr at the top of a `match`.

The Rust grammar's choices around which way this ambiguity is resolved
at various syntactic positions is fairly arbitrary. Really either parse
behavior could work in most positions, and language designers just
decide each case based on which is more likely to be what the programmer
had in mind most of the time.

    ```rust
    if return S {} {}

    // parsed by rustc as:
    //
    //    if (return (S {})) {
    //    }
    //
    // but could equally well have been this other arbitrary choice:
    //
    //    if (return S) {
    //    }
    //    {}
    ```

Note the grammar ambiguity on trailing braces is distinct from
precedence and is not captured by assigning a precedence level to the
braced struct init expr in relation to other operators. This can be
illustrated by `return 0..S {}` vs `match 0..S {}`. The former parses as
`return (0..(S {}))` implying tighter precedence for struct init than
`..`, while the latter parses as `match (0..S) {}` implying tighter
precedence for `..` than struct init, a contradiction.

### [`v1.0.30`](https://github.com/dtolnay/syn/releases/tag/1.0.30)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.29...1.0.30)

- Parse struct init expressions where the type name is an interpolated
macro_rules metavariable, such as `$struct {}` where $struct:ident
([#&#8203;842](https://github.com/dtolnay/syn/issues/842))
- Handle nesting of None-delimited groups
([#&#8203;843](https://github.com/dtolnay/syn/issues/843), thanks
[@&#8203;Aaron1011](https://github.com/Aaron1011))

### [`v1.0.29`](https://github.com/dtolnay/syn/releases/tag/1.0.29)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.28...1.0.29)

- Parse macro call exprs where the macro name is an interpolated
macro_rules metavariable, such as `$macro!()`
([#&#8203;838](https://github.com/dtolnay/syn/issues/838))
- Parse paths containing generic parameters where the first path segment
is an interpolated macro_rules metavariable, such as `$seg<'a>`
([#&#8203;839](https://github.com/dtolnay/syn/issues/839))

### [`v1.0.28`](https://github.com/dtolnay/syn/releases/tag/1.0.28)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.27...1.0.28)

- Recognize empty None-delimited group produced by interpolating a $:vis
macro metavariable when parsing a Visibility
([#&#8203;836](https://github.com/dtolnay/syn/issues/836))

### [`v1.0.27`](https://github.com/dtolnay/syn/releases/tag/1.0.27)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.26...1.0.27)

- Parse function calls in which the callee is an interpolated macro
variable `$fn(...)`
([#&#8203;833](https://github.com/dtolnay/syn/issues/833))

### [`v1.0.26`](https://github.com/dtolnay/syn/releases/tag/1.0.26)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.25...1.0.26)

- Parse paths containing an interpolated first component, such as
`$first::rest`
([https://github.com/rust-lang/rust/issues/72608](https://github.com/rust-lang/rust/issues/72608),
[#&#8203;832](https://github.com/dtolnay/syn/issues/832))

### [`v1.0.25`](https://github.com/dtolnay/syn/releases/tag/1.0.25)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.24...1.0.25)

- Parse opt-out `?const` trait bounds
([#&#8203;767](https://github.com/dtolnay/syn/issues/767))
- Parse const generics in method generic arguments
([#&#8203;816](https://github.com/dtolnay/syn/issues/816), thanks
[@&#8203;yodaldevoid](https://github.com/yodaldevoid))
- Parse trait bounds on type alias items
([#&#8203;821](https://github.com/dtolnay/syn/issues/821))
- Parse const generics on impl blocks
([#&#8203;822](https://github.com/dtolnay/syn/issues/822))
- Fix precedence of attributes on binary expressions to match rustc
([#&#8203;823](https://github.com/dtolnay/syn/issues/823))
- Remove parsing of `extern::` paths which were removed from nightly in
January 2019
([#&#8203;825](https://github.com/dtolnay/syn/issues/825),
[https://github.com/rust-lang/rust/pull/57572](https://github.com/rust-lang/rust/pull/57572))
- Add `Punctuated::clear`, analogous to Vec::clear
([#&#8203;828](https://github.com/dtolnay/syn/issues/828))

### [`v1.0.24`](https://github.com/dtolnay/syn/releases/tag/1.0.24)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.23...1.0.24)

- Parse `mut self` receiver in function pointer type
([#&#8203;812](https://github.com/dtolnay/syn/issues/812),
[#&#8203;814](https://github.com/dtolnay/syn/issues/814))
- Parse const trait impls
([#&#8203;813](https://github.com/dtolnay/syn/issues/813))
- Improve error reporting inside struct expressions and struct patterns
([#&#8203;818](https://github.com/dtolnay/syn/issues/818))

### [`v1.0.23`](https://github.com/dtolnay/syn/releases/tag/1.0.23)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.22...1.0.23)

- Parse inner attributes in traits
([#&#8203;803](https://github.com/dtolnay/syn/issues/803))
- Parse const underscore in traits and impls
([#&#8203;804](https://github.com/dtolnay/syn/issues/804))
- Implement Extend<Error> for Error
([#&#8203;805](https://github.com/dtolnay/syn/issues/805))
- Parse Or patterns
([#&#8203;806](https://github.com/dtolnay/syn/issues/806))
- Parse outer attributes on Expr\* structs
([#&#8203;807](https://github.com/dtolnay/syn/issues/807))
- Parse top level const/static without value
([#&#8203;808](https://github.com/dtolnay/syn/issues/808))
- Parse syntactically accepted functions
([#&#8203;809](https://github.com/dtolnay/syn/issues/809))
- Parse extern static with value
([#&#8203;810](https://github.com/dtolnay/syn/issues/810))

Thanks [@&#8203;taiki-e](https://github.com/taiki-e) for all of these.

### [`v1.0.22`](https://github.com/dtolnay/syn/releases/tag/1.0.22)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.21...1.0.22)

- Parse literal suffix on byte string, byte, and char literal tokens:
`br#"..."#suffix`, `b'?'suffix`, `'?'suffix`
([#&#8203;799](https://github.com/dtolnay/syn/issues/799),
[#&#8203;800](https://github.com/dtolnay/syn/issues/800))

### [`v1.0.21`](https://github.com/dtolnay/syn/releases/tag/1.0.21)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.20...1.0.21)

-   Documentation improvements

### [`v1.0.20`](https://github.com/dtolnay/syn/releases/tag/1.0.20)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.19...1.0.20)

- Improve span of error message when an error during
`syn::Macro::parse_body` is triggered past the last token of the macro
body ([#&#8203;791](https://github.com/dtolnay/syn/issues/791))

### [`v1.0.19`](https://github.com/dtolnay/syn/releases/tag/1.0.19)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.18...1.0.19)

- Parse a more lenient extern type syntax inside extern blocks
([#&#8203;763](https://github.com/dtolnay/syn/issues/763))

### [`v1.0.18`](https://github.com/dtolnay/syn/releases/tag/1.0.18)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.17...1.0.18)

- Ignore unparsed empty None-delimited groups at the end of a macro
input ([#&#8203;783](https://github.com/dtolnay/syn/issues/783))

### [`v1.0.17`](https://github.com/dtolnay/syn/releases/tag/1.0.17)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.16...1.0.17)

-   Expose `syn::Lit` in `default-features = false` mode

### [`v1.0.16`](https://github.com/dtolnay/syn/releases/tag/1.0.16)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.15...1.0.16)

- Fix parsing of `&raw` raw reference operator
([https://github.com/rust-lang/rust/issues/64490](https://github.com/rust-lang/rust/issues/64490))
to require explicitly specified constness, `&raw mut` or `&raw const`

### [`v1.0.15`](https://github.com/dtolnay/syn/releases/tag/1.0.15)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.14...1.0.15)

- Add
[`Punctuated::first_mut`](https://docs.rs/syn/1.0.15/syn/punctuated/struct.Punctuated.html#method.first_mut)
to return a mut reference to the first sequence element

### [`v1.0.14`](https://github.com/dtolnay/syn/releases/tag/1.0.14)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.13...1.0.14)

- Produce more helpful error messages from
[Attribute::parse_args](https://docs.rs/syn/1.0/syn/struct.Attribute.html#method.parse_args)

### [`v1.0.13`](https://github.com/dtolnay/syn/releases/tag/1.0.13)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.12...1.0.13)

- Allow parse_quote! to parse Vec\<Stmt>, with the same behavior as
Block::parse_within
([#&#8203;741](https://github.com/dtolnay/syn/issues/741))

### [`v1.0.12`](https://github.com/dtolnay/syn/releases/tag/1.0.12)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.11...1.0.12)

- Reject function signatures with an incorrectly placed receiver
parameter, like `fn f(x: u8, &self)`
- Produce correctly spanned error when parsing punct beyond the end of a
delimited group
([#&#8203;739](https://github.com/dtolnay/syn/issues/739))

### [`v1.0.11`](https://github.com/dtolnay/syn/releases/tag/1.0.11)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.10...1.0.11)

- Implement quote::IdentFragment for syn::Member and syn::Index so that
spans are preserved when using these types in quote's `format_ident!`
macro

    ```rust
    use quote::format_ident;
    use syn::Index;

    let index: Index = /* ... */;
    let ident = format_ident!("__{}", index); // produces __0, __1, etc
    ```

### [`v1.0.10`](https://github.com/dtolnay/syn/releases/tag/1.0.10)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.9...1.0.10)

- Provide `Hash` and `Eq` impls for syn::Member even without
"extra-traits" feature enabled, as this type is commonly useful in a
hashset

### [`v1.0.9`](https://github.com/dtolnay/syn/releases/tag/1.0.9)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.8...1.0.9)

- Fix failure to parse tuple struct fields of tuple type starting with
`crate` ([#&#8203;720](https://github.com/dtolnay/syn/issues/720),
[#&#8203;723](https://github.com/dtolnay/syn/issues/723), thanks
[@&#8203;mystor](https://github.com/mystor))
- Fix unexpected tokens being ignored when using Speculative::advance_to
([#&#8203;721](https://github.com/dtolnay/syn/issues/721),
[#&#8203;723](https://github.com/dtolnay/syn/issues/723), thanks
[@&#8203;mystor](https://github.com/mystor))

### [`v1.0.8`](https://github.com/dtolnay/syn/releases/tag/1.0.8)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.7...1.0.8)

- Require trailing comma when parsing TypeTuple with one element
([#&#8203;716](https://github.com/dtolnay/syn/issues/716), thanks
[@&#8203;8BitMate](https://github.com/8BitMate))

### [`v1.0.7`](https://github.com/dtolnay/syn/releases/tag/1.0.7)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.6...1.0.7)

- Add a receiver getter to syn::Signature
([#&#8203;714](https://github.com/dtolnay/syn/issues/714), thanks
[@&#8203;mystor](https://github.com/mystor))

    ```rust
    impl Signature {
/// A method's `self` receiver, such as `&self` or `self: Box<Self>`.
        pub fn receiver(&self) -> Option<&FnArg>;
    }
    ```

### [`v1.0.6`](https://github.com/dtolnay/syn/releases/tag/1.0.6)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.5...1.0.6)

- Add conversions from Item{Struct,Enum,Union} into DeriveInput
([#&#8203;711](https://github.com/dtolnay/syn/issues/711), thanks
[@&#8203;mystor](https://github.com/mystor))
- Add Fields::len and Fields::is_empty
([#&#8203;712](https://github.com/dtolnay/syn/issues/712), thanks
[@&#8203;mjbshaw](https://github.com/mjbshaw))

### [`v1.0.5`](https://github.com/dtolnay/syn/releases/tag/1.0.5)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.4...1.0.5)

- Expose syn::Variadic with just "derive" feature, not "full", because
it appears in Type::BareFn

### [`v1.0.4`](https://github.com/dtolnay/syn/releases/tag/1.0.4)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.3...1.0.4)

- Fix size_hint of Punctuated iterators
([#&#8203;700](https://github.com/dtolnay/syn/issues/700), thanks
[@&#8203;ExpHP](https://github.com/ExpHP))

### [`v1.0.3`](https://github.com/dtolnay/syn/releases/tag/1.0.3)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.2...1.0.3)

- Add
[`Path::get_ident`](https://docs.rs/syn/1.0/syn/struct.Path.html#method.get_ident)
([#&#8203;696](https://github.com/dtolnay/syn/issues/696), thanks
[@&#8203;infinity0](https://github.com/infinity0))

### [`v1.0.2`](https://github.com/dtolnay/syn/releases/tag/1.0.2)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.1...1.0.2)

-   Documentation improvements

### [`v1.0.1`](https://github.com/dtolnay/syn/releases/tag/1.0.1)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.0...1.0.1)

- Add
[`LitInt::base10_parse`](https://docs.rs/syn/1.0/syn/struct.LitInt.html#method.base10\_parse)
to produce error that has the right span when parsing literal digits

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/agbrs/agb).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4xMC4yIiwidXBkYXRlZEluVmVyIjoiMzUuMTcuMSJ9-->
yoav-lavi pushed a commit to grafbase/grafbase that referenced this issue Sep 5, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [syn](https://github.com/dtolnay/syn) | dependencies | major | `1`
-> `2` |

---

### Release Notes

<details>
<summary>dtolnay/syn (syn)</summary>

### [`v2.0.27`](https://github.com/dtolnay/syn/releases/tag/2.0.27)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.26...2.0.27)

- Documentation improvements (thanks
[@&#8203;GuillaumeGomez](https://github.com/GuillaumeGomez))

### [`v2.0.26`](https://github.com/dtolnay/syn/releases/tag/2.0.26)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.25...2.0.26)

- Implement `Spanned` for `QSelf`
([#&#8203;1465](https://github.com/dtolnay/syn/issues/1465))

### [`v2.0.25`](https://github.com/dtolnay/syn/releases/tag/2.0.25)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.24...2.0.25)

- Support single identifier as unbraced const generic argument
([#&#8203;1483](https://github.com/dtolnay/syn/issues/1483))
- Produce error message when LitStr::parse is used on a suffixed string
literal ([#&#8203;1484](https://github.com/dtolnay/syn/issues/1484))

### [`v2.0.24`](https://github.com/dtolnay/syn/releases/tag/2.0.24)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.23...2.0.24)

- Fix duplication of braces around const generic argument in non-full
mode ([#&#8203;1482](https://github.com/dtolnay/syn/issues/1482))

### [`v2.0.23`](https://github.com/dtolnay/syn/releases/tag/2.0.23)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.22...2.0.23)

- Preserve attributes on verbatim Item in statement position
([#&#8203;1476](https://github.com/dtolnay/syn/issues/1476))
- Support generic_const_exprs where-clauses such as `where [(); {
T::COUNT }]:` in non-"full" mode
([#&#8203;1478](https://github.com/dtolnay/syn/issues/1478))

### [`v2.0.22`](https://github.com/dtolnay/syn/releases/tag/2.0.22)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.21...2.0.22)

- Parse `c"…"` c-string literals (tracking issue:
[https://github.com/rust-lang/rust/issues/105723](https://github.com/rust-lang/rust/issues/105723))

### [`v2.0.21`](https://github.com/dtolnay/syn/releases/tag/2.0.21)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.20...2.0.21)

- Fix value computed by `LitByteStr::value` in the case of a cooked byte
string literal containing form feed or vertical tab characters following
an escaped newline
([#&#8203;1474](https://github.com/dtolnay/syn/issues/1474))

### [`v2.0.20`](https://github.com/dtolnay/syn/releases/tag/2.0.20)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.19...2.0.20)

-   Documentation improvements

### [`v2.0.19`](https://github.com/dtolnay/syn/releases/tag/2.0.19)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.18...2.0.19)

- Improve rendering of compile errors within 2015-edition code calling a
2018+ edition proc macro
([#&#8203;1467](https://github.com/dtolnay/syn/issues/1467), thanks
[@&#8203;danielhenrymantilla](https://github.com/danielhenrymantilla))

### [`v2.0.18`](https://github.com/dtolnay/syn/releases/tag/2.0.18)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.17...2.0.18)

- Permit empty attr in syn::meta::parser
([#&#8203;1460](https://github.com/dtolnay/syn/issues/1460))

### [`v2.0.17`](https://github.com/dtolnay/syn/releases/tag/2.0.17)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.16...2.0.17)

- Enable proc_macro support on wasm targets
([#&#8203;1459](https://github.com/dtolnay/syn/issues/1459))

### [`v2.0.16`](https://github.com/dtolnay/syn/releases/tag/2.0.16)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.15...2.0.16)

- Parse `builtin #` syntax as Expr::Verbatim
([https://github.com/rust-lang/rust/issues/110680](https://github.com/rust-lang/rust/issues/110680),
[#&#8203;1454](https://github.com/dtolnay/syn/issues/1454))

### [`v2.0.15`](https://github.com/dtolnay/syn/releases/tag/2.0.15)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.14...2.0.15)

- Ensure `Type::Tuple` of length 1 prints as a tuple even if trailing
comma is not provided in the Punctuated
([#&#8203;1444](https://github.com/dtolnay/syn/issues/1444), thanks
[@&#8203;Fancyflame](https://github.com/Fancyflame))

### [`v2.0.14`](https://github.com/dtolnay/syn/releases/tag/2.0.14)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.13...2.0.14)

- Add Punctuated::pop_punct()
([#&#8203;1442](https://github.com/dtolnay/syn/issues/1442), thanks
[@&#8203;programmerjake](https://github.com/programmerjake))

### [`v2.0.13`](https://github.com/dtolnay/syn/releases/tag/2.0.13)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.12...2.0.13)

- Improve spans of Expr::Field parsed from a float Literal
([#&#8203;1433](https://github.com/dtolnay/syn/issues/1433),
[#&#8203;1436](https://github.com/dtolnay/syn/issues/1436))

### [`v2.0.12`](https://github.com/dtolnay/syn/releases/tag/2.0.12)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.11...2.0.12)

- Refer to `compile_error!` by absolute path in token stream produced by
syn::Error::to_compile_error
([#&#8203;1431](https://github.com/dtolnay/syn/issues/1431), thanks
[@&#8203;smoelius](https://github.com/smoelius))

### [`v2.0.11`](https://github.com/dtolnay/syn/releases/tag/2.0.11)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.10...2.0.11)

- Improve error message on empty parens inside parse_nested_meta
([#&#8203;1428](https://github.com/dtolnay/syn/issues/1428))

### [`v2.0.10`](https://github.com/dtolnay/syn/releases/tag/2.0.10)

[Compare
Source](https://github.com/dtolnay/syn/compare/2.0.9...2.0.10)

- Fix visibility being parsed incorrectly on macro invocations inside of
a trait

### [`v2.0.9`](https://github.com/dtolnay/syn/releases/tag/2.0.9)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.8...2.0.9)

- Disallow `type` items in an extern block, trait, or module from being
marked `default`

### [`v2.0.8`](https://github.com/dtolnay/syn/releases/tag/2.0.8)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.7...2.0.8)

- Treat `try` keyword as 2015-edition identifier in definition of try
macro ([#&#8203;1422](https://github.com/dtolnay/syn/issues/1422))

### [`v2.0.7`](https://github.com/dtolnay/syn/releases/tag/2.0.7)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.6...2.0.7)

-   Fix parsing of `mut self` inside of Type::BareFn

### [`v2.0.6`](https://github.com/dtolnay/syn/releases/tag/2.0.6)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.5...2.0.6)

- Improve error message on missing ';' between statements
([#&#8203;1419](https://github.com/dtolnay/syn/issues/1419))
- Keep non-brace macro invocations in trailing expr position as
Expr::Macro
([#&#8203;1420](https://github.com/dtolnay/syn/issues/1420))

### [`v2.0.5`](https://github.com/dtolnay/syn/releases/tag/2.0.5)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.4...2.0.5)

- Expose `ExprMacro` data structure even when `features="full"` is not
used ([#&#8203;1417](https://github.com/dtolnay/syn/issues/1417))

### [`v2.0.4`](https://github.com/dtolnay/syn/releases/tag/2.0.4)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.3...2.0.4)

- Improve error reporting when parsing identifiers and paths
([#&#8203;1415](https://github.com/dtolnay/syn/issues/1415),
[#&#8203;1416](https://github.com/dtolnay/syn/issues/1416))

### [`v2.0.3`](https://github.com/dtolnay/syn/releases/tag/2.0.3)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.2...2.0.3)

- Expose `ExprGroup` data structure even when `features="full"` is not
used ([#&#8203;1412](https://github.com/dtolnay/syn/issues/1412))

### [`v2.0.2`](https://github.com/dtolnay/syn/releases/tag/2.0.2)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.1...2.0.2)

-   Documentation improvements

### [`v2.0.1`](https://github.com/dtolnay/syn/releases/tag/2.0.1)

[Compare Source](https://github.com/dtolnay/syn/compare/2.0.0...2.0.1)

- Add methods on syn::Meta for reporting error on an incorrect kind of
attribute ([#&#8203;1409](https://github.com/dtolnay/syn/issues/1409))

### [`v2.0.0`](https://github.com/dtolnay/syn/releases/tag/2.0.0)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.109...2.0.0)

This release contains a batch of syntax tree improvements to incorporate
ongoing Rust language development from the past 3.5 years since syn 1.

It never seems like an ideal time to finalize a syntax tree design,
considering the frankly alarming number of syntax-disrupting language
features currently in flight: keyword generics, restrictions,
capabilities and contexts, conditional constness, new varieties of
literals, dyn revamp such as explicitly dyn-safe traits and dyn-star,
expression syntax in various phases of being added or being torn out
(const blocks, try blocks, raw references), auto traits and negative
impls, generalizations to higher rank trait bounds, async closures and
static async trait methods, postfix keywords, pattern types, return type
notation, unsafe attributes, …

The plan continues to be the same as laid out originally in the 1.0.0
release announcement:

> Be aware that the underlying Rust language will continue to evolve.
Syn is able to accommodate most kinds of Rust grammar changes via the
nonexhaustive enums and `Verbatim` variants in the syntax tree, but we
will plan to put out new major versions on a 12 to 24 month cadence to
incorporate ongoing language changes as needed.

If anything, the takeaway from the 3.5 year longevity of syn 1 is that
this period was tamer from a language development perspective than
anticipated, but that is unlikely to last and I think around 24 months
is still the correct cadence to expect between releases going forward.

<br>

<p align="center"><a href="https://docs.rs/syn/2/syn/">[API
documentation for 2.0]</a></p>

### Breaking changes

-   Minimum required Rust version is raised from rustc 1.31 to 1.56.

##### Expressions

- Support for `box expr` syntax has been deleted, as it has been deleted
recently from rustc.

- Support for type ascription syntax `expr: Type` in expression position
has been deleted.

- Support for unstable `&raw const expr` raw-pointer reference syntax
has been deleted.

- The representation of generic arguments has been unified between
method calls and non-method paths into a single `GenericArgument` type,
which supersedes the previous `GenericMethodArgument` and
`MethodTurbofish`.

- Generic arguments now distinguish between associated types
(`AssocType`) and associated constant values (`AssocConst`). Previously
these would be parsed ambiguously as `Binding`.

- The binary assignment operators in `BinOp` have been renamed to align
with the naming used by the standard library's `core::ops` module's
traits. For example `BinOp::AddEq` is now called `BinOp::AddAssign`.

- `Expr::Struct` struct construction expressions now support structs
which are a variant of an enum associated type of a trait, as in `<Type
as Trait>::Assoc::Variant { ... }`, which has recently been added to
Rust.

- `Expr::Range` now follows the `start` and `end` naming used by the
standard library's `RangeBounds` trait, rather than `from`/`to` or
`lo`/`hi`.

- `Expr::AssignOp` has been merged into `Expr::Binary`, which now
represents both non-assignment and assignment binary operators.

- Stricter parsing of ranges. None of the following are valid
expressions, but were previously accepted by syn: `..=`, `lo..=`, `...`,
`...hi`, `lo...`, `lo...hi`.

- `Expr::Closure` now includes a representation for `for<...>`
lifetimes.

##### Statements

- Variants `Stmt::Expr` (tail-position expression without trailing
semicolon) and `Stmt::Semi` (non-tail expression with trailing
semicolon) have been combined into `Stmt::Expr` with the optional
semicolon represented by `Option<Token![;]>`.

- The syntax tree for `Stmt::Local` has been extended to handle
`let`/`else` syntax.

- Macros in statement position are now uniformly parsed as
`Stmt::Macro`. Previously these would be disambiguated to `Stmt::Item`,
although it was ambiguous whether a macro in statement position would
expand to an item (like `thread_local! { ... }`) vs an expression (like
`println! { ... }`).

##### Patterns

- Pattern parsing for all the different syntactic positions in which
patterns are allowed has been split into `Pat::parse_single` (for
function- and closure-argument position, where top-level `|` is not
allowed), `Pat::parse_multi` (where `|` is allowed) and
`Pat::parse_multi_with_leading_vert` (for the pattern of match arms,
which allow an optional leading `|`). Previously only a single `parse`
behavior was supported and behaved like the new `parse_single`.

- The `Pat` syntax tree now shares more common data structures with the
`Expr` syntax tree where possible, such as for literals, paths, macros,
and ranges in pattern position.

- Parsing of struct field patterns does a better job rejecting bogus
syntax such as `Struct { 0 asdf }` and `Struct { ref mut 0: asdf }`,
which were previously incorrectly accepted.

- `Pat::Range` now supports one-sided ranges by representing the start
and end bound of the range by `Option<Expr>`.

- `Pat::Struct` keeps track of attributes on the optional `..` "rest"
part of the pattern, as in `let Struct { x, #[cfg(any())] .. } = _;`.

- Parsing unary negation now enforces that only literal patterns can be
unarily negated. For example `-self::CONST` and `-const { 0i32 }` are
not valid syntax in pattern position.

- `Pat::TupleStruct` no longer wraps a value of type `PatTuple` but
represents that information in its fields directly.

- A single parenthesized pattern without trailing comma inside the
parentheses is no longer considered a `Pat::Tuple`, it will be parsed as
`Pat::Paren`.

- One-sided range patterns are no longer allowed inside of slice
patterns. `[lo..]` and `[..=hi]` are not considered valid pattern syntax
by Rust.

##### Items

- Typed `self` in a method signature, such as `self: Pin<&mut Self>`,
will now be parsed as `FnArg::Receiver`. This means `self`, whether with
or without an explicit type, is always treated as a `Receiver`.
Previously only the `&self` and `&mut self` shorthand receivers were
parsed as `Receiver`.

- `TraitItem::Method` and `ImplItem::Method` have been renamed to
`TraitItem::Fn` and `ImplItem::Fn`, as they do not necessarily represent
methods if the function signature contains no `self`.

- `Item::Macro2` has been deleted as "macros 2.0" syntax is no longer
considered on track for stabilization.

- Various item kinds now hold `Generics` which didn't used to have them.

- The variadic argument of an extern function signature can now be given
an optional parameter name.

-   `WherePredicate::Eq` is no longer supported.

- `Visibility::Crate` is no longer supported. This syntax has been
removed from rustc.

- Public visibility is now represented by a single `Token![pub]` token
rather than the old `VisPublic` struct.

- `LifetimeDef` is now called `LifetimeParam`. This name makes more
sense in the context of the `GenericParam` enum (which also includes
`TypeParam` and `ConstParam`), and is the name that the Rust Reference
uses.

- Modules and extern blocks (`Item::Mod` and `Item::ForeignMod`) can now
be marked `unsafe`.

##### Attributes

- The syntax tree for `Attribute` has been redesigned. The new API
better accommodates attributes which mix structured and unstructured
content at different levels of nesting.

-   `AttributeArgs` has been removed. Use `Punctuated<Meta, Token![,]>`.

- For parsing attribute contents, `parse_meta()` is superseded by a new
parsing library called `syn::meta`, and the `parse_nested_meta` method
on `Attribute`.

##### Tokens

- In string literals, the handling of non-ASCII whitespace after
trailing `\` now matches what is implemented by rustc. Space, horizontal
tab, line feed, and carriage return are the only 4 whitespace characters
which are supposed to be stripped from the beginning of the next line.

- The delimiter tokens `syn::token::Paren`, `Bracket`, and `Brace` now
store 2 spans (the open and close punctuation separately) rather than
just 1. Use `.join()` to obtain a single `Span` spanning the whole
group.

- Keyword construction now requires a single span; an array of 1 span is
no longer accepted. Use `Token![trait](span)` instead of
`Token![trait]([span])`.

- Some token types have been renamed to conform with terminology used by
the [Rust
Reference](https://doc.rust-lang.org/1.68.0/reference/tokens.html#punctuation).
These are `Add`->`Plus`, `Bang`->`Not`, `Colon2`->`PathSep`,
`Div`->`Slash`, `Dot2`->`DotDot`, `Dot3`->`DotDotDot`, `Rem`->`Percent`,
and `Sub`->`Minus`.

##### More

- Several enums have been made `#[non_exhaustive]` in anticipation of
upcoming language changes. This includes `WherePredicate`, `Lit`, and
`GenericArgument`.

- The `impl Extend<Pair<T, P>> for Punctuated<T, P>` now requires `P:
Default` and will push a default punctuation between the pre-existing
elements and the new ones, if there is not already a trailing
punctuation. Previously it would panic in this situation.

- `ParseStream::parse_terminated` now takes a peek-style punctuation
argument instead of turbofish. Replace `input.parse_terminated::<_,
Token![,]>(Thing::parse)` with `input.parse_terminated(Thing::parse,
Token![,])`.

###
[`v1.0.109`](https://github.com/dtolnay/syn/compare/1.0.108...1.0.109)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.108...1.0.109)

### [`v1.0.108`](https://github.com/dtolnay/syn/releases/tag/1.0.108)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.107...1.0.108)

- Fix handling of unusual whitespace after escaped newlines in
`LitStr::value`
([#&#8203;1381](https://github.com/dtolnay/syn/issues/1381), thanks
[@&#8203;ModProg](https://github.com/ModProg))

### [`v1.0.107`](https://github.com/dtolnay/syn/releases/tag/1.0.107)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.106...1.0.107)

-   Opt out of `-Zrustdoc-scrape-examples` on docs.rs for now

### [`v1.0.106`](https://github.com/dtolnay/syn/releases/tag/1.0.106)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.105...1.0.106)

-   Documentation improvements

### [`v1.0.105`](https://github.com/dtolnay/syn/releases/tag/1.0.105)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.104...1.0.105)

- Improve parse errors related to `dyn` and `impl` type syntax
([#&#8203;1245](https://github.com/dtolnay/syn/issues/1245))

### [`v1.0.104`](https://github.com/dtolnay/syn/releases/tag/1.0.104)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.103...1.0.104)

-   Add `PathArguments::is_none()`

### [`v1.0.103`](https://github.com/dtolnay/syn/releases/tag/1.0.103)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.102...1.0.103)

- Implement `PartialOrd` for `Cursor`
([#&#8203;1236](https://github.com/dtolnay/syn/issues/1236),
[#&#8203;1237](https://github.com/dtolnay/syn/issues/1237), thanks
[@&#8203;CAD97](https://github.com/CAD97))

### [`v1.0.102`](https://github.com/dtolnay/syn/releases/tag/1.0.102)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.101...1.0.102)

- More efficient internal representation for `TokenBuffer`
([#&#8203;1223](https://github.com/dtolnay/syn/issues/1223), thanks
[@&#8203;CAD97](https://github.com/CAD97))
- Fix parsing of a left shift after macro metavariable in type position
([#&#8203;1229](https://github.com/dtolnay/syn/issues/1229))

### [`v1.0.101`](https://github.com/dtolnay/syn/releases/tag/1.0.101)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.100...1.0.101)

- Eliminate a bunch of redundant work done by LitStr::parse
([#&#8203;1221](https://github.com/dtolnay/syn/issues/1221))

### [`v1.0.100`](https://github.com/dtolnay/syn/releases/tag/1.0.100)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.99...1.0.100)

- Parse closures with explicit empty lifetime parameter list `for<> ||
-> T {…}` ([#&#8203;1212](https://github.com/dtolnay/syn/issues/1212),
[https://github.com/rust-lang/rust/issues/97362](https://github.com/rust-lang/rust/issues/97362))
- Parse `dyn*` provisional syntax
([#&#8203;1213](https://github.com/dtolnay/syn/issues/1213),
[https://github.com/rust-lang/rust/issues/91611](https://github.com/rust-lang/rust/issues/91611))
- Parse attributes on the "rest" pattern of a struct in pattern
position, `Struct { #[attr] .. }`
([#&#8203;1214](https://github.com/dtolnay/syn/issues/1214))
- Parse `static async` and `static async move` closures
([#&#8203;1215](https://github.com/dtolnay/syn/issues/1215),
[https://github.com/rust-lang/rust/issues/62290](https://github.com/rust-lang/rust/issues/62290))

### [`v1.0.99`](https://github.com/dtolnay/syn/releases/tag/1.0.99)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.98...1.0.99)

-   Add categories and keywords to crates.io metadata

### [`v1.0.98`](https://github.com/dtolnay/syn/releases/tag/1.0.98)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.97...1.0.98)

-   Format example code with rustfmt

### [`v1.0.97`](https://github.com/dtolnay/syn/releases/tag/1.0.97)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.96...1.0.97)

-   Update examples

### [`v1.0.96`](https://github.com/dtolnay/syn/releases/tag/1.0.96)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.95...1.0.96)

- Add a `punct_mut()` method on `syn::punctuated::Pair` to return
`Option<&mut P>`
([#&#8203;1183](https://github.com/dtolnay/syn/issues/1183))

### [`v1.0.95`](https://github.com/dtolnay/syn/releases/tag/1.0.95)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.94...1.0.95)

- Replace unicode-xid with unicode-ident crate:
https://github.com/dtolnay/unicode-ident

### [`v1.0.94`](https://github.com/dtolnay/syn/releases/tag/1.0.94)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.93...1.0.94)

-   Resolve some unused_macro_rules warnings

### [`v1.0.93`](https://github.com/dtolnay/syn/releases/tag/1.0.93)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.92...1.0.93)

- Fix compile error when `Some` means something unusual in the
expression namespace of the scope where `custom_keyword` is invoked
([#&#8203;1171](https://github.com/dtolnay/syn/issues/1171), thanks
[@&#8203;zakarumych](https://github.com/zakarumych))

### [`v1.0.92`](https://github.com/dtolnay/syn/releases/tag/1.0.92)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.91...1.0.92)

- Make compatible with Miri's tag-raw-pointers mode
([#&#8203;1166](https://github.com/dtolnay/syn/issues/1166), thanks
[@&#8203;saethlin](https://github.com/saethlin))

### [`v1.0.91`](https://github.com/dtolnay/syn/releases/tag/1.0.91)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.90...1.0.91)

-   impl ToTokens for RangeLimits
-   impl Parse for ExprAwait
-   impl Parse for GenericMethodArgument
-   impl Parse for MethodTurbofish

### [`v1.0.90`](https://github.com/dtolnay/syn/releases/tag/1.0.90)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.89...1.0.90)

- Update recommended exhaustive matching idiom to use
`non_exhaustive_omitted_patterns` lint:

    ```rust
    match expr {
        Expr::Array(e) => {…}
        Expr::Assign(e) => {…}
        ...
        Expr::Yield(e) => {…}

        #[cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
        _ => {/* some sane fallback */}
    }
    ```

### [`v1.0.89`](https://github.com/dtolnay/syn/releases/tag/1.0.89)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.88...1.0.89)

- Remove support for inner attributes on non-block expressions
([#&#8203;1146](https://github.com/dtolnay/syn/issues/1146),
[https://github.com/rust-lang/rust/pull/83312](https://github.com/rust-lang/rust/pull/83312))
- Fix panic on comma after `mut self` in a bare fn type
([#&#8203;1148](https://github.com/dtolnay/syn/issues/1148))

### [`v1.0.88`](https://github.com/dtolnay/syn/releases/tag/1.0.88)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.87...1.0.88)

- Parse `..` pattern in pattern of `let`
([#&#8203;1136](https://github.com/dtolnay/syn/issues/1136))
- Parse `for<…>` lifetime introducer on closures
([#&#8203;1135](https://github.com/dtolnay/syn/issues/1135))
- Reject postfix operators after cast
([#&#8203;1117](https://github.com/dtolnay/syn/issues/1117))
- Implement extra-traits for `Nothing`
([#&#8203;1144](https://github.com/dtolnay/syn/issues/1144))

### [`v1.0.87`](https://github.com/dtolnay/syn/releases/tag/1.0.87)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.86...1.0.87)

- Parse trait bounds containing associated constant constraint
([#&#8203;1138](https://github.com/dtolnay/syn/issues/1138))
- Change syntax of where-clauses on generic associated types
([#&#8203;1071](https://github.com/dtolnay/syn/issues/1071),
[https://github.com/rust-lang/rust/issues/89122](https://github.com/rust-lang/rust/issues/89122))

### [`v1.0.86`](https://github.com/dtolnay/syn/releases/tag/1.0.86)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.85...1.0.86)

-   Add support for parsing if- and while-let-chains (RFC 2497)

### [`v1.0.85`](https://github.com/dtolnay/syn/releases/tag/1.0.85)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.84...1.0.85)

- Add `token()` method to each variant of syn::Lit to expose the
underlying token representation with original formatting

### [`v1.0.84`](https://github.com/dtolnay/syn/releases/tag/1.0.84)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.83...1.0.84)

- Add
[`parse_quote_spanned!`](https://docs.rs/syn/1.0.84/syn/macro.parse_quote_spanned.html)
macro which is a combination `parse_quote!` + `quote_spanned!`

### [`v1.0.83`](https://github.com/dtolnay/syn/releases/tag/1.0.83)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.82...1.0.83)

- Fix panic parsing trait impl with qself in trait type: `impl
<Thing<>>::Trait for Type {}`
([#&#8203;1109](https://github.com/dtolnay/syn/issues/1109))
- Preserve attributes on let-else stmt: `#[attr] let pat = val else {
return }` ([#&#8203;1110](https://github.com/dtolnay/syn/issues/1110))

### [`v1.0.82`](https://github.com/dtolnay/syn/releases/tag/1.0.82)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.81...1.0.82)

- Support parenthesized generic argument syntax with `::` disambiguator:
`Fn::() -> !`
([#&#8203;1096](https://github.com/dtolnay/syn/issues/1096))

### [`v1.0.81`](https://github.com/dtolnay/syn/releases/tag/1.0.81)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.80...1.0.81)

- Support arbitrary precision negative literal tokens on rustc 1.56+
([#&#8203;1087](https://github.com/dtolnay/syn/issues/1087),
[#&#8203;1088](https://github.com/dtolnay/syn/issues/1088))

### [`v1.0.80`](https://github.com/dtolnay/syn/releases/tag/1.0.80)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.79...1.0.80)

- Parse unstable `~const` syntax in where-clauses
([#&#8203;1083](https://github.com/dtolnay/syn/issues/1083), tracking
issue
[https://github.com/rust-lang/rust/issues/67792](https://github.com/rust-lang/rust/issues/67792))

### [`v1.0.79`](https://github.com/dtolnay/syn/releases/tag/1.0.79)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.78...1.0.79)

- Support trailing `+` in `dyn Trait` syntax, including bare (non-`dyn`)
pre-2018 trait object syntax
([#&#8203;1075](https://github.com/dtolnay/syn/issues/1075),
[#&#8203;1077](https://github.com/dtolnay/syn/issues/1077),
[#&#8203;1078](https://github.com/dtolnay/syn/issues/1078),
[#&#8203;1079](https://github.com/dtolnay/syn/issues/1079),
[#&#8203;1080](https://github.com/dtolnay/syn/issues/1080),
[#&#8203;1081](https://github.com/dtolnay/syn/issues/1081))

### [`v1.0.78`](https://github.com/dtolnay/syn/releases/tag/1.0.78)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.77...1.0.78)

- Parse trailing `+` in the bounds of `impl Trait` type
([#&#8203;1073](https://github.com/dtolnay/syn/issues/1073))

### [`v1.0.77`](https://github.com/dtolnay/syn/releases/tag/1.0.77)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.76...1.0.77)

- Match Rust 1.57+'s parsing of dot and question mark after a curly
braced macro invocation
([#&#8203;1068](https://github.com/dtolnay/syn/issues/1068))

### [`v1.0.76`](https://github.com/dtolnay/syn/releases/tag/1.0.76)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.75...1.0.76)

- Parse unstable `let`–`else` syntax
([#&#8203;1050](https://github.com/dtolnay/syn/issues/1050),
[#&#8203;1057](https://github.com/dtolnay/syn/issues/1057))
- Parse qualified braced variant expressions and patterns: `<E>::V {..}`
([#&#8203;1058](https://github.com/dtolnay/syn/issues/1058),
[#&#8203;1059](https://github.com/dtolnay/syn/issues/1059))
- Fix precedence of outer attributes in front of an assignment
expression in statement position
([#&#8203;1060](https://github.com/dtolnay/syn/issues/1060))

### [`v1.0.75`](https://github.com/dtolnay/syn/releases/tag/1.0.75)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.74...1.0.75)

-   Improve spans on a method without body inside an impl block
- Documentation improvements
([#&#8203;922](https://github.com/dtolnay/syn/issues/922), thanks
[@&#8203;Tamschi](https://github.com/Tamschi))

### [`v1.0.74`](https://github.com/dtolnay/syn/releases/tag/1.0.74)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.73...1.0.74)

- Reject `for<'a> dyn Trait<'a>` syntax; the correct representation is
`dyn for<'a> Trait<'a>`
([#&#8203;1042](https://github.com/dtolnay/syn/issues/1042))

### [`v1.0.73`](https://github.com/dtolnay/syn/releases/tag/1.0.73)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.72...1.0.73)

- Add From\<Ident>, From\<Index>, From\<usize> for Member
([#&#8203;1038](https://github.com/dtolnay/syn/issues/1038), thanks
[@&#8203;m-ou-se](https://github.com/m-ou-se))

### [`v1.0.72`](https://github.com/dtolnay/syn/releases/tag/1.0.72)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.71...1.0.72)

- Parse const generics which use value of a previous const generic
parameter as a default value
([#&#8203;1027](https://github.com/dtolnay/syn/issues/1027))

### [`v1.0.71`](https://github.com/dtolnay/syn/releases/tag/1.0.71)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.70...1.0.71)

- Fix panic deserializing an ItemImpl with a non-path in trait position
([#&#8203;1023](https://github.com/dtolnay/syn/issues/1023))
- Parse visibility on impl blocks
([#&#8203;1024](https://github.com/dtolnay/syn/issues/1024))
- Fix parsing a type parameter default on the first generic parameter of
an impl block
([#&#8203;1025](https://github.com/dtolnay/syn/issues/1025), thanks
[@&#8203;taiki-e](https://github.com/taiki-e))

### [`v1.0.70`](https://github.com/dtolnay/syn/releases/tag/1.0.70)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.69...1.0.70)

- Fix precedence of closure body vs ExprRange rhs: `|| .. .method()`
([#&#8203;1019](https://github.com/dtolnay/syn/issues/1019))
- Parse inner attributes inside of structs and enums
([#&#8203;1022](https://github.com/dtolnay/syn/issues/1022))

### [`v1.0.69`](https://github.com/dtolnay/syn/releases/tag/1.0.69)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.68...1.0.69)

- Improve Parse impls of ExprBox, ExprUnary, ExprLet, ExprClosure,
ExprReference, ExprBreak, ExprContinue, ExprReturn, ExprYield to respect
precedence for parsing a subexpression beginning with the respective
keyword/punctuation
([#&#8203;1007](https://github.com/dtolnay/syn/issues/1007),
[#&#8203;1008](https://github.com/dtolnay/syn/issues/1008),
[#&#8203;1009](https://github.com/dtolnay/syn/issues/1009),
[#&#8203;1010](https://github.com/dtolnay/syn/issues/1010),
[#&#8203;1011](https://github.com/dtolnay/syn/issues/1011),
[#&#8203;1012](https://github.com/dtolnay/syn/issues/1012),
[#&#8203;1013](https://github.com/dtolnay/syn/issues/1013),
[#&#8203;1014](https://github.com/dtolnay/syn/issues/1014),
[#&#8203;1015](https://github.com/dtolnay/syn/issues/1015))

### [`v1.0.68`](https://github.com/dtolnay/syn/releases/tag/1.0.68)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.67...1.0.68)

- Preserve span of `LexError` on conversion to `syn::Error`
([#&#8203;1006](https://github.com/dtolnay/syn/issues/1006))

### [`v1.0.67`](https://github.com/dtolnay/syn/releases/tag/1.0.67)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.66...1.0.67)

- Accept outer attributes in the Parse impl of ExprBlock
([#&#8203;1004](https://github.com/dtolnay/syn/issues/1004))

### [`v1.0.66`](https://github.com/dtolnay/syn/releases/tag/1.0.66)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.65...1.0.66)

- Parse equality constraints on generic associated types
([#&#8203;979](https://github.com/dtolnay/syn/issues/979))
- Parse default value exprs in const generic declarations
([#&#8203;980](https://github.com/dtolnay/syn/issues/980))
- Fix infinite loop parsing malformed type ascription expression in
non-`full` mode
([#&#8203;978](https://github.com/dtolnay/syn/issues/978))
- Improve Parse impls of ExprArray, ExprAsync, ExprBlock, ExprMacro,
ExprParen, ExprRepeat, ExprStruct, ExprTryBlock, ExprUnsafe to succeed
parsing even in the presence of trailing binary operators
([#&#8203;991](https://github.com/dtolnay/syn/issues/991),
[#&#8203;992](https://github.com/dtolnay/syn/issues/992),
[#&#8203;993](https://github.com/dtolnay/syn/issues/993),
[#&#8203;994](https://github.com/dtolnay/syn/issues/994),
[#&#8203;995](https://github.com/dtolnay/syn/issues/995),
[#&#8203;996](https://github.com/dtolnay/syn/issues/996),
[#&#8203;997](https://github.com/dtolnay/syn/issues/997),
[#&#8203;998](https://github.com/dtolnay/syn/issues/998),
[#&#8203;999](https://github.com/dtolnay/syn/issues/999))

### [`v1.0.65`](https://github.com/dtolnay/syn/releases/tag/1.0.65)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.64...1.0.65)

- Parse visibility on macro_rules
([#&#8203;981](https://github.com/dtolnay/syn/issues/981), tracking
issue
[rust-lang/rust#78855](https://github.com/rust-lang/rust/issues/78855))
- Parse leading vert in or-patterns
([#&#8203;982](https://github.com/dtolnay/syn/issues/982), matching
the Rust grammar change in
[rust-lang/rust#81869](https://github.com/rust-lang/rust/issues/81869))
- Parse static with omitted type
([#&#8203;983](https://github.com/dtolnay/syn/issues/983))
- Parse placeholder type in type parameter position
([#&#8203;984](https://github.com/dtolnay/syn/issues/984))

### [`v1.0.64`](https://github.com/dtolnay/syn/releases/tag/1.0.64)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.63...1.0.64)

- Avoid `clippy::expl_impl_clone_on_copy` pedantic lint in downstream
custom token types
([#&#8203;976](https://github.com/dtolnay/syn/issues/976))

### [`v1.0.63`](https://github.com/dtolnay/syn/releases/tag/1.0.63)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.62...1.0.63)

- Fix parsing associated types with empty trait bound list after colon
([#&#8203;974](https://github.com/dtolnay/syn/issues/974))

### [`v1.0.62`](https://github.com/dtolnay/syn/releases/tag/1.0.62)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.61...1.0.62)

- Republish to work around docs.rs bug
[https://github.com/rust-lang/docs.rs/issues/1300](https://github.com/rust-lang/docs.rs/issues/1300)

### [`v1.0.61`](https://github.com/dtolnay/syn/releases/tag/1.0.61)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.60...1.0.61)

- Improve assertion failures on invalid use of `Punctuated` API
([#&#8203;970](https://github.com/dtolnay/syn/issues/970), thanks
[@&#8203;osa1](https://github.com/osa1))
- Add `Lifetime::span` and `Lifetime::set_span` accessors
([#&#8203;971](https://github.com/dtolnay/syn/issues/971))

### [`v1.0.60`](https://github.com/dtolnay/syn/releases/tag/1.0.60)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.59...1.0.60)

- Provide an idiom for testing exhaustiveness of pattern matches on
`Expr`, `Type`, `Pat`, `Item`, `ForeignItem`, `TraitItem`, and
`ImplItem` ([#&#8203;694](https://github.com/dtolnay/syn/issues/694))

    ```rust
    match expr {
        Expr::Array(e) => {...}
        Expr::Assign(e) => {...}
        ...
        Expr::Yield(e) => {...}

        #[cfg(test)]
        Expr::__TestExhaustive(_) => unimplemented!(),
        #[cfg(not(test))]
        _ => { /* some sane fallback */ }
    }
    ```

The above is the only supported idiom for exhaustive matching of those
enum. Do not write anything differently as it is not supported.

The conditional compilation on match-arms lets us fail your tests but
not break your library when adding a variant. You will be notified by a
test failure when a variant is added, so that you can add code to handle
it, but your library will continue to compile and work for downstream
users in the interim.

### [`v1.0.59`](https://github.com/dtolnay/syn/releases/tag/1.0.59)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.58...1.0.59)

- Parse empty supertrait lists consistently with rustc
([#&#8203;952](https://github.com/dtolnay/syn/issues/952))
- Fix loss of span information on comma tokens inside of Type::Tuple
during parse
([#&#8203;959](https://github.com/dtolnay/syn/issues/959))

### [`v1.0.58`](https://github.com/dtolnay/syn/releases/tag/1.0.58)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.57...1.0.58)

- Allow literals to parse as a const generic path argument even without
"full" feature enabled
([#&#8203;951](https://github.com/dtolnay/syn/issues/951))

    ```rust
    pub struct Struct {
        array: Array<10>,  // used to require `features = "full"`
    }
    ```

### [`v1.0.57`](https://github.com/dtolnay/syn/releases/tag/1.0.57)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.56...1.0.57)

- Make Punctuated::new available as a `const fn`
([#&#8203;949](https://github.com/dtolnay/syn/issues/949))

### [`v1.0.56`](https://github.com/dtolnay/syn/releases/tag/1.0.56)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.55...1.0.56)

- Add
[`Error::into_compile_error`](https://docs.rs/syn/1.0.56/syn/struct.Error.html#method.into_compile_error)

### [`v1.0.55`](https://github.com/dtolnay/syn/releases/tag/1.0.55)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.54...1.0.55)

- Preserve None-delimited group around macro metavariable when parsing
`T<$ty>` ([#&#8203;944](https://github.com/dtolnay/syn/issues/944),
[#&#8203;945](https://github.com/dtolnay/syn/issues/945))

### [`v1.0.54`](https://github.com/dtolnay/syn/releases/tag/1.0.54)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.53...1.0.54)

- Fix parsing of `impl` items with macro metavariable in the trait path:
`impl $trait for Type {...}`
([#&#8203;942](https://github.com/dtolnay/syn/issues/942))

### [`v1.0.53`](https://github.com/dtolnay/syn/releases/tag/1.0.53)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.52...1.0.53)

- Parse `impl !Trait {...}` syntax
([#&#8203;936](https://github.com/dtolnay/syn/issues/936))

### [`v1.0.52`](https://github.com/dtolnay/syn/releases/tag/1.0.52)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.51...1.0.52)

- Parse `unsafe extern` block syntax
([#&#8203;918](https://github.com/dtolnay/syn/issues/918))
- Parse `unsafe mod` syntax
([#&#8203;919](https://github.com/dtolnay/syn/issues/919))
- Parse `const {...}` block syntax
([#&#8203;921](https://github.com/dtolnay/syn/issues/921))
- Parse destructuring assignment syntax
([#&#8203;933](https://github.com/dtolnay/syn/issues/933))

### [`v1.0.51`](https://github.com/dtolnay/syn/releases/tag/1.0.51)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.50...1.0.51)

- Allow parsing signatures in which const generic params appear in front
of lifetime params
([#&#8203;920](https://github.com/dtolnay/syn/issues/920))

### [`v1.0.50`](https://github.com/dtolnay/syn/releases/tag/1.0.50)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.48...1.0.50)

- Apply `doc(cfg(...))` on feature gated APIs for docs.rs-rendered
documentation
([#&#8203;925](https://github.com/dtolnay/syn/issues/925))

### [`v1.0.48`](https://github.com/dtolnay/syn/releases/tag/1.0.48)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.47...1.0.48)

-   Rebuild for https://astexplorer.net

### [`v1.0.47`](https://github.com/dtolnay/syn/releases/tag/1.0.47)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.46...1.0.47)

-   Documentation improvements

### [`v1.0.46`](https://github.com/dtolnay/syn/releases/tag/1.0.46)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.45...1.0.46)

- Fix parsing structured attributes that contain nested absolute paths,
such as `#[derive(::serde::Serialize)]`
([#&#8203;909](https://github.com/dtolnay/syn/issues/909))

### [`v1.0.45`](https://github.com/dtolnay/syn/releases/tag/1.0.45)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.44...1.0.45)

- Provide more detailed error messages when parsing specific literal
kind ([#&#8203;908](https://github.com/dtolnay/syn/issues/908))

### [`v1.0.44`](https://github.com/dtolnay/syn/releases/tag/1.0.44)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.43...1.0.44)

- Fix some parsing of patterns inside of None-delimited groups
([#&#8203;907](https://github.com/dtolnay/syn/issues/907))

### [`v1.0.43`](https://github.com/dtolnay/syn/releases/tag/1.0.43)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.42...1.0.43)

-   Add Parse impl for syn::Signature

### [`v1.0.42`](https://github.com/dtolnay/syn/releases/tag/1.0.42)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.41...1.0.42)

- Fix several bugs involving unusual suffixes on integer and floating
point literal tokens
([#&#8203;898](https://github.com/dtolnay/syn/issues/898),
[#&#8203;899](https://github.com/dtolnay/syn/issues/899),
[#&#8203;900](https://github.com/dtolnay/syn/issues/900))

### [`v1.0.41`](https://github.com/dtolnay/syn/releases/tag/1.0.41)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.40...1.0.41)

- Fix panic on printing an incomplete (having fewer path segments than
originally parsed with) qualified path (ExprPath, PatPath, TypePath
containing QSelf)
([#&#8203;891](https://github.com/dtolnay/syn/issues/891), thanks
[@&#8203;taiki-e](https://github.com/taiki-e))
- Fix panic triggered by syntactically invalid overflowing negative
float literal after `.` in a field access position, e.g. `let _ =
obj.-0.9E999999`
([#&#8203;895](https://github.com/dtolnay/syn/issues/895), thanks
[@&#8203;sameer](https://github.com/sameer))
- Enable using `parse_macro_input!` with a Parser function rather than
type having a Parse impl
([#&#8203;896](https://github.com/dtolnay/syn/issues/896), thanks
[@&#8203;sbrocket](https://github.com/sbrocket))

### [`v1.0.40`](https://github.com/dtolnay/syn/releases/tag/1.0.40)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.39...1.0.40)

- Fix panic on parsing float literals having both an exponent and a
suffix beginning with 'e' or 'E', such as `9e99e999`
([#&#8203;893](https://github.com/dtolnay/syn/issues/893))

### [`v1.0.39`](https://github.com/dtolnay/syn/releases/tag/1.0.39)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.38...1.0.39)

- Improve compile time by pre-expanding derives
([#&#8203;885](https://github.com/dtolnay/syn/issues/885))
- Parse const generic parameters in any order relative to type
parameters ([#&#8203;886](https://github.com/dtolnay/syn/issues/886))

### [`v1.0.38`](https://github.com/dtolnay/syn/releases/tag/1.0.38)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.37...1.0.38)

- Accept traits with parenthesized path arguments in impls
([#&#8203;880](https://github.com/dtolnay/syn/issues/880), thanks
[@&#8203;alecmocatta](https://github.com/alecmocatta))

### [`v1.0.37`](https://github.com/dtolnay/syn/releases/tag/1.0.37)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.36...1.0.37)

- Handle shebang in a way that matches rustc 1.46+
([#&#8203;876](https://github.com/dtolnay/syn/issues/876),
[https://github.com/rust-lang/rust/pull/71487](https://github.com/rust-lang/rust/pull/71487),
[https://github.com/rust-lang/rust/pull/73596](https://github.com/rust-lang/rust/pull/73596))

    ```rust
    #!//am/i/a/comment

    fn main() {} // ^ shebang
    ```

    ```rust
    #!//am/i/a/comment

    [allow(dead_code)] // ^ not a shebang
    fn main() {}
    ```

- Accept <code>tuple.0.  0</code> as a tuple indexing expression
([#&#8203;877](https://github.com/dtolnay/syn/issues/877))

### [`v1.0.36`](https://github.com/dtolnay/syn/releases/tag/1.0.36)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.35...1.0.36)

- Add Lit::span, Lit::set_span
([#&#8203;874](https://github.com/dtolnay/syn/issues/874))

### [`v1.0.35`](https://github.com/dtolnay/syn/releases/tag/1.0.35)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.34...1.0.35)

- Fix parsing of Expr::Field in non-full mode
([#&#8203;870](https://github.com/dtolnay/syn/issues/870))

### [`v1.0.34`](https://github.com/dtolnay/syn/releases/tag/1.0.34)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.33...1.0.34)

-   Documentation improvements

### [`v1.0.33`](https://github.com/dtolnay/syn/releases/tag/1.0.33)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.32...1.0.33)

- Parse `tuple.0.0` as an indexing expression
([https://github.com/rust-lang/rust/pull/71322](https://github.com/rust-lang/rust/pull/71322))
- Add `Parse` impls for optional of proc-macro2 types:
`Option<TokenTree>`, `Option<Punct>`, `Option<Literal>`, `Option<Group>`

### [`v1.0.32`](https://github.com/dtolnay/syn/releases/tag/1.0.32)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.31...1.0.32)

- Fix parsing $:item macro_rules metavariables containing outer
attributes ([#&#8203;852](https://github.com/dtolnay/syn/issues/852))

### [`v1.0.31`](https://github.com/dtolnay/syn/releases/tag/1.0.31)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.30...1.0.31)

- Add
[`Expr::parse_without_eager_brace`](https://docs.rs/syn/1.0.31/syn/enum.Expr.html#method.parse_without_eager_brace)
to parse expressions in ambiguous syntactic position.

Rust grammar has an ambiguity where braces sometimes turn a path
expression into a struct initialization and sometimes do not. In the
following code, the expression `S {}` is one expression. Presumably
there is an empty struct `struct S {}` defined somewhere which it is
instantiating.

    ```rust
    let _ = *S {};

    // parsed by rustc as: `*(S {})`
    ```

We would want to parse the above using `Expr::parse` after the `=`
token.

    But in the following, `S {}` is *not* a struct init expression.

    ```rust
    if *S {} {}

    // parsed by rustc as:
    //
    //    if (*S) {
    //        /* empty block */
    //    }
    //    {
    //        /* another empty block */
    //    }
    ```

For that reason we would want to parse if-conditions using
`Expr::parse_without_eager_brace` after the `if` token. Same for similar
syntactic positions such as the condition expr after a `while` token or
the expr at the top of a `match`.

The Rust grammar's choices around which way this ambiguity is resolved
at various syntactic positions is fairly arbitrary. Really either parse
behavior could work in most positions, and language designers just
decide each case based on which is more likely to be what the programmer
had in mind most of the time.

    ```rust
    if return S {} {}

    // parsed by rustc as:
    //
    //    if (return (S {})) {
    //    }
    //
    // but could equally well have been this other arbitrary choice:
    //
    //    if (return S) {
    //    }
    //    {}
    ```

Note the grammar ambiguity on trailing braces is distinct from
precedence and is not captured by assigning a precedence level to the
braced struct init expr in relation to other operators. This can be
illustrated by `return 0..S {}` vs `match 0..S {}`. The former parses as
`return (0..(S {}))` implying tighter precedence for struct init than
`..`, while the latter parses as `match (0..S) {}` implying tighter
precedence for `..` than struct init, a contradiction.

### [`v1.0.30`](https://github.com/dtolnay/syn/releases/tag/1.0.30)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.29...1.0.30)

- Parse struct init expressions where the type name is an interpolated
macro_rules metavariable, such as `$struct {}` where $struct:ident
([#&#8203;842](https://github.com/dtolnay/syn/issues/842))
- Handle nesting of None-delimited groups
([#&#8203;843](https://github.com/dtolnay/syn/issues/843), thanks
[@&#8203;Aaron1011](https://github.com/Aaron1011))

### [`v1.0.29`](https://github.com/dtolnay/syn/releases/tag/1.0.29)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.28...1.0.29)

- Parse macro call exprs where the macro name is an interpolated
macro_rules metavariable, such as `$macro!()`
([#&#8203;838](https://github.com/dtolnay/syn/issues/838))
- Parse paths containing generic parameters where the first path segment
is an interpolated macro_rules metavariable, such as `$seg<'a>`
([#&#8203;839](https://github.com/dtolnay/syn/issues/839))

### [`v1.0.28`](https://github.com/dtolnay/syn/releases/tag/1.0.28)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.27...1.0.28)

- Recognize empty None-delimited group produced by interpolating a $:vis
macro metavariable when parsing a Visibility
([#&#8203;836](https://github.com/dtolnay/syn/issues/836))

### [`v1.0.27`](https://github.com/dtolnay/syn/releases/tag/1.0.27)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.26...1.0.27)

- Parse function calls in which the callee is an interpolated macro
variable `$fn(...)`
([#&#8203;833](https://github.com/dtolnay/syn/issues/833))

### [`v1.0.26`](https://github.com/dtolnay/syn/releases/tag/1.0.26)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.25...1.0.26)

- Parse paths containing an interpolated first component, such as
`$first::rest`
([https://github.com/rust-lang/rust/issues/72608](https://github.com/rust-lang/rust/issues/72608),
[#&#8203;832](https://github.com/dtolnay/syn/issues/832))

### [`v1.0.25`](https://github.com/dtolnay/syn/releases/tag/1.0.25)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.24...1.0.25)

- Parse opt-out `?const` trait bounds
([#&#8203;767](https://github.com/dtolnay/syn/issues/767))
- Parse const generics in method generic arguments
([#&#8203;816](https://github.com/dtolnay/syn/issues/816), thanks
[@&#8203;yodaldevoid](https://github.com/yodaldevoid))
- Parse trait bounds on type alias items
([#&#8203;821](https://github.com/dtolnay/syn/issues/821))
- Parse const generics on impl blocks
([#&#8203;822](https://github.com/dtolnay/syn/issues/822))
- Fix precedence of attributes on binary expressions to match rustc
([#&#8203;823](https://github.com/dtolnay/syn/issues/823))
- Remove parsing of `extern::` paths which were removed from nightly in
January 2019
([#&#8203;825](https://github.com/dtolnay/syn/issues/825),
[https://github.com/rust-lang/rust/pull/57572](https://github.com/rust-lang/rust/pull/57572))
- Add `Punctuated::clear`, analogous to Vec::clear
([#&#8203;828](https://github.com/dtolnay/syn/issues/828))

### [`v1.0.24`](https://github.com/dtolnay/syn/releases/tag/1.0.24)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.23...1.0.24)

- Parse `mut self` receiver in function pointer type
([#&#8203;812](https://github.com/dtolnay/syn/issues/812),
[#&#8203;814](https://github.com/dtolnay/syn/issues/814))
- Parse const trait impls
([#&#8203;813](https://github.com/dtolnay/syn/issues/813))
- Improve error reporting inside struct expressions and struct patterns
([#&#8203;818](https://github.com/dtolnay/syn/issues/818))

### [`v1.0.23`](https://github.com/dtolnay/syn/releases/tag/1.0.23)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.22...1.0.23)

- Parse inner attributes in traits
([#&#8203;803](https://github.com/dtolnay/syn/issues/803))
- Parse const underscore in traits and impls
([#&#8203;804](https://github.com/dtolnay/syn/issues/804))
- Implement Extend<Error> for Error
([#&#8203;805](https://github.com/dtolnay/syn/issues/805))
- Parse Or patterns
([#&#8203;806](https://github.com/dtolnay/syn/issues/806))
- Parse outer attributes on Expr\* structs
([#&#8203;807](https://github.com/dtolnay/syn/issues/807))
- Parse top level const/static without value
([#&#8203;808](https://github.com/dtolnay/syn/issues/808))
- Parse syntactically accepted functions
([#&#8203;809](https://github.com/dtolnay/syn/issues/809))
- Parse extern static with value
([#&#8203;810](https://github.com/dtolnay/syn/issues/810))

Thanks [@&#8203;taiki-e](https://github.com/taiki-e) for all of these.

### [`v1.0.22`](https://github.com/dtolnay/syn/releases/tag/1.0.22)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.21...1.0.22)

- Parse literal suffix on byte string, byte, and char literal tokens:
`br#"..."#suffix`, `b'?'suffix`, `'?'suffix`
([#&#8203;799](https://github.com/dtolnay/syn/issues/799),
[#&#8203;800](https://github.com/dtolnay/syn/issues/800))

### [`v1.0.21`](https://github.com/dtolnay/syn/releases/tag/1.0.21)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.20...1.0.21)

-   Documentation improvements

### [`v1.0.20`](https://github.com/dtolnay/syn/releases/tag/1.0.20)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.19...1.0.20)

- Improve span of error message when an error during
`syn::Macro::parse_body` is triggered past the last token of the macro
body ([#&#8203;791](https://github.com/dtolnay/syn/issues/791))

### [`v1.0.19`](https://github.com/dtolnay/syn/releases/tag/1.0.19)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.18...1.0.19)

- Parse a more lenient extern type syntax inside extern blocks
([#&#8203;763](https://github.com/dtolnay/syn/issues/763))

### [`v1.0.18`](https://github.com/dtolnay/syn/releases/tag/1.0.18)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.17...1.0.18)

- Ignore unparsed empty None-delimited groups at the end of a macro
input ([#&#8203;783](https://github.com/dtolnay/syn/issues/783))

### [`v1.0.17`](https://github.com/dtolnay/syn/releases/tag/1.0.17)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.16...1.0.17)

-   Expose `syn::Lit` in `default-features = false` mode

### [`v1.0.16`](https://github.com/dtolnay/syn/releases/tag/1.0.16)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.15...1.0.16)

- Fix parsing of `&raw` raw reference operator
([https://github.com/rust-lang/rust/issues/64490](https://github.com/rust-lang/rust/issues/64490))
to require explicitly specified constness, `&raw mut` or `&raw const`

### [`v1.0.15`](https://github.com/dtolnay/syn/releases/tag/1.0.15)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.14...1.0.15)

- Add
[`Punctuated::first_mut`](https://docs.rs/syn/1.0.15/syn/punctuated/struct.Punctuated.html#method.first_mut)
to return a mut reference to the first sequence element

### [`v1.0.14`](https://github.com/dtolnay/syn/releases/tag/1.0.14)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.13...1.0.14)

- Produce more helpful error messages from
[Attribute::parse_args](https://docs.rs/syn/1.0/syn/struct.Attribute.html#method.parse_args)

### [`v1.0.13`](https://github.com/dtolnay/syn/releases/tag/1.0.13)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.12...1.0.13)

- Allow parse_quote! to parse Vec\<Stmt>, with the same behavior as
Block::parse_within
([#&#8203;741](https://github.com/dtolnay/syn/issues/741))

### [`v1.0.12`](https://github.com/dtolnay/syn/releases/tag/1.0.12)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.11...1.0.12)

- Reject function signatures with an incorrectly placed receiver
parameter, like `fn f(x: u8, &self)`
- Produce correctly spanned error when parsing punct beyond the end of a
delimited group
([#&#8203;739](https://github.com/dtolnay/syn/issues/739))

### [`v1.0.11`](https://github.com/dtolnay/syn/releases/tag/1.0.11)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.10...1.0.11)

- Implement quote::IdentFragment for syn::Member and syn::Index so that
spans are preserved when using these types in quote's `format_ident!`
macro

    ```rust
    use quote::format_ident;
    use syn::Index;

    let index: Index = /* ... */;
    let ident = format_ident!("__{}", index); // produces __0, __1, etc
    ```

### [`v1.0.10`](https://github.com/dtolnay/syn/releases/tag/1.0.10)

[Compare
Source](https://github.com/dtolnay/syn/compare/1.0.9...1.0.10)

- Provide `Hash` and `Eq` impls for syn::Member even without
"extra-traits" feature enabled, as this type is commonly useful in a
hashset

### [`v1.0.9`](https://github.com/dtolnay/syn/releases/tag/1.0.9)

[Compare Source](https://github.com/dtolnay/syn/compare/1.0.8...1.0.9)

- Fix failure to parse tuple struct fields of tuple type starting with
`crate` ([#&#8203;720](https://github.com/dtolnay/syn/issues/720),
[#&#8203;723](https://github.com/dtolnay/syn/issues/723), thanks
[@&#8203;mystor](https://github.com/mystor))
- Fix unexpected tokens being ignored when using Speculative::advance_to
([#&#8203;721](https://github.com/dtolnay/syn/issues/721),
[#&#8203;723](https://github.com/dtolnay/syn/issues/723), thank

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/grafbase/api).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMTEuMCIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->
@RalfJung
Copy link
Member

  • Collect a T-lang design notes document for "pointer pain points"
  • From the pain points, T-lang decides on which path we want to pursue: new pointer type(s) or old pointer types

Seems like we are still at this stage. So if someone wants to push this forward, working on such a document would be the best way to help. :)

@RalfJung
Copy link
Member

On the other hand, if we are getting a better raw pointer type in the future, we always have the option of using an edition transition to change the meaning of &raw. So maybe we should just stabilize what we got so that we can finally stop using a macro for this?

@RalfJung
Copy link
Member

Stabilization of this feature is in FCP over at #127679. :)

bors added a commit to rust-lang-ci/rust that referenced this issue Aug 18, 2024
Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](rust-lang#64490 (comment)) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: rust-lang/unsafe-code-guidelines#257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: rust-lang#127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of rust-lang#127679 (comment) for rationale
  - Implementation: rust-lang#128782
- [ ] Update the Reference.
  - rust-lang/reference#1567

Fixes rust-lang#64490

cc `@rust-lang/lang` `@rust-lang/opsem`

try-job: x86_64-msvc
try-job: i686-mingw
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this issue Aug 18, 2024
Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](rust-lang#64490 (comment)) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: rust-lang/unsafe-code-guidelines#257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: rust-lang#127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of rust-lang#127679 (comment) for rationale
  - Implementation: rust-lang#128782
- [ ] Update the Reference.
  - rust-lang/reference#1567

Fixes rust-lang#64490

cc `@rust-lang/lang` `@rust-lang/opsem`

// try-job: i686-mingw // `dump-ice-to-disk` is flaky
try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
jieyouxu added a commit to jieyouxu/rust that referenced this issue Aug 18, 2024
…,jieyouxu

Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](rust-lang#64490 (comment)) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: rust-lang/unsafe-code-guidelines#257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: rust-lang#127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of rust-lang#127679 (comment) for rationale
  - Implementation: rust-lang#128782
- [ ] Update the Reference.
  - rust-lang/reference#1567

Fixes rust-lang#64490

cc `@rust-lang/lang` `@rust-lang/opsem`

try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
@bors bors closed this as completed in f27a9b1 Aug 19, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Aug 19, 2024
Rollup merge of rust-lang#127679 - RalfJung:raw_ref_op, r=jieyouxu

Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](rust-lang#64490 (comment)) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: rust-lang/unsafe-code-guidelines#257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: rust-lang#127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of rust-lang#127679 (comment) for rationale
  - Implementation: rust-lang#128782
- [ ] Update the Reference.
  - rust-lang/reference#1567

Fixes rust-lang#64490

cc `@rust-lang/lang` `@rust-lang/opsem`

try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
github-actions bot pushed a commit to rust-lang/miri that referenced this issue Aug 20, 2024
Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](rust-lang/rust#64490 (comment)) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: rust-lang/unsafe-code-guidelines#257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: rust-lang/rust#127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of rust-lang/rust#127679 (comment) for rationale
  - Implementation: rust-lang/rust#128782
- [ ] Update the Reference.
  - rust-lang/reference#1567

Fixes rust-lang/rust#64490

cc `@rust-lang/lang` `@rust-lang/opsem`

try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-raw_ref_op `#![feature(raw_ref_op)]` requires-nightly This issue requires a nightly compiler in some way. S-tracking-needs-summary Status: It's hard to tell what's been done and what hasn't! Someone should do some investigation. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.