Skip to content

TreeMap: find_with is surprising #15635

Closed
@olivren

Description

@olivren

As far as I understand, the merged PR #15220 introduces the methods find_with and find_mut_with on TreeMap, in order to provide a general solution to the problem of finding an equivalent string key. In particular, these methods make it possible to search a TreeMap using String keys to be searched without performing an allocation, using t.find_with(|k| "test".cmp(&k.as_slice()).

I see an issue here : this method only works if the logic of the closure passed as an argument is exactly the same than the logic used to provide the natural ordering of the keys. Using a different logic in the comparision closure does not work as expected, and gives random result.

The documentation on these methods don't warn about this very strong restriction, and instead they present a wrong use of the API : using these methods to find a string by performing case insensitive comparisions. It happens that the provided example works as expected, but it is easy to modify this example such that the search does not find the expected result.

Here is a variation of the provided example:

extern crate collections;
fn main() {
    use std::ascii::StrAsciiExt;

    let mut t = collections::treemap::TreeMap::new();
    t.insert("a1", "a1");
    t.insert("A2", "a2");

    let ua_key = "a1";
    let ua = t.find_with(|&k| {
       ua_key.cmp(&k.to_ascii_lower().as_slice())
    });

    println!("{}", ua);
}

This prints None.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions