Skip to content

DST coercions and DST fields in structs #14397

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/liballoc/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
// and `nonnull`

use core::ptr::RawPtr;
#[cfg(not(test))] use core::raw;
#[cfg(not(test))] use util;

Expand Down Expand Up @@ -69,6 +70,11 @@ pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint,
/// the value returned by `usable_size` for the requested size.
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
// FIXME(14395) This is only required for DST ~[T], it should be removed once
// we fix that representation to not use null pointers.
if ptr.is_null() {
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The drop glue has the responsibility to not do anything if the entire value is zeroed - structures with a Drop impl have a drop flag by default, and pointers use null values.
For ~T/Box<T>, drop glue makes the null check. I would've expected ~[T]/Box<[T]> to be even more like that after this change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop glue should make the null check, but it was not trivial to do (probably easy, but not trivial - I got bugs which I didn't start to investigate), so I left it for a follow up (the 'hard' case is when the vec has length 0, then I use a null pointer inside the fat pointer).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: put an octothorpe (#) in front of the number in the fixme.

imp::deallocate(ptr, size, align)
}

Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/bitv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2557,7 +2557,7 @@ mod tests {
}

fn rng() -> rand::IsaacRng {
let seed = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
rand::SeedableRng::from_seed(seed)
}

Expand Down
3 changes: 2 additions & 1 deletion src/libcollections/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,8 @@ mod tests {
let n = list_from([1i,2,3]);
spawn(proc() {
check_links(&n);
assert_eq!(&[&1,&2,&3], n.iter().collect::<Vec<&int>>().as_slice());
let a: &[_] = &[&1,&2,&3];
assert_eq!(a, n.iter().collect::<Vec<&int>>().as_slice());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here and elsewhere: Does the <expr> as <type> syntax work yet for coercing a sized type to an unsized one?

E.g. could we here instead write assert_eq!(&[&1,&2,&3] as &[_], n.iter().collect::<Vec<&int>>().as_slice()); ?

I am not sure if it would actually make things look nicer, but it might help stress that a coercion is happening here, not just a type assertion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not. From what I could tell at the time, the as syntax was for casts and coercions were always implicit. In retrospect, I think I am wrong about that. I envisaged addressing this with type ascription. But I think that highlights some potentially confusing overlap between type ascription and explicit casts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I might be using the term "coercion" incorrectly here. anyway the point is whether we have any expression form, other than a let nested in an ExprBlock, for turning a thin pointer into a fat one. But it sounds like we do not have that yet.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nick29581 Anyway, if possible, when you squash your commits together, I would appreciate it if you put these preparatory refactorings on a separate early commit, so that people looking at the history can easily focus in on the substansive changes.

});
}

Expand Down
3 changes: 2 additions & 1 deletion src/libcollections/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,8 @@ mod tests {
assert_eq!(hasher.hash(&'a'), 97);

assert_eq!(hasher.hash(&("a")), 97 + 0xFF);
assert_eq!(hasher.hash(& &[1u8, 2u8, 3u8]), 9);
let cs: &[u8] = &[1u8, 2u8, 3u8];
assert_eq!(hasher.hash(& cs), 9);

unsafe {
let ptr: *const int = mem::transmute(5i);
Expand Down
4 changes: 2 additions & 2 deletions src/libcollections/hash/sip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,8 @@ mod tests {
assert!(s != t && t != u);
assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));

let v = (&[1u8], &[0u8, 0], &[0u8]);
let w = (&[1u8, 0, 0, 0], &[], &[]);
let v: (&[u8], &[u8], &[u8]) = (&[1u8], &[0u8, 0], &[0u8]);
let w: (&[u8], &[u8], &[u8]) = (&[1u8, 0, 0, 0], &[], &[]);

assert!(v != w);
assert!(hash(&v) != hash(&w));
Expand Down
24 changes: 18 additions & 6 deletions src/libcollections/ringbuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ impl<T> RingBuf<T> {
/// buf.push(5i);
/// buf.push(3);
/// buf.push(4);
/// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), &[&5, &3, &4]);
/// let b: &[_] = &[&5, &3, &4];
/// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
/// ```
pub fn iter<'a>(&'a self) -> Items<'a, T> {
Items{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts.as_slice()}
Expand All @@ -263,7 +264,8 @@ impl<T> RingBuf<T> {
/// for num in buf.mut_iter() {
/// *num = *num - 2;
/// }
/// assert_eq!(buf.mut_iter().collect::<Vec<&mut int>>().as_slice(), &[&mut 3, &mut 1, &mut 2]);
/// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
/// assert_eq!(buf.mut_iter().collect::<Vec<&mut int>>().as_slice(), b);
/// ```
pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a, T> {
let start_index = raw_index(self.lo, self.elts.len(), 0);
Expand Down Expand Up @@ -865,12 +867,18 @@ mod tests {
for i in range(0i, 5) {
d.push_back(i);
}
assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), &[&0,&1,&2,&3,&4]);
{
let b: &[_] = &[&0,&1,&2,&3,&4];
assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
}

for i in range(6i, 9) {
d.push_front(i);
}
assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), &[&8,&7,&6,&0,&1,&2,&3,&4]);
{
let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
}

let mut it = d.iter();
let mut len = d.len();
Expand All @@ -890,12 +898,16 @@ mod tests {
for i in range(0i, 5) {
d.push_back(i);
}
assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), &[&4,&3,&2,&1,&0]);
{
let b: &[_] = &[&4,&3,&2,&1,&0];
assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
}

for i in range(6i, 9) {
d.push_front(i);
}
assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), &[&4,&3,&2,&1,&0,&6,&7,&8]);
let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
}

#[test]
Expand Down
Loading