Skip to content

normalizing in writeback causes cycle errors with generators #82

@compiler-errors

Description

@compiler-errors

We normalize types during writeback resolve:
https://github.com/rust-lang/rust/blob/b6a8c762eed0ae0383658c38d65cb91bbd9800a1/compiler/rustc_hir_typeck/src/writeback.rs#L790-L794

When normalizing types, this may cause us to try to prove an auto trait bound on a generator witness that is local to the body:

trait Mirror {
    type Assoc;
}

impl<T> Mirror for T where T: Send {
    type Assoc = T;
}

fn mirror<T: Mirror>(x: Option<&T>) -> Option<T::Assoc> { None }

fn main() {
    let mut async_block = None;
    //^^ begins as `<?0 as Mirror>::Assoc`
    let local = mirror(async_block.as_ref());
    async_block = Some(async {});
    //^^ Now `<Generator as Mirror>::Assoc`.
    // When we try to resolve during writeback, we need to prove `Generator: Send`,
    // which makes the trait solver attempt to compute `GeneratorWitness: Send`. Cycle!
}

From #82 (comment) this should probably be fixed by extending TypingMode::Analysis to also track the generator witnesses of the current function.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions