Skip to content

Commit 74454e4

Browse files
committed
---
yaml --- r: 63079 b: refs/heads/snap-stage3 c: ebf7281 h: refs/heads/master i: 63077: a47f4eb 63075: 59abfba 63071: 315fb59 v: v3
1 parent 508eeb9 commit 74454e4

File tree

14 files changed

+356
-438
lines changed

14 files changed

+356
-438
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: af863cf2a4b8d14483d5ba34d29d1040ae740891
4+
refs/heads/snap-stage3: ebf7281b7b16d5083d1a6d114ae49e6f878c72d3
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/metadata/decoder.rs

Lines changed: 82 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -476,91 +476,103 @@ pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) -> bool {
476476
}
477477

478478
/// Iterates over all the paths in the given crate.
479-
pub fn each_path(intr: @ident_interner,
480-
cdata: cmd,
481-
get_crate_data: GetCrateDataCb,
482-
f: &fn(&str, def_like, ast::visibility) -> bool)
483-
-> bool {
484-
// FIXME #4572: This function needs to be nuked, as it's impossible to make fast.
485-
// It's the source of most of the performance problems when compiling small crates.
486-
479+
pub fn _each_path(intr: @ident_interner,
480+
cdata: cmd,
481+
get_crate_data: GetCrateDataCb,
482+
f: &fn(&str, def_like, ast::visibility) -> bool)
483+
-> bool {
487484
let root = reader::Doc(cdata.data);
488485
let items = reader::get_doc(root, tag_items);
489486
let items_data = reader::get_doc(items, tag_items_data);
490487

488+
let mut broken = false;
489+
491490
// First, go through all the explicit items.
492491
for reader::tagged_docs(items_data, tag_items_data_item) |item_doc| {
493-
let path = ast_map::path_to_str(item_path(item_doc), intr);
494-
let path_is_empty = path.is_empty();
495-
if !path_is_empty {
496-
// Extract the def ID.
497-
let def_id = item_def_id(item_doc, cdata);
498-
499-
// Construct the def for this item.
500-
debug!("(each_path) yielding explicit item: %s", path);
501-
let def_like = item_to_def_like(item_doc, def_id, cdata.cnum);
502-
503-
let vis = item_visibility(item_doc);
504-
505-
// Hand the information off to the iteratee.
506-
if !f(path, def_like, vis) {
507-
return false;
492+
if !broken {
493+
let path = ast_map::path_to_str_with_sep(
494+
item_path(item_doc), "::", intr);
495+
let path_is_empty = path.is_empty();
496+
if !path_is_empty {
497+
// Extract the def ID.
498+
let def_id = item_def_id(item_doc, cdata);
499+
500+
// Construct the def for this item.
501+
debug!("(each_path) yielding explicit item: %s", path);
502+
let def_like = item_to_def_like(item_doc, def_id, cdata.cnum);
503+
504+
let vis = item_visibility(item_doc);
505+
506+
// Hand the information off to the iteratee.
507+
if !f(path, def_like, vis) {
508+
broken = true; // FIXME #4572: This is awful.
509+
}
508510
}
509-
}
510511

511-
// If this is a module, find the reexports.
512-
for each_reexport(item_doc) |reexport_doc| {
513-
let def_id_doc =
514-
reader::get_doc(reexport_doc,
515-
tag_items_data_item_reexport_def_id);
516-
let def_id =
517-
reader::with_doc_data(def_id_doc,
518-
|d| parse_def_id(d));
519-
let def_id = translate_def_id(cdata, def_id);
520-
521-
let reexport_name_doc =
522-
reader::get_doc(reexport_doc,
523-
tag_items_data_item_reexport_name);
524-
let reexport_name = reader::doc_as_str(reexport_name_doc);
525-
526-
let reexport_path;
527-
if path_is_empty {
528-
reexport_path = reexport_name;
529-
} else {
530-
reexport_path = path + "::" + reexport_name;
531-
}
512+
// If this is a module, find the reexports.
513+
for each_reexport(item_doc) |reexport_doc| {
514+
if !broken {
515+
let def_id_doc =
516+
reader::get_doc(reexport_doc,
517+
tag_items_data_item_reexport_def_id);
518+
let def_id =
519+
reader::with_doc_data(def_id_doc,
520+
|d| parse_def_id(d));
521+
let def_id = translate_def_id(cdata, def_id);
522+
523+
let reexport_name_doc =
524+
reader::get_doc(reexport_doc,
525+
tag_items_data_item_reexport_name);
526+
let reexport_name = reader::doc_as_str(reexport_name_doc);
527+
528+
let reexport_path;
529+
if path_is_empty {
530+
reexport_path = reexport_name;
531+
} else {
532+
reexport_path = path + "::" + reexport_name;
533+
}
532534

533-
// This reexport may be in yet another crate
534-
let other_crates_items = if def_id.crate == cdata.cnum {
535-
items
536-
} else {
537-
let crate_data = get_crate_data(def_id.crate);
538-
let root = reader::Doc(crate_data.data);
539-
reader::get_doc(root, tag_items)
540-
};
541-
542-
// Get the item.
543-
match maybe_find_item(def_id.node, other_crates_items) {
544-
None => {}
545-
Some(item_doc) => {
546-
// Construct the def for this item.
547-
let def_like = item_to_def_like(item_doc,
548-
def_id,
549-
cdata.cnum);
550-
551-
// Hand the information off to the iteratee.
552-
debug!("(each_path) yielding reexported \
553-
item: %s", reexport_path);
554-
555-
if (!f(reexport_path, def_like, ast::public)) {
556-
return false;
535+
// This reexport may be in yet another crate
536+
let other_crates_items = if def_id.crate == cdata.cnum {
537+
items
538+
} else {
539+
let crate_data = get_crate_data(def_id.crate);
540+
let root = reader::Doc(crate_data.data);
541+
reader::get_doc(root, tag_items)
542+
};
543+
544+
// Get the item.
545+
match maybe_find_item(def_id.node, other_crates_items) {
546+
None => {}
547+
Some(item_doc) => {
548+
// Construct the def for this item.
549+
let def_like = item_to_def_like(item_doc,
550+
def_id,
551+
cdata.cnum);
552+
553+
// Hand the information off to the iteratee.
554+
debug!("(each_path) yielding reexported \
555+
item: %s", reexport_path);
556+
557+
if (!f(reexport_path, def_like, ast::public)) {
558+
broken = true; // FIXME #4572: This is awful.
559+
}
560+
}
557561
}
558562
}
559563
}
560564
}
561565
}
562566

563-
return true;
567+
return broken;
568+
}
569+
570+
pub fn each_path(intr: @ident_interner,
571+
cdata: cmd,
572+
get_crate_data: GetCrateDataCb,
573+
f: &fn(&str, def_like, ast::visibility) -> bool)
574+
-> bool {
575+
_each_path(intr, cdata, get_crate_data, f)
564576
}
565577

566578
pub fn get_item_path(cdata: cmd, id: ast::node_id)

branches/snap-stage3/src/libsyntax/ext/deriving/clone.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ pub fn expand_deriving_clone(cx: @ExtCtxt,
3838
]
3939
};
4040

41-
expand_deriving_generic(cx, span,
42-
mitem, in_items,
43-
&trait_def)
41+
trait_def.expand(cx, span, mitem, in_items)
4442
}
4543

4644
pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
@@ -67,9 +65,7 @@ pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
6765
]
6866
};
6967

70-
expand_deriving_generic(cx, span,
71-
mitem, in_items,
72-
&trait_def)
68+
trait_def.expand(cx, span, mitem, in_items)
7369
}
7470

7571
fn cs_clone(

branches/snap-stage3/src/libsyntax/ext/deriving/cmp/eq.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,5 @@ pub fn expand_deriving_eq(cx: @ExtCtxt,
5454
md!("ne", cs_ne)
5555
]
5656
};
57-
58-
expand_deriving_generic(cx, span, mitem, in_items,
59-
&trait_def)
57+
trait_def.expand(cx, span, mitem, in_items)
6058
}

branches/snap-stage3/src/libsyntax/ext/deriving/cmp/ord.rs

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use core::prelude::*;
1212

13+
use ast;
1314
use ast::{meta_item, item, expr};
1415
use codemap::span;
1516
use ext::base::ExtCtxt;
@@ -21,106 +22,105 @@ pub fn expand_deriving_ord(cx: @ExtCtxt,
2122
mitem: @meta_item,
2223
in_items: ~[@item]) -> ~[@item] {
2324
macro_rules! md (
24-
($name:expr, $less:expr, $equal:expr) => {
25+
($name:expr, $func:expr, $op:expr) => {
2526
MethodDef {
2627
name: $name,
2728
generics: LifetimeBounds::empty(),
2829
explicit_self: borrowed_explicit_self(),
2930
args: ~[borrowed_self()],
3031
ret_ty: Literal(Path::new(~["bool"])),
3132
const_nonmatching: false,
32-
combine_substructure: |cx, span, substr|
33-
cs_ord($less, $equal, cx, span, substr)
33+
combine_substructure: |cx, span, substr| $func($op, cx, span, substr)
3434
}
3535
}
3636
);
3737

38-
39-
4038
let trait_def = TraitDef {
4139
path: Path::new(~["std", "cmp", "Ord"]),
42-
// XXX: Ord doesn't imply Eq yet
43-
additional_bounds: ~[Literal(Path::new(~["std", "cmp", "Eq"]))],
40+
additional_bounds: ~[],
4441
generics: LifetimeBounds::empty(),
4542
methods: ~[
46-
md!("lt", true, false),
47-
md!("le", true, true),
48-
md!("gt", false, false),
49-
md!("ge", false, true)
43+
md!("lt", cs_strict, true),
44+
md!("le", cs_nonstrict, true), // inverse operation
45+
md!("gt", cs_strict, false),
46+
md!("ge", cs_nonstrict, false)
5047
]
5148
};
52-
53-
expand_deriving_generic(cx, span, mitem, in_items,
54-
&trait_def)
49+
trait_def.expand(cx, span, mitem, in_items)
5550
}
5651

57-
/// `less`: is this `lt` or `le`? `equal`: is this `le` or `ge`?
58-
fn cs_ord(less: bool, equal: bool,
59-
cx: @ExtCtxt, span: span,
60-
substr: &Substructure) -> @expr {
61-
let binop = if less {
62-
cx.ident_of("lt")
63-
} else {
64-
cx.ident_of("gt")
65-
};
66-
let base = cx.expr_bool(span, equal);
67-
52+
/// Strict inequality.
53+
fn cs_strict(less: bool, cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
54+
let op = if less {ast::lt} else {ast::gt};
6855
cs_fold(
6956
false, // need foldr,
7057
|cx, span, subexpr, self_f, other_fs| {
7158
/*
72-
73-
build up a series of nested ifs from the inside out to get
74-
lexical ordering (hence foldr), i.e.
59+
build up a series of chain ||'s and &&'s from the inside
60+
out (hence foldr) to get lexical ordering, i.e. for op ==
61+
`ast::lt`
7562
7663
```
77-
if self.f1 `binop` other.f1 {
78-
true
79-
} else if self.f1 == other.f1 {
80-
if self.f2 `binop` other.f2 {
81-
true
82-
} else if self.f2 == other.f2 {
83-
`equal`
84-
} else {
85-
false
86-
}
87-
} else {
88-
false
89-
}
64+
self.f1 < other.f1 || (!(other.f1 < self.f1) &&
65+
(self.f2 < other.f2 || (!(other.f2 < self.f2) &&
66+
(false)
67+
))
68+
)
9069
```
9170
92-
The inner "`equal`" case is only reached if the two
93-
items have all fields equal.
71+
The optimiser should remove the redundancy. We explicitly
72+
get use the binops to avoid auto-deref derefencing too many
73+
layers of pointers, if the type includes pointers.
9474
*/
95-
if other_fs.len() != 1 {
96-
cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`");
97-
}
75+
let other_f = match other_fs {
76+
[o_f] => o_f,
77+
_ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
78+
};
79+
80+
let cmp = cx.expr_binary(span, op,
81+
cx.expr_deref(span, self_f),
82+
cx.expr_deref(span, other_f));
9883

99-
let cmp = cx.expr_method_call(span,
100-
self_f, cx.ident_of("eq"), other_fs.to_owned());
101-
let elseif = cx.expr_if(span, cmp,
102-
subexpr, Some(cx.expr_bool(span, false)));
84+
let not_cmp = cx.expr_binary(span, op,
85+
cx.expr_deref(span, other_f),
86+
cx.expr_deref(span, self_f));
87+
let not_cmp = cx.expr_unary(span, ast::not, not_cmp);
10388

104-
let cmp = cx.expr_method_call(span,
105-
self_f, binop, other_fs.to_owned());
106-
cx.expr_if(span, cmp,
107-
cx.expr_bool(span, true), Some(elseif))
89+
let and = cx.expr_binary(span, ast::and,
90+
not_cmp, subexpr);
91+
cx.expr_binary(span, ast::or, cmp, and)
10892
},
109-
base,
93+
cx.expr_bool(span, false),
11094
|cx, span, args, _| {
11195
// nonmatching enums, order by the order the variants are
11296
// written
11397
match args {
11498
[(self_var, _, _),
11599
(other_var, _, _)] =>
116100
cx.expr_bool(span,
117-
if less {
118-
self_var < other_var
119-
} else {
120-
self_var > other_var
121-
}),
101+
if less {
102+
self_var < other_var
103+
} else {
104+
self_var > other_var
105+
}),
122106
_ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
123107
}
124108
},
125109
cx, span, substr)
126110
}
111+
112+
fn cs_nonstrict(less: bool, cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
113+
// Example: ge becomes !(*self < *other), le becomes !(*self > *other)
114+
115+
let inverse_op = if less {ast::gt} else {ast::lt};
116+
match substr.self_args {
117+
[self_, other] => {
118+
let inverse_cmp = cx.expr_binary(span, inverse_op,
119+
cx.expr_deref(span, self_),
120+
cx.expr_deref(span, other));
121+
122+
cx.expr_unary(span, ast::not, inverse_cmp)
123+
}
124+
_ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
125+
}
126+
}

branches/snap-stage3/src/libsyntax/ext/deriving/cmp/totaleq.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,5 @@ pub fn expand_deriving_totaleq(cx: @ExtCtxt,
4242
}
4343
]
4444
};
45-
46-
expand_deriving_generic(cx, span, mitem, in_items,
47-
&trait_def)
45+
trait_def.expand(cx, span, mitem, in_items)
4846
}

0 commit comments

Comments
 (0)