[rust-dev] Converting ~[T] embedded in struct to &[T]

Ashish Myles marcianx at gmail.com
Sun Jan 19 09:28:21 PST 2014


Thanks for the detailed explanations!

On Sun, Jan 19, 2014 at 2:01 AM, Alex Crichton <alex at crichton.co> wrote:

> >     fn borrow1<'a>(&'a self) -> &'a int {
> >         match (self) {
> >             // error: mismatched types: expected `&'a int` but found
> `~int`
> >             // (expected &-ptr but found ~-ptr)
> >             &Foo(ref v) => *v
> >         }
> >     }
>
> This doesn't work because the local variable v has type &~int, when
> you dereference this you get something of type ~int which if you load
> is a move so you're not allowed to do that. Additionally, the return
> type wants &int when you're giving it ~int
>

What's the reason ~T not coerced to &T the same way as in the main()
function and borrow3 -- ie. why isn't it automatically converted to &**v as
it is in these cases? The conversion is identical, no?  The inability in
this particular context seems rather arbitrary.

> ... *snip* ...

>     fn borrow3<'a>(&'a self) -> &'a [int] {
>         match (self) {
>             // error: mismatched types: expected `&'a [int]` but found
>             // `&<V2>` (expected vector but found &-ptr)
>             &FooVec(ref v) => do_borrow(*v)
>         }
>     }
> }

This doesn't work because the do_borrow function takes something of
> type &int, not ~[int] (which is the type of *v). You'd need to rewrite
> the borrow function to take &[int] instead of &int.
>
> Another solution for vectors is to return v.as_slice() which is a
> function that will convert all forms of vectors to its slice
> representation (&[T])
>
> Hope that helps!
>

Wow, thanks...this worked (surprisingly to me).
fn do_borrow_ary<'a, T>(t : &'a [T]) -> &'a [T] {
    t
}
...
    fn borrow3<'a>(&'a self) -> &'a [int] {
        match (self) {
            // WORKS
            &FooVec(ref v) => do_borrow_ary(*v)
        }
    }

This leads to multiple points of confusion for me.  It seems that [T] is
special-cased in a way that prevents it from being used as a regular type.
In particular,

1. How did do_borrow_ary manage to coerce ~[T] to &[T] when the other
methods (eg. automatic insertion of &*)  failed? Is this special-cased by
the compiler?  Is there some way to trigger this coercion without requiring
an intermediate function like do_borrow_ary (say, if one wants to return a
static array value type, not a slice)?

2. Why did
    fn do_borrow<'a, T>(t : &'a T) -> &'a T
fail to match types? Isn't [S] a type T and of the same kind?  (Any other
language also exhibit this dichotomy?)  This prevents one from being able
to write a truly generic function -- one must duplicate the code for T and
[T] variations.

Ashish
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140119/9673f5f2/attachment.html>


More information about the Rust-dev mailing list