Skip to content
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

mismatched types when dereferencing T where T : Deref #20502

Closed
rrichardson opened this issue Jan 4, 2015 · 4 comments
Closed

mismatched types when dereferencing T where T : Deref #20502

rrichardson opened this issue Jan 4, 2015 · 4 comments

Comments

@rrichardson
Copy link

When deref'ing values which impl Deref from other trait impls, I get this mismatch:

main.rs:31:21: 31:30 error: mismatched types: expected `_`, found `<T as core::ops::Deref>::Target` (expected integral variable, found associated type)
main.rs:31         let a = 1 + *self.var;

The basic trait implementation and test case works, such as what is in the example for std::ops::Deref.

The (not so small) reproduction is here:

#![feature(associated_types)]

use std::ops::Deref;
use std::fmt::Show;

struct DerefExample<T> {
    value: T
}

impl<T> Deref for DerefExample<T> {
    type Target = T;

    fn deref<'a>(&'a self) -> &'a T {
        &self.value
    }
}

trait Showy<A> {

    fn dosomething(self);
}

struct MyStruct<T> {
    var: T
}

impl<T> Showy<T> for MyStruct<T>
where T : Deref
{
    fn dosomething(self) {
        let a = 1 + *self.var;//
        let a = 1 + self.var.deref();
    }
}

fn main() {
    let x = DerefExample { value: 1u };
    let y = MyStruct::<DerefExample<uint>> { var: x };
    y.dosomething();

    //assert_eq!('a', *x);
}
@sfackler
Copy link
Member

sfackler commented Jan 4, 2015

That error seems fine to me. The impl where dosomething is defined places no bounds on what T derefs to. <T as Deref>::Target isn't necessarily add-able to an integer.

@rrichardson
Copy link
Author

Afaict it is not complaining about the addition, but the deference into the integer.
I apologize for the distracting +, it was unnecessary. If you change those lines to:

        let a : uint = *self.var;
        let a : uint = self.var.deref();

you get the same result.

@sfackler
Copy link
Member

sfackler commented Jan 4, 2015

Right. There's no constraint on what type T dereferences to. It's not necessarily a uint. What would happen if this compiled and then I did this?:

let x = DerefExample { value: "foobar" };
    let y = MyStruct::<DerefExample<&'static str>> { var: x };
    y.dosomething();

@rrichardson
Copy link
Author

I see your point. In addition, the error that I was seeing that caused me to try to repo seems to have gone away. So I'm going to go ahead and close this.

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

2 participants