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

Alex Crichton alex at crichton.co
Sun Jan 19 10:17:55 PST 2014


> 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.

Sadly this is correct. Right now type coercion does not happen in all
places, where the return expression is one of them. Coercion is
allowed in let expressions through type ascription and around method
calls.

The conversion is indeed similar, and we've talked about refining this
sort of behavior in the past. This is partly the topic of
https://github.com/mozilla/rust/issues/10504, but specifically
concerning return type coercion I don't think a bug exists.

It can be argued though that coercion on the return type is a little
different than coercion on a function call, though. You've explicitly
listed the return type as &int, but then you return something of type
~int. This reasoning isn't very strong though, and I think I would
personally like to see coercion *everywhere* as opposed to just a few
locations.

> 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,

That is correct. Sadly you cannot instantiate a type parameter T with
something that looks like [U] (but soon you will be able to)!

This is the source of a number of difficulties throughout the stdlib
and language, which is why we definitely intend to fix it!

> 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)?

This sort of coercion is special-cased in the compiler to allow it to
be possible.

> 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.

Ah, it appears I answered this above! I would recommend reading
http://smallcultfollowing.com/babysteps/blog/2014/01/05/dst-take-5/,
the most recent development in DST and it should explain how we intend
to allow this in the future. Soon, hopefully!


More information about the Rust-dev mailing list