Skip to content

Using &mut Trait requires mut local variable for some cases #10088

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mukilan opened this issue Oct 26, 2013 · 4 comments
Closed

Using &mut Trait requires mut local variable for some cases #10088

mukilan opened this issue Oct 26, 2013 · 4 comments

Comments

@mukilan
Copy link
Contributor

mukilan commented Oct 26, 2013

Looks like some cases were not tested in #8398

The following code:

use std::rt::io::Reader;
use std::rt::io::extensions::ReaderUtil;


fn parse(reader: &mut Reader) {
    reader.read_byte();
}

fn main() {
}

still yields a compilation error:

test.rs:6:4: 6:10 error: cannot borrow immutable argument as mutable
test.rs:6     reader.read_byte();
@mukilan
Copy link
Contributor Author

mukilan commented Dec 14, 2013

Issue still present in master. Updating code to compile.

trait Foo {
   fn foo(&mut self);
}

impl<'a> Foo for &'a mut Foo {
    fn foo(&mut self) { self.foo(); }
}

struct S {
    i :int
}


impl Foo for S {
    fn foo(&mut self) {
        self.i = self.i + 1;
    }
}

trait Bar {
    fn bar(&mut self);
}

impl<T: Foo> Bar for T {
    fn bar(&mut self) {
        self.foo();
    }
}

fn main() {
    let s = &mut S{i:0} as &mut Foo;
    s.foo(); // works fine
    s.bar(); // error: cannot borrow immutable local variable as mutable

    let mut s = &mut S{i:0} as &mut Foo;
    s.bar(); // works fine

}

@pnkfelix
Copy link
Member

reading the updated example, I do wonder if this is "working as designed" ... I'm not 100% sure yet (I haven't tried playing around with it locally).

(I'm also not sure if that impl<'a> Foo for &'a mut Foo is quite right ... does it infinite loop in its current state, once you get main to compile? You might need (**self).foo() or something along those lines instead.)

@mukilan
Copy link
Contributor Author

mukilan commented Dec 15, 2013

@pnkfelix : You are right. It does "work as designed". Here's my explanation as to why. Please correct me if I'm wrong. When s.foo() invoked, since s is &mut Foo, the compiler can invoke foo() using the vtable pointer in s. However, when s.bar() is invoked, the compiler has no way of knowing the right trait Bar vtable to use, given that "s" is just &mut Foo . Hence the need for the impl<'a> Foo for &'a mut Foo, which can now be used with impl<T: Foo> Bar for T to create the Bar vtable with the self type as &mut Foo .But since the method is bar(&mut self) , the actual type of the first parameter is &mut &mut Foo and hence s is required to be mutable.

For the original code I submitted in the issue (the one with the &mut Reader), I was told in IRC that it was probably a bug and was asked to raise an issue. But even that was working per design, if the the above explanation is valid and correct.

Shall I close this issue?

@steveklabnik
Copy link
Member

Looks like this should be closed.

@mukilan mukilan closed this as completed Oct 10, 2014
flip1995 pushed a commit to flip1995/rust that referenced this issue Dec 29, 2022
fix manual_filter false positive

fixes rust-lang#10088
fixes rust-lang#9766

changelog: FP: [`manual_filter`]: Now ignores if expressions where the else branch has side effects or doesn't return `None`
[rust-lang#10091](rust-lang/rust-clippy#10091)
<!-- changelog_checked -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants