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

Do we need to manually create a destructor for a linked list?
Is it possible to create a macro to implement builder pattern methods?
Safely traversing a directed acyclic graph
Borrowing reference in structure
Is only using references the most idiomatic/efficient for “big” structures?
How to write a method that adds `self` as a mutable trait reference to a collection?
How do I modify a value after matching on it?
Drop a Rust void pointer stored in an FFI
Iterate two vectors and the rest of the larger one
How do I implement Clone/Copy for an enum that contains a String?
Modeling embedded hardware in Rust and how to have multiple mutable references cleanly?
Should I borrow or copy my small data types?
Using pointer casting to change the “type” of data in memory [duplicate]
Export function only to module test?
Take slice of certain length known at compile time
Is it possible to deactivate file locking in cargo?

Categories

HOME
entity-framework
flask
memory
mc
opencart
typelite
selenium-builder
antd
openlayers-3
iverilog
vsts-build
google-play-services
cryptography
gallery
yahoo
nsstring
sap-fiori
smartgwt
asp.net-core-1.0
android-5.1.1-lollipop
vertica
hidden
office-ui-fabric
pfobject
gollum-wiki
mod-wsgi
hevc
amazon-cloudtrail
tsung
toad
instructions
windows2012
cucumber-junit
counting
markov-chains
jfxtras
spring-restcontroller
oauth2
grails-spring-security
vb.net-to-c#
access-denied
fiware-wirecloud
doctrine-extensions
directwrite
cloudwatch
icecast
node-apn
exc-bad-access
wikimapia
predicates
google-shopping-api
yargs
xcode8-beta4
piping
eclemma
odp.net-managed
facebook-ios-sdk
accessibilityservice
jsr363
odesk
directx-9
compositetype
swagger-maven-plugin
shell-extensions
microsoft-expression-web
tabris
two.js
principalcontext
jmenubar
pbkdf2
saga
eclim
mp4parser
jquery-transit
codahale-metrics
google-code-prettify
arel
donut-chart
lynx
idispatch
playorm
getopt-long
voice-recording
kobold2d
firebird1.5
kolite
page-curl
mediacontroller
ccl
raw-data
rational-unified-process
fxruby
rtti
accumulator
ning
version-control-migration
account-management

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