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

Make associated type bounds in supertrait position implied #112629

Merged
merged 2 commits into from
Jun 29, 2023

Conversation

compiler-errors
Copy link
Member

trait A: B<Assoc: C> {} should be able to imply both Self: B and <Self as B>::Assoc: C. Adjust the way that we collect implied predicates to do so.

Fixes #112573
Fixes #112568

@rustbot
Copy link
Collaborator

rustbot commented Jun 14, 2023

r? @spastorino

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 14, 2023
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@jackh726
Copy link
Member

I took a look at this briefly at one point. Trying to remember why trait Trait: Super<Assoc = Bound> {} is fine but trait Trait: Super<Assoc: Bound> {} isn't.

@compiler-errors
Copy link
Member Author

(had to move some code around in the last commit, since astconv was hitting the size limit for a single file)

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Jun 18, 2023

☔ The latest upstream changes (presumably #112755) made this pull request unmergeable. Please resolve the merge conflicts.

@spastorino
Copy link
Member

Looks good to me but given that @jackh726 reviewed it and left comments already, I'd give it up to him.

r? @jackh726

@rustbot rustbot assigned jackh726 and unassigned spastorino Jun 19, 2023
@bors
Copy link
Contributor

bors commented Jun 21, 2023

☔ The latest upstream changes (presumably #112877) made this pull request unmergeable. Please resolve the merge conflicts.

@bors
Copy link
Contributor

bors commented Jun 27, 2023

☔ The latest upstream changes (presumably #112938) made this pull request unmergeable. Please resolve the merge conflicts.

@jackh726
Copy link
Member

@bors r+ rollup=never

@bors
Copy link
Contributor

bors commented Jun 28, 2023

📌 Commit de0e7d3 has been approved by jackh726

It is now in the queue for this repository.

@bors bors removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 28, 2023
@bors bors added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jun 28, 2023
@bors
Copy link
Contributor

bors commented Jun 28, 2023

⌛ Testing commit de0e7d3 with merge 75726ca...

@bors
Copy link
Contributor

bors commented Jun 29, 2023

☀️ Test successful - checks-actions
Approved by: jackh726
Pushing 75726ca to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 29, 2023
@bors bors merged commit 75726ca into rust-lang:master Jun 29, 2023
@rustbot rustbot added this to the 1.72.0 milestone Jun 29, 2023
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (75726ca): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
1.7% [0.4%, 4.9%] 5
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.7% [-1.0%, -0.4%] 2
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 1.0% [-1.0%, 4.9%] 7

Cycles

This benchmark run did not return any relevant results for this metric.

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 661.172s -> 659.556s (-0.24%)

@compiler-errors compiler-errors deleted the atb-imply branch August 11, 2023 19:55
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Mar 18, 2024
…li-obk

Stabilize associated type bounds (RFC 2289)

This PR stabilizes associated type bounds, which were laid out in [RFC 2289]. This gives us a shorthand to express nested type bounds that would otherwise need to be expressed with nested `impl Trait` or broken into several `where` clauses.

### What are we stabilizing?

We're stabilizing the associated item bounds syntax, which allows us to put bounds in associated type position within other bounds, i.e. `T: Trait<Assoc: Bounds...>`. See [RFC 2289] for motivation.

In all position, the associated type bound syntax expands into a set of two (or more) bounds, and never anything else (see "How does this differ[...]" section for more info).

Associated type bounds are stabilized in four positions:
* **`where` clauses (and APIT)** - This is equivalent to breaking up the bound into two (or more) `where` clauses. For example, `where T: Trait<Assoc: Bound>` is equivalent to `where T: Trait, <T as Trait>::Assoc: Bound`.
* **Supertraits** - Similar to above, `trait CopyIterator: Iterator<Item: Copy> {}`. This is almost equivalent to breaking up the bound into two (or more) `where` clauses; however, the bound on the associated item is implied whenever the trait is used. See rust-lang#112573/rust-lang#112629.
* **Associated type item bounds** - This allows constraining the *nested* rigid projections that are associated with a trait's associated types. e.g. `trait Trait { type Assoc: Trait2<Assoc2: Copy>; }`.
* **opaque item bounds (RPIT, TAIT)** - This allows constraining associated types that are associated with the opaque without having to *name* the opaque. For example, `impl Iterator<Item: Copy>` defines an iterator whose item is `Copy` without having to actually name that item bound.

The latter three are not expressible in surface Rust (though for associated type item bounds, this will change in rust-lang#120752, which I don't believe should block this PR), so this does represent a slight expansion of what can be expressed in trait bounds.

### How does this differ from the RFC?

Compared to the RFC, the current implementation *always* desugars associated type bounds to sets of `ty::Clause`s internally. Specifically, it does *not* introduce a position-dependent desugaring as laid out in [RFC 2289], and in particular:
* It does *not* desugar to anonymous associated items in associated type item bounds.
* It does *not* desugar to nested RPITs in RPIT bounds, nor nested TAITs in TAIT bounds.

This position-dependent desugaring laid out in the RFC existed simply to side-step limitations of the trait solver, which have mostly been fixed in rust-lang#120584. The desugaring laid out in the RFC also added unnecessary complication to the design of the feature, and introduces its own limitations to, for example:
* Conditionally lowering to nested `impl Trait` in certain positions such as RPIT and TAIT means that we inherit the limitations of RPIT/TAIT, namely lack of support for higher-ranked opaque inference. See this code example: rust-lang#120752 (comment).
* Introducing anonymous associated types makes traits no longer object safe, since anonymous associated types are not nameable, and all associated types must be named in `dyn` types.

This last point motivates why this PR is *not* stabilizing support for associated type bounds in `dyn` types, e.g, `dyn Assoc<Item: Bound>`. Why? Because `dyn` types need to have *concrete* types for all associated items, this would necessitate a distinct lowering for associated type bounds, which seems both complicated and unnecessary compared to just requiring the user to write `impl Trait` themselves. See rust-lang#120719.

### Implementation history:

Limited to the significant behavioral changes and fixes and relevant PRs, ping me if I left something out--
* rust-lang#57428
* rust-lang#108063
* rust-lang#110512
* rust-lang#112629
* rust-lang#120719
* rust-lang#120584

Closes rust-lang#52662

[RFC 2289]: https://rust-lang.github.io/rfcs/2289-associated-type-bounds.html
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 19, 2024
…-obk

Stabilize associated type bounds (RFC 2289)

This PR stabilizes associated type bounds, which were laid out in [RFC 2289]. This gives us a shorthand to express nested type bounds that would otherwise need to be expressed with nested `impl Trait` or broken into several `where` clauses.

### What are we stabilizing?

We're stabilizing the associated item bounds syntax, which allows us to put bounds in associated type position within other bounds, i.e. `T: Trait<Assoc: Bounds...>`. See [RFC 2289] for motivation.

In all position, the associated type bound syntax expands into a set of two (or more) bounds, and never anything else (see "How does this differ[...]" section for more info).

Associated type bounds are stabilized in four positions:
* **`where` clauses (and APIT)** - This is equivalent to breaking up the bound into two (or more) `where` clauses. For example, `where T: Trait<Assoc: Bound>` is equivalent to `where T: Trait, <T as Trait>::Assoc: Bound`.
* **Supertraits** - Similar to above, `trait CopyIterator: Iterator<Item: Copy> {}`. This is almost equivalent to breaking up the bound into two (or more) `where` clauses; however, the bound on the associated item is implied whenever the trait is used. See rust-lang#112573/rust-lang#112629.
* **Associated type item bounds** - This allows constraining the *nested* rigid projections that are associated with a trait's associated types. e.g. `trait Trait { type Assoc: Trait2<Assoc2: Copy>; }`.
* **opaque item bounds (RPIT, TAIT)** - This allows constraining associated types that are associated with the opaque without having to *name* the opaque. For example, `impl Iterator<Item: Copy>` defines an iterator whose item is `Copy` without having to actually name that item bound.

The latter three are not expressible in surface Rust (though for associated type item bounds, this will change in rust-lang#120752, which I don't believe should block this PR), so this does represent a slight expansion of what can be expressed in trait bounds.

### How does this differ from the RFC?

Compared to the RFC, the current implementation *always* desugars associated type bounds to sets of `ty::Clause`s internally. Specifically, it does *not* introduce a position-dependent desugaring as laid out in [RFC 2289], and in particular:
* It does *not* desugar to anonymous associated items in associated type item bounds.
* It does *not* desugar to nested RPITs in RPIT bounds, nor nested TAITs in TAIT bounds.

This position-dependent desugaring laid out in the RFC existed simply to side-step limitations of the trait solver, which have mostly been fixed in rust-lang#120584. The desugaring laid out in the RFC also added unnecessary complication to the design of the feature, and introduces its own limitations to, for example:
* Conditionally lowering to nested `impl Trait` in certain positions such as RPIT and TAIT means that we inherit the limitations of RPIT/TAIT, namely lack of support for higher-ranked opaque inference. See this code example: rust-lang#120752 (comment).
* Introducing anonymous associated types makes traits no longer object safe, since anonymous associated types are not nameable, and all associated types must be named in `dyn` types.

This last point motivates why this PR is *not* stabilizing support for associated type bounds in `dyn` types, e.g, `dyn Assoc<Item: Bound>`. Why? Because `dyn` types need to have *concrete* types for all associated items, this would necessitate a distinct lowering for associated type bounds, which seems both complicated and unnecessary compared to just requiring the user to write `impl Trait` themselves. See rust-lang#120719.

### Implementation history:

Limited to the significant behavioral changes and fixes and relevant PRs, ping me if I left something out--
* rust-lang#57428
* rust-lang#108063
* rust-lang#110512
* rust-lang#112629
* rust-lang#120719
* rust-lang#120584

Closes rust-lang#52662

[RFC 2289]: https://rust-lang.github.io/rfcs/2289-associated-type-bounds.html
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 22, 2024
…cates-always, r=<try>

Encode implied predicates for traits

In rust-lang#112629, we decided to make associated type bounds in the "supertrait" AST position *implied* even though they're not supertraits themselves.

This means that the `super_predicates` and `implied_predicates` queries now differ for regular traits. The assumption that they didn't differ was hard-coded in rust-lang#107614, so in cross-crate positions this means that we forget the implied predicates from associated type bounds.

This isn't unsound, just kind of annoying. This should be backported since associated type bounds are slated to stabilize for 1.78 -- either that, or associated type bounds can be reverted on beta and re-shipped in 1.79 with this patch.

Fixes rust-lang#122859
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 24, 2024
…cates-always, r=oli-obk

Encode implied predicates for traits

In rust-lang#112629, we decided to make associated type bounds in the "supertrait" AST position *implied* even though they're not supertraits themselves.

This means that the `super_predicates` and `implied_predicates` queries now differ for regular traits. The assumption that they didn't differ was hard-coded in rust-lang#107614, so in cross-crate positions this means that we forget the implied predicates from associated type bounds.

This isn't unsound, just kind of annoying. This should be backported since associated type bounds are slated to stabilize for 1.78 -- either that, or associated type bounds can be reverted on beta and re-shipped in 1.79 with this patch.

Fixes rust-lang#122859
RenjiSann pushed a commit to RenjiSann/rust that referenced this pull request Mar 25, 2024
…cates-always, r=oli-obk

Encode implied predicates for traits

In rust-lang#112629, we decided to make associated type bounds in the "supertrait" AST position *implied* even though they're not supertraits themselves.

This means that the `super_predicates` and `implied_predicates` queries now differ for regular traits. The assumption that they didn't differ was hard-coded in rust-lang#107614, so in cross-crate positions this means that we forget the implied predicates from associated type bounds.

This isn't unsound, just kind of annoying. This should be backported since associated type bounds are slated to stabilize for 1.78 -- either that, or associated type bounds can be reverted on beta and re-shipped in 1.79 with this patch.

Fixes rust-lang#122859
GuillaumeGomez pushed a commit to GuillaumeGomez/rust that referenced this pull request Jul 10, 2024
…-obk

Stabilize associated type bounds (RFC 2289)

This PR stabilizes associated type bounds, which were laid out in [RFC 2289]. This gives us a shorthand to express nested type bounds that would otherwise need to be expressed with nested `impl Trait` or broken into several `where` clauses.

### What are we stabilizing?

We're stabilizing the associated item bounds syntax, which allows us to put bounds in associated type position within other bounds, i.e. `T: Trait<Assoc: Bounds...>`. See [RFC 2289] for motivation.

In all position, the associated type bound syntax expands into a set of two (or more) bounds, and never anything else (see "How does this differ[...]" section for more info).

Associated type bounds are stabilized in four positions:
* **`where` clauses (and APIT)** - This is equivalent to breaking up the bound into two (or more) `where` clauses. For example, `where T: Trait<Assoc: Bound>` is equivalent to `where T: Trait, <T as Trait>::Assoc: Bound`.
* **Supertraits** - Similar to above, `trait CopyIterator: Iterator<Item: Copy> {}`. This is almost equivalent to breaking up the bound into two (or more) `where` clauses; however, the bound on the associated item is implied whenever the trait is used. See rust-lang#112573/rust-lang#112629.
* **Associated type item bounds** - This allows constraining the *nested* rigid projections that are associated with a trait's associated types. e.g. `trait Trait { type Assoc: Trait2<Assoc2: Copy>; }`.
* **opaque item bounds (RPIT, TAIT)** - This allows constraining associated types that are associated with the opaque without having to *name* the opaque. For example, `impl Iterator<Item: Copy>` defines an iterator whose item is `Copy` without having to actually name that item bound.

The latter three are not expressible in surface Rust (though for associated type item bounds, this will change in rust-lang#120752, which I don't believe should block this PR), so this does represent a slight expansion of what can be expressed in trait bounds.

### How does this differ from the RFC?

Compared to the RFC, the current implementation *always* desugars associated type bounds to sets of `ty::Clause`s internally. Specifically, it does *not* introduce a position-dependent desugaring as laid out in [RFC 2289], and in particular:
* It does *not* desugar to anonymous associated items in associated type item bounds.
* It does *not* desugar to nested RPITs in RPIT bounds, nor nested TAITs in TAIT bounds.

This position-dependent desugaring laid out in the RFC existed simply to side-step limitations of the trait solver, which have mostly been fixed in rust-lang#120584. The desugaring laid out in the RFC also added unnecessary complication to the design of the feature, and introduces its own limitations to, for example:
* Conditionally lowering to nested `impl Trait` in certain positions such as RPIT and TAIT means that we inherit the limitations of RPIT/TAIT, namely lack of support for higher-ranked opaque inference. See this code example: rust-lang#120752 (comment).
* Introducing anonymous associated types makes traits no longer object safe, since anonymous associated types are not nameable, and all associated types must be named in `dyn` types.

This last point motivates why this PR is *not* stabilizing support for associated type bounds in `dyn` types, e.g, `dyn Assoc<Item: Bound>`. Why? Because `dyn` types need to have *concrete* types for all associated items, this would necessitate a distinct lowering for associated type bounds, which seems both complicated and unnecessary compared to just requiring the user to write `impl Trait` themselves. See rust-lang#120719.

### Implementation history:

Limited to the significant behavioral changes and fixes and relevant PRs, ping me if I left something out--
* rust-lang#57428
* rust-lang#108063
* rust-lang#110512
* rust-lang#112629
* rust-lang#120719
* rust-lang#120584

Closes rust-lang#52662

[RFC 2289]: https://rust-lang.github.io/rfcs/2289-associated-type-bounds.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
7 participants