about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-12 21:42:10 +0000
committerbors <bors@rust-lang.org>2022-02-12 21:42:10 +0000
commit3cfa4def7c87d571bd46d92fed608edf8fad236e (patch)
tree43fadb34acfa47419ac74221dbca1161938dbeee /compiler/rustc_borrowck/src
parent5d8767cb229b097fedb1dd4bd9420d463c37774f (diff)
parent10cf626d0ea7be3eb971691772b5eb30013d4f02 (diff)
downloadrust-3cfa4def7c87d571bd46d92fed608edf8fad236e.tar.gz
rust-3cfa4def7c87d571bd46d92fed608edf8fad236e.zip
Auto merge of #91403 - cjgillot:inherit-async, r=oli-obk
Inherit lifetimes for async fn instead of duplicating them.

The current desugaring of `async fn foo<'a>(&usize) -> &u8` is equivalent to
```rust
fn foo<'a, '0>(&'0 usize) -> foo<'static, 'static>::Opaque<'a, '0, '_>;
type foo<'_a, '_0>::Opaque<'a, '0, '1> = impl Future<Output = &'1 u8>;
```
following the RPIT model.

Duplicating all the inherited lifetime parameters and setting the inherited version to `'static` makes lowering more complex and causes issues like #61949. This PR removes the duplication of inherited lifetimes to directly use
```rust
fn foo<'a, '0>(&'0 usize) -> foo<'a, '0>::Opaque<'_>;
type foo<'a, '0>::Opaque<'1> = impl Future<Output = &'1 u8>;
```
following the TAIT model.

Fixes https://github.com/rust-lang/rust/issues/61949
Diffstat (limited to 'compiler/rustc_borrowck/src')
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs18
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index d9120ff2457..0f0d3eaa293 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -2156,6 +2156,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 }
             }
 
+            // When in async fn, prefer errors that come from inside the closure.
+            if !categorized_path[i].from_closure {
+                let span = categorized_path.iter().find_map(|p| {
+                    if p.from_closure
+                        && p.category == categorized_path[i].category
+                        && categorized_path[i].cause.span.contains(p.cause.span)
+                    {
+                        Some(p.cause.span)
+                    } else {
+                        None
+                    }
+                });
+
+                if let Some(span) = span {
+                    categorized_path[i].cause.span = span;
+                }
+            }
+
             return categorized_path[i].clone();
         }