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

Proposal: Change syntax of where clauses on type aliases #89122

Closed
nikomatsakis opened this issue Sep 20, 2021 · 47 comments · Fixed by #90076
Closed

Proposal: Change syntax of where clauses on type aliases #89122

nikomatsakis opened this issue Sep 20, 2021 · 47 comments · Fixed by #90076
Labels
A-GATs Area: Generic associated types (GATs) F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs GATs-blocking Issues using the `generic_associated_types` feature that block stabilization GATs-triaged Issues using the `generic_associated_types` feature that have been triaged T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

Source

Summary

Proposed: to alter the syntax of where clauses on type aliases so that they appear after the value:

type StringMap<K> = BTreeMap<K, String>
where
    K: PartialOrd

This applies both in top-level modules and in trats (associated types, generic or otherwise).

Background

The current syntax for where to place the "where clause" of a generic associated types is awkward. Consider this example (playground):

trait Iterable {
    type Iter<'a> where Self: 'a;

    fn iter(&self) -> Self::Iter<'_>;
}

impl<T> Iterable for Vec<T> {
    type Iter<'a>
    where 
        Self: 'a = <&'a [T] as IntoIterator>::IntoIter;

    fn iter(&self) -> Self::Iter<'_> {
        self.iter()
    }
}

Note the impl. Most people expect the impl to be written as follows (indeed, the author wrote it this way in the first draft):

impl Iterable for Vec<T> {
    type Iter<'a>  = <&'a [T] as Iterator>::Iter
    where 
        Self: 'a;

    fn iter(&self) -> Self::Iter<'_> {
        self.iter()
    }
}

However, this placement of the where clause is in fact rather inconsistent, since the = <&'a [T] as Iterator>::Iter is in some sense the "body" of the item.

The same current syntax is used for where clauses on type aliases (playground):

type Foo<T> where T: Eq = Vec<T>;

fn main() { }

Top-level type aliases

Currently, we accept where clauses in top-level type aliases, but they are deprecated (warning) and semi-ignored:

type StringMap<K> where
    K: PartialOrd
= BTreeMap<K, String>

Under this proposal, this syntax remains, but is deprecated. The newer syntax for type aliases (with where coming after the type) would remain feature gated until such time as we enforce the expected semantics.

Alternatives

Keep the current syntax.

In this case, we must settle the question of how we expect it to be formatted (surely not as I have shown it above).

impl<T> Iterable for Vec<T> {
    type Iter<'a> where Self: 'a 
        = <&'a [T] as IntoIterator>::IntoIter;

    fn iter(&self) -> Self::Iter<'_> {
        self.iter()
    }
}

Accept either

What do we do if both are supplied?

@nikomatsakis nikomatsakis added T-lang Relevant to the language team, which will review and decide on the PR/issue. F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs labels Sep 20, 2021
@nikomatsakis
Copy link
Contributor Author

@rfcbot fcp merge

@jackh726 and I have discussed this issue and we both agree that changing the syntax here would be correct. I propose that we go ahead and do it.

@rfcbot
Copy link

rfcbot commented Sep 20, 2021

Team member @nikomatsakis has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Sep 20, 2021
@cramertj
Copy link
Member

Interesting! I can see why this would be desirable-- the formatting can work out a bit nicer in the new version, and it helps front-load the most important part of the alias (that is, it visually defers the bound until after the main part of the alias has been stated). However, I see two advantages to the previous approach:

  1. It's simpler to copy-paste bounds from the trait definition to the impl. trait Foo { type Bar where X: Y; } -> impl Foo for X { type Bar where X: Y = ...; } both match up visually, and one can create an impl by merely copy-pasting the trait definition and adding the appropriate = .... I appreciate this symmetry, and it would be surprising to me if this were not supported, or if I was given a warning.
  2. Conceptually, the bound is applying to the way the type alias may be used as stated in the trait definition. That is, the bound is not a property specific to the impl. This makes it more similar to the type signature of a trait method than the body of a trait method. Based on this, I'd expect it to belong on the left-hand side of the =. Trait definition / requirements first / on the left, followed by specifics of the impl is a useful pattern to keep, I think.

I don't think I feel particularly strongly either way, but the reasons above contribute to my initial preference for the old syntax.

@shepmaster
Copy link
Member

@estebank pointed out to me that the parser might end up parsing both forms anyway, in order to provide useful diagnostics.

@nikomatsakis
Copy link
Contributor Author

Yes, I expect the parser to parse both forms and offer useful tips for how to transform from one to the other.

@joshtriplett
Copy link
Member

joshtriplett commented Sep 20, 2021

FWIW, I can see why the type ... where ... = ... syntax would make sense as well, since it seems analogous to fn ...() where ... { ... }. I do think the proposed change feels more likely to produce readable code, though. On balance, I'd expect a where to get more complex than the RHS of the =.

@camelid
Copy link
Member

camelid commented Sep 20, 2021

Note also that trailing where clauses are supported for tuple structs:

// Compiles successfully.
pub struct Struct<T>(T)
where
    T: Eq;

@petrochenkov
Copy link
Contributor

@estebank pointed out to me that the parser might end up parsing both forms anyway, in order to provide useful diagnostics.

I think this is the way to go.
If this proposal is accepted, then we'll need to support where clauses in both positions anyway due to compatibility.
In that case why not return a non-fatal error in one of the cases, and normalize legal syntax to the single already existing form.

Most people expect the impl to be written as follows

What makes you think so?
In functions where clauses are between the header and the body, why in types it should be after the "body"?

In trait aliases, which have similar syntax with =, where is actually a part of the "body".
Will it use a second where for where clauses?

trait Alias = Body1 where Self: Body2 where NotABodyAnymore;

?

@nikomatsakis
Copy link
Contributor Author

What makes you think so?

A fair question! Anecdotal reports. It's hard to quantify this, perhaps I should rewrite to "many people". We could try to get more precise about this, perhaps via a survey.

In that case why not return a non-fatal error in one of the cases, and normalize legal syntax to the single already existing form.

e.g., via rustfmt? That is an option, yes. We could simply union where clauses in the two positions.

@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Sep 21, 2021
@rfcbot
Copy link

rfcbot commented Sep 21, 2021

🔔 This is now entering its final comment period, as per the review above. 🔔

@cramertj
Copy link
Member

Ah-- I made a procedural mistake and did not file a concern. I assume we're still considering this pending further discussion?

@rfcbot concern do-we-want-to-make-this-change

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Sep 21, 2021
@nikomatsakis
Copy link
Contributor Author

We discussed this in our @rust-lang/lang meeting today. There wasn't a clear consensus one way or the other.

Some points we identified:

There are plenty of cases in Rust's existing grammar where where clauses follow types:

fn foo() -> T
where ...
{ }

impl Foo for Bar
where ...
{}

Therefore, there isn't really a concern about introducing new grammatical ambiguities (this was raised as a concern in the meeting).

One thing we did find is that, when reading type Foo = Bar where Baz, Some people mentally "group" the where clause with Bar, and some mentally group it with Foo. Note that, in all existing instances, where clauses are attached to the surrounding item.

We discussed whether changes to the formatting rules might help, but we didn't discuss that very much.

@estebank
Copy link
Contributor

Third option: support both 😬

We have to support both in the parser for diagnostics, what if we just... accepted both ways?

@thorjelly
Copy link

thorjelly commented Sep 23, 2021

I personally feel as though type Foo<T> = Bar<T> where T: ... is semantically equivalent to fn foo<T>() -> Bar<T> where T: ... and impl Foo<T> for Bar<T> where T: ..., where in each case =, ->, and for sort of act as operators on Foo and Bar. Therefore, I feel like the new proposal is most consistent with the syntax people are most used to.

This is coming from someone who has barely used the current implementation of GATs, so I am unused to its syntax, I would find the new proposal a fair bit more intuitive.

@nikomatsakis
Copy link
Contributor Author

@estebank I feel like supporting both without a real reason to support both is suboptimal. Then there will be confusion over whether there is a difference, for example, and perhaps two camps (one who prefers one, one who prefers the other). I don't mind more than one way to do things, but it feels like it needs strong justification to me.

One thing I would like is if rustfmt quietly changed from one to the other, though =) that would affect my opinion. But this isn't generally how rustfmt does things.

@dtolnay
Copy link
Member

dtolnay commented Sep 23, 2021

In the context of the FCP proposed in #89122 (comment), what behavior is proposed if where is given in both places?

type Thing<T> where T: IntoIterator = T::IntoIter
where
    T::Item: Clone;

Does this union the clauses, or does it reject? From the discussion above I'm unable to tell whether a concrete behavior was proposed. Asking as someone who will need to implement this in a Rust parser.

@dtolnay
Copy link
Member

dtolnay commented Sep 24, 2021

Separately, I feel that #89122 (comment) is going to require a response/consensus before completing the FCP.

Here is a concrete example to consider:

#![feature(trait_alias)]

trait Alias<T: Clone> = where T: Default;

// okay, equivalent to `where T: Clone + Default`
fn clone<T: Alias<T> + Clone>() {}

// ERROR, trait bound `T: Clone` not satisfied
fn default<T: Alias<T> + Default>() {}

In this situation, what is proposed to be the where equivalent of the T: Clone bound on Alias? Prior to this proposal, it's natural to expect that it would be:

trait Alias<T> where T: Clone = where T: Default;

This proposal throws a wrench in the works, as @petrochenkov called attention to. It would now seem to be the somewhat bizarre:

trait Alias<T> = where T: Default where T: Clone;

Relatedly, what does the following mean?

trait Alias<T> = Default
where
    T: Clone;

Is this equivalent to trait Alias<T: Clone> = Default, or to (the old interpretation of) trait Alias<T> = Default where T: Clone, which are not the same thing?

