rust


Why does a reference not live long enough in case of “as_slice”?


I cannot figure out why this code compiles:
fn f(v: &mut Vec<isize>) -> &[isize] {
v.as_mut_slice()
}
and this does not:
fn f(v: &mut Vec<isize>) -> &[isize] {
v.as_slice()
}
producing:
<anon>:2:5: 2:6 error: `v` does not live long enough
<anon>:2 v.as_slice()
^
<anon>:1:38: 3:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 1:37...
<anon>:1 fn f(v: &mut Vec<isize>) -> &[isize] {
<anon>:2 v.as_slice()
<anon>:3 }
<anon>:1:38: 3:2 note: ...but borrowed value is only valid for the block at 1:37
<anon>:1 fn f(v: &mut Vec<isize>) -> &[isize] {
<anon>:2 v.as_slice()
<anon>:3 }
If I understand correctly, in either case function signature is same, and return value lifetime is equal to the input parameter one. So why "as_slice" does not work?
it's a "bug" or better a limitation of the AsSlice trait. Since v.as_slice() is now unstable and will probably be removed in favor of &v[] (which already works as intended in your case) I will not open a bug, but I'll try explaining why the current trait does not work to the best of my knowledge.
First, look at the definition of the as_slice that is invoked in your case.
impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U {
#[inline(always)]
fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
}
note that as_slice is actually eliding a new lifetime. If we give it a name ('b) we're actually writing something like:
impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U {
#[inline(always)]
fn as_slice<'b>(&'b self) -> &'b [T] { AsSlice::as_slice(*self) }
}
What we would actually want is 'b to be the same as 'a, but I think there was no way to express this at the time AsSlice was created (now this might be possible with Higher Ranked Trait Bounds). The effect of this is that, when we call as_slice() in your function f, we're returning a fresh lifetime, that can't escape f. This is in fact the error you're getting.
If AsSlice was written now, it would be using associated types and would be able to link lifetimes in the way we want. It would be something similar to this:
pub trait AsSlice2 {
type Item;
fn as_slice_2(&self) -> & [Self::Item];
}
impl<T> AsSlice2 for [T] {
type Item = T;
fn as_slice_2(&self) -> &[T] { &self[] }
}
playpen
This is similar to how as_mut_slice is currently implemented (that's why that one works)

Related Links

Re-using a range for iteration
How to convert DateTime<UTC> to DateTime<FixedOffset> or vice versa?
Redefine trait for infix operators
Result has no method called “unwrap()”?
Wrapping a Rust struct in a C++ class
How to create a String directly?
Acessing data from a global struct, gives error “borrowed value does not live long enough”
captured variable does not outlive the enclosing closure [duplicate]
PI constant is ambiguous
Calling an impl method from another impl method
compilation of openssl-sys fails with `openssl/hmac.h: No such file or directory`
Indexing a String
Importing mio::tcp::TcpStream but get std::net::tcp::TcpStream
It is possible to always have Cargo show warnings?
Copy files to the target directory after build
Is it ok to return in main?

Categories

HOME
elasticsearch
visual-studio
flask
artificial-intelligence
knockout.js
windows-8.1
yahoo-weather-api
bots
windows-10
haproxy
nsview
embedded-resource
visual-studio-2010
navigation
share
cisco
swarm
solution
xades4j
responsivevoice
sslhandshakeexception
supervisord
c#-7.0
playframework-2.0
robolectric
checkout
scheduled-tasks
adobe-illustrator
adminlte
jest
liferay-6.2
math.js
sparkle
fusion
substance
progid
commonsware-cwac
quickcheck
winrm
busboy
ms-dos
iscroll
assert
windows-store
game-center
grails3.2.0
angular-datatables
word-cloud
expandablelistview
permission-denied
kitura
daz3d
brightscript
freshdesk
mongodb-aggregation
stateless-session-bean
ltrace
instafeedjs
yui3
wininet
zynq
ftp-client
msbuild-4.0
conan
deferred-rendering
adjacency-list
fdt
preferenceactivity
management-studio-express
gitlab-omnibus
unhandled
componentart
unidata
web-api
webproject
thoughtworks-go
jquery-mobile-flipswitch
osascript
treeline
pageviews
ivalueconverter
flipboard
principalcontext
visual-c++-2005
saga
.net-remoting
cmath
2d-vector
contextswitchdeadlock
icenium
dojo-1.9
onconfigurationchanged
audiotoolbox
dynamic-c
fragment-identifier
jdownloader
yahoo-maps
rawcontacts
eai
watchpoint

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App