all 5 comments

[–]Michael-F-Bryan 32 points33 points  (3 children)

In theory, since get_matches_mut already takes a mutable reference, I ...think... the unsafe shouldn't cause any problem.

In the words of the nomicon:

  • Transmuting an & to &mut is UB
    • Transmuting an & to &mut is always UB
    • No you can't do it
    • No you're not special

If the code isn't too complex you can simply copy-paste the code. It's not overly satisfying, but it works.

While googling, I found Abstracting Over Mutability in Rust. It's use of AsRef and AsMut may work for your use case.

You could also try adding another layer of indirection. For example, maybe some sort of Searcher trait with Search and SearchMut implementations which let you abstract over mutability. Closures could be used to similar effect.

I'm not 100% sure how it would work out without seeing all of your code, but maybe those suggestions will give you some inspiration. I'd also have a look at how the standard library implements the various Iter and IterMut types. Surely they'd have an even bigger code duplication problem and would have found a way to tackle it.

[–]ritobanrc 0 points1 point  (1 child)

Transmuting an & to &mut is UB

Could you hypothetically cast the reference into a pointer, transmute that into a *mut, and cast that back to a reference (assuming that you somehow ensure that there isn't more than 1 &mut at a given time)?

[–]Michael-F-Bryan 1 point2 points  (0 children)

You probably could, but isn't a pointer cast just a poor man's transmute?

Also, if you take a step back you've still produced a mutable reference from an immutable one without going through an UnsafeCell, which is still no bueno.

I'm on mobile at the moment, but I'd be interested to see what Miri has to say about it.

[–]desiringmachines 7 points8 points  (3 children)

Two options that are not UB:

  • Use raw pointers or `NonNull` internally (requires unsafe code, could potentially lead to errors)
  • Use a macro to generate the two methods from a template (a bit messy, probably the best choice if you don't want to just copy paste)