Skip to content

Commit

Permalink
inliner: Avoid query cycles when optimizing generators
Browse files Browse the repository at this point in the history
The HIR Id trick is insufficient to prevent query cycles when optimizing
generators, since merely requesting a layout of a generator also
computes its `optimized_mir`.

Make no attempts to inline functions into generators within the same
crate to avoid query cycles.
  • Loading branch information
tmiasko committed Sep 2, 2020
1 parent da897df commit 6c51ec9
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
10 changes: 8 additions & 2 deletions compiler/rustc_mir/src/transform/inline.rs
Expand Up @@ -107,8 +107,14 @@ impl Inliner<'tcx> {
// Avoid a cycle here by only using `optimized_mir` only if we have
// a lower `HirId` than the callee. This ensures that the callee will
// not inline us. This trick only works without incremental compilation.
// So don't do it if that is enabled.
if !self.tcx.dep_graph.is_fully_enabled() && self_hir_id < callee_hir_id {
// So don't do it if that is enabled. Also avoid inlining into generators,
// since their `optimized_mir` is used for layout computation, which can
// create a cycle, even when no attempt is made to inline the function
// in the other direction.
if !self.tcx.dep_graph.is_fully_enabled()
&& self_hir_id < callee_hir_id
&& caller_body.generator_kind.is_none()
{
self.tcx.optimized_mir(callsite.callee)
} else {
continue;
Expand Down
18 changes: 18 additions & 0 deletions src/test/mir-opt/inline/inline-async.rs
@@ -0,0 +1,18 @@
// Checks that inliner doesn't introduce cycles when optimizing generators.
// The outcome of optimization is not verfied, just the absence of the cycle.
// Regression test for #76181.
//
// edition:2018

#![crate_type = "lib"]

pub struct S;

impl S {
pub async fn g(&mut self) {
self.h();
}
pub fn h(&mut self) {
let _ = self.g();
}
}

0 comments on commit 6c51ec9

Please sign in to comment.