Skip to content

Commit 1a3a707

Browse files
committed
Implement proper subtyping for region fn types (part of #2263)
1 parent f04a6fc commit 1a3a707

20 files changed

+877
-417
lines changed

src/libcore/at_vec.rs

+11
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,23 @@ pub pure fn from_elem<T: Copy>(n_elts: uint, t: T) -> @[T] {
136136
#[cfg(notest)]
137137
pub mod traits {
138138
#[legacy_exports];
139+
140+
#[cfg(stage0)]
139141
pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
140142
#[inline(always)]
141143
pure fn add(rhs: & &[const T]) -> @[T] {
142144
append(self, (*rhs))
143145
}
144146
}
147+
148+
#[cfg(stage1)]
149+
#[cfg(stage2)]
150+
pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
151+
#[inline(always)]
152+
pure fn add(rhs: & &self/[const T]) -> @[T] {
153+
append(self, (*rhs))
154+
}
155+
}
145156
}
146157

147158
#[cfg(test)]

src/libcore/ptr.rs

+18
Original file line numberDiff line numberDiff line change
@@ -226,19 +226,37 @@ impl<T> *const T : Ord {
226226
}
227227

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

235+
#[cfg(stage1)]
236+
#[cfg(stage2)]
237+
impl<T:Eq> &const T : Eq {
238+
pure fn eq(other: & &self/const T) -> bool { return *self == *(*other); }
239+
pure fn ne(other: & &self/const T) -> bool { return *self != *(*other); }
240+
}
241+
234242
// Comparison for region pointers
243+
#[cfg(stage0)]
235244
impl<T:Ord> &const T : Ord {
236245
pure fn lt(other: & &const T) -> bool { *self < *(*other) }
237246
pure fn le(other: & &const T) -> bool { *self <= *(*other) }
238247
pure fn ge(other: & &const T) -> bool { *self >= *(*other) }
239248
pure fn gt(other: & &const T) -> bool { *self > *(*other) }
240249
}
241250

251+
#[cfg(stage1)]
252+
#[cfg(stage2)]
253+
impl<T:Ord> &const T : Ord {
254+
pure fn lt(other: & &self/const T) -> bool { *self < *(*other) }
255+
pure fn le(other: & &self/const T) -> bool { *self <= *(*other) }
256+
pure fn ge(other: & &self/const T) -> bool { *self >= *(*other) }
257+
pure fn gt(other: & &self/const T) -> bool { *self > *(*other) }
258+
}
259+
242260
#[test]
243261
pub fn test() {
244262
unsafe {

src/libcore/str.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,7 @@ pure fn gt(a: &str, b: &str) -> bool {
735735
!le(a, b)
736736
}
737737

738+
#[cfg(stage0)]
738739
impl &str : Eq {
739740
#[inline(always)]
740741
pure fn eq(other: & &str) -> bool {
@@ -744,6 +745,17 @@ impl &str : Eq {
744745
pure fn ne(other: & &str) -> bool { !self.eq(other) }
745746
}
746747

748+
#[cfg(stage1)]
749+
#[cfg(stage2)]
750+
impl &str : Eq {
751+
#[inline(always)]
752+
pure fn eq(other: & &self/str) -> bool {
753+
eq_slice(self, (*other))
754+
}
755+
#[inline(always)]
756+
pure fn ne(other: & &self/str) -> bool { !self.eq(other) }
757+
}
758+
747759
impl ~str : Eq {
748760
#[inline(always)]
749761
pure fn eq(other: &~str) -> bool {
@@ -773,6 +785,7 @@ impl ~str : Ord {
773785
pure fn gt(other: &~str) -> bool { gt(self, (*other)) }
774786
}
775787

788+
#[cfg(stage0)]
776789
impl &str : Ord {
777790
#[inline(always)]
778791
pure fn lt(other: & &str) -> bool { lt(self, (*other)) }
@@ -784,6 +797,19 @@ impl &str : Ord {
784797
pure fn gt(other: & &str) -> bool { gt(self, (*other)) }
785798
}
786799

800+
#[cfg(stage1)]
801+
#[cfg(stage2)]
802+
impl &str : Ord {
803+
#[inline(always)]
804+
pure fn lt(other: & &self/str) -> bool { lt(self, (*other)) }
805+
#[inline(always)]
806+
pure fn le(other: & &self/str) -> bool { le(self, (*other)) }
807+
#[inline(always)]
808+
pure fn ge(other: & &self/str) -> bool { ge(self, (*other)) }
809+
#[inline(always)]
810+
pure fn gt(other: & &self/str) -> bool { gt(self, (*other)) }
811+
}
812+
787813
impl @str : Ord {
788814
#[inline(always)]
789815
pure fn lt(other: &@str) -> bool { lt(self, (*other)) }
@@ -2096,12 +2122,22 @@ impl ~str: Trimmable {
20962122

20972123
#[cfg(notest)]
20982124
pub mod traits {
2125+
#[cfg(stage0)]
20992126
impl ~str : Add<&str,~str> {
21002127
#[inline(always)]
21012128
pure fn add(rhs: & &str) -> ~str {
21022129
append(copy self, (*rhs))
21032130
}
21042131
}
2132+
2133+
#[cfg(stage1)]
2134+
#[cfg(stage2)]
2135+
impl ~str : Add<&str,~str> {
2136+
#[inline(always)]
2137+
pure fn add(rhs: & &self/str) -> ~str {
2138+
append(copy self, (*rhs))
2139+
}
2140+
}
21052141
}
21062142

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

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

src/libcore/vec.rs

+81-7
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,27 @@ pub pure fn filter<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> ~[T] {
736736
move result
737737
}
738738

739+
/**
740+
* Like `filter()`, but in place. Preserves order of `v`. Linear time.
741+
*/
742+
pub fn retain<T>(v: &mut ~[T], f: pure fn(t: &T) -> bool) {
743+
let len = v.len();
744+
let mut deleted: uint = 0;
745+
746+
for uint::range(0, len) |i| {
747+
if !f(&v[i]) {
748+
deleted += 1;
749+
} else if deleted > 0 {
750+
v[i - deleted] <-> v[i];
751+
}
752+
}
753+
754+
while deleted > 0 {
755+
v.pop();
756+
deleted -= 1;
757+
}
758+
}
759+
739760
/**
740761
* Concatenate a vector of vectors.
741762
*
@@ -759,14 +780,17 @@ pub pure fn connect<T: Copy>(v: &[~[T]], sep: &T) -> ~[T] {
759780
}
760781

761782
/// Reduce a vector from left to right
762-
pub pure fn foldl<T: Copy, U>(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T {
763-
let mut accum = z;
764-
for each(v) |elt| {
765-
// it should be possible to move accum in, but the liveness analysis
766-
// is not smart enough.
767-
accum = p(accum, elt);
783+
pub pure fn foldl<T, U>(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T {
784+
let mut accum = move z;
785+
let mut i = 0;
786+
let l = v.len();
787+
while i < l {
788+
// Use a while loop so that liveness analysis can handle moving
789+
// the accumulator.
790+
accum = p(move accum, &v[i]);
791+
i += 1;
768792
}
769-
return accum;
793+
return move accum;
770794
}
771795

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

1320+
#[cfg(stage0)]
12961321
impl<T: Eq> &[T] : Eq {
12971322
#[inline(always)]
12981323
pure fn eq(other: & &[T]) -> bool { eq(self, (*other)) }
12991324
#[inline(always)]
13001325
pure fn ne(other: & &[T]) -> bool { !self.eq(other) }
13011326
}
13021327

1328+
#[cfg(stage1)]
1329+
#[cfg(stage2)]
1330+
impl<T: Eq> &[T] : Eq {
1331+
#[inline(always)]
1332+
pure fn eq(other: & &self/[T]) -> bool { eq(self, (*other)) }
1333+
#[inline(always)]
1334+
pure fn ne(other: & &self/[T]) -> bool { !self.eq(other) }
1335+
}
1336+
1337+
13031338
impl<T: Eq> ~[T] : Eq {
13041339
#[inline(always)]
13051340
pure fn eq(other: &~[T]) -> bool { eq(self, (*other)) }
@@ -1335,6 +1370,7 @@ pure fn le<T: Ord>(a: &[T], b: &[T]) -> bool { !lt(b, a) }
13351370
pure fn ge<T: Ord>(a: &[T], b: &[T]) -> bool { !lt(a, b) }
13361371
pure fn gt<T: Ord>(a: &[T], b: &[T]) -> bool { lt(b, a) }
13371372

1373+
#[cfg(stage0)]
13381374
impl<T: Ord> &[T] : Ord {
13391375
#[inline(always)]
13401376
pure fn lt(other: & &[T]) -> bool { lt(self, (*other)) }
@@ -1346,6 +1382,19 @@ impl<T: Ord> &[T] : Ord {
13461382
pure fn gt(other: & &[T]) -> bool { gt(self, (*other)) }
13471383
}
13481384

1385+
#[cfg(stage1)]
1386+
#[cfg(stage2)]
1387+
impl<T: Ord> &[T] : Ord {
1388+
#[inline(always)]
1389+
pure fn lt(other: & &self/[T]) -> bool { lt(self, (*other)) }
1390+
#[inline(always)]
1391+
pure fn le(other: & &self/[T]) -> bool { le(self, (*other)) }
1392+
#[inline(always)]
1393+
pure fn ge(other: & &self/[T]) -> bool { ge(self, (*other)) }
1394+
#[inline(always)]
1395+
pure fn gt(other: & &self/[T]) -> bool { gt(self, (*other)) }
1396+
}
1397+
13491398
impl<T: Ord> ~[T] : Ord {
13501399
#[inline(always)]
13511400
pure fn lt(other: &~[T]) -> bool { lt(self, (*other)) }
@@ -1370,19 +1419,39 @@ impl<T: Ord> @[T] : Ord {
13701419

13711420
#[cfg(notest)]
13721421
pub mod traits {
1422+
#[cfg(stage0)]
13731423
impl<T: Copy> ~[T] : Add<&[const T],~[T]> {
13741424
#[inline(always)]
13751425
pure fn add(rhs: & &[const T]) -> ~[T] {
13761426
append(copy self, (*rhs))
13771427
}
13781428
}
13791429

1430+
#[cfg(stage1)]
1431+
#[cfg(stage2)]
1432+
impl<T: Copy> ~[T] : Add<&[const T],~[T]> {
1433+
#[inline(always)]
1434+
pure fn add(rhs: & &self/[const T]) -> ~[T] {
1435+
append(copy self, (*rhs))
1436+
}
1437+
}
1438+
1439+
#[cfg(stage0)]
13801440
impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> {
13811441
#[inline(always)]
13821442
pure fn add(rhs: & &[const T]) -> ~[mut T] {
13831443
append_mut(copy self, (*rhs))
13841444
}
13851445
}
1446+
1447+
#[cfg(stage1)]
1448+
#[cfg(stage2)]
1449+
impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> {
1450+
#[inline(always)]
1451+
pure fn add(rhs: & &self/[const T]) -> ~[mut T] {
1452+
append_mut(copy self, (*rhs))
1453+
}
1454+
}
13861455
}
13871456

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

15951665
pub trait MutableCopyableVector<T: Copy> {
@@ -1631,6 +1701,10 @@ impl<T> ~[T]: MutableVector<T> {
16311701
fn truncate(&mut self, newlen: uint) {
16321702
truncate(self, newlen);
16331703
}
1704+
1705+
fn retain(&mut self, f: pure fn(t: &T) -> bool) {
1706+
retain(self, f);
1707+
}
16341708
}
16351709

16361710
impl<T: Copy> ~[T]: MutableCopyableVector<T> {

src/rustc/metadata/tyencode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fn enc_region(w: io::Writer, cx: @ctxt, r: ty::Region) {
147147
ty::re_static => {
148148
w.write_char('t');
149149
}
150-
ty::re_var(_) => {
150+
ty::re_infer(_) => {
151151
// these should not crop up after typeck
152152
cx.diag.handler().bug(~"Cannot encode region variables");
153153
}

src/rustc/middle/astencode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ impl ty::Region: tr {
387387
ty::re_bound(br) => ty::re_bound(br.tr(xcx)),
388388
ty::re_free(id, br) => ty::re_free(xcx.tr_id(id), br.tr(xcx)),
389389
ty::re_scope(id) => ty::re_scope(xcx.tr_id(id)),
390-
ty::re_static | ty::re_var(*) => self,
390+
ty::re_static | ty::re_infer(*) => self,
391391
}
392392
}
393393
}

src/rustc/middle/kind.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ fn check_cast_for_escaping_regions(
580580
match target_substs.self_r {
581581
Some(ty::re_scope(*)) => { return; /* case (1) */ }
582582
None | Some(ty::re_static) | Some(ty::re_free(*)) => {}
583-
Some(ty::re_bound(*)) | Some(ty::re_var(*)) => {
583+
Some(ty::re_bound(*)) | Some(ty::re_infer(*)) => {
584584
cx.tcx.sess.span_bug(
585585
source.span,
586586
fmt!("bad region found in kind: %?", target_substs.self_r));

src/rustc/middle/region.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,18 @@ fn is_subregion_of(region_map: region_map,
112112
super_region: ty::Region) -> bool {
113113
sub_region == super_region ||
114114
match (sub_region, super_region) {
115-
(_, ty::re_static) => {
116-
true
117-
}
115+
(_, ty::re_static) => {
116+
true
117+
}
118118

119-
(ty::re_scope(sub_scope), ty::re_scope(super_scope)) |
120-
(ty::re_scope(sub_scope), ty::re_free(super_scope, _)) => {
121-
scope_contains(region_map, super_scope, sub_scope)
122-
}
119+
(ty::re_scope(sub_scope), ty::re_scope(super_scope)) |
120+
(ty::re_scope(sub_scope), ty::re_free(super_scope, _)) => {
121+
scope_contains(region_map, super_scope, sub_scope)
122+
}
123123

124-
_ => {
125-
false
126-
}
124+
_ => {
125+
false
126+
}
127127
}
128128
}
129129

0 commit comments

Comments
 (0)