Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
kythyria opened this issue Oct 18, 2021 · 2 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kythyria
Copy link

kythyria commented Oct 18, 2021

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()
}
@kythyria kythyria added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 18, 2021
@cuviper
Copy link
Member

cuviper commented Oct 18, 2021

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.

@estebank
Copy link
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
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants