Skip to content

Inference fails because it doesn't consider deref coercions #37164

Open
@cristicbz

Description

@cristicbz

Maybe this is intended, but it's not super-clear.

Playground

use std::collections::HashMap;

fn check(_: &str) -> bool { false }

fn chain<'a>(some_key: &'a str) -> HashMap<&'a str, Vec<usize>> {
    let mut map = HashMap::new();
    map.get(&some_key);
    {
        // uncomment type annotation to fix
        let key_ref /*: &&str*/ = map.keys().next().unwrap();
        if check(key_ref) {} // due to autoderef `key_ref` could be `&&str` and
                             // this would work. but `key_ref` is inferred to be
                             // `&str` due to the `check` call, causing `map` to
                             // be `HashMap<str, _>`.
    }
    map
}

fn main() {}

fails with

error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> min.rs:6:19
  |
6 |     let mut map = HashMap::new();
  |                   ^^^^^^^^^^^^
  |
  = note: `str` does not have a constant size known at compile-time
  = note: required by `<std::collections::HashMap<K, V>>::new`

error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> min.rs:7:9
  |
7 |     map.get(&some_key);
  |         ^^^
  |
  = note: `str` does not have a constant size known at compile-time

error[E0277]: the trait bound `str: std::borrow::Borrow<&str>` is not satisfied
 --> min.rs:7:9
  |
7 |     map.get(&some_key);
  |         ^^^

error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> min.rs:8:18
  |
8 |     if check(map.keys().next().unwrap()) {}
  |                  ^^^^
  |
  = note: `str` does not have a constant size known at compile-time

error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> min.rs:8:25
  |
8 |     if check(map.keys().next().unwrap()) {}
  |                         ^^^^
  |
  = note: `str` does not have a constant size known at compile-time
  = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::collections::hash_map::Keys<'_, str, _>`

error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> min.rs:8:14
  |
8 |     if check(map.keys().next().unwrap()) {}
  |              ^^^^^^^^^^^^^^^^^
  |
  = note: `str` does not have a constant size known at compile-time
  = note: required by `std::collections::hash_map::Keys`

error[E0308]: mismatched types
 --> min.rs:9:5
  |
9 |     map
  |     ^^^ expected reference, found str
  |
  = note: expected type `std::collections::HashMap<&'a str, std::vec::Vec<usize>>`
  = note:    found type `std::collections::HashMap<str, _>`

error: aborting due to 7 previous errors

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-inferenceArea: Type inferenceC-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions