Given code like `v[&field].boo();` where `field: String` and `.boo(&mut self)`, typeck will have decided that `v` is accessed using `Index`, but when `boo` adds a new `mut` obligation, `convert_place_op_to_mutable` is called. When this happens, for *some reason* the arguments' dereference adjustments are completely ignored causing an error saying that `IndexMut` is not satisfied: ``` error[E0596]: cannot borrow data in an index of `Indexable` as mutable --> src/main.rs:30:5 | 30 | v[&field].boo(); | ^^^^^^^^^ cannot borrow as mutable | = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `Indexable` ``` This is not true, but by changing `try_overloaded_place_op` to retry when given `Needs::MutPlace` without passing the argument types, the example successfully compiles. I believe there might be more appropriate ways to deal with this.
29 lines
503 B
Rust
29 lines
503 B
Rust
// check-pass
|
|
struct Indexable;
|
|
|
|
impl Indexable {
|
|
fn boo(&mut self) {}
|
|
}
|
|
|
|
impl std::ops::Index<&str> for Indexable {
|
|
type Output = Indexable;
|
|
|
|
fn index(&self, field: &str) -> &Indexable {
|
|
self
|
|
}
|
|
}
|
|
|
|
impl std::ops::IndexMut<&str> for Indexable {
|
|
fn index_mut(&mut self, field: &str) -> &mut Indexable {
|
|
self
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let mut v = Indexable;
|
|
let field = "hello".to_string();
|
|
|
|
v[field.as_str()].boo();
|
|
|
|
v[&field].boo(); // < This should work
|
|
}
|