Skip to content

Inference failure sometimes results in things being considered functions. #89995

Closed

Description

@kythyria

Given the following code (playground):

use std::collections::HashSet;
use std::rc::Rc;

fn intern(cache: &mut HashSet<Rc<str>>, data: &str) -> Rc<str> {
   match cache.get(data) {
        Some(s) => s.clone(),
        None => {
            let d = Rc::from(data);
            cache.insert(d.clone());
            d
        }
    }
}

The current output is:

error[E0282]: type annotations needed
 --> src/lib.rs:9:28
  |
9 |             cache.insert(d.clone());
  |                            ^^^^^ cannot infer type
  |
  = note: type must be known at this point

error[E0599]: no method named `clone` found for struct `Rc<_>` in the current scope
 --> src/lib.rs:9:28
  |
9 |             cache.insert(d.clone());
  |                            ^^^^^ method not found in `Rc<_>`
  |
  = note: `d` is a function, perhaps you wish to call it

I'm surprised it can't infer the type of d correctly, considering there are multiple indications it must be Rc<str> (and R-A does so). Maybe it's confused by Rc<&str> being a thing?

The final note is straight up perplexing, however: where on earth is it getting the idea that that's a function from? That should probably be squashed.

Edit: even shorter reproduction (playground):

use std::rc::Rc;
fn intern(data: &str) -> Rc<str> {
    Rc::from(data).clone()
}

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Oct 18, 2021
  2. cuviper commented on Oct 18, 2021

    @cuviper
    Member

    I'm surprised it can't infer the type of d correctly, considering there are multiple indications it must be Rc<str> (and R-A does so). Maybe it's confused by Rc<&str> being a thing?

    In the smaller reproducer, the return type does solve the inference when you take out the .clone(), but that method call interrupts the link. It works if you write Rc::clone(&...) though.

    The final note is straight up perplexing, however: where on earth is it getting the idea that that's a function from? That should probably be squashed.

    For a coarse bisect, that note first appeared on stable in Rust 1.33.0. Just looking at the release notes, I'll make a wild guess that it's related to #56805, and I can indeed reproduce the note with Arc and Pin as well.

  3. estebank commented on Aug 14, 2023

    @estebank
    Contributor

    Current output:

    error[E0282]: type annotations needed for `Rc<T, A>`
     --> f71.rs:8:17
      |
    8 |             let d = Rc::from(data);
      |                 ^
    9 |             cache.insert(d.clone());
      |                            ----- type must be known at this point
      |
    help: consider giving `d` an explicit type, where the type for type parameter `T` is specified
      |
    8 |             let d: Rc<T, A> = Rc::from(data);
      |                  ++++++++++
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-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