Skip to content
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

Issue 2263 fn subtyping #3872

Closed
Closed
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
11 changes: 11 additions & 0 deletions src/libcore/at_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,23 @@ pub pure fn from_elem<T: Copy>(n_elts: uint, t: T) -> @[T] {
#[cfg(notest)]
pub mod traits {
#[legacy_exports];

#[cfg(stage0)]
pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
#[inline(always)]
pure fn add(rhs: & &[const T]) -> @[T] {
append(self, (*rhs))
}
}

#[cfg(stage1)]
#[cfg(stage2)]
pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
#[inline(always)]
pure fn add(rhs: & &self/[const T]) -> @[T] {
append(self, (*rhs))
}
}
}

#[cfg(test)]
Expand Down
18 changes: 18 additions & 0 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,19 +226,37 @@ impl<T> *const T : Ord {
}

// Equality for region pointers
#[cfg(stage0)]
impl<T:Eq> &const T : Eq {
pure fn eq(other: & &const T) -> bool { return *self == *(*other); }
pure fn ne(other: & &const T) -> bool { return *self != *(*other); }
}

#[cfg(stage1)]
#[cfg(stage2)]
impl<T:Eq> &const T : Eq {
pure fn eq(other: & &self/const T) -> bool { return *self == *(*other); }
pure fn ne(other: & &self/const T) -> bool { return *self != *(*other); }
}

// Comparison for region pointers
#[cfg(stage0)]
impl<T:Ord> &const T : Ord {
pure fn lt(other: & &const T) -> bool { *self < *(*other) }
pure fn le(other: & &const T) -> bool { *self <= *(*other) }
pure fn ge(other: & &const T) -> bool { *self >= *(*other) }
pure fn gt(other: & &const T) -> bool { *self > *(*other) }
}

#[cfg(stage1)]
#[cfg(stage2)]
impl<T:Ord> &const T : Ord {
pure fn lt(other: & &self/const T) -> bool { *self < *(*other) }
pure fn le(other: & &self/const T) -> bool { *self <= *(*other) }
pure fn ge(other: & &self/const T) -> bool { *self >= *(*other) }
pure fn gt(other: & &self/const T) -> bool { *self > *(*other) }
}

