Only record extra lifetime params for async trait fn with no body
This commit is contained in:
parent
59c4a92baf
commit
3d7e9a7b27
4 changed files with 44 additions and 88 deletions
|
@ -789,8 +789,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
let previous_value = self.diagnostic_metadata.current_function;
|
let previous_value = self.diagnostic_metadata.current_function;
|
||||||
match fn_kind {
|
match fn_kind {
|
||||||
// Bail if the function is foreign, and thus cannot validly have
|
// Bail if the function is foreign, and thus cannot validly have
|
||||||
// a body.
|
// a body, or if there's no body for some other reason.
|
||||||
FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _) => {
|
FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _)
|
||||||
|
| FnKind::Fn(_, _, sig, _, generics, None) => {
|
||||||
self.visit_fn_header(&sig.header);
|
self.visit_fn_header(&sig.header);
|
||||||
self.visit_generics(generics);
|
self.visit_generics(generics);
|
||||||
self.with_lifetime_rib(
|
self.with_lifetime_rib(
|
||||||
|
@ -804,7 +805,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
sig.decl.has_self(),
|
sig.decl.has_self(),
|
||||||
sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
|
sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
|
||||||
&sig.decl.output,
|
&sig.decl.output,
|
||||||
)
|
);
|
||||||
|
|
||||||
|
this.record_lifetime_params_for_async(
|
||||||
|
fn_id,
|
||||||
|
sig.header.asyncness.opt_return_id(),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -846,41 +852,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Construct the list of in-scope lifetime parameters for async lowering.
|
this.record_lifetime_params_for_async(fn_id, async_node_id);
|
||||||
// We include all lifetime parameters, either named or "Fresh".
|
|
||||||
// The order of those parameters does not matter, as long as it is
|
|
||||||
// deterministic.
|
|
||||||
if let Some((async_node_id, _)) = async_node_id {
|
|
||||||
let mut extra_lifetime_params = this
|
|
||||||
.r
|
|
||||||
.extra_lifetime_params_map
|
|
||||||
.get(&fn_id)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default();
|
|
||||||
for rib in this.lifetime_ribs.iter().rev() {
|
|
||||||
extra_lifetime_params.extend(
|
|
||||||
rib.bindings
|
|
||||||
.iter()
|
|
||||||
.map(|(&ident, &(node_id, res))| (ident, node_id, res)),
|
|
||||||
);
|
|
||||||
match rib.kind {
|
|
||||||
LifetimeRibKind::Item => break,
|
|
||||||
LifetimeRibKind::AnonymousCreateParameter {
|
|
||||||
binder, ..
|
|
||||||
} => {
|
|
||||||
if let Some(earlier_fresh) =
|
|
||||||
this.r.extra_lifetime_params_map.get(&binder)
|
|
||||||
{
|
|
||||||
extra_lifetime_params.extend(earlier_fresh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.r
|
|
||||||
.extra_lifetime_params_map
|
|
||||||
.insert(async_node_id, extra_lifetime_params);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
// Ignore errors in function bodies if this is rustdoc
|
// Ignore errors in function bodies if this is rustdoc
|
||||||
|
@ -3925,6 +3897,36 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
Some((ident.name, ns)),
|
Some((ident.name, ns)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct the list of in-scope lifetime parameters for async lowering.
|
||||||
|
/// We include all lifetime parameters, either named or "Fresh".
|
||||||
|
/// The order of those parameters does not matter, as long as it is
|
||||||
|
/// deterministic.
|
||||||
|
fn record_lifetime_params_for_async(
|
||||||
|
&mut self,
|
||||||
|
fn_id: NodeId,
|
||||||
|
async_node_id: Option<(NodeId, Span)>,
|
||||||
|
) {
|
||||||
|
if let Some((async_node_id, _)) = async_node_id {
|
||||||
|
let mut extra_lifetime_params =
|
||||||
|
self.r.extra_lifetime_params_map.get(&fn_id).cloned().unwrap_or_default();
|
||||||
|
for rib in self.lifetime_ribs.iter().rev() {
|
||||||
|
extra_lifetime_params.extend(
|
||||||
|
rib.bindings.iter().map(|(&ident, &(node_id, res))| (ident, node_id, res)),
|
||||||
|
);
|
||||||
|
match rib.kind {
|
||||||
|
LifetimeRibKind::Item => break,
|
||||||
|
LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
|
||||||
|
if let Some(earlier_fresh) = self.r.extra_lifetime_params_map.get(&binder) {
|
||||||
|
extra_lifetime_params.extend(earlier_fresh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.r.extra_lifetime_params_map.insert(async_node_id, extra_lifetime_params);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LifetimeCountVisitor<'a, 'b> {
|
struct LifetimeCountVisitor<'a, 'b> {
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
// check-pass
|
|
||||||
// edition:2021
|
|
||||||
|
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
|
|
||||||
use std::future::Future;
|
|
||||||
|
|
||||||
async fn yield_now() {}
|
|
||||||
|
|
||||||
trait AsyncIterator {
|
|
||||||
type Item;
|
|
||||||
async fn next(&mut self) -> Option<Self::Item>;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct YieldingRange {
|
|
||||||
counter: u32,
|
|
||||||
stop: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsyncIterator for YieldingRange {
|
|
||||||
type Item = u32;
|
|
||||||
|
|
||||||
async fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if self.counter == self.stop {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let c = self.counter;
|
|
||||||
self.counter += 1;
|
|
||||||
yield_now().await;
|
|
||||||
Some(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn async_main() {
|
|
||||||
let mut x = YieldingRange { counter: 0, stop: 10 };
|
|
||||||
|
|
||||||
while let Some(v) = x.next().await {
|
|
||||||
println!("Hi: {v}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let _ = async_main();
|
|
||||||
}
|
|
|
@ -2,5 +2,5 @@ fn main() {}
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
||||||
fn fn_with_type_named_same_as_local_in_param(b: b);
|
fn fn_with_type_named_same_as_local_in_param(b: b);
|
||||||
//~^ ERROR expected type, found local variable `b`
|
//~^ ERROR cannot find type `b` in this scope [E0412]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
error[E0573]: expected type, found local variable `b`
|
error[E0412]: cannot find type `b` in this scope
|
||||||
--> $DIR/issue-69401-trait-fn-no-body-ty-local.rs:4:53
|
--> $DIR/issue-69401-trait-fn-no-body-ty-local.rs:4:53
|
||||||
|
|
|
|
||||||
LL | fn fn_with_type_named_same_as_local_in_param(b: b);
|
LL | fn fn_with_type_named_same_as_local_in_param(b: b);
|
||||||
| ^ not a type
|
| ^ not found in this scope
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0573`.
|
For more information about this error, try `rustc --explain E0412`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue