diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2021-05-27 03:02:07 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-27 03:02:07 +0200 |
| commit | 3530a7895acd495983a9cd6d7c5b2a9773337366 (patch) | |
| tree | 28b03945a3e7a0872d5af1673e24bb671b7c0d44 /compiler/rustc_codegen_llvm/src/llvm_util.rs | |
| parent | f2810d5fa0fb5930a02e2bb4827b037292a83cea (diff) | |
| parent | b3054d2c2180631f9574ee3c6c3d138ce5e25798 (diff) | |
| download | rust-3530a7895acd495983a9cd6d7c5b2a9773337366.tar.gz rust-3530a7895acd495983a9cd6d7c5b2a9773337366.zip | |
Rollup merge of #84701 - nikomatsakis:stabilize-member-constraints-61997, r=jackh726
stabilize member constraints
Stabilizes the use of "member constraints" in solving `impl Trait` bindings. This is a step towards stabilizing a "MVP" of "named impl Trait".
# Member constraint stabilization report
| Info | |
| --- | --- |
| Tracking issue | [rust-lang/rust#61997](https://github.com/rust-lang/rust/issues/61997) |
| Implementation history | [rust-lang/rust#61775] |
| rustc-dev-guide coverage | [link](https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/member_constraints.html) |
| Complications | [rust-lang/rust#61773] |
[rust-lang/rust#61775]: https://github.com/rust-lang/rust/pull/61775
[rust-lang/rust#61773]: https://github.com/rust-lang/rust/issues/61773
## Background
Member constraints are an extension to our region solver that was introduced to make async fn region solving tractable. There are used in situations like the following:
```rust
fn foo<'a, 'b>(...) -> impl Trait<'a, 'b> { .. }
```
The problem here is that every region R in the hidden type must be equal to *either* `'a` *or* `'b` (or `'static`). This cannot be expressed simply via 'outlives constriants' like `R: 'a`. Therefore, we introduce a 'member constraint' `R member of ['a, 'b]`.
These constraints were introduced in [rust-lang/rust#61775]. At the time, we kept them feature gated and used them only for `impl Trait` return types that are derived from `async fn`. The intention, however, was always to support them in other contexts once we had time to gain more experience with them.
**In the time since their introduction, we have encountered no surprises or bugs due to these member constraints.** They are tested extensively as part of every async function that involves multiple unrelated lifetimes in its arguments.
## Tests
The behavior of member constraints is covered by the following tests:
* [`src/test/ui/async-await/multiple-lifetimes`](https://github.com/rust-lang/rust/tree/20e032e65007ff1376e8480c1fbdb0a5068028fa/src/test/ui/async-await/multiple-lifetimes) -- tests using the async await, which are mostly already stabilized
* [`src/test/ui/impl-trait/multiple-lifetimes.rs`](https://github.com/rust-lang/rust/blob/20e032e65007ff1376e8480c1fbdb0a5068028fa/src/test/ui/impl-trait/multiple-lifetimes.rs)
* [`src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs`](https://github.com/rust-lang/rust/blob/20e032e65007ff1376e8480c1fbdb0a5068028fa/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs)
* [`src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs`](https://github.com/rust-lang/rust/blob/20e032e65007ff1376e8480c1fbdb0a5068028fa/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs)
* [`src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs`](https://github.com/rust-lang/rust/blob/20e032e65007ff1376e8480c1fbdb0a5068028fa/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs)
These tests cover a number of scenarios:
* `-> implTrait<'a, 'b>` with unrelated lifetimes `'a` and `'b`, as described above
* `async fn` that returns an `impl Trait` like the previous case, which desugars to a kind of "nested" impl trait like `impl Future<Output = impl Trait<'a, 'b>>`
## Potential concerns
There is a potential interaction with `impl Trait` on local variables, described in [rust-lang/rust#61773]. The challenge is that if you have a program like:
```rust=
trait Foo<'_> { }
impl Foo<'_> for &u32 { }
fn bar() {
let x: impl Foo<'_> = &44; // let's call the region variable for `'_` `'1`
}
```
then we would wind up with `'0 member of ['1, 'static]`, where `'0` is the region variable in the hidden type (`&'0 u32`) and `'1` is the region variable in the bounds `Foo<'1>`. This is tricky because both `'0` and `'1` are being inferred -- so making them equal may have other repercussions.
That said, `impl Trait` in bindings are not stable, and the implementation is pretty far from stabilization. Moreover, the difficulty highlighted here is not due to the presence of member constraints -- it's inherent to the design of the language. In other words, stabilizing member constraints does not actually cause us to accept anything that would make this problem any harder.
So I don't see this as a blocker to stabilization of member constraints; it is potentially a blocker to stablization of `impl trait` in let bindings.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/llvm_util.rs')
0 files changed, 0 insertions, 0 deletions
