Anyway around this slightly awkward type requirement

In the example here:

use pstd::{ alloc::Global, collections::btree_map::{BTreeMap,CustomAllocTuning} };
let a = Global {};
let mut map = BTreeMap::<_, _, CustomAllocTuning<Global>>::new_in(a);
map.insert("England", "London");

It will not compile without the type specification

::<_, _, CustomAllocTuning<Global>>::

I was a bit surprised by this ( it also took me a fair while to figure out what was needed ), I am now wondering if there is anything I could do differently here.

Seems like a design mistake in the library. Basically, the BTreeMap<K, V, A1> type has a method new_in::<A2> that returns a BTreeMap<K, V, CustomAllocTuning<A2>>. So there's an extra type parameter A1 that's not used for anything, and since it's not used for anything, you have to explicitly specify it.

3 Likes

Hmm, I expect you are right, but I don't see what to do differently.

In case it helps, here is the error output without the explicit type:

---- src\collections\btree_map\mod.rs - collections::btree_map::BTreeMap<K,V,A>::new_in (line 97) stdout ----
error[E0283]: type annotations needed
   --> src\collections\btree_map\mod.rs:101:15
    |
7   | let mut map = BTreeMap::new_in(a);
    |               ^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `A` declared on the struct `BTreeMap`
    |
    = note: cannot satisfy `_: AllocTuning`
    = help: the trait `AllocTuning` is implemented for `CustomAllocTuning<AL>`
note: required by a bound in `pstd::collections::BTreeMap::<K, V, A>::new_in`
   --> C:\Users\ano31\Rust\pstd\src\collections\btree_map\mod.rs:89:15
    |
89  | impl<K, V, A: AllocTuning> BTreeMap<K, V, A> {
    |               ^^^^^^^^^^^ required by this bound in `BTreeMap::<K, V, A>::new_in`
...
105 |     pub fn new_in<AL>(a: AL) -> BTreeMap<K, V, CustomAllocTuning<AL>>
    |            ------ required by a bound in this associated function
help: consider specifying the generic arguments
    |
7   | let mut map = BTreeMap::<&str, &str, A>::new_in(a);
    |                       +++++++++++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
Couldn't compile the test.

I mean, that type parameter is for the return type. in case it is relevant, BTreeMap has this declaration, with a default type for A:

pub struct BTreeMap<K, V, A: AllocTuning = DefaultAllocTuning>

Ah, I think I solved it by moving that function to an impl section without the A parameter.

I thought I had already tried that and it didn't work, but now it does!

Thanks for you help!

Here is the fixed version:

1 Like

An alternate solution:

impl<K, V, AL: Allocator + Clone> BTreeMap<K, V, CustomAllocTuning<AL>> {
    pub fn new_in(a: AL) -> Self { ... }
}

In practical terms this is equivalent to your code, but I think it makes the documentation and code organization a bit more readable.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.