about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-04-09 01:50:01 +0000
committerbors <bors@rust-lang.org>2021-04-09 01:50:01 +0000
commitcd56e255c43030d583aa0aa09f7eb92f2d8d1d81 (patch)
treeb4cfedb97c10d5d7aabfc3562c53a0c8ddcbb03b /src
parent619d19c3181e4793de789302d60a0343f0081139 (diff)
parentc1dc0b7bbc239290388d2365c6d0b282e299bdbc (diff)
downloadrust-cd56e255c43030d583aa0aa09f7eb92f2d8d1d81.tar.gz
rust-cd56e255c43030d583aa0aa09f7eb92f2d8d1d81.zip
Auto merge of #83870 - jackh726:binder-refactor-fix, r=nikomatsakis
Don't concatenate binders across types

Partially addresses #83737

There's actually two issues that I uncovered in #83737. The first is that we are concatenating bound vars across types, i.e. in
```
F: Fn(&()) -> &mut (dyn Future<Output = ()> + Unpin)
```
the bound vars on `Future` get set as `for<anon>` since those are the binders on `Fn(&()`. This is obviously wrong, since we should only concatenate directly nested trait refs. This is solved here by introducing a new `TraitRefBoundary` scope, that we put around the "syntactical" trait refs and basically don't allow concatenation across.

Now, this alone *shouldn't* be a super terrible problem. At least not until you consider the other issue, which is a much more elusive and harder to design a "perfect" fix. A repro can be seen in:
```
use core::future::Future;

async fn handle<F>(slf: &F)
where
    F: Fn(&()) -> &mut (dyn for<'a> Future<Output = ()> + Unpin),
{
    (slf)(&()).await;
}
```
Notice the `for<'a>` around `Future`. Here, `'a` is unused, so the `for<'a>` Binder gets changed to a `for<>` Binder in the generator witness, but the "local decl" still has it. This has heavy intersections with region anonymization and erasing. Luckily, it's not *super* common to find this unique set of circumstances. It only became apparently because of the first issue mentioned here. However, this *is* still a problem, so I'm leaving #83737 open.

r? `@nikomatsakis`
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/lifetimes/issue-83737-binders-across-types.rs14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/test/ui/lifetimes/issue-83737-binders-across-types.rs b/src/test/ui/lifetimes/issue-83737-binders-across-types.rs
new file mode 100644
index 00000000000..e130561e466
--- /dev/null
+++ b/src/test/ui/lifetimes/issue-83737-binders-across-types.rs
@@ -0,0 +1,14 @@
+// build-pass
+// compile-flags: --edition 2018
+// compile-flags: --crate-type rlib
+
+use std::future::Future;
+
+async fn handle<F>(slf: &F)
+where
+    F: Fn(&()) -> Box<dyn Future<Output = ()> + Unpin>,
+{
+    (slf)(&()).await;
+}
+
+fn main() {}