Skip to content

function call inference incorrectly handles autoderef chains which encounter infer #146437

@lcnr

Description

@lcnr
fn main() {
    let mut x: Option<Box<_>> = None;
    loop {
        if let Some(x) = x {
            x();
            break;
        } else {
            let str = String::new();
            x = Some(Box::new(move || drop(str)));
        }
    }
}

This results in

error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
 --> src/main.rs:9:31
  |
5 |             x();
  |             --- the requirement to implement `Fn` derives from here
...
9 |             x = Some(Box::new(move || drop(str)));
  |                               ^^^^^^^      --- closure is `FnOnce` because it moves the variable `str` out of its environment
  |                               |
  |                               this closure implements `FnOnce`, not `Fn`
  |
  = note: required for `Box<{closure@src/main.rs:9:31: 9:38}>` to implement `Fn()`

When typechecking the function call x() we only test whether Box<?infer>: Fn results in an error. It does not so that's what we select for the call.

This differs from the way method selection works where autoderef chains encountering inference variables result in ambiguity errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-inferenceArea: Type inferenceT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types 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