1
Fork 0

Rollup merge of #98705 - WaffleLapkin:closure_binder, r=cjgillot

Implement `for<>` lifetime binder for closures

This PR implements RFC 3216 ([TI](https://github.com/rust-lang/rust/issues/97362)) and allows code like the following:

```rust
let _f = for<'a, 'b> |a: &'a A, b: &'b B| -> &'b C { b.c(a) };
//       ^^^^^^^^^^^--- new!
```

cc ``@Aaron1011`` ``@cjgillot``
This commit is contained in:
Dylan DPC 2022-07-14 14:14:21 +05:30 committed by GitHub
commit e5a86d7358
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
91 changed files with 843 additions and 208 deletions

View file

@ -6,6 +6,7 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
use rustc_ast_pretty::pp::{self, Breaks};
use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir as hir;
use rustc_hir::LifetimeParamKind;
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node, Term};
use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
use rustc_span::source_map::SourceMap;
@ -1452,15 +1453,16 @@ impl<'a> State<'a> {
}
self.bclose(expr.span);
}
hir::ExprKind::Closure {
hir::ExprKind::Closure(&hir::Closure {
binder,
capture_clause,
bound_generic_params,
fn_decl,
body,
fn_decl_span: _,
movability: _,
} => {
self.print_formal_generic_params(bound_generic_params);
}) => {
self.print_closure_binder(binder, bound_generic_params);
self.print_capture_clause(capture_clause);
self.print_closure_params(fn_decl, body);
@ -2045,6 +2047,42 @@ impl<'a> State<'a> {
}
}
pub fn print_closure_binder(
&mut self,
binder: hir::ClosureBinder,
generic_params: &[GenericParam<'_>],
) {
let generic_params = generic_params
.iter()
.filter(|p| {
matches!(
p,
GenericParam {
kind: GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit },
..
}
)
})
.collect::<Vec<_>>();
match binder {
hir::ClosureBinder::Default => {}
// we need to distinguish `|...| {}` from `for<> |...| {}` as `for<>` adds additional restrictions
hir::ClosureBinder::For { .. } if generic_params.is_empty() => self.word("for<>"),
hir::ClosureBinder::For { .. } => {
self.word("for");
self.word("<");
self.commasep(Inconsistent, &generic_params, |s, param| {
s.print_generic_param(param)
});
self.word(">");
self.nbsp();
}
}
}
pub fn print_bounds<'b>(
&mut self,
prefix: &'static str,