-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.Performance or correctness regression from stable to nightly.
Description
#35447 replaced a *const T
by a *mut T
in IntoIter<T>
, which changed IntoIter
from being covariant to being invariant. This breaks crates like vec_map
which relied on IntoIter
being invariant, e.g. https://travis-ci.org/asajeffrey/presort/jobs/152720189#L208 has error:
error[E0308]: mismatched types
--> /home/ajeffrey/.cargo/registry/src/github.com-1ecc6299db9ec823/vec_map-0.6.0/src/lib.rs:952:84
|
952 | fn into_iter_covariant<'a, T>(iter: IntoIter<&'static T>) -> IntoIter<&'a T> { iter }
| ^^^^ lifetime mismatch
|
= note: expected type `IntoIter<&'a T>`
= note: found type `IntoIter<&'static T>`
note: the lifetime 'a as defined on the block at 952:81...
--> /home/ajeffrey/.cargo/registry/src/github.com-1ecc6299db9ec823/vec_map-0.6.0/src/lib.rs:952:82
|
952 | fn into_iter_covariant<'a, T>(iter: IntoIter<&'static T>) -> IntoIter<&'a T> { iter }
| ^^^^^^^^
= note: ...does not necessarily outlive the static lifetime
Compiling rustc-serialize v0.3.19
error: aborting due to previous error
Metadata
Metadata
Assignees
Labels
T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.Performance or correctness regression from stable to nightly.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
apasel422 commentedon Aug 16, 2016
See my comment here: #35447 (comment)
frewsxcv commentedon Aug 16, 2016
I'll be honest, I don't entirely know what covariant means, but I'm sorry for whatever pain it caused and wouldn't be offended if it got reverted.
Does anyone know of a resource explaining the terms 'covariant' and 'invariant' in this context?
asajeffrey commentedon Aug 16, 2016
@frewsxcv the docs on variance are at https://doc.rust-lang.org/nomicon/subtyping.html
apasel422 commentedon Aug 16, 2016
@frewsxcv: Basically, we just need to change
ptr: *mut T
back toptr: *const T
.asajeffrey commentedon Aug 16, 2016
@apasel422 is it safe to do that without also removing
as_mut_slice
?frewsxcv commentedon Aug 16, 2016
We probably need something like this for
IntoIter
.apasel422 commentedon Aug 16, 2016
@asajeffrey It seems to me that
IntoIter<T>
is logically aVec<T>
, so ifVec<T>
is covariant inT
and supports deref-ing to a mutable slice, thenIntoIter<T>
should also be OK to provideas_mut_slice
.asajeffrey commentedon Aug 16, 2016
@apasel422 okay, good point. The thing that's worrying me is that the *const T is being treated as a constant pointer by LLVM, which may trigger unsafe LLVM optimizations it it's then exposed as a &mut[T].
asajeffrey commentedon Aug 16, 2016
@apasel422 I think the difference is that
Vec
can be aUnique
pointer, whereasIntoIter
has two pointers into the vector, in order to be double-ended, so can't beUnique
.apasel422 commentedon Aug 16, 2016
@asajeffrey It's already safe to cast a
*const T
to a*mut T
. The standard library does this all over the place, including inRawVec
(which internally usesUnique
), which is howVec<T>
is covariant in the first place.In terms of duplicating
Unique
, yes, eventually Rust might make use of optimizations that indicate that the underlying pointer is globally unaliased, so we should probably useShared
here, or at the very least, something that isn'tUnique
(e.g. two*const T
s). I made a similar fix in #34608.asajeffrey commentedon Aug 16, 2016
@apasel422 okay, sounds like I'm being overly conservative!
17 remaining items