#[test]
pub fn test() {
unsafe {
Expand Down
38 changes: 37 additions & 1 deletion src/libcore/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ pure fn gt(a: &str, b: &str) -> bool {
!le(a, b)
}

#[cfg(stage0)]
impl &str : Eq {
#[inline(always)]
pure fn eq(other: & &str) -> bool {
Expand All @@ -744,6 +745,17 @@ impl &str : Eq {
pure fn ne(other: & &str) -> bool { !self.eq(other) }
}

#[cfg(stage1)]
#[cfg(stage2)]
impl &str : Eq {
#[inline(always)]
pure fn eq(other: & &self/str) -> bool {
eq_slice(self, (*other))
}
#[inline(always)]
pure fn ne(other: & &self/str) -> bool { !self.eq(other) }
}

impl ~str : Eq {
#[inline(always)]
pure fn eq(other: &~str) -> bool {
Expand Down Expand Up @@ -773,6 +785,7 @@ impl ~str : Ord {
pure fn gt(other: &~str) -> bool { gt(self, (*other)) }
}

#[cfg(stage0)]
impl &str : Ord {
#[inline(always)]
pure fn lt(other: & &str) -> bool { lt(self, (*other)) }
Expand All @@ -784,6 +797,19 @@ impl &str : Ord {
pure fn gt(other: & &str) -> bool { gt(self, (*other)) }
}

#[cfg(stage1)]
#[cfg(stage2)]
impl &str : Ord {
#[inline(always)]
pure fn lt(other: & &self/str) -> bool { lt(self, (*other)) }
#[inline(always)]
pure fn le(other: & &self/str) -> bool { le(self, (*other)) }
#[inline(always)]
pure fn ge(other: & &self/str) -> bool { ge(self, (*other)) }
#[inline(always)]
pure fn gt(other: & &self/str) -> bool { gt(self, (*other)) }
}

impl @str : Ord {
#[inline(always)]
pure fn lt(other: &@str) -> bool { lt(self, (*other)) }
Expand Down Expand Up @@ -2096,12 +2122,22 @@ impl ~str: Trimmable {

#[cfg(notest)]
pub mod traits {
#[cfg(stage0)]
impl ~str : Add<&str,~str> {
#[inline(always)]
pure fn add(rhs: & &str) -> ~str {
append(copy self, (*rhs))
}
}

#[cfg(stage1)]
#[cfg(stage2)]
impl ~str : Add<&str,~str> {
#[inline(always)]
pure fn add(rhs: & &self/str) -> ~str {
append(copy self, (*rhs))
}
}
}

#[cfg(test)]
Expand Down Expand Up @@ -2558,7 +2594,7 @@ mod tests {
assert find_str_between(data, ~"ab", 2u, 4u).is_none();

let mut data = ~"ประเทศไทย中华Việt Nam";
data += data;
data = data + data;
assert find_str_between(data, ~"", 0u, 43u) == Some(0u);
assert find_str_between(data, ~"", 6u, 43u) == Some(6u);

Expand Down
88 changes: 81 additions & 7 deletions src/libcore/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,27 @@ pub pure fn filter<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> ~[T] {
move result
}

/**
* Like `filter()`, but in place. Preserves order of `v`. Linear time.
*/
pub fn retain<T>(v: &mut ~[T], f: pure fn(t: &T) -> bool) {
let len = v.len();
let mut deleted: uint = 0;

for uint::range(0, len) |i| {
if !f(&v[i]) {
deleted += 1;
} else if deleted > 0 {
v[i - deleted] <-> v[i];
}
}

while deleted > 0 {
v.pop();
deleted -= 1;
}
}

/**
* Concatenate a vector of vectors.
*
Expand All @@ -759,14 +780,17 @@ pub pure fn connect<T: Copy>(v: &[~[T]], sep: &T) -> ~[T] {
}

/// Reduce a vector from left to right
pub pure fn foldl<T: Copy, U>(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T {
let mut accum = z;
for each(v) |elt| {
// it should be possible to move accum in, but the liveness analysis
// is not smart enough.
accum = p(accum, elt);
pub pure fn foldl<T, U>(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T {
let mut accum = move z;
let mut i = 0;
let l = v.len();
while i < l {
// Use a while loop so that liveness analysis can handle moving
// the accumulator.
accum = p(move accum, &v[i]);
i += 1;
}
return accum;
return move accum;
}

/// Reduce a vector from right to left
Expand Down Expand Up @@ -1293,13 +1317,24 @@ pure fn eq<T: Eq>(a: &[T], b: &[T]) -> bool {
return true;
}

#[cfg(stage0)]
impl<T: Eq> &[T] : Eq {
#[inline(always)]
pure fn eq(other: & &[T]) -> bool { eq(self, (*other)) }
#[inline(always)]
pure fn ne(other: & &[T]) -> bool { !self.eq(other) }
}

#[cfg(stage1)]
#[cfg(stage2)]
impl<T: Eq> &[T] : Eq {
#[inline(always)]
pure fn eq(other: & &self/[T]) -> bool { eq(self, (*other)) }
#[inline(always)]
pure fn ne(other: & &self/[T]) -> bool { !self.eq(other) }
}


impl<T: Eq> ~[T] : Eq {
#[inline(always)]
pure fn eq(other: &~[T]) -> bool { eq(self, (*other)) }
Expand Down Expand Up @@ -1335,6 +1370,7 @@ pure fn le<T: Ord>(a: &[T], b: &[T]) -> bool { !lt(b, a) }
pure fn ge<T: Ord>(a: &[T], b: &[T]) -> bool { !lt(a, b) }
pure fn gt<T: Ord>(a: &[T], b: &[T]) -> bool { lt(b, a) }

#[cfg(stage0)]
impl<T: Ord> &[T] : Ord {
#[inline(always)]
pure fn lt(other: & &[T]) -> bool { lt(self, (*other)) }
Expand All @@ -1346,6 +1382,19 @@ impl<T: Ord> &[T] : Ord {
pure fn gt(other: & &[T]) -> bool { gt(self, (*other)) }
}

#[cfg(stage1)]
#[cfg(stage2)]
impl<T: Ord> &[T] : Ord {
#[inline(always)]
pure fn lt(other: & &self/[T]) -> bool { lt(self, (*other)) }
#[inline(always)]
pure fn le(other: & &self/[T]) -> bool { le(self, (*other)) }
#[inline(always)]
pure fn ge(other: & &self/[T]) -> bool { ge(self, (*other)) }
#[inline(always)]
pure fn gt(other: & &self/[T]) -> bool { gt(self, (*other)) }
}

impl<T: Ord> ~[T] : Ord {
#[inline(always)]
pure fn lt(other: &~[T]) -> bool { lt(self, (*other)) }
Expand All @@ -1370,19 +1419,39 @@ impl<T: Ord> @[T] : Ord {

#[cfg(notest)]
pub mod traits {
#[cfg(stage0)]
impl<T: Copy> ~[T] : Add<&[const T],~[T]> {
#[inline(always)]
pure fn add(rhs: & &[const T]) -> ~[T] {
append(copy self, (*rhs))
}
}

#[cfg(stage1)]
#[cfg(stage2)]
impl<T: Copy> ~[T] : Add<&[const T],~[T]> {
#[inline(always)]
pure fn add(rhs: & &self/[const T]) -> ~[T] {
append(copy self, (*rhs))
}
}

#[cfg(stage0)]
impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> {
#[inline(always)]
pure fn add(rhs: & &[const T]) -> ~[mut T] {
append_mut(copy self, (*rhs))
}
}

#[cfg(stage1)]
#[cfg(stage2)]
impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> {
#[inline(always)]
pure fn add(rhs: & &self/[const T]) -> ~[mut T] {
append_mut(copy self, (*rhs))
}
}
}

#[cfg(test)]
Expand Down Expand Up @@ -1590,6 +1659,7 @@ pub trait MutableVector<T> {
fn unshift(&mut self, x: T);
fn swap_remove(&mut self, index: uint) -> T;
fn truncate(&mut self, newlen: uint);
fn retain(&mut self, f: pure fn(t: &T) -> bool);
}

pub trait MutableCopyableVector<T: Copy> {
Expand Down Expand Up @@ -1631,6 +1701,10 @@ impl<T> ~[T]: MutableVector<T> {
fn truncate(&mut self, newlen: uint) {
truncate(self, newlen);
}

fn retain(&mut self, f: pure fn(t: &T) -> bool) {
retain(self, f);
}
}

impl<T: Copy> ~[T]: MutableCopyableVector<T> {
Expand Down
2 changes: 1 addition & 1 deletion src/rustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ fn enc_region(w: io::Writer, cx: @ctxt, r: ty::Region) {
ty::re_static => {
w.write_char('t');
}
ty::re_var(_) => {
ty::re_infer(_) => {
// these should not crop up after typeck
cx.diag.handler().bug(~"Cannot encode region variables");
}
Expand Down
2 changes: 1 addition & 1 deletion src/rustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ impl ty::Region: tr {
ty::re_bound(br) => ty::re_bound(br.tr(xcx)),
ty::re_free(id, br) => ty::re_free(xcx.tr_id(id), br.tr(xcx)),
ty::re_scope(id) => ty::re_scope(xcx.tr_id(id)),
ty::re_static | ty::re_var(*) => self,
ty::re_static | ty::re_infer(*) => self,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/rustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ fn check_cast_for_escaping_regions(
match target_substs.self_r {
Some(ty::re_scope(*)) => { return; /* case (1) */ }
None | Some(ty::re_static) | Some(ty::re_free(*)) => {}
Some(ty::re_bound(*)) | Some(ty::re_var(*)) => {
Some(ty::re_bound(*)) | Some(ty::re_infer(*)) => {
cx.tcx.sess.span_bug(
source.span,
fmt!("bad region found in kind: %?", target_substs.self_r));
Expand Down
20 changes: 10 additions & 10 deletions src/rustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,18 @@ fn is_subregion_of(region_map: region_map,
super_region: ty::Region) -> bool {
sub_region == super_region ||
match (sub_region, super_region) {
(_, ty::re_static) => {
true
}
(_, ty::re_static) => {
true
}

(ty::re_scope(sub_scope), ty::re_scope(super_scope)) |
(ty::re_scope(sub_scope), ty::re_free(super_scope, _)) => {
scope_contains(region_map, super_scope, sub_scope)
}
(ty::re_scope(sub_scope), ty::re_scope(super_scope)) |
(ty::re_scope(sub_scope), ty::re_free(super_scope, _)) => {
scope_contains(region_map, super_scope, sub_scope)
}

_ => {
false
}
_ => {
false
}
}
}

Expand Down
Loading