1
Fork 0

Rollup merge of #97720 - cjgillot:all-fresh, r=petrochenkov

Always create elided lifetime parameters for functions

Anonymous and elided lifetimes in functions are sometimes (async fns) --and sometimes not (regular fns)-- desugared to implicit generic parameters.

This difference of treatment makes it some downstream analyses more complicated to handle.  This step is a pre-requisite to perform lifetime elision resolution on AST.

There is currently an inconsistency in the treatment of argument-position impl-trait for functions and async fns:
```rust
trait Foo<'a> {}
fn foo(t: impl Foo<'_>) {} //~ ERROR missing lifetime specifier
async fn async_foo(t: impl Foo<'_>) {} //~ OK
fn bar(t: impl Iterator<Item = &'_ u8>) {} //~ ERROR missing lifetime specifier
async fn async_bar(t: impl Iterator<Item = &'_ u8>) {} //~ OK
```

The current implementation reports "missing lifetime specifier" on `foo`, but **accepts it** in `async_foo`.
This PR **proposes to accept** the anonymous lifetime in both cases as an extra generic lifetime parameter.
This change would be insta-stable, so let's ping t-lang.
Anonymous lifetimes in GAT bindings keep being forbidden:
```rust
fn foo(t: impl Foo<Assoc<'_> = Bar<'_>>) {}
                         ^^        ^^
                       forbidden   ok
```
I started a discussion here: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Anonymous.20lifetimes.20in.20universal.20impl-trait/near/284968606

r? ``@petrochenkov``
This commit is contained in:
Dylan DPC 2022-07-14 14:14:19 +05:30 committed by GitHub
commit f5e9cb53ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 163 additions and 56 deletions

View file

@ -758,7 +758,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
// We don't need to deal with patterns in parameters, because
// they are not possible for foreign or bodiless functions.
self.with_lifetime_rib(
LifetimeRibKind::AnonymousPassThrough(fn_id, false),
LifetimeRibKind::AnonymousCreateParameter {
binder: fn_id,
report_in_path: false,
},
|this| walk_list!(this, visit_param, &sig.decl.inputs),
);
self.with_lifetime_rib(
@ -792,18 +795,13 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
// generic parameters. This is especially useful for `async fn`, where
// these fresh generic parameters can be applied to the opaque `impl Trait`
// return type.
let rib = if async_node_id.is_some() {
// Only emit a hard error for `async fn`, since this kind of
// elision has always been allowed in regular `fn`s.
this.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter {
binder: fn_id,
report_in_path: true,
}
} else {
LifetimeRibKind::AnonymousPassThrough(fn_id, false)
};
this.with_lifetime_rib(
rib,
// Only emit a hard error for `async fn`, since this kind of
// elision has always been allowed in regular `fn`s.
report_in_path: async_node_id.is_some(),
},
// Add each argument to the rib.
|this| this.resolve_params(&declaration.inputs),
);

View file

@ -1677,7 +1677,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
break None;
}
Scope::Binder { ref lifetimes, scope_type, s, .. } => {
Scope::Binder { ref lifetimes, scope_type, s, where_bound_origin, .. } => {
if let Some(&def) = lifetimes.get(&region_def_id) {
break Some(def.shifted(late_depth));
}
@ -1685,6 +1685,21 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
BinderScopeType::Normal => late_depth += 1,
BinderScopeType::Concatenating => {}
}
// Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
// regular fns.
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
&& let hir::LifetimeName::Param(_, hir::ParamName::Fresh) = lifetime_ref.name
&& let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner)
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
{
rustc_session::parse::feature_err(
&self.tcx.sess.parse_sess,
sym::anonymous_lifetime_in_impl_trait,
lifetime_ref.span,
"anonymous lifetimes in `impl Trait` are unstable",
).emit();
return;
}
scope = s;
}