trait_alias is unstable (cc tracking issue #41517) but since the syntax is heavily inspired by type alias syntax, I think it's worth acknowledging the implications that type alias syntax changes would have on it, and maybe loop in people involved in that proposal if there are specific people.

@yasammez
Copy link

Third option: support both 😬

We have to support both in the parser for diagnostics, what if we just... accepted both ways?

This would be my least preferred option: if you support two variants for the same thing, any codebase of sufficient size will eventually contain both, no matter how strict you are trying to be. This increases the mental burden for developers trying to understand existing code and leads to needless discussions about which style to prefer within teams.

@nikomatsakis
Copy link
Contributor Author

@petrochenkov

In trait aliases, which have similar syntax with =, where is actually a part of the "body".

Remind me, do trait aliases currently permit where clauses in both places?

@petrochenkov
Copy link
Contributor

do trait aliases currently permit where clauses in both places?

Not right now, but both positions have a well-defined meaning in theory, as @dtolnay describes in #89122 (comment).

BigBigos added a commit to BigBigos/apex-tux that referenced this issue Nov 23, 2022
The feature(generic_associated_types) has been recently stabilized and
does not need to be listed in the `#![feature(...)]` block.

Also, move the `where` clauses on GAT impls to after the type
assignment, taking advantage of a syntax change described here:

  rust-lang/rust#89122
not-jan pushed a commit to not-jan/apex-tux that referenced this issue Nov 29, 2022
* Add rust-toolchain.toml file

This file tells cargo (and other tools, like vscode rust-analyzer
plugin) to use the nightly toolchain by default.

This is needed to correctly open the project in vscode with
rust-analyzer.

We should probably fix a nigthly version, but for now leave it as a
generic `nightly`.

* Use feature(generic_associated_types) as in stable

The feature(generic_associated_types) has been recently stabilized and
does not need to be listed in the `#![feature(...)]` block.

Also, move the `where` clauses on GAT impls to after the type
assignment, taking advantage of a syntax change described here:

  rust-lang/rust#89122

* Update bitvec to 1.0.1

bitvec-0.22.3 depends on yanked funty-1.2.0 and no longer builds. Update
to bitvec-1.0.1 as this is the most recent version.

Change a few API calls as they have been renamed. Move the framebuffer
BitArray size to a constant so that it is not repeated.

* Fix a typo in settings.toml

* Invoke `cargo fmt` on the whole workspace

* Fix apex-ctl clap usage and update it

Update clap to 4.0.26. Enable the `derive` feature to fix compilation.

Change the derive attributes to work with newer version of clap.

Drop apex_hardware::FareBuffer use.

* Fix `debug` feature

Make `src/render/debug.rs` buildable.

* Fix `coindesk` section in `settings.toml`

It was called `crypto`, but the provider is called `coindesk` instead.

* fixup! Update bitvec to 1.0.1
calebcartwright pushed a commit to calebcartwright/rustfmt that referenced this issue Jan 24, 2023
Stabilize generic associated types

Closes #44265

r? `@nikomatsakis`

# ⚡ Status of the discussion ⚡

* [x] There have been several serious concerns raised, [summarized here](rust-lang/rust#96709 (comment)).
* [x] There has also been a [deep-dive comment](rust-lang/rust#96709 (comment)) explaining some of the "patterns of code" that are enabled by GATs, based on use-cases posted to this thread or on the tracking issue.
* [x] We have modeled some aspects of GATs in [a-mir-formality](https://github.com/nikomatsakis/a-mir-formality) to give better confidence in how they will be resolved in the future. [You can read a write-up here](https://github.com/rust-lang/types-team/blob/master/minutes/2022-07-08-implied-bounds-and-wf-checking.md).
* [x] The major points of the discussion have been [summarized on the GAT initiative repository](https://rust-lang.github.io/generic-associated-types-initiative/mvp.html).
* [x] [FCP has been proposed](rust-lang/rust#96709 (comment)) and we are awaiting final decisions and discussion amidst the relevant team members.

# Stabilization proposal

This PR proposes the stabilization of `#![feature(generic_associated_types)]`. While there a number of future additions to be made and bugs to be fixed (both discussed below), properly doing these will require significant language design and will ultimately likely be backwards-compatible. Given the overwhelming desire to have some form of generic associated types (GATs) available on stable and the stability of the "simple" uses, stabilizing the current subset of GAT features is almost certainly the correct next step.

Tracking issue: #44265
Initiative: https://rust-lang.github.io/generic-associated-types-initiative/
RFC: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
Version: 1.65 (2022-08-22 => beta, 2022-11-03 => stable).

## Motivation

There are a myriad of potential use cases for GATs. Stabilization unblocks probable future language features (e.g. async functions in traits), potential future standard library features (e.g. a `LendingIterator` or some form of `Iterator` with a lifetime generic), and a plethora of user use cases (some of which can be seen just by scrolling through the tracking issue and looking at all the issues linking to it).

There are a myriad of potential use cases for GATs. First, there are many users that have chosen to not use GATs primarily because they are not stable (some of which can be seen just by scrolling through the tracking issue and looking at all the issues linking to it). Second, while language feature desugaring isn't *blocked* on stabilization, it gives more confidence on using the feature. Likewise, library features like `LendingIterator` are not necessarily blocked on stabilization to be implemented unstably; however few, if any, public-facing APIs actually use unstable features.

This feature has a long history of design, discussion, and developement - the RFC was first introduced roughly 6 years ago. While there are still a number of features left to implement and bugs left to fix, it's clear that it's unlikely those will have backwards-incompatibility concerns. Additionally, the bugs that do exist do not strongly impede the most-common use cases.

## What is stabilized

The primary language feature stabilized here is the ability to have generics on associated types, as so. Additionally, where clauses on associated types will now be accepted, regardless if the associated type is generic or not.

```rust
trait ATraitWithGATs {
    type Assoc<'a, T> where T: 'a;
}

trait ATraitWithoutGATs<'a, T> {
    type Assoc where T: 'a;
}
```

When adding an impl for a trait with generic associated types, the generics for the associated type are copied as well. Note that where clauses are allowed both after the specified type and before the equals sign; however, the latter is a warn-by-default deprecation.

```rust
struct X;
struct Y;

impl ATraitWithGATs for X {
    type Assoc<'a, T> = &'a T
      where T: 'a;
}
impl ATraitWithGATs for Y {
    type Assoc<'a, T>
      where T: 'a
    = &'a T;
}
```

To use a GAT in a function, generics are specified on the associated type, as if it was a struct or enum. GATs can also be specified in trait bounds:

```rust
fn accepts_gat<'a, T>(t: &'a T) -> T::Assoc<'a, T>
  where for<'x> T: ATraitWithGATs<Assoc<'a, T> = &'a T> {
    ...
}
```

GATs can also appear in trait methods. However, depending on how they are used, they may confer where clauses on the associated type definition. More information can be found [here](rust-lang/rust#87479). Briefly, where clauses are required when those bounds can be proven in the methods that *construct* the GAT or other associated types that use the GAT in the trait. This allows impls to have maximum flexibility in the types defined for the associated type.

To take a relatively simple example:

```rust
trait Iterable {
    type Item<'a>;
    type Iterator<'a>: Iterator<Item = Self::Item<'a>>;

    fn iter<'x>(&'x self) -> Self::Iterator<'x>;
    //^ We know that `Self: 'a` for `Iterator<'a>`, so we require that bound on `Iterator`
    //  `Iterator` uses `Self::Item`, so we also require a `Self: 'a` on `Item` too
}
```

A couple well-explained examples are available in a previous [blog post](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html).

## What isn't stabilized/implemented

### Universal type/const quantification

Currently, you can write a bound like `X: for<'a> Trait<Assoc<'a> = &'a ()>`. However, you cannot currently write `for<T> X: Trait<Assoc<T> = T>` or `for<const N> X: Trait<Assoc<N> = [usize; N]>`.

Here is an example where this is needed:

```rust
trait Foo {}

trait Trait {
    type Assoc<F: Foo>;
}

trait Trait2: Sized {
    fn foo<F: Foo, T: Trait<Assoc<F> = F>>(_t: T);
}
```

In the above example, the *caller* must specify `F`, which is likely not what is desired.

### Object-safe GATs

Unlike non-generic associated types, traits with GATs are not currently object-safe. In other words the following are not allowed:

```rust
trait Trait {
    type Assoc<'a>;
}

fn foo(t: &dyn for<'a> Trait<Assoc<'a> = &'a ()>) {}
         //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed

let ty: Box<dyn for<'a> Trait<Assoc<'a> = &'a ()>>;
          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed
```

### Higher-kinded types

You cannot write currently (and there are no current plans to implement this):

```rust
struct Struct<'a> {}

fn foo(s: for<'a> Struct<'a>) {}
```

## Tests

There are many tests covering GATs that can be found in  `src/test/ui/generic-associated-types`. Here, I'll list (in alphanumeric order) tests highlight some important behavior or contain important patterns.

- `./parse/*`: Parsing of GATs in traits and impls, and the trait path with GATs
- `./collections-project-default.rs`: Interaction with associated type defaults
- `./collections.rs`: The `Collection` pattern
- `./const-generics-gat-in-trait-return-type-*.rs`: Const parameters
- `./constraint-assoc-type-suggestion.rs`: Emit correct syntax in suggestion
- `./cross-crate-bounds.rs`: Ensure we handles bounds across crates the same
- `./elided-in-expr-position.rs`: Disallow lifetime elision in return position
- `./gat-in-trait-path-undeclared-lifetime.rs`: Ensure we error on undeclared lifetime in trait path
- `./gat-in-trait-path.rs`: Base trait path case
- `./gat-trait-path-generic-type-arg.rs`: Don't allow shadowing of parameters
- `./gat-trait-path-parenthesised-args.rs`: Don't allow paranthesized args in trait path
- `./generic-associated-types-where.rs`: Ensure that we require where clauses from trait to be met on impl
- `./impl_bounds.rs`: Check that the bounds on GATs in an impl are checked
- `./issue-76826.rs`: `Windows` pattern
- `./issue-78113-lifetime-mismatch-dyn-trait-box.rs`: Implicit 'static diagnostics
- `./issue-84931.rs`: Ensure that we have a where clause on GAT to ensure trait parameter lives long enough
- `./issue-87258_a.rs`: Unconstrained opaque type with TAITs
- `./issue-87429-2.rs`: Ensure we can use bound vars in the bounds
- `./issue-87429-associated-type-default.rs`: Ensure bounds hold with associated type defaults, for both trait and impl
- `./issue-87429-specialization.rs`: Check that bounds hold under specialization
- `./issue-88595.rs`: Under the outlives lint, we require a bound for both trait and GAT lifetime when trait lifetime is used in function
- `./issue-90014.rs`: Lifetime bounds are checked with TAITs
- `./issue-91139.rs`: Under migrate mode, but not NLL, we don't capture implied bounds from HRTB lifetimes used in a function and GATs
- `./issue-91762.rs`: We used to too eagerly pick param env candidates when normalizing with GATs. We now require explicit parameters specified.
- `./issue-95305.rs`: Disallow lifetime elision in trait paths
- `./iterable.rs`: `Iterable` pattern
- `./method-unsatified-assoc-type-predicate.rs`: Print predicates with GATs correctly in method resolve error
- `./missing_lifetime_const.rs`: Ensure we must specify lifetime args (not elidable)
- `./missing-where-clause-on-trait.rs`: Ensure we don't allow stricter bounds on impl than trait
- `./parameter_number_and_kind_impl.rs`: Ensure paramters on GAT in impl match GAT in trait
- `./pointer_family.rs`: `PointerFamily` pattern
- `./projection-bound-cycle.rs`: Don't allow invalid cycles to prove bounds
- `./self-outlives-lint.rs`: Ensures that an e.g. `Self: 'a` is written on the traits GAT if that bound can be implied from the GAT usage in the trait
- `./shadowing.rs`: Don't allow lifetime shadowing in params
- `./streaming_iterator.rs`: `StreamingIterator`(`LendingIterator`) pattern
- `./trait-objects.rs`: Disallow trait objects for traits with GATs
- `./variance_constraints.rs`: Require that GAT substs be invariant

## Remaining bugs and open issues

A full list of remaining open issues can be found at: https://github.com/rust-lang/rust/labels/F-generic_associated_types

There are some `known-bug` tests in-tree at `src/test/ui/generic-associated-types/bugs`.

Here I'll categorize most of those that GAT bugs (or involve a pattern found more with GATs), but not those that include GATs but not a GAT issue in and of itself. (I also won't include issues directly for things listed elsewhere here.)

Using the concrete type of a GAT instead of the projection type can give errors, since lifetimes are chosen to be early-bound vs late-bound.
- #85533
- #87803

In certain cases, we can run into cycle or overflow errors. This is more generally a problem with associated types.
- #87755
- #87758

Bounds on an associatd type need to be proven by an impl, but where clauses need to be proven by the usage. This can lead to confusion when users write one when they mean the other.
- #87831
- #90573

We sometimes can't normalize closure signatures fully. Really an asociated types issue, but might happen a bit more frequently with GATs, since more obvious place for HRTB lifetimes.
- #88382

When calling a function, we assign types to parameters "too late", after we already try (and fail) to normalize projections. Another associated types issue that might pop up more with GATs.
- #88460
- #96230

We don't fully have implied bounds for lifetimes appearing in GAT trait paths, which can lead to unconstrained type errors.
- #88526

Suggestion for adding lifetime bounds can suggest unhelpful fixes (`T: 'a` instead of `Self: 'a`), but the next compiler error after making the suggested change is helpful.
- #90816
- #92096
- #95268

We can end up requiring that `for<'a> I: 'a` when we really want `for<'a where I: 'a> I: 'a`. This can leave unhelpful errors than effectively can't be satisfied unless `I: 'static`. Requires bigger changes and not only GATs.
- #91693

Unlike with non-generic associated types, we don't eagerly normalize with param env candidates. This is intended behavior (for now), to avoid accidentaly stabilizing picking arbitrary impls.
- #91762

Some Iterator adapter patterns (namely `filter`) require Polonius or unsafe to work.
- #92985

## Potential Future work

### Universal type/const quantification

No work has been done to implement this. There are also some questions around implied bounds.

###  Object-safe GATs

The intention is to make traits with GATs object-safe. There are some design work to be done around well-formedness rules and general implementation.

### GATified std lib types

It would be helpful to either introduce new std lib traits (like `LendingIterator`) or to modify existing ones (adding a `'a` generic to `Iterator::Item`). There also a number of other candidates, like `Index`/`IndexMut` and `Fn`/`FnMut`/`FnOnce`.

### Reduce the need for `for<'a>`

Seen [here](rust-lang/rfcs#1598 (comment)). One possible syntax:

```rust
trait Iterable {
    type Iter<'a>: Iterator<Item = Self::Item<'a>>;
}

fn foo<T>() where T: Iterable, T::Item<let 'a>: Display { } //note the `let`!
```

### Better implied bounds on higher-ranked things

Currently if we have a `type Item<'a> where self: 'a`, and a `for<'a> T: Iterator<Item<'a> = &'a ()`, this requires `for<'a> Self: 'a`. Really, we want `for<'a where T: 'a> ...`

There was some mentions of this all the back in the RFC thread [here](rust-lang/rfcs#1598 (comment)).

## Alternatives

### Make generics on associated type in bounds a binder

Imagine the bound `for<'a> T: Trait<Item<'a>= &'a ()>`. It might be that `for<'a>` is "too large" and it should instead be `T: Trait<for<'a> Item<'a>= &'a ()>`. Brought up in RFC thread [here](rust-lang/rfcs#1598 (comment)) and in a few places since.

Another related question: Is `for<'a>` the right syntax? Maybe `where<'a>`? Also originally found in RFC thread [here](rust-lang/rfcs#1598 (comment)).

### Stabilize lifetime GATs first

This has been brought up a few times. The idea is to only allow GATs with lifetime parameters to in initial stabilization. This was probably most useful prior to actual implementation. At this point, lifetimes, types, and consts are all implemented and work. It feels like an arbitrary split without strong reason.

## History

* On 2016-04-30, [RFC opened](rust-lang/rfcs#1598)
* On 2017-09-02, RFC merged and [tracking issue opened](rust-lang/rust#44265)
* On 2017-10-23, [Move Generics from MethodSig to TraitItem and ImplItem](rust-lang/rust#44766)
* On 2017-12-01, [Generic Associated Types Parsing & Name Resolution](rust-lang/rust#45904)
* On 2017-12-15, [https://github.com/rust-lang/rust/pull/46706](https://github.com/rust-lang/rust/pull/46706)
* On 2018-04-23, [Feature gate where clauses on associated types](rust-lang/rust#49368)
* On 2018-05-10, [Extend tests for RFC1598 (GAT)](rust-lang/rust#49423)
* On 2018-05-24, [Finish implementing GATs (Chalk)](rust-lang/chalk#134)
* On 2019-12-21, [Make GATs less ICE-prone](rust-lang/rust#67160)
* On 2020-02-13, [fix lifetime shadowing check in GATs](rust-lang/rust#68938)
* On 2020-06-20, [Projection bound validation](rust-lang/rust#72788)
* On 2020-10-06, [Separate projection bounds and predicates](rust-lang/rust#73905)
* On 2021-02-05, [Generic associated types in trait paths](rust-lang/rust#79554)
* On 2021-02-06, [Trait objects do not work with generic associated types](rust-lang/rust#81823)
* On 2021-04-28, [Make traits with GATs not object safe](rust-lang/rust#84622)
* On 2021-05-11, [Improve diagnostics for GATs](rust-lang/rust#82272)
* On 2021-07-16, [Make GATs no longer an incomplete feature](rust-lang/rust#84623)
* On 2021-07-16, [Replace associated item bound vars with placeholders when projecting](rust-lang/rust#86993)
* On 2021-07-26, [GATs: Decide whether to have defaults for `where Self: 'a`](rust-lang/rust#87479)
* On 2021-08-25, [Normalize projections under binders](rust-lang/rust#85499)
* On 2021-08-03, [The push for GATs stabilization](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html)
* On 2021-08-12, [Detect stricter constraints on gats where clauses in impls vs trait](rust-lang/rust#88336)
* On 2021-09-20, [Proposal: Change syntax of where clauses on type aliases](rust-lang/rust#89122)
* On 2021-11-06, [Implementation of GATs outlives lint](rust-lang/rust#89970)
* On 2021-12-29. [Parse and suggest moving where clauses after equals for type aliases](rust-lang/rust#92118)
* On 2022-01-15, [Ignore static lifetimes for GATs outlives lint](rust-lang/rust#92865)
* On 2022-02-08, [Don't constrain projection predicates with inference vars in GAT substs](rust-lang/rust#92917)
* On 2022-02-15, [Rework GAT where clause check](rust-lang/rust#93820)
* On 2022-02-19, [Only mark projection as ambiguous if GAT substs are constrained](rust-lang/rust#93892)
* On 2022-03-03, [Support GATs in Rustdoc](rust-lang/rust#94009)
* On 2022-03-06, [Change location of where clause on GATs](rust-lang/rust#90076)
* On 2022-05-04, [A shiny future with GATs blog post](https://jackh726.github.io/rust/2022/05/04/a-shiny-future-with-gats.html)
* On 2022-05-04, [Stabilization PR](rust-lang/rust#96709)
gwilymk referenced this issue in agbrs/agb 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://togithub.com/dtolnay/syn) | dependencies | major | `1`
-> `2` |

---

### Release Notes

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

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

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1422))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-   Documentation improvements

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

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1409))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/compare/1.0.108...1.0.109)

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.106)

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

-   Documentation improvements

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

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

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

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

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

-   Add `PathArguments::is_none()`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-   Add categories and keywords to crates.io metadata

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

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

-   Format example code with rustfmt

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

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

-   Update examples

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1183))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.94)

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

-   Resolve some unused_macro_rules warnings

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1171), thanks
[@&#8203;zakarumych](https://togithub.com/zakarumych))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.90)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.89)

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

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

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.85)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.84)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.83)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1109))
- Preserve attributes on let-else stmt: `#[attr] let pat = val else {
return }` ([#&#8203;1110](https://togithub.com/dtolnay/syn/issues/1110))

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

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

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

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1075),
[#&#8203;1077](https://togithub.com/dtolnay/syn/issues/1077),
[#&#8203;1078](https://togithub.com/dtolnay/syn/issues/1078),
[#&#8203;1079](https://togithub.com/dtolnay/syn/issues/1079),
[#&#8203;1080](https://togithub.com/dtolnay/syn/issues/1080),
[#&#8203;1081](https://togithub.com/dtolnay/syn/issues/1081))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1068))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/922), thanks
[@&#8203;Tamschi](https://togithub.com/Tamschi))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1042))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1027))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1023))
- Parse visibility on impl blocks
([#&#8203;1024](https://togithub.com/dtolnay/syn/issues/1024))
- Fix parsing a type parameter default on the first generic parameter of
an impl block
([#&#8203;1025](https://togithub.com/dtolnay/syn/issues/1025), thanks
[@&#8203;taiki-e](https://togithub.com/taiki-e))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1007),
[#&#8203;1008](https://togithub.com/dtolnay/syn/issues/1008),
[#&#8203;1009](https://togithub.com/dtolnay/syn/issues/1009),
[#&#8203;1010](https://togithub.com/dtolnay/syn/issues/1010),
[#&#8203;1011](https://togithub.com/dtolnay/syn/issues/1011),
[#&#8203;1012](https://togithub.com/dtolnay/syn/issues/1012),
[#&#8203;1013](https://togithub.com/dtolnay/syn/issues/1013),
[#&#8203;1014](https://togithub.com/dtolnay/syn/issues/1014),
[#&#8203;1015](https://togithub.com/dtolnay/syn/issues/1015))

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

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

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

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

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

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

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

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

- Parse equality constraints on generic associated types
([#&#8203;979](https://togithub.com/dtolnay/syn/issues/979))
- Parse default value exprs in const generic declarations
([#&#8203;980](https://togithub.com/dtolnay/syn/issues/980))
- Fix infinite loop parsing malformed type ascription expression in
non-`full` mode
([#&#8203;978](https://togithub.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://togithub.com/dtolnay/syn/issues/991),
[#&#8203;992](https://togithub.com/dtolnay/syn/issues/992),
[#&#8203;993](https://togithub.com/dtolnay/syn/issues/993),
[#&#8203;994](https://togithub.com/dtolnay/syn/issues/994),
[#&#8203;995](https://togithub.com/dtolnay/syn/issues/995),
[#&#8203;996](https://togithub.com/dtolnay/syn/issues/996),
[#&#8203;997](https://togithub.com/dtolnay/syn/issues/997),
[#&#8203;998](https://togithub.com/dtolnay/syn/issues/998),
[#&#8203;999](https://togithub.com/dtolnay/syn/issues/999))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/976))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/rust-lang/docs.rs/issues/1300)

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

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

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

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

[Compare
Source](https://togithub.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://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.59)

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/951))

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.55)

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/942))

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/920))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/925))

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

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

-   Rebuild for https://astexplorer.net

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

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

-   Documentation improvements

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/909))

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

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

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

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

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

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

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

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

-   Add Parse impl for syn::Signature

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/898),
[#&#8203;899](https://togithub.com/dtolnay/syn/issues/899),
[#&#8203;900](https://togithub.com/dtolnay/syn/issues/900))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/891), thanks
[@&#8203;taiki-e](https://togithub.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://togithub.com/dtolnay/syn/issues/895), thanks
[@&#8203;sameer](https://togithub.com/sameer))
- Enable using `parse_macro_input!` with a Parser function rather than
type having a Parse impl
([#&#8203;896](https://togithub.com/dtolnay/syn/issues/896), thanks
[@&#8203;sbrocket](https://togithub.com/sbrocket))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/893))

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

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

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

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

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

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

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

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

- Handle shebang in a way that matches rustc 1.46+
([#&#8203;876](https://togithub.com/dtolnay/syn/issues/876),
[https://github.com/rust-lang/rust/pull/71487](https://togithub.com/rust-lang/rust/pull/71487),
[https://github.com/rust-lang/rust/pull/73596](https://togithub.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://togithub.com/dtolnay/syn/issues/877))

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

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

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

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

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

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

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

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

-   Documentation improvements

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

[Compare
Source](https://togithub.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://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.32)

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.30)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/842))
- Handle nesting of None-delimited groups
([#&#8203;843](https://togithub.com/dtolnay/syn/issues/843), thanks
[@&#8203;Aaron1011](https://togithub.com/Aaron1011))

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

[Compare
Source](https://togithub.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://togithub.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://togithub.com/dtolnay/syn/issues/839))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/836))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/833))

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

[Compare
Source](https://togithub.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://togithub.com/rust-lang/rust/issues/72608),
[#&#8203;832](https://togithub.com/dtolnay/syn/issues/832))

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

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

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

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

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/799),
[#&#8203;800](https://togithub.com/dtolnay/syn/issues/800))

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

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

-   Documentation improvements

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/791))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/783))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/rust-lang/rust/issues/64490))
to require explicitly specified constness, `&raw mut` or `&raw const`

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.14)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.13)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/741))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/739))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.10)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.9)

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/issues/720),
[#&#8203;723](https://togithub.com/dtolnay/syn/issues/723), thanks
[@&#8203;mystor](https://togithub.com/mystor))
- Fix unexpected tokens being ignored when using Speculative::advance_to
([#&#8203;721](https://togithub.com/dtolnay/syn/issues/721),
[#&#8203;723](https://togithub.com/dtolnay/syn/issues/723), thanks
[@&#8203;mystor](https://togithub.com/mystor))

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

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

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

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

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

- Add a receiver getter to syn::Signature
([#&#8203;714](https://togithub.com/dtolnay/syn/issues/714), thanks
[@&#8203;mystor](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.6)

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

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

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

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.4)

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

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

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

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/issues/696), thanks
[@&#8203;infinity0](https://togithub.com/infinity0))

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

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

-   Documentation improvements

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

[Compare Source](https://togithub.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-->
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jul 11, 2023
…-loc, r=compiler-errors

Lint against misplaced where-clauses on associated types in traits

Extends the scope of the lint `deprecated_where_clause_location` (rust-lang#89122) from associated types in impls to associated types in any location (impl or trait). This is only relevant for `#![feature(associated_type_defaults)]`. Previously we didn't warn on the following code for example:

```rs
#![feature(associated_type_defaults)]
trait Trait { type Assoc where u32: Copy = (); }
```

Personally I would've preferred to emit a *hard* error here instead of a lint warning since the feature is unstable but unfortunately we are constrained by back compat as associated type defaults won't necessarily trigger the feature-gate error if they are inside of a macro call (since they use a post-expansion feature-gate due to historical reasons, see also rust-lang#66004).

I've renamed and moved related preexisting tests: 1. They test AST validation passes not the parser & thus shouldn't live in `parser/` (historical reasons?). 2. One test file was named after type aliases even though it tests assoc tys.

`@rustbot` label A-lint
compiler-errors added a commit to compiler-errors/rust that referenced this issue Aug 11, 2023
…ling-wcs, r=oli-obk

Unlock trailing where-clauses for lazy type aliases

Allows trailing where-clauses on lazy type aliases and forbids[^1] leading ones.
Completes rust-lang#89122 (see section *Top-level type aliases*).

`@rustbot` label F-lazy_type_alias
r? `@oli-obk`

[^1]: This is absolutely fine since lazy type aliases are only meant to be stabilized as part of a new edition.
yoav-lavi referenced this issue in grafbase/grafbase 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://togithub.com/dtolnay/syn) | dependencies | major | `1`
-> `2` |

---

### Release Notes

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

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

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

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

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1482))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/rust-lang/rust/issues/105723))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1474))

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

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

-   Documentation improvements

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1467), thanks
[@&#8203;danielhenrymantilla](https://togithub.com/danielhenrymantilla))

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/rust-lang/rust/issues/110680),
[#&#8203;1454](https://togithub.com/dtolnay/syn/issues/1454))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1444), thanks
[@&#8203;Fancyflame](https://togithub.com/Fancyflame))

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1431), thanks
[@&#8203;smoelius](https://togithub.com/smoelius))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/2.0.9)

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/2.0.8)

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1422))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-   Documentation improvements

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

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1409))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/compare/1.0.108...1.0.109)

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.106)

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

-   Documentation improvements

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

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

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

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

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

-   Add `PathArguments::is_none()`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-   Add categories and keywords to crates.io metadata

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

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

-   Format example code with rustfmt

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

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

-   Update examples

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1183))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.94)

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

-   Resolve some unused_macro_rules warnings

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1171), thanks
[@&#8203;zakarumych](https://togithub.com/zakarumych))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.90)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.89)

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

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

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.85)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.84)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.83)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1109))
- Preserve attributes on let-else stmt: `#[attr] let pat = val else {
return }` ([#&#8203;1110](https://togithub.com/dtolnay/syn/issues/1110))

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

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

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

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1075),
[#&#8203;1077](https://togithub.com/dtolnay/syn/issues/1077),
[#&#8203;1078](https://togithub.com/dtolnay/syn/issues/1078),
[#&#8203;1079](https://togithub.com/dtolnay/syn/issues/1079),
[#&#8203;1080](https://togithub.com/dtolnay/syn/issues/1080),
[#&#8203;1081](https://togithub.com/dtolnay/syn/issues/1081))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1068))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/922), thanks
[@&#8203;Tamschi](https://togithub.com/Tamschi))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1042))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1027))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1023))
- Parse visibility on impl blocks
([#&#8203;1024](https://togithub.com/dtolnay/syn/issues/1024))
- Fix parsing a type parameter default on the first generic parameter of
an impl block
([#&#8203;1025](https://togithub.com/dtolnay/syn/issues/1025), thanks
[@&#8203;taiki-e](https://togithub.com/taiki-e))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/1007),
[#&#8203;1008](https://togithub.com/dtolnay/syn/issues/1008),
[#&#8203;1009](https://togithub.com/dtolnay/syn/issues/1009),
[#&#8203;1010](https://togithub.com/dtolnay/syn/issues/1010),
[#&#8203;1011](https://togithub.com/dtolnay/syn/issues/1011),
[#&#8203;1012](https://togithub.com/dtolnay/syn/issues/1012),
[#&#8203;1013](https://togithub.com/dtolnay/syn/issues/1013),
[#&#8203;1014](https://togithub.com/dtolnay/syn/issues/1014),
[#&#8203;1015](https://togithub.com/dtolnay/syn/issues/1015))

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

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

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

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

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

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

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

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

- Parse equality constraints on generic associated types
([#&#8203;979](https://togithub.com/dtolnay/syn/issues/979))
- Parse default value exprs in const generic declarations
([#&#8203;980](https://togithub.com/dtolnay/syn/issues/980))
- Fix infinite loop parsing malformed type ascription expression in
non-`full` mode
([#&#8203;978](https://togithub.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://togithub.com/dtolnay/syn/issues/991),
[#&#8203;992](https://togithub.com/dtolnay/syn/issues/992),
[#&#8203;993](https://togithub.com/dtolnay/syn/issues/993),
[#&#8203;994](https://togithub.com/dtolnay/syn/issues/994),
[#&#8203;995](https://togithub.com/dtolnay/syn/issues/995),
[#&#8203;996](https://togithub.com/dtolnay/syn/issues/996),
[#&#8203;997](https://togithub.com/dtolnay/syn/issues/997),
[#&#8203;998](https://togithub.com/dtolnay/syn/issues/998),
[#&#8203;999](https://togithub.com/dtolnay/syn/issues/999))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/976))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/rust-lang/docs.rs/issues/1300)

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

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

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

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

[Compare
Source](https://togithub.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://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.59)

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/951))

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.55)

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/942))

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/920))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/925))

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

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

-   Rebuild for https://astexplorer.net

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

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

-   Documentation improvements

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/909))

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

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

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

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

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

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

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

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

-   Add Parse impl for syn::Signature

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/898),
[#&#8203;899](https://togithub.com/dtolnay/syn/issues/899),
[#&#8203;900](https://togithub.com/dtolnay/syn/issues/900))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/891), thanks
[@&#8203;taiki-e](https://togithub.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://togithub.com/dtolnay/syn/issues/895), thanks
[@&#8203;sameer](https://togithub.com/sameer))
- Enable using `parse_macro_input!` with a Parser function rather than
type having a Parse impl
([#&#8203;896](https://togithub.com/dtolnay/syn/issues/896), thanks
[@&#8203;sbrocket](https://togithub.com/sbrocket))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/893))

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

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

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

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

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

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

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

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

- Handle shebang in a way that matches rustc 1.46+
([#&#8203;876](https://togithub.com/dtolnay/syn/issues/876),
[https://github.com/rust-lang/rust/pull/71487](https://togithub.com/rust-lang/rust/pull/71487),
[https://github.com/rust-lang/rust/pull/73596](https://togithub.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://togithub.com/dtolnay/syn/issues/877))

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

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

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

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

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

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

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

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

-   Documentation improvements

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

[Compare
Source](https://togithub.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://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.32)

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.30)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/842))
- Handle nesting of None-delimited groups
([#&#8203;843](https://togithub.com/dtolnay/syn/issues/843), thanks
[@&#8203;Aaron1011](https://togithub.com/Aaron1011))

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

[Compare
Source](https://togithub.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://togithub.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://togithub.com/dtolnay/syn/issues/839))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/836))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/833))

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

[Compare
Source](https://togithub.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://togithub.com/rust-lang/rust/issues/72608),
[#&#8203;832](https://togithub.com/dtolnay/syn/issues/832))

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

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

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

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

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

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

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

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/799),
[#&#8203;800](https://togithub.com/dtolnay/syn/issues/800))

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

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

-   Documentation improvements

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/791))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/783))

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

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

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

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

[Compare
Source](https://togithub.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://togithub.com/rust-lang/rust/issues/64490))
to require explicitly specified constness, `&raw mut` or `&raw const`

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.14)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.13)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/741))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/issues/739))

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

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.10)

[Compare
Source](https://togithub.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://togithub.com/dtolnay/syn/releases/tag/1.0.9)

[Compare Source](https://togithub.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://togithub.com/dtolnay/syn/issues/720),
[#&#8203;723](https://togithub.com/dtolnay/syn/issues/723), thanks
[@&#8203;mystor](https://togithub.com/mystor))
- Fix unexpected tokens being ignored when using Speculative::advance_to
([#&#8203;721](https://togithub.com/dtolnay/syn/issues/721),
[#&#8203;723](https://togithub.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==-->
bors added a commit to rust-lang-ci/rust that referenced this issue Sep 27, 2023
…lebcartwright

Amend style guide section for formatting where clauses in type aliases

This PR has two parts:
1. Amend wording about breaking before or after the `=`, which is a style guide bugfix to align it with current rustfmt behavior.
2. Explain how to format trailing (rust-lang#89122) where clauses, which are preferred in both GATs (rust-lang#90076) and type aliases (rust-lang#114662).

r? `@joshtriplett`
nickjiang2378 pushed a commit to nickjiang2378/hydroflow that referenced this issue Jan 24, 2024
nickjiang2378 pushed a commit to nickjiang2378/hydroflow that referenced this issue Jan 25, 2024
RalfJung pushed a commit to RalfJung/rust-analyzer that referenced this issue Apr 20, 2024
Stabilize generic associated types

Closes #44265

r? `@nikomatsakis`

# ⚡ Status of the discussion ⚡

* [x] There have been several serious concerns raised, [summarized here](rust-lang/rust#96709 (comment)).
* [x] There has also been a [deep-dive comment](rust-lang/rust#96709 (comment)) explaining some of the "patterns of code" that are enabled by GATs, based on use-cases posted to this thread or on the tracking issue.
* [x] We have modeled some aspects of GATs in [a-mir-formality](https://github.com/nikomatsakis/a-mir-formality) to give better confidence in how they will be resolved in the future. [You can read a write-up here](https://github.com/rust-lang/types-team/blob/master/minutes/2022-07-08-implied-bounds-and-wf-checking.md).
* [x] The major points of the discussion have been [summarized on the GAT initiative repository](https://rust-lang.github.io/generic-associated-types-initiative/mvp.html).
* [x] [FCP has been proposed](rust-lang/rust#96709 (comment)) and we are awaiting final decisions and discussion amidst the relevant team members.

# Stabilization proposal

This PR proposes the stabilization of `#![feature(generic_associated_types)]`. While there a number of future additions to be made and bugs to be fixed (both discussed below), properly doing these will require significant language design and will ultimately likely be backwards-compatible. Given the overwhelming desire to have some form of generic associated types (GATs) available on stable and the stability of the "simple" uses, stabilizing the current subset of GAT features is almost certainly the correct next step.

Tracking issue: #44265
Initiative: https://rust-lang.github.io/generic-associated-types-initiative/
RFC: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
Version: 1.65 (2022-08-22 => beta, 2022-11-03 => stable).

## Motivation

There are a myriad of potential use cases for GATs. Stabilization unblocks probable future language features (e.g. async functions in traits), potential future standard library features (e.g. a `LendingIterator` or some form of `Iterator` with a lifetime generic), and a plethora of user use cases (some of which can be seen just by scrolling through the tracking issue and looking at all the issues linking to it).

There are a myriad of potential use cases for GATs. First, there are many users that have chosen to not use GATs primarily because they are not stable (some of which can be seen just by scrolling through the tracking issue and looking at all the issues linking to it). Second, while language feature desugaring isn't *blocked* on stabilization, it gives more confidence on using the feature. Likewise, library features like `LendingIterator` are not necessarily blocked on stabilization to be implemented unstably; however few, if any, public-facing APIs actually use unstable features.

This feature has a long history of design, discussion, and developement - the RFC was first introduced roughly 6 years ago. While there are still a number of features left to implement and bugs left to fix, it's clear that it's unlikely those will have backwards-incompatibility concerns. Additionally, the bugs that do exist do not strongly impede the most-common use cases.

## What is stabilized

The primary language feature stabilized here is the ability to have generics on associated types, as so. Additionally, where clauses on associated types will now be accepted, regardless if the associated type is generic or not.

```rust
trait ATraitWithGATs {
    type Assoc<'a, T> where T: 'a;
}

trait ATraitWithoutGATs<'a, T> {
    type Assoc where T: 'a;
}
```

When adding an impl for a trait with generic associated types, the generics for the associated type are copied as well. Note that where clauses are allowed both after the specified type and before the equals sign; however, the latter is a warn-by-default deprecation.

```rust
struct X;
struct Y;

impl ATraitWithGATs for X {
    type Assoc<'a, T> = &'a T
      where T: 'a;
}
impl ATraitWithGATs for Y {
    type Assoc<'a, T>
      where T: 'a
    = &'a T;
}
```

To use a GAT in a function, generics are specified on the associated type, as if it was a struct or enum. GATs can also be specified in trait bounds:

```rust
fn accepts_gat<'a, T>(t: &'a T) -> T::Assoc<'a, T>
  where for<'x> T: ATraitWithGATs<Assoc<'a, T> = &'a T> {
    ...
}
```

GATs can also appear in trait methods. However, depending on how they are used, they may confer where clauses on the associated type definition. More information can be found [here](rust-lang/rust#87479). Briefly, where clauses are required when those bounds can be proven in the methods that *construct* the GAT or other associated types that use the GAT in the trait. This allows impls to have maximum flexibility in the types defined for the associated type.

To take a relatively simple example:

```rust
trait Iterable {
    type Item<'a>;
    type Iterator<'a>: Iterator<Item = Self::Item<'a>>;

    fn iter<'x>(&'x self) -> Self::Iterator<'x>;
    //^ We know that `Self: 'a` for `Iterator<'a>`, so we require that bound on `Iterator`
    //  `Iterator` uses `Self::Item`, so we also require a `Self: 'a` on `Item` too
}
```

A couple well-explained examples are available in a previous [blog post](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html).

## What isn't stabilized/implemented

### Universal type/const quantification

Currently, you can write a bound like `X: for<'a> Trait<Assoc<'a> = &'a ()>`. However, you cannot currently write `for<T> X: Trait<Assoc<T> = T>` or `for<const N> X: Trait<Assoc<N> = [usize; N]>`.

Here is an example where this is needed:

```rust
trait Foo {}

trait Trait {
    type Assoc<F: Foo>;
}

trait Trait2: Sized {
    fn foo<F: Foo, T: Trait<Assoc<F> = F>>(_t: T);
}
```

In the above example, the *caller* must specify `F`, which is likely not what is desired.

### Object-safe GATs

Unlike non-generic associated types, traits with GATs are not currently object-safe. In other words the following are not allowed:

```rust
trait Trait {
    type Assoc<'a>;
}

fn foo(t: &dyn for<'a> Trait<Assoc<'a> = &'a ()>) {}
         //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed

let ty: Box<dyn for<'a> Trait<Assoc<'a> = &'a ()>>;
          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed
```

### Higher-kinded types

You cannot write currently (and there are no current plans to implement this):

```rust
struct Struct<'a> {}

fn foo(s: for<'a> Struct<'a>) {}
```

## Tests

There are many tests covering GATs that can be found in  `src/test/ui/generic-associated-types`. Here, I'll list (in alphanumeric order) tests highlight some important behavior or contain important patterns.

- `./parse/*`: Parsing of GATs in traits and impls, and the trait path with GATs
- `./collections-project-default.rs`: Interaction with associated type defaults
- `./collections.rs`: The `Collection` pattern
- `./const-generics-gat-in-trait-return-type-*.rs`: Const parameters
- `./constraint-assoc-type-suggestion.rs`: Emit correct syntax in suggestion
- `./cross-crate-bounds.rs`: Ensure we handles bounds across crates the same
- `./elided-in-expr-position.rs`: Disallow lifetime elision in return position
- `./gat-in-trait-path-undeclared-lifetime.rs`: Ensure we error on undeclared lifetime in trait path
- `./gat-in-trait-path.rs`: Base trait path case
- `./gat-trait-path-generic-type-arg.rs`: Don't allow shadowing of parameters
- `./gat-trait-path-parenthesised-args.rs`: Don't allow paranthesized args in trait path
- `./generic-associated-types-where.rs`: Ensure that we require where clauses from trait to be met on impl
- `./impl_bounds.rs`: Check that the bounds on GATs in an impl are checked
- `./issue-76826.rs`: `Windows` pattern
- `./issue-78113-lifetime-mismatch-dyn-trait-box.rs`: Implicit 'static diagnostics
- `./issue-84931.rs`: Ensure that we have a where clause on GAT to ensure trait parameter lives long enough
- `./issue-87258_a.rs`: Unconstrained opaque type with TAITs
- `./issue-87429-2.rs`: Ensure we can use bound vars in the bounds
- `./issue-87429-associated-type-default.rs`: Ensure bounds hold with associated type defaults, for both trait and impl
- `./issue-87429-specialization.rs`: Check that bounds hold under specialization
- `./issue-88595.rs`: Under the outlives lint, we require a bound for both trait and GAT lifetime when trait lifetime is used in function
- `./issue-90014.rs`: Lifetime bounds are checked with TAITs
- `./issue-91139.rs`: Under migrate mode, but not NLL, we don't capture implied bounds from HRTB lifetimes used in a function and GATs
- `./issue-91762.rs`: We used to too eagerly pick param env candidates when normalizing with GATs. We now require explicit parameters specified.
- `./issue-95305.rs`: Disallow lifetime elision in trait paths
- `./iterable.rs`: `Iterable` pattern
- `./method-unsatified-assoc-type-predicate.rs`: Print predicates with GATs correctly in method resolve error
- `./missing_lifetime_const.rs`: Ensure we must specify lifetime args (not elidable)
- `./missing-where-clause-on-trait.rs`: Ensure we don't allow stricter bounds on impl than trait
- `./parameter_number_and_kind_impl.rs`: Ensure paramters on GAT in impl match GAT in trait
- `./pointer_family.rs`: `PointerFamily` pattern
- `./projection-bound-cycle.rs`: Don't allow invalid cycles to prove bounds
- `./self-outlives-lint.rs`: Ensures that an e.g. `Self: 'a` is written on the traits GAT if that bound can be implied from the GAT usage in the trait
- `./shadowing.rs`: Don't allow lifetime shadowing in params
- `./streaming_iterator.rs`: `StreamingIterator`(`LendingIterator`) pattern
- `./trait-objects.rs`: Disallow trait objects for traits with GATs
- `./variance_constraints.rs`: Require that GAT substs be invariant

## Remaining bugs and open issues

A full list of remaining open issues can be found at: https://github.com/rust-lang/rust/labels/F-generic_associated_types

There are some `known-bug` tests in-tree at `src/test/ui/generic-associated-types/bugs`.

Here I'll categorize most of those that GAT bugs (or involve a pattern found more with GATs), but not those that include GATs but not a GAT issue in and of itself. (I also won't include issues directly for things listed elsewhere here.)

Using the concrete type of a GAT instead of the projection type can give errors, since lifetimes are chosen to be early-bound vs late-bound.
- #85533
- #87803

In certain cases, we can run into cycle or overflow errors. This is more generally a problem with associated types.
- #87755
- #87758

Bounds on an associatd type need to be proven by an impl, but where clauses need to be proven by the usage. This can lead to confusion when users write one when they mean the other.
- #87831
- #90573

We sometimes can't normalize closure signatures fully. Really an asociated types issue, but might happen a bit more frequently with GATs, since more obvious place for HRTB lifetimes.
- #88382

When calling a function, we assign types to parameters "too late", after we already try (and fail) to normalize projections. Another associated types issue that might pop up more with GATs.
- #88460
- #96230

We don't fully have implied bounds for lifetimes appearing in GAT trait paths, which can lead to unconstrained type errors.
- #88526

Suggestion for adding lifetime bounds can suggest unhelpful fixes (`T: 'a` instead of `Self: 'a`), but the next compiler error after making the suggested change is helpful.
- #90816
- #92096
- #95268

We can end up requiring that `for<'a> I: 'a` when we really want `for<'a where I: 'a> I: 'a`. This can leave unhelpful errors than effectively can't be satisfied unless `I: 'static`. Requires bigger changes and not only GATs.
- #91693

Unlike with non-generic associated types, we don't eagerly normalize with param env candidates. This is intended behavior (for now), to avoid accidentaly stabilizing picking arbitrary impls.
- #91762

Some Iterator adapter patterns (namely `filter`) require Polonius or unsafe to work.
- #92985

## Potential Future work

### Universal type/const quantification

No work has been done to implement this. There are also some questions around implied bounds.

###  Object-safe GATs

The intention is to make traits with GATs object-safe. There are some design work to be done around well-formedness rules and general implementation.

### GATified std lib types

It would be helpful to either introduce new std lib traits (like `LendingIterator`) or to modify existing ones (adding a `'a` generic to `Iterator::Item`). There also a number of other candidates, like `Index`/`IndexMut` and `Fn`/`FnMut`/`FnOnce`.

### Reduce the need for `for<'a>`

Seen [here](rust-lang/rfcs#1598 (comment)). One possible syntax:

```rust
trait Iterable {
    type Iter<'a>: Iterator<Item = Self::Item<'a>>;
}

fn foo<T>() where T: Iterable, T::Item<let 'a>: Display { } //note the `let`!
```

### Better implied bounds on higher-ranked things

Currently if we have a `type Item<'a> where self: 'a`, and a `for<'a> T: Iterator<Item<'a> = &'a ()`, this requires `for<'a> Self: 'a`. Really, we want `for<'a where T: 'a> ...`

There was some mentions of this all the back in the RFC thread [here](rust-lang/rfcs#1598 (comment)).

## Alternatives

### Make generics on associated type in bounds a binder

Imagine the bound `for<'a> T: Trait<Item<'a>= &'a ()>`. It might be that `for<'a>` is "too large" and it should instead be `T: Trait<for<'a> Item<'a>= &'a ()>`. Brought up in RFC thread [here](rust-lang/rfcs#1598 (comment)) and in a few places since.

Another related question: Is `for<'a>` the right syntax? Maybe `where<'a>`? Also originally found in RFC thread [here](rust-lang/rfcs#1598 (comment)).

### Stabilize lifetime GATs first

This has been brought up a few times. The idea is to only allow GATs with lifetime parameters to in initial stabilization. This was probably most useful prior to actual implementation. At this point, lifetimes, types, and consts are all implemented and work. It feels like an arbitrary split without strong reason.

## History

* On 2016-04-30, [RFC opened](rust-lang/rfcs#1598)
* On 2017-09-02, RFC merged and [tracking issue opened](rust-lang/rust#44265)
* On 2017-10-23, [Move Generics from MethodSig to TraitItem and ImplItem](rust-lang/rust#44766)
* On 2017-12-01, [Generic Associated Types Parsing & Name Resolution](rust-lang/rust#45904)
* On 2017-12-15, [https://github.com/rust-lang/rust/pull/46706](https://github.com/rust-lang/rust/pull/46706)
* On 2018-04-23, [Feature gate where clauses on associated types](rust-lang/rust#49368)
* On 2018-05-10, [Extend tests for RFC1598 (GAT)](rust-lang/rust#49423)
* On 2018-05-24, [Finish implementing GATs (Chalk)](rust-lang/chalk#134)
* On 2019-12-21, [Make GATs less ICE-prone](rust-lang/rust#67160)
* On 2020-02-13, [fix lifetime shadowing check in GATs](rust-lang/rust#68938)
* On 2020-06-20, [Projection bound validation](rust-lang/rust#72788)
* On 2020-10-06, [Separate projection bounds and predicates](rust-lang/rust#73905)
* On 2021-02-05, [Generic associated types in trait paths](rust-lang/rust#79554)
* On 2021-02-06, [Trait objects do not work with generic associated types](rust-lang/rust#81823)
* On 2021-04-28, [Make traits with GATs not object safe](rust-lang/rust#84622)
* On 2021-05-11, [Improve diagnostics for GATs](rust-lang/rust#82272)
* On 2021-07-16, [Make GATs no longer an incomplete feature](rust-lang/rust#84623)
* On 2021-07-16, [Replace associated item bound vars with placeholders when projecting](rust-lang/rust#86993)
* On 2021-07-26, [GATs: Decide whether to have defaults for `where Self: 'a`](rust-lang/rust#87479)
* On 2021-08-25, [Normalize projections under binders](rust-lang/rust#85499)
* On 2021-08-03, [The push for GATs stabilization](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html)
* On 2021-08-12, [Detect stricter constraints on gats where clauses in impls vs trait](rust-lang/rust#88336)
* On 2021-09-20, [Proposal: Change syntax of where clauses on type aliases](rust-lang/rust#89122)
* On 2021-11-06, [Implementation of GATs outlives lint](rust-lang/rust#89970)
* On 2021-12-29. [Parse and suggest moving where clauses after equals for type aliases](rust-lang/rust#92118)
* On 2022-01-15, [Ignore static lifetimes for GATs outlives lint](rust-lang/rust#92865)
* On 2022-02-08, [Don't constrain projection predicates with inference vars in GAT substs](rust-lang/rust#92917)
* On 2022-02-15, [Rework GAT where clause check](rust-lang/rust#93820)
* On 2022-02-19, [Only mark projection as ambiguous if GAT substs are constrained](rust-lang/rust#93892)
* On 2022-03-03, [Support GATs in Rustdoc](rust-lang/rust#94009)
* On 2022-03-06, [Change location of where clause on GATs](rust-lang/rust#90076)
* On 2022-05-04, [A shiny future with GATs blog post](https://jackh726.github.io/rust/2022/05/04/a-shiny-future-with-gats.html)
* On 2022-05-04, [Stabilization PR](rust-lang/rust#96709)
RalfJung pushed a commit to RalfJung/rust-analyzer that referenced this issue Apr 27, 2024
Stabilize generic associated types

Closes #44265

r? `@nikomatsakis`

# ⚡ Status of the discussion ⚡

* [x] There have been several serious concerns raised, [summarized here](rust-lang/rust#96709 (comment)).
* [x] There has also been a [deep-dive comment](rust-lang/rust#96709 (comment)) explaining some of the "patterns of code" that are enabled by GATs, based on use-cases posted to this thread or on the tracking issue.
* [x] We have modeled some aspects of GATs in [a-mir-formality](https://github.com/nikomatsakis/a-mir-formality) to give better confidence in how they will be resolved in the future. [You can read a write-up here](https://github.com/rust-lang/types-team/blob/master/minutes/2022-07-08-implied-bounds-and-wf-checking.md).
* [x] The major points of the discussion have been [summarized on the GAT initiative repository](https://rust-lang.github.io/generic-associated-types-initiative/mvp.html).
* [x] [FCP has been proposed](rust-lang/rust#96709 (comment)) and we are awaiting final decisions and discussion amidst the relevant team members.

# Stabilization proposal

This PR proposes the stabilization of `#![feature(generic_associated_types)]`. While there a number of future additions to be made and bugs to be fixed (both discussed below), properly doing these will require significant language design and will ultimately likely be backwards-compatible. Given the overwhelming desire to have some form of generic associated types (GATs) available on stable and the stability of the "simple" uses, stabilizing the current subset of GAT features is almost certainly the correct next step.

Tracking issue: #44265
Initiative: https://rust-lang.github.io/generic-associated-types-initiative/
RFC: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
Version: 1.65 (2022-08-22 => beta, 2022-11-03 => stable).

## Motivation

There are a myriad of potential use cases for GATs. Stabilization unblocks probable future language features (e.g. async functions in traits), potential future standard library features (e.g. a `LendingIterator` or some form of `Iterator` with a lifetime generic), and a plethora of user use cases (some of which can be seen just by scrolling through the tracking issue and looking at all the issues linking to it).

There are a myriad of potential use cases for GATs. First, there are many users that have chosen to not use GATs primarily because they are not stable (some of which can be seen just by scrolling through the tracking issue and looking at all the issues linking to it). Second, while language feature desugaring isn't *blocked* on stabilization, it gives more confidence on using the feature. Likewise, library features like `LendingIterator` are not necessarily blocked on stabilization to be implemented unstably; however few, if any, public-facing APIs actually use unstable features.

This feature has a long history of design, discussion, and developement - the RFC was first introduced roughly 6 years ago. While there are still a number of features left to implement and bugs left to fix, it's clear that it's unlikely those will have backwards-incompatibility concerns. Additionally, the bugs that do exist do not strongly impede the most-common use cases.

## What is stabilized

The primary language feature stabilized here is the ability to have generics on associated types, as so. Additionally, where clauses on associated types will now be accepted, regardless if the associated type is generic or not.

```rust
trait ATraitWithGATs {
    type Assoc<'a, T> where T: 'a;
}

trait ATraitWithoutGATs<'a, T> {
    type Assoc where T: 'a;
}
```

When adding an impl for a trait with generic associated types, the generics for the associated type are copied as well. Note that where clauses are allowed both after the specified type and before the equals sign; however, the latter is a warn-by-default deprecation.

```rust
struct X;
struct Y;

impl ATraitWithGATs for X {
    type Assoc<'a, T> = &'a T
      where T: 'a;
}
impl ATraitWithGATs for Y {
    type Assoc<'a, T>
      where T: 'a
    = &'a T;
}
```

To use a GAT in a function, generics are specified on the associated type, as if it was a struct or enum. GATs can also be specified in trait bounds:

```rust
fn accepts_gat<'a, T>(t: &'a T) -> T::Assoc<'a, T>
  where for<'x> T: ATraitWithGATs<Assoc<'a, T> = &'a T> {
    ...
}
```

GATs can also appear in trait methods. However, depending on how they are used, they may confer where clauses on the associated type definition. More information can be found [here](rust-lang/rust#87479). Briefly, where clauses are required when those bounds can be proven in the methods that *construct* the GAT or other associated types that use the GAT in the trait. This allows impls to have maximum flexibility in the types defined for the associated type.

To take a relatively simple example:

```rust
trait Iterable {
    type Item<'a>;
    type Iterator<'a>: Iterator<Item = Self::Item<'a>>;

    fn iter<'x>(&'x self) -> Self::Iterator<'x>;
    //^ We know that `Self: 'a` for `Iterator<'a>`, so we require that bound on `Iterator`
    //  `Iterator` uses `Self::Item`, so we also require a `Self: 'a` on `Item` too
}
```

A couple well-explained examples are available in a previous [blog post](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html).

## What isn't stabilized/implemented

### Universal type/const quantification

Currently, you can write a bound like `X: for<'a> Trait<Assoc<'a> = &'a ()>`. However, you cannot currently write `for<T> X: Trait<Assoc<T> = T>` or `for<const N> X: Trait<Assoc<N> = [usize; N]>`.

Here is an example where this is needed:

```rust
trait Foo {}

trait Trait {
    type Assoc<F: Foo>;
}

trait Trait2: Sized {
    fn foo<F: Foo, T: Trait<Assoc<F> = F>>(_t: T);
}
```

In the above example, the *caller* must specify `F`, which is likely not what is desired.

### Object-safe GATs

Unlike non-generic associated types, traits with GATs are not currently object-safe. In other words the following are not allowed:

```rust
trait Trait {
    type Assoc<'a>;
}

fn foo(t: &dyn for<'a> Trait<Assoc<'a> = &'a ()>) {}
         //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed

let ty: Box<dyn for<'a> Trait<Assoc<'a> = &'a ()>>;
          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed
```

### Higher-kinded types

You cannot write currently (and there are no current plans to implement this):

```rust
struct Struct<'a> {}

fn foo(s: for<'a> Struct<'a>) {}
```

## Tests

There are many tests covering GATs that can be found in  `src/test/ui/generic-associated-types`. Here, I'll list (in alphanumeric order) tests highlight some important behavior or contain important patterns.

- `./parse/*`: Parsing of GATs in traits and impls, and the trait path with GATs
- `./collections-project-default.rs`: Interaction with associated type defaults
- `./collections.rs`: The `Collection` pattern
- `./const-generics-gat-in-trait-return-type-*.rs`: Const parameters
- `./constraint-assoc-type-suggestion.rs`: Emit correct syntax in suggestion
- `./cross-crate-bounds.rs`: Ensure we handles bounds across crates the same
- `./elided-in-expr-position.rs`: Disallow lifetime elision in return position
- `./gat-in-trait-path-undeclared-lifetime.rs`: Ensure we error on undeclared lifetime in trait path
- `./gat-in-trait-path.rs`: Base trait path case
- `./gat-trait-path-generic-type-arg.rs`: Don't allow shadowing of parameters
- `./gat-trait-path-parenthesised-args.rs`: Don't allow paranthesized args in trait path
- `./generic-associated-types-where.rs`: Ensure that we require where clauses from trait to be met on impl
- `./impl_bounds.rs`: Check that the bounds on GATs in an impl are checked
- `./issue-76826.rs`: `Windows` pattern
- `./issue-78113-lifetime-mismatch-dyn-trait-box.rs`: Implicit 'static diagnostics
- `./issue-84931.rs`: Ensure that we have a where clause on GAT to ensure trait parameter lives long enough
- `./issue-87258_a.rs`: Unconstrained opaque type with TAITs
- `./issue-87429-2.rs`: Ensure we can use bound vars in the bounds
- `./issue-87429-associated-type-default.rs`: Ensure bounds hold with associated type defaults, for both trait and impl
- `./issue-87429-specialization.rs`: Check that bounds hold under specialization
- `./issue-88595.rs`: Under the outlives lint, we require a bound for both trait and GAT lifetime when trait lifetime is used in function
- `./issue-90014.rs`: Lifetime bounds are checked with TAITs
- `./issue-91139.rs`: Under migrate mode, but not NLL, we don't capture implied bounds from HRTB lifetimes used in a function and GATs
- `./issue-91762.rs`: We used to too eagerly pick param env candidates when normalizing with GATs. We now require explicit parameters specified.
- `./issue-95305.rs`: Disallow lifetime elision in trait paths
- `./iterable.rs`: `Iterable` pattern
- `./method-unsatified-assoc-type-predicate.rs`: Print predicates with GATs correctly in method resolve error
- `./missing_lifetime_const.rs`: Ensure we must specify lifetime args (not elidable)
- `./missing-where-clause-on-trait.rs`: Ensure we don't allow stricter bounds on impl than trait
- `./parameter_number_and_kind_impl.rs`: Ensure paramters on GAT in impl match GAT in trait
- `./pointer_family.rs`: `PointerFamily` pattern
- `./projection-bound-cycle.rs`: Don't allow invalid cycles to prove bounds
- `./self-outlives-lint.rs`: Ensures that an e.g. `Self: 'a` is written on the traits GAT if that bound can be implied from the GAT usage in the trait
- `./shadowing.rs`: Don't allow lifetime shadowing in params
- `./streaming_iterator.rs`: `StreamingIterator`(`LendingIterator`) pattern
- `./trait-objects.rs`: Disallow trait objects for traits with GATs
- `./variance_constraints.rs`: Require that GAT substs be invariant

## Remaining bugs and open issues

A full list of remaining open issues can be found at: https://github.com/rust-lang/rust/labels/F-generic_associated_types

There are some `known-bug` tests in-tree at `src/test/ui/generic-associated-types/bugs`.

Here I'll categorize most of those that GAT bugs (or involve a pattern found more with GATs), but not those that include GATs but not a GAT issue in and of itself. (I also won't include issues directly for things listed elsewhere here.)

Using the concrete type of a GAT instead of the projection type can give errors, since lifetimes are chosen to be early-bound vs late-bound.
- #85533
- #87803

In certain cases, we can run into cycle or overflow errors. This is more generally a problem with associated types.
- #87755
- #87758

Bounds on an associatd type need to be proven by an impl, but where clauses need to be proven by the usage. This can lead to confusion when users write one when they mean the other.
- #87831
- #90573

We sometimes can't normalize closure signatures fully. Really an asociated types issue, but might happen a bit more frequently with GATs, since more obvious place for HRTB lifetimes.
- #88382

When calling a function, we assign types to parameters "too late", after we already try (and fail) to normalize projections. Another associated types issue that might pop up more with GATs.
- #88460
- #96230

We don't fully have implied bounds for lifetimes appearing in GAT trait paths, which can lead to unconstrained type errors.
- #88526

Suggestion for adding lifetime bounds can suggest unhelpful fixes (`T: 'a` instead of `Self: 'a`), but the next compiler error after making the suggested change is helpful.
- #90816
- #92096
- #95268

We can end up requiring that `for<'a> I: 'a` when we really want `for<'a where I: 'a> I: 'a`. This can leave unhelpful errors than effectively can't be satisfied unless `I: 'static`. Requires bigger changes and not only GATs.
- #91693

Unlike with non-generic associated types, we don't eagerly normalize with param env candidates. This is intended behavior (for now), to avoid accidentaly stabilizing picking arbitrary impls.
- #91762

Some Iterator adapter patterns (namely `filter`) require Polonius or unsafe to work.
- #92985

## Potential Future work

### Universal type/const quantification

No work has been done to implement this. There are also some questions around implied bounds.

###  Object-safe GATs

The intention is to make traits with GATs object-safe. There are some design work to be done around well-formedness rules and general implementation.

### GATified std lib types

It would be helpful to either introduce new std lib traits (like `LendingIterator`) or to modify existing ones (adding a `'a` generic to `Iterator::Item`). There also a number of other candidates, like `Index`/`IndexMut` and `Fn`/`FnMut`/`FnOnce`.

### Reduce the need for `for<'a>`

Seen [here](rust-lang/rfcs#1598 (comment)). One possible syntax:

```rust
trait Iterable {
    type Iter<'a>: Iterator<Item = Self::Item<'a>>;
}

fn foo<T>() where T: Iterable, T::Item<let 'a>: Display { } //note the `let`!
```

### Better implied bounds on higher-ranked things

Currently if we have a `type Item<'a> where self: 'a`, and a `for<'a> T: Iterator<Item<'a> = &'a ()`, this requires `for<'a> Self: 'a`. Really, we want `for<'a where T: 'a> ...`

There was some mentions of this all the back in the RFC thread [here](rust-lang/rfcs#1598 (comment)).

## Alternatives

### Make generics on associated type in bounds a binder

Imagine the bound `for<'a> T: Trait<Item<'a>= &'a ()>`. It might be that `for<'a>` is "too large" and it should instead be `T: Trait<for<'a> Item<'a>= &'a ()>`. Brought up in RFC thread [here](rust-lang/rfcs#1598 (comment)) and in a few places since.

Another related question: Is `for<'a>` the right syntax? Maybe `where<'a>`? Also originally found in RFC thread [here](rust-lang/rfcs#1598 (comment)).

### Stabilize lifetime GATs first

This has been brought up a few times. The idea is to only allow GATs with lifetime parameters to in initial stabilization. This was probably most useful prior to actual implementation. At this point, lifetimes, types, and consts are all implemented and work. It feels like an arbitrary split without strong reason.

## History

* On 2016-04-30, [RFC opened](rust-lang/rfcs#1598)
* On 2017-09-02, RFC merged and [tracking issue opened](rust-lang/rust#44265)
* On 2017-10-23, [Move Generics from MethodSig to TraitItem and ImplItem](rust-lang/rust#44766)
* On 2017-12-01, [Generic Associated Types Parsing & Name Resolution](rust-lang/rust#45904)
* On 2017-12-15, [https://github.com/rust-lang/rust/pull/46706](https://github.com/rust-lang/rust/pull/46706)
* On 2018-04-23, [Feature gate where clauses on associated types](rust-lang/rust#49368)
* On 2018-05-10, [Extend tests for RFC1598 (GAT)](rust-lang/rust#49423)
* On 2018-05-24, [Finish implementing GATs (Chalk)](rust-lang/chalk#134)
* On 2019-12-21, [Make GATs less ICE-prone](rust-lang/rust#67160)
* On 2020-02-13, [fix lifetime shadowing check in GATs](rust-lang/rust#68938)
* On 2020-06-20, [Projection bound validation](rust-lang/rust#72788)
* On 2020-10-06, [Separate projection bounds and predicates](rust-lang/rust#73905)
* On 2021-02-05, [Generic associated types in trait paths](rust-lang/rust#79554)
* On 2021-02-06, [Trait objects do not work with generic associated types](rust-lang/rust#81823)
* On 2021-04-28, [Make traits with GATs not object safe](rust-lang/rust#84622)
* On 2021-05-11, [Improve diagnostics for GATs](rust-lang/rust#82272)
* On 2021-07-16, [Make GATs no longer an incomplete feature](rust-lang/rust#84623)
* On 2021-07-16, [Replace associated item bound vars with placeholders when projecting](rust-lang/rust#86993)
* On 2021-07-26, [GATs: Decide whether to have defaults for `where Self: 'a`](rust-lang/rust#87479)
* On 2021-08-25, [Normalize projections under binders](rust-lang/rust#85499)
* On 2021-08-03, [The push for GATs stabilization](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html)
* On 2021-08-12, [Detect stricter constraints on gats where clauses in impls vs trait](rust-lang/rust#88336)
* On 2021-09-20, [Proposal: Change syntax of where clauses on type aliases](rust-lang/rust#89122)
* On 2021-11-06, [Implementation of GATs outlives lint](rust-lang/rust#89970)
* On 2021-12-29. [Parse and suggest moving where clauses after equals for type aliases](rust-lang/rust#92118)
* On 2022-01-15, [Ignore static lifetimes for GATs outlives lint](rust-lang/rust#92865)
* On 2022-02-08, [Don't constrain projection predicates with inference vars in GAT substs](rust-lang/rust#92917)
* On 2022-02-15, [Rework GAT where clause check](rust-lang/rust#93820)
* On 2022-02-19, [Only mark projection as ambiguous if GAT substs are constrained](rust-lang/rust#93892)
* On 2022-03-03, [Support GATs in Rustdoc](rust-lang/rust#94009)
* On 2022-03-06, [Change location of where clause on GATs](rust-lang/rust#90076)
* On 2022-05-04, [A shiny future with GATs blog post](https://jackh726.github.io/rust/2022/05/04/a-shiny-future-with-gats.html)
* On 2022-05-04, [Stabilization PR](rust-lang/rust#96709)
YoungHaKim7 added a commit to YoungHaKim7/Async_Rust_Training that referenced this issue Jun 8, 2024
@fmease fmease added the A-GATs Area: Generic associated types (GATs) label Nov 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-GATs Area: Generic associated types (GATs) F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs GATs-blocking Issues using the `generic_associated_types` feature that block stabilization GATs-triaged Issues using the `generic_associated_types` feature that have been triaged 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.