[rust-dev] Clone and enum<'a>

Huon Wilson dbau.pp at gmail.com
Tue Jun 3 03:08:26 PDT 2014


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 at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev



More information about the Rust-dev mailing list