Rollup merge of #74960 - nbdd0121:typeck, r=nikomatsakis
Fix regionck failure when converting Index to IndexMut Fixes #74933 Consider an overloaded index expression `base[index]`. Without knowing whether it will be mutated, this will initially be desugared into `<U as Index<T>>::index(&base, index)` for some `U` and `T`. Let `V` be the `expr_ty_adjusted` of `index`. If this expression ends up being used in any mutable context (or used in a function call with `&mut self` receiver before #72280), we will need to fix it up. The current code will rewrite it to `<U as IndexMut<V>>::index_mut(&mut base, index)`. In most cases this is fine as `V` will be equal to `T`, however this is not always true when `V/T` are references, as they may have different region. This issue is quite subtle before #72280 as this code path is only used to fixup function receivers, but after #72280 we've made this a common path. The solution is basically just rewrite it to `<U as IndexMut<T>>::index_mut(&mut base, index)`. `T` can retrieved in the fixup path using `node_substs`.
This commit is contained in:
commit
43babed7e2
2 changed files with 62 additions and 13 deletions
38
src/test/ui/typeck/issue-74933.rs
Normal file
38
src/test/ui/typeck/issue-74933.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// check-pass
|
||||
//
|
||||
// rust-lang/rust#74933: Lifetime error when indexing with borrowed index
|
||||
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
struct S(V);
|
||||
struct K<'a>(&'a ());
|
||||
struct V;
|
||||
|
||||
impl<'a> Index<&'a K<'a>> for S {
|
||||
type Output = V;
|
||||
|
||||
fn index(&self, _: &'a K<'a>) -> &V {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IndexMut<&'a K<'a>> for S {
|
||||
fn index_mut(&mut self, _: &'a K<'a>) -> &mut V {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl V {
|
||||
fn foo(&mut self) {}
|
||||
}
|
||||
|
||||
fn test(s: &mut S, k: &K<'_>) {
|
||||
s[k] = V;
|
||||
s[k].foo();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut s = S(V);
|
||||
let k = K(&());
|
||||
test(&mut s, &k);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue