What causes type matching to fail?

⚓ Rust    📅 2025-08-27    👤 surdeus    👁️ 3      

surdeus

I had a function that called map_or(None, …), which clippy suggests one should change to an .and_then() (because of the None case (it will go on to suggest another change, but that’s not important for my question)). Just copy’n’paste:ing clippy’s suggestion will cause an compilation error, because it detects a mismatched return type:

error[E0308]: mismatched types
  --> src/main.rs:25:9
   |
14 |   impl<K, V> MyMap<K, V>
   |           - expected this type parameter
...
18 |       fn get<'a>(&'a self, k: &'a K) -> Option<(&'a K, &'a V)> {
   |                                         ---------------------- expected `std::option::Option<(&'a K, &'a V)>` because of return type
...
25 | /         self.inner.get(k).and_then(|v| {
26 | |             let v = &v.v;
27 | |             Some((k, v))
28 | |         })
   | |__________^ expected `Option<(&K, &V)>`, found `Option<(&K, &ManuallyDrop<V>)>`
   |
   = note: expected enum `std::option::Option<(&'a _, &'a V)>`
              found enum `std::option::Option<(&_, &std::mem::ManuallyDrop<V>)>`

What’s causing the map_or() case to allow the compiler to detect that it can shoehorn a &ManuallyDrop<V> into a &V, while this isn’t allowed for the and_then() case?

(The fix for the and_then() case is trivial, I’m just curious where the difference in magic matching ability comes from).

3 posts - 3 participants

Read full topic

🏷️ Rust_feed