inliner: Avoid query cycles when optimizing generators

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.
This commit is contained in:
Tomasz Miąsko 2020-09-02 00:00:00 +00:00
parent da897dfb6d
commit 6c51ec96bb
2 changed files with 26 additions and 2 deletions

View File

@ -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;

View File

@ -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();
}
}