From ebe35f3873b0ad48d48b009a871843e583584379 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 6 May 2013 23:29:54 -0400 Subject: [PATCH 1/2] remove borrowck workarounds from the containers --- src/libcore/hashmap.rs | 78 ++++++++++++++++++++++++++++++++++++++++-- src/libcore/trie.rs | 15 ++++++-- 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 9b01c1dad06..4ec2e911bf8 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -347,16 +347,27 @@ impl Map for HashMap { } /// Return a mutable reference to the value corresponding to the key + #[cfg(stage0)] fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> { let idx = match self.bucket_for_key(k) { FoundEntry(idx) => idx, TableFull | FoundHole(_) => return None }; - unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker + unsafe { Some(::cast::transmute_mut_region(self.mut_value_for_bucket(idx))) } } + /// Return a mutable reference to the value corresponding to the key + #[cfg(not(stage0))] + fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> { + let idx = match self.bucket_for_key(k) { + FoundEntry(idx) => idx, + TableFull | FoundHole(_) => return None + }; + Some(self.mut_value_for_bucket(idx)) + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -429,6 +440,7 @@ pub impl HashMap { /// Return the value corresponding to the key in the map, or insert /// and return the value if it doesn't exist. + #[cfg(stage0)] fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V { if self.size >= self.resize_at { // n.b.: We could also do this after searching, so @@ -452,13 +464,43 @@ pub impl HashMap { }, }; - unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker + unsafe { ::cast::transmute_region(self.value_for_bucket(idx)) } } + /// Return the value corresponding to the key in the map, or insert + /// and return the value if it doesn't exist. + #[cfg(not(stage0))] + fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V { + if self.size >= self.resize_at { + // n.b.: We could also do this after searching, so + // that we do not resize if this call to insert is + // simply going to update a key in place. My sense + // though is that it's worse to have to search through + // buckets to find the right spot twice than to just + // resize in this corner case. + self.expand(); + } + + let hash = k.hash_keyed(self.k0, self.k1) as uint; + let idx = match self.bucket_for_key_with_hash(hash, &k) { + TableFull => fail!(~"Internal logic error"), + FoundEntry(idx) => idx, + FoundHole(idx) => { + self.buckets[idx] = Some(Bucket{hash: hash, key: k, + value: v}); + self.size += 1; + idx + }, + }; + + self.value_for_bucket(idx) + } + /// Return the value corresponding to the key in the map, or create, /// insert, and return a new value if it doesn't exist. + #[cfg(stage0)] fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V { if self.size >= self.resize_at { // n.b.: We could also do this after searching, so @@ -483,11 +525,41 @@ pub impl HashMap { }, }; - unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker + unsafe { ::cast::transmute_region(self.value_for_bucket(idx)) } } + /// Return the value corresponding to the key in the map, or create, + /// insert, and return a new value if it doesn't exist. + #[cfg(not(stage0))] + fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V { + if self.size >= self.resize_at { + // n.b.: We could also do this after searching, so + // that we do not resize if this call to insert is + // simply going to update a key in place. My sense + // though is that it's worse to have to search through + // buckets to find the right spot twice than to just + // resize in this corner case. + self.expand(); + } + + let hash = k.hash_keyed(self.k0, self.k1) as uint; + let idx = match self.bucket_for_key_with_hash(hash, &k) { + TableFull => fail!(~"Internal logic error"), + FoundEntry(idx) => idx, + FoundHole(idx) => { + let v = f(&k); + self.buckets[idx] = Some(Bucket{hash: hash, key: k, + value: v}); + self.size += 1; + idx + }, + }; + + self.value_for_bucket(idx) + } + fn consume(&mut self, f: &fn(K, V)) { let mut buckets = ~[]; self.buckets <-> buckets; diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index f0756be9944..f6cd898e08a 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -276,9 +276,9 @@ fn chunk(n: uint, idx: uint) -> uint { (n >> sh) & MASK } -fn find_mut<'r, T>(child: &'r mut Child, key: uint, idx: uint) - -> Option<&'r mut T> { - unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker +#[cfg(stage0)] +fn find_mut<'r, T>(child: &'r mut Child, key: uint, idx: uint) -> Option<&'r mut T> { + unsafe { (match *child { External(_, ref value) => Some(cast::transmute_mut(value)), Internal(ref x) => find_mut(cast::transmute_mut(&x.children[chunk(key, idx)]), @@ -288,6 +288,15 @@ fn find_mut<'r, T>(child: &'r mut Child, key: uint, idx: uint) } } +#[cfg(not(stage0))] +fn find_mut<'r, T>(child: &'r mut Child, key: uint, idx: uint) -> Option<&'r mut T> { + match *child { + External(_, ref mut value) => Some(value), + Internal(ref mut x) => find_mut(&mut x.children[chunk(key, idx)], key, idx + 1), + Nothing => None + } +} + fn insert(count: &mut uint, child: &mut Child, key: uint, value: T, idx: uint) -> bool { let mut tmp = Nothing; From d800147abba010328c00e7518073085ed6ceb133 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 6 May 2013 21:09:34 -0400 Subject: [PATCH 2/2] minor automatic whitespace fixes --- mk/install.mk | 8 ++++---- mk/tests.mk | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mk/install.mk b/mk/install.mk index 5fa477a790d..47fcb224a73 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -192,9 +192,9 @@ ifeq ($(CFG_ADB_DEVICE_STATUS),true) ifdef VERBOSE ADB = adb $(1) ADB_PUSH = adb push $(1) $(2) - ADB_SHELL = adb shell $(1) $(2) + ADB_SHELL = adb shell $(1) $(2) else - ADB = $(Q)$(call E, adb $(1)) && adb $(1) 1>/dev/null + ADB = $(Q)$(call E, adb $(1)) && adb $(1) 1>/dev/null ADB_PUSH = $(Q)$(call E, adb push $(1)) && adb push $(1) $(2) 1>/dev/null ADB_SHELL = $(Q)$(call E, adb shell $(1) $(2)) && adb shell $(1) $(2) 1>/dev/null endif @@ -222,8 +222,8 @@ install-runtime-target: \ install-runtime-target-arm-linux-androideabi-cleanup \ install-runtime-target-arm-linux-androideabi-host-$(CFG_BUILD_TRIPLE) else -install-runtime-target: +install-runtime-target: @echo "No device to install runtime library" - @echo + @echo endif endif diff --git a/mk/tests.mk b/mk/tests.mk index a04ec3e6514..8ac2ad68e3a 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -92,7 +92,7 @@ endef $(foreach target,$(CFG_TARGET_TRIPLES), \ $(eval $(call DEF_TARGET_COMMANDS,$(target)))) -# Target platform specific variables +# Target platform specific variables # for arm-linux-androidabi define DEF_ADB_DEVICE_STATUS CFG_ADB_DEVICE_STATUS=$(1) @@ -402,7 +402,7 @@ $(foreach host,$(CFG_HOST_TRIPLES), \ $(eval $(call DEF_TEST_CRATE_RULES_null,$(stage),$(target),$(host),$(crate))) \ ), \ $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))) \ - )))))) + )))))) ######################################################################