Skip to content

Conversation

canova
Copy link
Contributor

@canova canova commented Aug 5, 2020

This is a pretty small change on the lifetime bounds of IntoIterator implementations of both &BTreeMap and &mut BTreeMap. This is loosening the lifetime bounds, so more code should be accepted with this PR. This is lifetime bounds will still be implicit since we have type Item = (&'a K, &'a V); in the implementation. This change will make the HashMap and BTreeMap share the same signature, so we can share the same function/trait with both HashMap and BTreeMap in the code.

Fixes #74034.
r? @dtolnay hey, I was touching this file on my previous PR and wanted to fix this on the way. Would you mind taking a look at this, or redirecting it if you are busy?

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 5, 2020
Copy link
Contributor

@pickfire pickfire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@nbdd0121
Copy link
Member

nbdd0121 commented Aug 6, 2020

I don't quite understand the reason why K: 'a, V: 'a would make a difference here, isn't this implied because that's needed for &'a BTreeMap<K, V> to be well-formed?

@canova
Copy link
Contributor Author

canova commented Aug 6, 2020

Yeah, 'a lifetime should be implied for K and V, since also we have (&'a K, &'a V) as the Item type. But apparently it does make a difference when we put that lifetime bound to the IntoIterator impl signature. You can see that the test I added doesn't compile without this patch in this playground.

@nbdd0121
Copy link
Member

nbdd0121 commented Aug 6, 2020

What I am suggesting is that this may be an issue with the compiler and we might want to fix that instead.

@canova
Copy link
Contributor Author

canova commented Aug 6, 2020

Well, yes, we can investigate more if we think this is a bug, but I don't think so really. I'm looking all the use cases of IntoIterator implementations in the rust codebase and there is no other implementation that actually adds lifetime bounds to type params: https://dxr.mozilla.org/rust/search?q=%22%3E+IntoIterator+for+%26%27%22&redirect=false
This doesn't look like the correct way of using this trait. Also, I don't see a reason not to land this change, because it's better to make the signatures of HashMap and BTreeMap match each other.

Copy link
Member

@dtolnay dtolnay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@dtolnay
Copy link
Member

dtolnay commented Aug 6, 2020

@bors r+

@bors
Copy link
Collaborator

bors commented Aug 6, 2020

📌 Commit cedf96c has been approved by dtolnay

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 6, 2020
@dtolnay dtolnay added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Aug 6, 2020
@nbdd0121
Copy link
Member

nbdd0121 commented Aug 7, 2020

Well, yes, we can investigate more if we think this is a bug, but I don't think so really.

This is certainly a bug. If you look at the minimal example in the original issue:

fn foo<'a, K, V, I: 'a + IntoIterator<Item = (&'a K, &'a V)>>(i: I) {}

fn bar() {
    let map = HashMap::<u32, u32>::new();
    foo(&map);
    
    let map = BTreeMap::<u32, u32>::new();
    foo(&map);
}

This code is rejected in Rust 2015 for both HashMap and BTreeMap, suggesting that K: 'a and V: 'a must be added. In Rust 2018 this is now implied, so it should accept BTreeMap, regardless that bound is specified implicitly or explicitly. I have no objection to this PR, but I suggest we keep the original issue open or open a new issue after this PR is merged to track this discrepancy.

bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 7, 2020
…arth

Rollup of 4 pull requests

Successful merges:

 - rust-lang#74774 (adds [*mut|*const] ptr::set_ptr_value)
 - rust-lang#75079 (Disallow linking to items with a mismatched disambiguator)
 - rust-lang#75203 (Make `IntoIterator` lifetime bounds of `&BTreeMap` match with `&HashMap` )
 - rust-lang#75227 (Fix ICE when using asm! on an unsupported architecture)

Failed merges:

r? @ghost
@bors bors merged commit 25c8e9a into rust-lang:master Aug 7, 2020
@canova
Copy link
Contributor Author

canova commented Aug 7, 2020

This code is rejected in Rust 2015 for both HashMap and BTreeMap, suggesting that K: 'a and V: 'a must be added. In Rust 2018 this is now implied, so it should accept BTreeMap, regardless that bound is specified implicitly or explicitly. I have no objection to this PR, but I suggest we keep the original issue open or open a new issue after this PR is merged to track this discrepancy.

Hm, this minimal example also fails for HashMap in version 2018 and 2015. So I assume this is not exactly the bug issue tried explain. But you're right, there is something wrong with the example and should be fixed. I can't reopen the previous issue, so I opened #75252 to track this instead. Thanks for the explanation!

@canova canova deleted the btreemap-into-iter branch August 7, 2020 11:41
@cuviper cuviper added this to the 1.47.0 milestone May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inconsistency between &HashMap and &BTreeMap implementation of IntoIterator
7 participants