Somewhat. It is due to auto-deref: deriving(Clone) essentially expands to

    fn clone(&self) -> List<'a> {
        match *self {
            Nil => Nil,
            Next(ref x) => Next(x.clone())
        }
    }

`x` is of type `&&List<'a>`, but the `x.clone()` call auto-derefs through both layers of & to be calling List's clone directly (returning a `List<'a>`), rather than duplicating the reference.

This will be fixed with UFCS, which will allow deriving to expand to something like `Next(Clone::clone(x))` and this does not undergo auto-deref.


You can work around this by writing a Clone implementation by hand. In this case, List is Copy, so the implementation can be written as

    impl<'a> Clone for List<'a> {
        fn clone(&self) -> List<'a> {
            *self
        }
    }

(Clone for more "interesting" List types (which aren't Copy, in general) will likely need to be implemented with a match and some internal Clones.)

Huon


On 03/06/14 19:59, Igor Bukanov wrote:
Consider the following enum:

#[deriving(Clone)]
enum List<'a> {
     Nil,
     Next(&'a List<'a>)
}


It generates en error:

<anon>:4:10: 4:22 error: mismatched types: expected `&List<>` but
found `List<>` (expected &-ptr but found enum List)
<anon>:4     Next(&'a List<'a>)
                   ^~~~~~~~~~~~
note: in expansion of #[deriving]
<anon>:1:1: 2:5 note: expansion site
error: aborting due to previous error

Is it a bug in #[deriving] ?
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to