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

method resolution problem related to Box<Trait> #38425

Open
whitequark opened this Issue Dec 17, 2016 · 2 comments

Comments

Projects
None yet
3 participants
@whitequark
Copy link
Member

whitequark commented Dec 17, 2016

To reproduce:

use std::ops::{Deref, DerefMut};
use std::borrow::BorrowMut;

pub enum Managed<'a, T: 'a + ?Sized> {
    Borrowed(&'a mut T),
    Owned(Box<BorrowMut<T>>)
}

impl<'a, T: 'a + ?Sized> Deref for Managed<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        match self {
            &Managed::Borrowed(ref value) => value,
            &Managed::Owned(ref value) => value.borrow()
        }
    }
}

impl<'a, T: 'a + ?Sized> DerefMut for Managed<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        match self {
            &mut Managed::Borrowed(ref mut value) => value,
            &mut Managed::Owned(ref mut value) => value.borrow_mut()
        }
    }
}

If you comment the impl DerefMut, everything compiles. If you uncomment it:

error[E0277]: the trait bound `Box<std::borrow::BorrowMut<T> + 'static>: std::borrow::Borrow<T>` is not satisfied
  --> <anon>:24:57
   |
24 |             &mut Managed::Owned(ref mut value) => value.borrow_mut()
   |                                                         ^^^^^^^^^^ trait `Box<std::borrow::BorrowMut<T> + 'static>: std::borrow::Borrow<T>` not satisfied
   |
   = help: the following implementations were found:
   = help:   <Box<T> as std::borrow::Borrow<T>>

which seems clearly nonsensical.

Changing value.borrow_mut() to (**value).borrow_mut() fixes it.

@talchas

This comment has been minimized.

Copy link

talchas commented Dec 17, 2016

In addition, doing use std::borrow::Borrow; breaks the earlier Deref impl, which is even weirder.

@Mark-Simulacrum

This comment has been minimized.

Copy link
Member

Mark-Simulacrum commented Dec 21, 2016

Simplified the test case:

use std::ops::Deref;
use std::borrow::Borrow;

struct A(Box<Borrow<u32>>);

impl Deref for A {
    type Target = u32;

    fn deref(&self) -> &u32 {
        self.0.borrow()
    }
}

fn main() {}

Error:

rustc 1.15.0-nightly (71c06a56a 2016-12-18)
error[E0277]: the trait bound `Box<std::borrow::Borrow<u32>>: std::borrow::Borrow<u32>` is not satisfied
  --> <anon>:10:16
   |
10 |         self.0.borrow()
   |                ^^^^^^ the trait `std::borrow::Borrow<u32>` is not implemented for `Box<std::borrow::Borrow<u32>>`
   |
   = help: the following implementations were found:
   = help:   <Box<T> as std::borrow::Borrow<T>>

error: aborting due to previous error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.