"Expected mutable reference `&mut ()`, found mutable reference `&mut ()`"
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
fn foo(t: &mut ()) -> &mut () {
t
}
fn bar<T, E>(_: impl FnOnce(&mut T) -> E) {}
fn test() {
bar(foo)
}
Current output
error[E0308]: mismatched types
--> src/lib.rs:8:5
|
8 | bar(foo)
| ^^^ one type is more general than the other
|
= note: expected mutable reference `&mut ()`
found mutable reference `&mut ()`
note: the lifetime requirement is introduced here
--> src/lib.rs:5:40
|
5 | fn bar<T, E>(_: impl FnOnce(&mut T) -> E) {}
| ^
For more information about this error, try `rustc --explain E0308`.
Desired output
Something that allows to distinguish the lifetimes.
I doubt this is a false compiler error, because the following compiles just fine:
fn foo(t: &mut ()) -> &mut () {
t
}
fn bar<'a, T: 'a, E: 'a>(_: impl FnOnce(&'a mut T) -> E) {}
fn test() {
bar(foo)
}
Rationale and extra context
No response
Other cases
The output above is from 1.75.0-beta.1.
This is what 1.62.1 gives me:
error[E0308]: mismatched types
--> src/lib.rs:8:5
|
8 | bar(foo)
| ^^^ lifetime mismatch
|
= note: expected associated type `<for<'r> fn(&'r mut ()) -> &'r mut () {foo} as FnOnce<(&mut (),)>>::Output`
found associated type `<for<'r> fn(&'r mut ()) -> &'r mut () {foo} as FnOnce<(&mut (),)>>::Output`
= note: the required lifetime does not necessarily outlive the empty lifetime
note: the lifetime requirement is introduced here
--> src/lib.rs:5:40
|
5 | fn bar<T, E>(_: impl FnOnce(&mut T) -> E) {}
| ^
For more information about this error, try `rustc --explain E0308`.
Which is even worse.
cargo-bisect-rustc tells me the error message changed at some point during e3dfeeaa45f117281b19773d67f3f253de65cee1...900c3540378c8422b8087ffa3db60fa6c8abfcad
Anything else?
Initially I was trying to write a function like RefMut::filter_map, but for Result instead of Option
Came up with this piece of code:
fn try_map<'a, T, U, E, F>(mut r: RefMut<'a, T>, f: F) -> Result<RefMut<'a, U>, E>
where
T: ?Sized + 'a,
U: ?Sized + 'a,
F: FnOnce(&mut T) -> Result<&mut U, E>,
{
let t: *mut T = r.deref_mut() as *mut T;
let u: *mut U = f(unsafe { &mut *t })? as *mut U;
Ok(RefMut::<'a, T>::map(r, |_| unsafe { &mut *u }))
}
& was trying to test that you cannot leak any 'a data in E. (That's where I was greeted with a similar error message saying it found Result<_, &mut ...> where Result<_, &mut ...> was expected.)
Anyways, is this implementation actually sound or am I missing something?
If it's not, is it even possible to do something like this in Rust at all?
If it is okay, I would actually love to try to get this into std. Any tip on what I should start with in that case? An "RFC" thing or a simple PR?
Thanks!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the example in src/lib.rs and compare the E0308 diagnostics across the reported compiler versions, using cargo-bisect-rustc around e3dfeeaa45f117281b19773d67f3f253de65cee1...900c3540378c8422b8087ffa3db60fa6c8abfcad. Start with rustc --explain E0308 and the lifetime mismatch output; done means the diagnostic distinguishes the relevant lifetimes without obscuring the mismatch.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100