Skip to content

Commit dca745e

Browse files
author
Nick Desaulniers
committed
---
yaml --- r: 65523 b: refs/heads/master c: ecd08b9 h: refs/heads/master i: 65521: 82276b6 65519: 0dadfb3 v: v3
1 parent 72d6288 commit dca745e

21 files changed

+215
-137
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: 75f1b7f96fa4e91244a96ba92f615f3213d97519
2+
refs/heads/master: ecd08b989ae006660929bce6b719d9f7bc34a7fe
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 18e3db7392d2d0697b7e27d6d986139960144d85
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9

trunk/src/librustc/metadata/encoder.rs

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -374,50 +374,90 @@ fn encode_path(ecx: @EncodeContext,
374374
fn encode_reexported_static_method(ecx: @EncodeContext,
375375
ebml_w: &mut writer::Encoder,
376376
exp: &middle::resolve::Export2,
377-
m: @ty::Method) {
378-
debug!("(encode static trait method) reexport '%s::%s'",
379-
*exp.name, *ecx.tcx.sess.str_of(m.ident));
377+
method_def_id: def_id,
378+
method_ident: ident) {
379+
debug!("(encode reexported static method) %s::%s",
380+
*exp.name, *ecx.tcx.sess.str_of(method_ident));
380381
ebml_w.start_tag(tag_items_data_item_reexport);
381382
ebml_w.start_tag(tag_items_data_item_reexport_def_id);
382-
ebml_w.wr_str(def_to_str(m.def_id));
383+
ebml_w.wr_str(def_to_str(method_def_id));
383384
ebml_w.end_tag();
384385
ebml_w.start_tag(tag_items_data_item_reexport_name);
385-
ebml_w.wr_str(*exp.name + "::" + *ecx.tcx.sess.str_of(m.ident));
386+
ebml_w.wr_str(*exp.name + "::" + *ecx.tcx.sess.str_of(method_ident));
386387
ebml_w.end_tag();
387388
ebml_w.end_tag();
388389
}
389390

391+
fn encode_reexported_static_base_methods(ecx: @EncodeContext,
392+
ebml_w: &mut writer::Encoder,
393+
exp: &middle::resolve::Export2)
394+
-> bool {
395+
match ecx.tcx.base_impls.find(&exp.def_id) {
396+
Some(implementations) => {
397+
for implementations.each |&base_impl| {
398+
for base_impl.methods.each |&m| {
399+
if m.explicit_self == ast::sty_static {
400+
encode_reexported_static_method(ecx, ebml_w, exp,
401+
m.did, m.ident);
402+
}
403+
}
404+
}
405+
406+
true
407+
}
408+
None => { false }
409+
}
410+
}
411+
412+
fn encode_reexported_static_trait_methods(ecx: @EncodeContext,
413+
ebml_w: &mut writer::Encoder,
414+
exp: &middle::resolve::Export2)
415+
-> bool {
416+
match ecx.tcx.trait_methods_cache.find(&exp.def_id) {
417+
Some(methods) => {
418+
for methods.each |&m| {
419+
if m.explicit_self == ast::sty_static {
420+
encode_reexported_static_method(ecx, ebml_w, exp,
421+
m.def_id, m.ident);
422+
}
423+
}
424+
425+
true
426+
}
427+
None => { false }
428+
}
429+
}
430+
390431
fn encode_reexported_static_methods(ecx: @EncodeContext,
391432
ebml_w: &mut writer::Encoder,
392433
mod_path: &[ast_map::path_elt],
393434
exp: &middle::resolve::Export2) {
394-
match ecx.tcx.trait_methods_cache.find(&exp.def_id) {
395-
Some(methods) => {
396-
match ecx.tcx.items.find(&exp.def_id.node) {
397-
Some(&ast_map::node_item(item, path)) => {
398-
let original_name = ecx.tcx.sess.str_of(item.ident);
399-
400-
//
401-
// We don't need to reexport static methods on traits
402-
// declared in the same module as our `pub use ...` since
403-
// that's done when we encode the trait item.
404-
//
405-
// The only exception is when the reexport *changes* the
406-
// name e.g. `pub use Foo = self::Bar` -- we have
407-
// encoded metadata for static methods relative to Bar,
408-
// but not yet for Foo.
409-
//
410-
if mod_path != *path || *exp.name != *original_name {
411-
for methods.each |&m| {
412-
if m.explicit_self == ast::sty_static {
413-
encode_reexported_static_method(ecx,
414-
ebml_w,
415-
exp, m);
416-
}
417-
}
435+
match ecx.tcx.items.find(&exp.def_id.node) {
436+
Some(&ast_map::node_item(item, path)) => {
437+
let original_name = ecx.tcx.sess.str_of(item.ident);
438+
439+
//
440+
// We don't need to reexport static methods on items
441+
// declared in the same module as our `pub use ...` since
442+
// that's done when we encode the item itself.
443+
//
444+
// The only exception is when the reexport *changes* the
445+
// name e.g. `pub use Foo = self::Bar` -- we have
446+
// encoded metadata for static methods relative to Bar,
447+
// but not yet for Foo.
448+
//
449+
if mod_path != *path || *exp.name != *original_name {
450+
if !encode_reexported_static_base_methods(ecx, ebml_w, exp) {
451+
if encode_reexported_static_trait_methods(ecx, ebml_w, exp) {
452+
debug!(fmt!("(encode reexported static methods) %s \
453+
[trait]",
454+
*original_name));
418455
}
419456
}
420-
_ => {}
457+
else {
458+
debug!(fmt!("(encode reexported static methods) %s [base]",
459+
*original_name));
460+
}
421461
}
422462
}
423463
_ => {}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,14 @@ fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr,
727727
}
728728
}
729729
ast::def_struct(*) => {
730-
// Nothing to do here.
731-
// FIXME #6572: May not be true in the case of classes with destructors.
730+
let ty = expr_ty(bcx, ref_expr);
731+
match ty::get(ty).sty {
732+
ty::ty_struct(did, _) if ty::has_dtor(ccx.tcx, did) => {
733+
let repr = adt::represent_type(ccx, ty);
734+
adt::trans_start_init(bcx, repr, lldest, 0);
735+
}
736+
_ => {}
737+
}
732738
return bcx;
733739
}
734740
_ => {

trunk/src/librustc/middle/ty.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ struct ctxt_ {
307307
// Maps a trait onto a mapping from self-ty to impl
308308
trait_impls: @mut HashMap<ast::def_id, @mut HashMap<t, @Impl>>,
309309

310+
// Maps a base type to its impl
311+
base_impls: @mut HashMap<ast::def_id, @mut ~[@Impl]>,
312+
310313
// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
311314
// present in this set can be warned about.
312315
used_unsafe: @mut HashSet<ast::node_id>,
@@ -972,6 +975,7 @@ pub fn mk_ctxt(s: session::Session,
972975
destructor_for_type: @mut HashMap::new(),
973976
destructors: @mut HashSet::new(),
974977
trait_impls: @mut HashMap::new(),
978+
base_impls: @mut HashMap::new(),
975979
used_unsafe: @mut HashSet::new(),
976980
used_mut_nodes: @mut HashSet::new(),
977981
}
@@ -3700,6 +3704,21 @@ pub fn trait_method(cx: ctxt, trait_did: ast::def_id, idx: uint) -> @Method {
37003704
ty::method(cx, method_def_id)
37013705
}
37023706

3707+
3708+
pub fn add_base_impl(cx: ctxt, base_def_id: def_id, implementation: @Impl) {
3709+
let implementations;
3710+
match cx.base_impls.find(&base_def_id) {
3711+
None => {
3712+
implementations = @mut ~[];
3713+
cx.base_impls.insert(base_def_id, implementations);
3714+
}
3715+
Some(&existing) => {
3716+
implementations = existing;
3717+
}
3718+
}
3719+
implementations.push(implementation);
3720+
}
3721+
37033722
pub fn trait_methods(cx: ctxt, trait_did: ast::def_id) -> @~[@Method] {
37043723
match cx.trait_methods_cache.find(&trait_did) {
37053724
Some(&methods) => methods,

trunk/src/librustc/middle/typeck/coherence.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ pub fn get_base_type_def_id(inference_context: @mut InferCtxt,
146146
}
147147
_ => {
148148
fail!("get_base_type() returned a type that wasn't an \
149-
enum, class, or trait");
149+
enum, struct, or trait");
150150
}
151151
}
152152
}
@@ -313,6 +313,7 @@ impl CoherenceChecker {
313313
implementation = existing_implementation;
314314
}
315315
}
316+
316317
self.add_inherent_method(base_type_def_id,
317318
implementation);
318319
}
@@ -434,6 +435,8 @@ impl CoherenceChecker {
434435
}
435436

436437
implementation_list.push(implementation);
438+
439+
ty::add_base_impl(self.crate_context.tcx, base_def_id, implementation);
437440
}
438441

439442
pub fn add_trait_method(&self, trait_id: def_id, implementation: @Impl) {

trunk/src/libstd/comm.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ mod pipesy {
376376
priv use core::kinds::Owned;
377377
use ptr::to_mut_unsafe_ptr;
378378

379-
pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) {
379+
pub fn init<T: Owned>() -> (server::Oneshot<T>, client::Oneshot<T>) {
380380
pub use core::pipes::HasBuffer;
381381

382382
let buffer = ~::core::pipes::Buffer {
@@ -466,7 +466,7 @@ mod pipesy {
466466

467467
/// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair.
468468
pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
469-
let (chan, port) = oneshot::init();
469+
let (port, chan) = oneshot::init();
470470
(PortOne::new(port), ChanOne::new(chan))
471471
}
472472

@@ -550,7 +550,7 @@ mod pipesy {
550550
pub mod streamp {
551551
priv use core::kinds::Owned;
552552

553-
pub fn init<T: Owned>() -> (client::Open<T>, server::Open<T>) {
553+
pub fn init<T: Owned>() -> (server::Open<T>, client::Open<T>) {
554554
pub use core::pipes::HasBuffer;
555555
::core::pipes::entangle()
556556
}
@@ -567,7 +567,7 @@ mod pipesy {
567567
::core::option::Option<Open<T>> {
568568
{
569569
use super::data;
570-
let (c, s) = ::core::pipes::entangle();
570+
let (s, c) = ::core::pipes::entangle();
571571
let message = data(x_0, s);
572572
if ::core::pipes::send(pipe, message) {
573573
::core::pipes::rt::make_some(c)
@@ -579,7 +579,7 @@ mod pipesy {
579579
pub fn data<T: Owned>(pipe: Open<T>, x_0: T) -> Open<T> {
580580
{
581581
use super::data;
582-
let (c, s) = ::core::pipes::entangle();
582+
let (s, c) = ::core::pipes::entangle();
583583
let message = data(x_0, s);
584584
::core::pipes::send(pipe, message);
585585
c
@@ -615,7 +615,7 @@ mod pipesy {
615615
616616
*/
617617
pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) {
618-
let (c, s) = streamp::init();
618+
let (s, c) = streamp::init();
619619

620620
(Port {
621621
endp: Some(s)

trunk/src/libstd/hashmap.rs

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,9 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
425425
}
426426
}
427427

428-
/// Modify and return the value corresponding to the key in the map, or
429-
/// insert and return a new value if it doesn't exist.
430-
pub fn mangle<'a,A>(&'a mut self, k: K, a: A, not_found: &fn(&K, A) -> V,
431-
found: &fn(&K, &mut V, A)) -> &'a mut V {
428+
/// Return the value corresponding to the key in the map, or insert
429+
/// and return the value if it doesn't exist.
430+
pub fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
432431
if self.size >= self.resize_at {
433432
// n.b.: We could also do this after searching, so
434433
// that we do not resize if this call to insert is
@@ -442,37 +441,46 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
442441
let hash = k.hash_keyed(self.k0, self.k1) as uint;
443442
let idx = match self.bucket_for_key_with_hash(hash, &k) {
444443
TableFull => fail!("Internal logic error"),
445-
FoundEntry(idx) => { found(&k, self.mut_value_for_bucket(idx), a); idx }
444+
FoundEntry(idx) => idx,
446445
FoundHole(idx) => {
447-
let v = not_found(&k, a);
448-
self.buckets[idx] = Some(Bucket{hash: hash, key: k, value: v});
446+
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
447+
value: v});
449448
self.size += 1;
450449
idx
451-
}
450+
},
452451
};
453452

454-
self.mut_value_for_bucket(idx)
455-
}
456-
457-
/// Return the value corresponding to the key in the map, or insert
458-
/// and return the value if it doesn't exist.
459-
pub fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a mut V {
460-
self.mangle(k, v, |_k, a| a, |_k,_v,_a| ())
453+
self.value_for_bucket(idx)
461454
}
462455

463456
/// Return the value corresponding to the key in the map, or create,
464457
/// insert, and return a new value if it doesn't exist.
465458
pub fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V)
466-
-> &'a mut V {
467-
self.mangle(k, (), |k,_a| f(k), |_k,_v,_a| ())
468-
}
459+
-> &'a V {
460+
if self.size >= self.resize_at {
461+
// n.b.: We could also do this after searching, so
462+
// that we do not resize if this call to insert is
463+
// simply going to update a key in place. My sense
464+
// though is that it's worse to have to search through
465+
// buckets to find the right spot twice than to just
466+
// resize in this corner case.
467+
self.expand();
468+
}
469469

470-
/// Insert a key-value pair into the map if the key is not already present.
471-
/// Otherwise, modify the existing value for the key.
472-
/// Returns the new or modified value for the key.
473-
pub fn insert_or_update_with<'a>(&'a mut self, k: K, v: V,
474-
f: &fn(&K, &mut V)) -> &'a mut V {
475-
self.mangle(k, v, |_k,a| a, |k,v,_a| f(k,v))
470+
let hash = k.hash_keyed(self.k0, self.k1) as uint;
471+
let idx = match self.bucket_for_key_with_hash(hash, &k) {
472+
TableFull => fail!("Internal logic error"),
473+
FoundEntry(idx) => idx,
474+
FoundHole(idx) => {
475+
let v = f(&k);
476+
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
477+
value: v});
478+
self.size += 1;
479+
idx
480+
},
481+
};
482+
483+
self.value_for_bucket(idx)
476484
}
477485

478486
/// Calls a function on each element of a hash map, destroying the hash
@@ -755,22 +763,15 @@ mod test_map {
755763
#[test]
756764
fn test_find_or_insert() {
757765
let mut m = HashMap::new::<int, int>();
758-
assert_eq!(*m.find_or_insert(1, 2), 2);
759-
assert_eq!(*m.find_or_insert(1, 3), 2);
766+
assert_eq!(m.find_or_insert(1, 2), &2);
767+
assert_eq!(m.find_or_insert(1, 3), &2);
760768
}
761769

762770
#[test]
763771
fn test_find_or_insert_with() {
764772
let mut m = HashMap::new::<int, int>();
765-
assert_eq!(*m.find_or_insert_with(1, |_| 2), 2);
766-
assert_eq!(*m.find_or_insert_with(1, |_| 3), 2);
767-
}
768-
769-
#[test]
770-
fn test_insert_or_update_with() {
771-
let mut m = HashMap::new::<int, int>();
772-
assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2);
773-
assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3);
773+
assert_eq!(m.find_or_insert_with(1, |_| 2), &2);
774+
assert_eq!(m.find_or_insert_with(1, |_| 3), &2);
774775
}
775776

776777
#[test]

trunk/src/libstd/pipes.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,11 @@ pub fn packet<T>() -> *mut Packet<T> {
237237
pub fn entangle_buffer<T:Owned,Tstart:Owned>(
238238
mut buffer: ~Buffer<T>,
239239
init: &fn(*libc::c_void, x: &mut T) -> *mut Packet<Tstart>)
240-
-> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>) {
240+
-> (RecvPacketBuffered<Tstart, T>, SendPacketBuffered<Tstart, T>) {
241241
unsafe {
242242
let p = init(transmute_copy(&buffer), &mut buffer.data);
243243
forget(buffer);
244-
(SendPacketBuffered(p), RecvPacketBuffered(p))
244+
(RecvPacketBuffered(p), SendPacketBuffered(p))
245245
}
246246
}
247247

@@ -775,9 +775,9 @@ pub fn RecvPacketBuffered<T,Tbuffer>(p: *mut Packet<T>)
775775
}
776776
}
777777

778-
pub fn entangle<T>() -> (SendPacket<T>, RecvPacket<T>) {
778+
pub fn entangle<T>() -> (RecvPacket<T>, SendPacket<T>) {
779779
let p = packet();
780-
(SendPacket(p), RecvPacket(p))
780+
(RecvPacket(p), SendPacket(p))
781781
}
782782

783783
/** Receives a message from one of two endpoints.

0 commit comments

Comments
 (0)