Skip to content

Commit db49686

Browse files
authored
Rollup merge of #65936 - Xanewok:save-analysis-async, r=nikomatsakis
save-analysis: Account for async desugaring in async fn return types Closes #65590 When visiting the return type of an async function we need to take into account its desugaring, since it introduces a new definition under which the return type is redefined. r? @nikomatsakis
2 parents 73dcb96 + e755963 commit db49686

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/librustc_save_analysis/dump_visitor.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,16 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
300300
}
301301

302302
if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output {
303-
v.visit_ty(ret_ty);
303+
// In async functions, return types are desugared and redefined
304+
// as an `impl Trait` existential type. Because of this, to match
305+
// the definition paths when resolving nested types we need to
306+
// start walking from the newly-created definition.
307+
match sig.header.asyncness.node {
308+
ast::IsAsync::Async { return_impl_trait_id, .. } => {
309+
v.nest_tables(return_impl_trait_id, |v| v.visit_ty(ret_ty))
310+
}
311+
_ => v.visit_ty(ret_ty)
312+
}
304313
}
305314

306315
// walk the fn body
@@ -369,6 +378,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
369378
&mut self,
370379
item: &'l ast::Item,
371380
decl: &'l ast::FnDecl,
381+
header: &'l ast::FnHeader,
372382
ty_params: &'l ast::Generics,
373383
body: &'l ast::Block,
374384
) {
@@ -391,7 +401,16 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
391401
// FIXME: Opaque type desugaring prevents us from easily
392402
// processing trait bounds. See `visit_ty` for more details.
393403
} else {
394-
v.visit_ty(&ret_ty);
404+
// In async functions, return types are desugared and redefined
405+
// as an `impl Trait` existential type. Because of this, to match
406+
// the definition paths when resolving nested types we need to
407+
// start walking from the newly-created definition.
408+
match header.asyncness.node {
409+
ast::IsAsync::Async { return_impl_trait_id, .. } => {
410+
v.nest_tables(return_impl_trait_id, |v| v.visit_ty(ret_ty))
411+
}
412+
_ => v.visit_ty(ret_ty)
413+
}
395414
}
396415
}
397416

@@ -1315,8 +1334,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
13151334
);
13161335
}
13171336
}
1318-
Fn(ref decl, .., ref ty_params, ref body) => {
1319-
self.process_fn(item, &decl, ty_params, &body)
1337+
Fn(ref decl, ref header, ref ty_params, ref body) => {
1338+
self.process_fn(item, &decl, &header, ty_params, &body)
13201339
}
13211340
Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr),
13221341
Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr),
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
// compile-flags: -Zsave-analysis
3+
// edition:2018
4+
5+
// Async desugaring for return types in (associated) functions introduces a
6+
// separate definition internally, which we need to take into account
7+
// (or else we ICE).
8+
trait Trait { type Assoc; }
9+
struct Struct;
10+
11+
async fn foobar<T: Trait>() -> T::Assoc {
12+
unimplemented!()
13+
}
14+
15+
impl Struct {
16+
async fn foo<T: Trait>(&self) -> T::Assoc {
17+
unimplemented!()
18+
}
19+
}
20+
21+
fn main() {}

0 commit comments

Comments
 (0)