Skip to content

Cycle error through variance computation when using -> _. #72730

Open
@eddyb

Description

@eddyb

Reduced example (playground):

struct Wrapper<T>(T);

fn foo<T>(x: Wrapper<T>) -> _ {
    drop(x);
}
error[E0391]: cycle detected when processing `foo`
 --> src/lib.rs:3:1
  |
3 | fn foo<T>(x: Wrapper<T>) -> _ {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
note: ...which requires type-checking `foo`...
 --> src/lib.rs:3:1
  |
3 | fn foo<T>(x: Wrapper<T>) -> _ {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `Wrapper`...
 --> src/lib.rs:1:1
  |
1 | struct Wrapper<T>(T);
  | ^^^^^^^^^^^^^^^^^^^^^
  = note: ...which requires computing the variances for items in this crate...
  = note: ...which again requires processing `foo`, completing the cycle
note: cycle used when collecting item types in top-level module
 --> src/lib.rs:1:1
  |
1 | / struct Wrapper<T>(T);
2 | |
3 | | fn foo<T>(x: Wrapper<T>) -> _ {
4 | |     drop(x);
5 | | }
  | |_^

You can see right away that it's hard to figure out what "processing" means and we should probably start a cleanup effort to add proper descriptions to queries (or at least name the query in the default message, even if it might not look pretty at all). cc @rust-lang/compiler


Using -Ztreat-err-as-bug + RUST_BACKTRACE=1 I can turn the error into an ICE and get this:

#0 [crate_variances] computing the variances for items in this crate
#1 [variances_of] processing `Wrapper`
#2 [typeck_tables_of] type-checking `foo`
#3 [fn_sig] processing `foo`
#4 [collect_mod_item_types] collecting item types in top-level module
#5 [analysis] running analysis passes on this crate

So variance computation uses fn_sig (not sure why it would need to), which is normally harmless, as function signatures are fully explicit.

But we nowadays "allow" _ in the signature, guaranteeing an error still, while showing the user the inferred type (this should be useful during prototyping but I keep forgetting it exists).

As a result of that, instead of typeck_tables_of depending on fn_sig, fn_sig depends on typeck_tables_of (since it needs the results of type inference from the fn body), so an otherwise harmless fn_sig turns into a cycle as soon as type-checking needs any variances.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-inferenceArea: Type inferenceC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions