Skip to content

autoderef: (&mut foo[bar]).baz() works, but foo[bar].baz() fails to type check due to wrong deref #21630

@japaric

Description

@japaric

STR

use std::ops::{Index, IndexMut};

struct Foo;
struct Bar(Vec<i8>);

#[cfg(not(works))]
impl Index<Foo> for Bar {
    type Output = [i8];

    fn index(&self, _: &Foo) -> &[i8] {
        &*self.0
    }
}

#[cfg(works)]
impl Index<Foo> for Bar {
    type Output = Vec<i8>;

    fn index(&self, _: &Foo) -> &Vec<i8> {
        &self.0
    }
}

impl IndexMut<Foo> for Bar {
    type Output = Vec<i8>;

    fn index_mut(&mut self, _: &Foo) -> &mut Vec<i8> {
        &mut self.0
    }
}

fn test(bar: &mut Bar) {
    // these two should work
    bar[Foo].push(0);  //~ error: type `[i8]` does not implement any method in scope named `push`
    (&mut bar[Foo]).push(0);  // OK
}

fn main() {}

Version

rustc 1.0.0-nightly (4e4e8cff1 2015-01-24 22:14:14 +0000)

When <Bar as Index<Foo>>::Output == <Bar as IndexMut<Foo>>::Output == Vec<i8>, the bar[Foo].push(0) method call properly derefs bar[Foo] to Vec<i8>. But, when [i8] = <Bar as Index<Foo>>::Output != <Bar as IndexMut<Foo>>::Output = Vec<i8>, the method call wrongly derefs bar[Foo] to [i8]. In both cases explictly using (&mut bar[Foo]).push(0) does work.

cc @nikomatsakis @nick29581

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-resolveArea: Name/path resolution done by `rustc_resolve` specifically

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions