Skip to content

Commit caa2296

Browse files
tmmcguireemberian
authored andcommitted
---
yaml --- r: 60405 b: refs/heads/master c: 2264c79 h: refs/heads/master i: 60403: 097e2ea v: v3
1 parent 61d5e41 commit caa2296

File tree

10 files changed

+237
-57
lines changed

10 files changed

+237
-57
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 17970a91115dd30dd6ee445ef344153f46f0a946
2+
refs/heads/master: 2264c7927dbfc6124b9b756de47200ded1ca76ac
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2d28d645422c1617be58c8ca7ad9a457264ca850
55
refs/heads/try: c50a9d5b664478e533ba1d1d353213d70c8ad589

trunk/src/libcore/vec.rs

Lines changed: 193 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,46 @@ pub fn reverse<T>(v: &mut [T]) {
14451445
}
14461446
}
14471447

1448+
/**
1449+
* Reverse part of a vector in place.
1450+
*
1451+
* Reverse the elements in the vector between `start` and `end - 1`.
1452+
*
1453+
* # Arguments
1454+
*
1455+
* * `v` - The mutable vector to be modified
1456+
*
1457+
* * `start` - Index of the first element of the slice
1458+
*
1459+
* * `end` - Index one past the final element to be reversed.
1460+
*
1461+
* # Example
1462+
*
1463+
* Assume a mutable vector `v` contains `[1,2,3,4,5]`. After the call:
1464+
*
1465+
* ~~~
1466+
*
1467+
* reverse_part(v, 1, 4);
1468+
*
1469+
* ~~~
1470+
*
1471+
* `v` now contains `[1,4,3,2,5]`.
1472+
*
1473+
* # Safety note
1474+
*
1475+
* Behavior is undefined if `start` or `end` do not represent valid
1476+
* positions in `v`.
1477+
*/
1478+
pub fn reverse_part<T>(v: &mut [T], start: uint, end : uint) {
1479+
let mut i = start;
1480+
let mut j = end - 1;
1481+
while i < j {
1482+
v[i] <-> v[j];
1483+
i += 1;
1484+
j -= 1;
1485+
}
1486+
}
1487+
14481488
/// Returns a vector with the order of elements reversed
14491489
pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] {
14501490
let mut rs: ~[T] = ~[];
@@ -1739,31 +1779,75 @@ pub fn each2_mut<U, T>(v1: &mut [U], v2: &mut [T], f: &fn(u: &mut U, t: &mut T)
17391779
*
17401780
* The total number of permutations produced is `len(v)!`. If `v` contains
17411781
* repeated elements, then some permutations are repeated.
1782+
*
1783+
* See [Algorithms to generate
1784+
* permutations](http://en.wikipedia.org/wiki/Permutation).
1785+
*
1786+
* # Arguments
1787+
*
1788+
* * `values` - A vector of values from which the permutations are
1789+
* chosen
1790+
*
1791+
* * `fun` - The function to iterate over the combinations
17421792
*/
17431793
#[cfg(not(stage0))]
1744-
pub fn each_permutation<T:Copy>(v: &[T], put: &fn(ts: &[T]) -> bool) -> bool {
1745-
let ln = len(v);
1746-
if ln <= 1 {
1747-
put(v);
1748-
} else {
1749-
// This does not seem like the most efficient implementation. You
1750-
// could make far fewer copies if you put your mind to it.
1751-
let mut i = 0u;
1752-
while i < ln {
1753-
let elt = v[i];
1754-
let mut rest = slice(v, 0u, i).to_vec();
1755-
rest.push_all(const_slice(v, i+1u, ln));
1756-
for each_permutation(rest) |permutation| {
1757-
if !put(append(~[elt], permutation)) {
1758-
return false;
1759-
}
1760-
}
1761-
i += 1u;
1794+
pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) {
1795+
let length = values.len();
1796+
let mut permutation = vec::from_fn(length, |i| values[i]);
1797+
if length <= 1 {
1798+
fun(permutation);
1799+
return;
1800+
}
1801+
let mut indices = vec::from_fn(length, |i| i);
1802+
loop {
1803+
if !fun(permutation) { return; }
1804+
// find largest k such that indices[k] < indices[k+1]
1805+
// if no such k exists, all permutations have been generated
1806+
let mut k = length - 2;
1807+
while k > 0 && indices[k] >= indices[k+1] {
1808+
k -= 1;
1809+
}
1810+
if k == 0 && indices[0] > indices[1] { return; }
1811+
// find largest l such that indices[k] < indices[l]
1812+
// k+1 is guaranteed to be such
1813+
let mut l = length - 1;
1814+
while indices[k] >= indices[l] {
1815+
l -= 1;
1816+
}
1817+
// swap indices[k] and indices[l]; sort indices[k+1..]
1818+
// (they're just reversed)
1819+
indices[k] <-> indices[l];
1820+
unsafe {
1821+
reverse_part(indices, k+1, length);
1822+
}
1823+
// fixup permutation based on indices
1824+
for uint::range(k, length) |i| {
1825+
permutation[i] = values[indices[i]];
17621826
}
17631827
}
17641828
return true;
17651829
}
17661830

1831+
/**
1832+
* Iterate over all permutations of vector `values`.
1833+
*
1834+
* This is an alternative to each_permutation that uses references to
1835+
* avoid copying the elements of the values vector.
1836+
*
1837+
* To avoid copying, the iterator will be passed a reference to a vector
1838+
* containing references to the elements in the original `values` vector.
1839+
*
1840+
* # Arguments
1841+
*
1842+
* * `values` - A vector of values from which the permutations are chosen
1843+
*
1844+
* * `fun` - The function to iterate over the permutations
1845+
*/
1846+
#[cfg(not(stage0))]
1847+
pub fn each_permutation_ref<T>(values : &'v[T], fun : &fn(perm : &[&'v T]) -> bool) {
1848+
each_permutation(vec::from_fn(values.len(), |i| &values[i]), fun);
1849+
}
1850+
17671851
/**
17681852
* Iterate over all contiguous windows of length `n` of the vector `v`.
17691853
*
@@ -4730,6 +4814,97 @@ mod tests {
47304814
}
47314815
}
47324816

4817+
fn dup<T:Copy>(values : &[&T]) -> ~[T] {
4818+
from_fn(values.len(), |i| *values[i])
4819+
}
4820+
4821+
#[test]
4822+
fn test_reverse_part() {
4823+
let mut values = [1,2,3,4,5];
4824+
reverse_part(values,1,4);
4825+
assert values == [1,4,3,2,5];
4826+
}
4827+
4828+
#[test]
4829+
fn test_permutations0() {
4830+
let values = [];
4831+
let mut v : ~[~[int]] = ~[];
4832+
for each_permutation(values) |p| {
4833+
v.push(vec::from_slice(p));
4834+
}
4835+
assert v == ~[~[]];
4836+
}
4837+
4838+
#[test]
4839+
fn test_permutations0_ref() {
4840+
let values = [];
4841+
let mut v : ~[~[int]] = ~[];
4842+
for each_permutation_ref(values) |p| {
4843+
v.push(dup(p));
4844+
}
4845+
assert v == ~[~[]];
4846+
}
4847+
4848+
#[test]
4849+
fn test_permutations1() {
4850+
let values = [1];
4851+
let mut v : ~[~[int]] = ~[];
4852+
for each_permutation(values) |p| {
4853+
v.push(vec::from_slice(p));
4854+
}
4855+
assert v == ~[~[1]];
4856+
}
4857+
4858+
#[test]
4859+
fn test_permutations1_ref() {
4860+
let values = [1];
4861+
let mut v : ~[~[int]] = ~[];
4862+
for each_permutation_ref(values) |p| {
4863+
v.push(dup(p));
4864+
}
4865+
assert v == ~[~[1]];
4866+
}
4867+
4868+
#[test]
4869+
fn test_permutations2() {
4870+
let values = [1,2];
4871+
let mut v : ~[~[int]] = ~[];
4872+
for each_permutation(values) |p| {
4873+
v.push(vec::from_slice(p));
4874+
}
4875+
assert v == ~[~[1,2],~[2,1]];
4876+
}
4877+
4878+
#[test]
4879+
fn test_permutations2_ref() {
4880+
let values = [1,2];
4881+
let mut v : ~[~[int]] = ~[];
4882+
for each_permutation_ref(values) |p| {
4883+
v.push(dup(p));
4884+
}
4885+
assert v == ~[~[1,2],~[2,1]];
4886+
}
4887+
4888+
#[test]
4889+
fn test_permutations3() {
4890+
let values = [1,2,3];
4891+
let mut v : ~[~[int]] = ~[];
4892+
for each_permutation(values) |p| {
4893+
v.push(vec::from_slice(p));
4894+
}
4895+
assert v == ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]];
4896+
}
4897+
4898+
#[test]
4899+
fn test_permutations3_ref() {
4900+
let values = [1,2,3];
4901+
let mut v : ~[~[int]] = ~[];
4902+
for each_permutation_ref(values) |p| {
4903+
v.push(dup(p));
4904+
}
4905+
assert v == ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]];
4906+
}
4907+
47334908
#[test]
47344909
fn test_each_val() {
47354910
use old_iter::CopyableNonstrictIter;

trunk/src/librustc/metadata/csearch.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,14 @@ pub fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
234234
}
235235
}
236236

237-
// Given a def_id for an impl, return the trait it implements,
238-
// if there is one.
239-
pub fn get_impl_trait(tcx: ty::ctxt,
240-
def: ast::def_id) -> Option<@ty::TraitRef> {
237+
// Given a def_id for an impl or class, return the traits it implements,
238+
// or the empty vector if it's not for an impl or for a class that implements
239+
// traits
240+
pub fn get_impl_traits(tcx: ty::ctxt,
241+
def: ast::def_id) -> ~[@ty::TraitRef] {
241242
let cstore = tcx.cstore;
242243
let cdata = cstore::get_crate_data(cstore, def.crate);
243-
decoder::get_impl_trait(cdata, def.node, tcx)
244+
decoder::get_impl_traits(cdata, def.node, tcx)
244245
}
245246

246247
pub fn get_impl_method(cstore: @mut cstore::CStore,

trunk/src/librustc/metadata/decoder.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -415,20 +415,19 @@ pub fn get_type_param_count(data: @~[u8], id: ast::node_id) -> uint {
415415
item_ty_param_count(lookup_item(id, data))
416416
}
417417

418-
pub fn get_impl_trait(cdata: cmd,
418+
pub fn get_impl_traits(cdata: cmd,
419419
id: ast::node_id,
420-
tcx: ty::ctxt) -> Option<@ty::TraitRef>
420+
tcx: ty::ctxt) -> ~[@ty::TraitRef]
421421
{
422422
let item_doc = lookup_item(id, cdata.data);
423-
let mut result = None;
423+
let mut results = ~[];
424424
for reader::tagged_docs(item_doc, tag_item_trait_ref) |tp| {
425425
let trait_ref =
426426
@parse_trait_ref_data(tp.data, cdata.cnum, tp.start, tcx,
427427
|_, did| translate_def_id(cdata, did));
428-
result = Some(trait_ref);
429-
break;
428+
results.push(trait_ref);
430429
};
431-
result
430+
results
432431
}
433432

434433
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,

trunk/src/librustc/middle/trans/base.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2228,7 +2228,8 @@ pub fn register_fn_fuller(ccx: @CrateContext,
22282228
mangle_exported_name(ccx, /*bad*/copy path, node_type)
22292229
};
22302230
2231-
let llfn: ValueRef = decl_fn(ccx.llmod, ps, cc, llfty);
2231+
// XXX: Bad copy.
2232+
let llfn: ValueRef = decl_fn(ccx.llmod, copy ps, cc, llfty);
22322233
ccx.item_symbols.insert(node_id, ps);
22332234
22342235
// FIXME #4404 android JNI hacks

trunk/src/librustc/middle/trans/datum.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ use middle::ty;
101101
use util::common::indenter;
102102
use util::ppaux::ty_to_str;
103103

104+
use core::container::Set; // XXX: this should not be necessary
104105
use core::to_bytes;
105106
use syntax::ast;
106107
use syntax::codemap::span;

trunk/src/librustc/middle/trans/meth.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -795,11 +795,8 @@ pub fn make_impl_vtable(ccx: @CrateContext,
795795
let _icx = ccx.insn_ctxt("impl::make_impl_vtable");
796796
let tcx = ccx.tcx;
797797

798-
let trt_id = match ty::impl_trait_ref(tcx, impl_id) {
799-
Some(t_id) => t_id.def_id,
800-
None => ccx.sess.bug("make_impl_vtable: don't know how to \
801-
make a vtable for a type impl!")
802-
};
798+
// XXX: This should support multiple traits.
799+
let trt_id = ty::impl_trait_refs(tcx, impl_id)[0].def_id;
803800

804801
let has_tps =
805802
!ty::lookup_item_type(ccx.tcx, impl_id).generics.type_param_defs.is_empty();

trunk/src/librustc/middle/ty.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3883,23 +3883,23 @@ pub fn trait_method_def_ids(cx: ctxt, id: ast::def_id) -> @~[def_id] {
38833883
|| @csearch::get_trait_method_def_ids(cx.cstore, id))
38843884
}
38853885

3886-
pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> {
3886+
pub fn impl_trait_refs(cx: ctxt, id: ast::def_id) -> ~[@TraitRef] {
38873887
if id.crate == ast::local_crate {
3888-
debug!("(impl_trait_ref) searching for trait impl %?", id);
3888+
debug!("(impl_traits) searching for trait impl %?", id);
38893889
match cx.items.find(&id.node) {
38903890
Some(&ast_map::node_item(@ast::item {
38913891
node: ast::item_impl(_, opt_trait, _, _),
38923892
_},
38933893
_)) => {
38943894
match opt_trait {
3895-
Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)),
3896-
None => None
3895+
Some(t) => ~[ty::node_id_to_trait_ref(cx, t.ref_id)],
3896+
None => ~[]
38973897
}
38983898
}
3899-
_ => None
3899+
_ => ~[]
39003900
}
39013901
} else {
3902-
csearch::get_impl_trait(cx, id)
3902+
csearch::get_impl_traits(cx, id)
39033903
}
39043904
}
39053905

trunk/src/librustc/middle/typeck/check/vtable.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,24 @@ fn lookup_vtable(vcx: &VtableContext,
261261
}
262262
impls_seen.insert(im.did);
263263

264-
// ty::impl_traits gives us the trait im implements,
265-
// if there is one (there's either zero or one).
264+
// ty::impl_traits gives us the list of all
265+
// traits that im implements. Again, usually
266+
// there's just one.
266267
//
267-
// If foo implements a trait t, and if t is the
268-
// same trait as trait_ref, we need to
268+
// For example, if im represented the struct
269+
// in:
270+
//
271+
// struct foo : baz<int>, bar, quux { ... }
272+
//
273+
// then ty::impl_traits would return
274+
//
275+
// ~[baz<int>, bar, quux]
276+
//
277+
// For each of the traits foo implements, if
278+
// it's the same trait as trait_ref, we need to
269279
// unify it with trait_ref in order to get all
270280
// the ty vars sorted out.
271-
for ty::impl_trait_ref(tcx, im.did).each |&of_trait_ref|
281+
for ty::impl_trait_refs(tcx, im.did).each |&of_trait_ref|
272282
{
273283
if of_trait_ref.def_id != trait_ref.def_id { loop; }
274284

@@ -446,12 +456,8 @@ fn connect_trait_tps(vcx: &VtableContext,
446456
{
447457
let tcx = vcx.tcx();
448458

449-
let impl_trait_ref = match ty::impl_trait_ref(tcx, impl_did) {
450-
Some(t) => t,
451-
None => vcx.tcx().sess.span_bug(location_info.span,
452-
"connect_trait_tps invoked on a type impl")
453-
};
454-
459+
// XXX: This should work for multiple traits.
460+
let impl_trait_ref = ty::impl_trait_refs(tcx, impl_did)[0];
455461
let impl_trait_ref = (*impl_trait_ref).subst(tcx, impl_substs);
456462
relate_trait_refs(vcx, location_info, &impl_trait_ref, trait_ref);
457463
}

0 commit comments

Comments
 (0)