1
Fork 0

Stop resolving static methods at the module level. Closes #4179

This commit is contained in:
Brian Anderson 2012-12-18 18:05:16 -08:00
parent 8e28f23c60
commit 97ddf3c7bd
25 changed files with 74 additions and 82 deletions

View file

@ -25,7 +25,7 @@ use reader = std::ebml::reader;
use std::ebml; use std::ebml;
use std::map::HashMap; use std::map::HashMap;
use std::map; use std::map;
use std::serialize::decode; use std::serialize::traits::Decodable;
use syntax::ast_map; use syntax::ast_map;
use syntax::attr; use syntax::attr;
use syntax::diagnostic::span_handler; use syntax::diagnostic::span_handler;
@ -284,7 +284,7 @@ fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd)
fn item_ty_region_param(item: ebml::Doc) -> Option<ty::region_variance> { fn item_ty_region_param(item: ebml::Doc) -> Option<ty::region_variance> {
reader::maybe_get_doc(item, tag_region_param).map(|doc| { reader::maybe_get_doc(item, tag_region_param).map(|doc| {
decode(&reader::Decoder(*doc)) Decodable::decode(&reader::Decoder(*doc))
}) })
} }

View file

@ -28,7 +28,8 @@ use std::ebml::writer::Encoder;
use std::ebml; use std::ebml;
use std::map::HashMap; use std::map::HashMap;
use std::serialize; use std::serialize;
use std::serialize::{Encodable, EncoderHelpers, DecoderHelpers, decode}; use std::serialize::{Encodable, EncoderHelpers, DecoderHelpers};
use std::serialize::traits::Decodable;
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util; use syntax::ast_util;
@ -117,7 +118,7 @@ fn decode_inlined_item(cdata: cstore::crate_metadata,
debug!("> Decoding inlined fn: %s::?", debug!("> Decoding inlined fn: %s::?",
ast_map::path_to_str(path, tcx.sess.parse_sess.interner)); ast_map::path_to_str(path, tcx.sess.parse_sess.interner));
let ast_dsr = &reader::Decoder(ast_doc); let ast_dsr = &reader::Decoder(ast_doc);
let from_id_range = decode(ast_dsr); let from_id_range = Decodable::decode(ast_dsr);
let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range); let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range);
let xcx = extended_decode_ctxt_(@{dcx: dcx, let xcx = extended_decode_ctxt_(@{dcx: dcx,
from_id_range: from_id_range, from_id_range: from_id_range,
@ -210,7 +211,7 @@ trait def_id_decoder_helpers {
impl<D: serialize::Decoder> D: def_id_decoder_helpers { impl<D: serialize::Decoder> D: def_id_decoder_helpers {
fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id { fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id {
let did: ast::def_id = decode(&self); let did: ast::def_id = Decodable::decode(&self);
did.tr(xcx) did.tr(xcx)
} }
} }
@ -287,7 +288,7 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item { fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item {
let chi_doc = par_doc[c::tag_tree as uint]; let chi_doc = par_doc[c::tag_tree as uint];
let d = &reader::Decoder(chi_doc); let d = &reader::Decoder(chi_doc);
decode(d) Decodable::decode(d)
} }
fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item) fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item)
@ -332,7 +333,7 @@ fn encode_def(ebml_w: writer::Encoder, def: ast::def) {
fn decode_def(xcx: extended_decode_ctxt, doc: ebml::Doc) -> ast::def { fn decode_def(xcx: extended_decode_ctxt, doc: ebml::Doc) -> ast::def {
let dsr = &reader::Decoder(doc); let dsr = &reader::Decoder(doc);
let def: ast::def = decode(dsr); let def: ast::def = Decodable::decode(dsr);
def.tr(xcx) def.tr(xcx)
} }
@ -430,7 +431,7 @@ trait ebml_decoder_helper {
impl reader::Decoder: ebml_decoder_helper { impl reader::Decoder: ebml_decoder_helper {
fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry { fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry {
let fv: freevar_entry = decode(&self); let fv: freevar_entry = Decodable::decode(&self);
fv.tr(xcx) fv.tr(xcx)
} }
} }
@ -473,12 +474,13 @@ impl reader::Decoder: read_method_map_entry_helper {
}), }),
explicit_self: explicit_self:
self.read_field(~"explicit_self", 2u, || { self.read_field(~"explicit_self", 2u, || {
let self_type: ast::self_ty_ = decode(&self); let self_type: ast::self_ty_ = Decodable::decode(&self);
self_type self_type
}), }),
origin: origin:
self.read_field(~"origin", 1u, || { self.read_field(~"origin", 1u, || {
let method_origin: method_origin = decode(&self); let method_origin: method_origin =
Decodable::decode(&self);
method_origin.tr(xcx) method_origin.tr(xcx)
})} })}
} }
@ -926,7 +928,7 @@ impl reader::Decoder: ebml_decoder_decoder_helpers {
@self.read_to_vec(|| self.read_bounds(xcx) ) @self.read_to_vec(|| self.read_bounds(xcx) )
}), }),
region_param: self.read_field(~"region_param", 1u, || { region_param: self.read_field(~"region_param", 1u, || {
decode(&self) Decodable::decode(&self)
}), }),
ty: self.read_field(~"ty", 2u, || { ty: self.read_field(~"ty", 2u, || {
self.read_ty(xcx) self.read_ty(xcx)
@ -990,11 +992,11 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
dcx.maps.vtable_map.insert(id, dcx.maps.vtable_map.insert(id,
val_dsr.read_vtable_res(xcx)); val_dsr.read_vtable_res(xcx));
} else if tag == (c::tag_table_adjustments as uint) { } else if tag == (c::tag_table_adjustments as uint) {
let adj: @ty::AutoAdjustment = @decode(val_dsr); let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr);
adj.tr(xcx); adj.tr(xcx);
dcx.tcx.adjustments.insert(id, adj); dcx.tcx.adjustments.insert(id, adj);
} else if tag == (c::tag_table_value_mode as uint) { } else if tag == (c::tag_table_value_mode as uint) {
let vm: ty::ValueMode = decode(val_dsr); let vm: ty::ValueMode = Decodable::decode(val_dsr);
dcx.tcx.value_modes.insert(id, vm); dcx.tcx.value_modes.insert(id, vm);
} else { } else {
xcx.dcx.tcx.sess.bug( xcx.dcx.tcx.sess.bug(
@ -1020,7 +1022,7 @@ fn encode_item_ast(ebml_w: writer::Encoder, item: @ast::item) {
fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item { fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item {
let chi_doc = par_doc[c::tag_tree as uint]; let chi_doc = par_doc[c::tag_tree as uint];
let d = &reader::Decoder(chi_doc); let d = &reader::Decoder(chi_doc);
@decode(d) @Decodable::decode(d)
} }
#[cfg(test)] #[cfg(test)]

View file

@ -1336,17 +1336,6 @@ impl Resolver {
Some(local_def(item.id)), Some(local_def(item.id)),
ty_m.purity); ty_m.purity);
// For now, add to both the trait module and the
// enclosing module, for backwards compatibility.
let (method_name_bindings, _) =
self.add_child(ident,
new_parent,
ForbidDuplicateValues,
ty_m.span);
method_name_bindings.define_value(Public,
def,
ty_m.span);
let (method_name_bindings, _) = let (method_name_bindings, _) =
self.add_child(ident, self.add_child(ident,
module_parent_opt.get(), module_parent_opt.get(),

View file

@ -272,8 +272,9 @@ fn run(repl: Repl, input: ~str) -> Repl {
vtable_map: vtable_map}; vtable_map: vtable_map};
debug!("translation"); debug!("translation");
let path = ~path::GenericPath::from_str("<repl>");
let (llmod, _) = trans::base::trans_crate(sess, crate, ty_cx, let (llmod, _) = trans::base::trans_crate(sess, crate, ty_cx,
~path::from_str("<repl>"), path,
exp_map2, maps); exp_map2, maps);
let pm = llvm::LLVMCreatePassManager(); let pm = llvm::LLVMCreatePassManager();

View file

@ -657,7 +657,7 @@ mod tests {
}; };
let ebml_doc = reader::Doc(@bytes); let ebml_doc = reader::Doc(@bytes);
let deser = reader::Decoder(ebml_doc); let deser = reader::Decoder(ebml_doc);
let v1 = serialize::decode(&deser); let v1 = serialize::traits::Decodable::decode(&deser);
debug!("v1 == %?", v1); debug!("v1 == %?", v1);
assert v == v1; assert v == v1;
} }

View file

@ -324,7 +324,6 @@ pub mod flatteners {
use serialize::{Encoder, Decoder, use serialize::{Encoder, Decoder,
Encodable, Decodable}; Encodable, Decodable};
use serialize::decode;
use core::io::{Writer, Reader, BytesWriter, ReaderUtil}; use core::io::{Writer, Reader, BytesWriter, ReaderUtil};
use flatpipes::util::BufReader; use flatpipes::util::BufReader;
@ -433,15 +432,15 @@ pub mod flatteners {
let buf = vec::from_slice(buf); let buf = vec::from_slice(buf);
let buf_reader = @BufReader::new(move buf); let buf_reader = @BufReader::new(move buf);
let reader = buf_reader as @Reader; let reader = buf_reader as @Reader;
let deser: D = from_reader(reader); let deser: D = FromReader::from_reader(reader);
decode(&deser) Decodable::decode(&deser)
} }
pub fn serialize_value<D: Encoder FromWriter, pub fn serialize_value<D: Encoder FromWriter,
T: Encodable<D>>(val: &T) -> ~[u8] { T: Encodable<D>>(val: &T) -> ~[u8] {
let bytes_writer = @BytesWriter(); let bytes_writer = @BytesWriter();
let writer = bytes_writer as @Writer; let writer = bytes_writer as @Writer;
let ser = from_writer(writer); let ser = FromWriter::from_writer(writer);
val.encode(&ser); val.encode(&ser);
let bytes = bytes_writer.bytes.check_out(|bytes| move bytes); let bytes = bytes_writer.bytes.check_out(|bytes| move bytes);
return move bytes; return move bytes;

View file

@ -298,7 +298,7 @@ pub impl<S: Encoder, T: Encodable<S>> ~T: Encodable<S> {
pub impl<D: Decoder, T: Decodable<D>> ~T: Decodable<D> { pub impl<D: Decoder, T: Decodable<D>> ~T: Decodable<D> {
static fn decode(&self, d: &D) -> ~T { static fn decode(&self, d: &D) -> ~T {
d.read_owned(|| ~decode(d)) d.read_owned(|| ~Decodable::decode(d))
} }
} }
@ -310,7 +310,7 @@ pub impl<S: Encoder, T: Encodable<S>> @T: Encodable<S> {
pub impl<D: Decoder, T: Decodable<D>> @T: Decodable<D> { pub impl<D: Decoder, T: Decodable<D>> @T: Decodable<D> {
static fn decode(&self, d: &D) -> @T { static fn decode(&self, d: &D) -> @T {
d.read_managed(|| @decode(d)) d.read_managed(|| @Decodable::decode(d))
} }
} }
@ -338,7 +338,7 @@ pub impl<D: Decoder, T: Decodable<D>> ~[T]: Decodable<D> {
static fn decode(&self, d: &D) -> ~[T] { static fn decode(&self, d: &D) -> ~[T] {
do d.read_owned_vec |len| { do d.read_owned_vec |len| {
do vec::from_fn(len) |i| { do vec::from_fn(len) |i| {
d.read_vec_elt(i, || decode(d)) d.read_vec_elt(i, || Decodable::decode(d))
} }
} }
} }
@ -358,7 +358,7 @@ pub impl<D: Decoder, T: Decodable<D>> @[T]: Decodable<D> {
static fn decode(&self, d: &D) -> @[T] { static fn decode(&self, d: &D) -> @[T] {
do d.read_managed_vec |len| { do d.read_managed_vec |len| {
do at_vec::from_fn(len) |i| { do at_vec::from_fn(len) |i| {
d.read_vec_elt(i, || decode(d)) d.read_vec_elt(i, || Decodable::decode(d))
} }
} }
} }
@ -385,7 +385,8 @@ pub impl<D: Decoder, T: Decodable<D>> Option<T>: Decodable<D> {
do d.read_enum_variant |i| { do d.read_enum_variant |i| {
match i { match i {
0 => None, 0 => None,
1 => Some(d.read_enum_variant_arg(0u, || decode(d))), 1 => Some(d.read_enum_variant_arg(
0u, || Decodable::decode(d))),
_ => fail(fmt!("Bad variant for option: %u", i)) _ => fail(fmt!("Bad variant for option: %u", i))
} }
} }
@ -418,8 +419,8 @@ pub impl<
static fn decode(&self, d: &D) -> (T0, T1) { static fn decode(&self, d: &D) -> (T0, T1) {
do d.read_tup(2) { do d.read_tup(2) {
( (
d.read_tup_elt(0, || decode(d)), d.read_tup_elt(0, || Decodable::decode(d)),
d.read_tup_elt(1, || decode(d)) d.read_tup_elt(1, || Decodable::decode(d))
) )
} }
} }
@ -453,9 +454,9 @@ pub impl<
static fn decode(&self, d: &D) -> (T0, T1, T2) { static fn decode(&self, d: &D) -> (T0, T1, T2) {
do d.read_tup(3) { do d.read_tup(3) {
( (
d.read_tup_elt(0, || decode(d)), d.read_tup_elt(0, || Decodable::decode(d)),
d.read_tup_elt(1, || decode(d)), d.read_tup_elt(1, || Decodable::decode(d)),
d.read_tup_elt(2, || decode(d)) d.read_tup_elt(2, || Decodable::decode(d))
) )
} }
} }
@ -492,10 +493,10 @@ pub impl<
static fn decode(&self, d: &D) -> (T0, T1, T2, T3) { static fn decode(&self, d: &D) -> (T0, T1, T2, T3) {
do d.read_tup(4) { do d.read_tup(4) {
( (
d.read_tup_elt(0, || decode(d)), d.read_tup_elt(0, || Decodable::decode(d)),
d.read_tup_elt(1, || decode(d)), d.read_tup_elt(1, || Decodable::decode(d)),
d.read_tup_elt(2, || decode(d)), d.read_tup_elt(2, || Decodable::decode(d)),
d.read_tup_elt(3, || decode(d)) d.read_tup_elt(3, || Decodable::decode(d))
) )
} }
} }
@ -536,11 +537,11 @@ pub impl<
-> (T0, T1, T2, T3, T4) { -> (T0, T1, T2, T3, T4) {
do d.read_tup(5) { do d.read_tup(5) {
( (
d.read_tup_elt(0, || decode(d)), d.read_tup_elt(0, || Decodable::decode(d)),
d.read_tup_elt(1, || decode(d)), d.read_tup_elt(1, || Decodable::decode(d)),
d.read_tup_elt(2, || decode(d)), d.read_tup_elt(2, || Decodable::decode(d)),
d.read_tup_elt(3, || decode(d)), d.read_tup_elt(3, || Decodable::decode(d)),
d.read_tup_elt(4, || decode(d)) d.read_tup_elt(4, || Decodable::decode(d))
) )
} }
} }

View file

@ -15,7 +15,7 @@ use either::{Right,Left,Either};
use json; use json;
use sha1; use sha1;
use serialize::{Encoder, Encodable, Decoder, Decodable, decode}; use serialize::{Encoder, Encodable, Decoder, Decodable};
/** /**
* *

View file

@ -36,7 +36,7 @@ impl bool: read {
} }
fn read<T: read Copy>(s: ~str) -> T { fn read<T: read Copy>(s: ~str) -> T {
match readMaybe(s) { match read::readMaybe(s) {
Some(x) => x, Some(x) => x,
_ => fail ~"read failed!" _ => fail ~"read failed!"
} }

View file

@ -22,7 +22,7 @@ use std::ebml;
use EBReader = std::ebml::reader; use EBReader = std::ebml::reader;
use EBWriter = std::ebml::writer; use EBWriter = std::ebml::writer;
use io::Writer; use io::Writer;
use std::serialize::{Encodable, Decodable, decode}; use std::serialize::traits::{Encodable, Decodable};
use std::prettyprint; use std::prettyprint;
use std::time; use std::time;
@ -47,7 +47,7 @@ fn test_ebml<A:
a1.encode(ebml_w) a1.encode(ebml_w)
}; };
let d = EBReader::Doc(@move bytes); let d = EBReader::Doc(@move bytes);
let a2: A = decode(&EBReader::Decoder(d)); let a2: A = Decodable::decode(&EBReader::Decoder(d));
assert *a1 == a2; assert *a1 == a2;
} }

View file

@ -16,5 +16,5 @@ extern mod mycore(name ="static_fn_inline_xc_aux");
use mycore::num; use mycore::num;
fn main() { fn main() {
let _1:float = num::from_int2(1i); let _1:float = num::Num2::from_int2(1i);
} }

View file

@ -6,5 +6,5 @@ extern mod mycore(name ="static_fn_trait_xc_aux");
use mycore::num; use mycore::num;
fn main() { fn main() {
let _1:float = num::from_int2(1i); let _1:float = num::Num2::from_int2(1i);
} }

View file

@ -30,6 +30,6 @@ impl FromThinAir: Deserializer {
fn main() { fn main() {
let d = FromThinAir { dummy: () }; let d = FromThinAir { dummy: () };
let i: int = deserialize(&d); let i: int = Deserializable::deserialize(&d);
assert i == 22; assert i == 22;
} }

View file

@ -18,7 +18,7 @@ trait bool_like {
} }
fn andand<T: bool_like Copy>(x1: T, x2: T) -> T { fn andand<T: bool_like Copy>(x1: T, x2: T) -> T {
select(x1, x2, x1) bool_like::select(x1, x2, x1)
} }
impl bool: bool_like { impl bool: bool_like {
@ -57,7 +57,7 @@ impl<A> ~[A]: buildable<A> {
#[inline(always)] #[inline(always)]
pure fn build<A, B: buildable<A>>(builder: fn(push: pure fn(+v: A))) -> B { pure fn build<A, B: buildable<A>>(builder: fn(push: pure fn(+v: A))) -> B {
build_sized(4, builder) buildable::build_sized(4, builder)
} }
/// Apply a function to each element of an iterable and return the results /// Apply a function to each element of an iterable and return the results
@ -71,7 +71,7 @@ fn map<T, IT: BaseIter<T>, U, BU: buildable<U>>
} }
fn seq_range<BT: buildable<int>>(lo: uint, hi: uint) -> BT { fn seq_range<BT: buildable<int>>(lo: uint, hi: uint) -> BT {
do build_sized(hi-lo) |push| { do buildable::build_sized(hi-lo) |push| {
for uint::range(lo, hi) |i| { for uint::range(lo, hi) |i| {
push(i as int); push(i as int);
} }
@ -87,7 +87,7 @@ fn main() {
let v: ~[int] = map(&[1,2,3], |x| 1+x); let v: ~[int] = map(&[1,2,3], |x| 1+x);
assert v == ~[2, 3, 4]; assert v == ~[2, 3, 4];
assert select(true, 9, 14) == 9; assert bool_like::select(true, 9, 14) == 9;
assert !andand(true, false); assert !andand(true, false);
assert andand(7, 12) == 12; assert andand(7, 12) == 12;
assert andand(0, 12) == 0; assert andand(0, 12) == 0;

View file

@ -14,7 +14,7 @@
extern mod static_methods_crate; extern mod static_methods_crate;
use static_methods_crate::read; use static_methods_crate::read;
use readMaybeRenamed = static_methods_crate::readMaybe; use readMaybeRenamed = static_methods_crate::read::readMaybe;
fn main() { fn main() {
let result: int = read(~"5"); let result: int = read(~"5");

View file

@ -11,7 +11,7 @@
// except according to those terms. // except according to those terms.
use cmp::{Eq, Ord}; use cmp::{Eq, Ord};
use num::from_int; use num::Num::from_int;
extern mod std; extern mod std;
use std::cmp::FuzzyEq; use std::cmp::FuzzyEq;

View file

@ -12,7 +12,7 @@
// Extending Num and using inherited static methods // Extending Num and using inherited static methods
use num::from_int; use Num::from_int;
trait Num { trait Num {
static fn from_int(i: int) -> self; static fn from_int(i: int) -> self;

View file

@ -11,7 +11,7 @@
// Using the real Num from core // Using the real Num from core
use cmp::Ord; use cmp::Ord;
use num::from_int; use num::Num::from_int;
pub trait NumExt: Num Ord { } pub trait NumExt: Num Ord { }

View file

@ -13,7 +13,7 @@
// A more complex example of numeric extensions // A more complex example of numeric extensions
use cmp::{Eq, Ord}; use cmp::{Eq, Ord};
use num::from_int; use num::Num::from_int;
extern mod std; extern mod std;
use std::cmp::FuzzyEq; use std::cmp::FuzzyEq;

View file

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use cmp::{Eq, Ord}; use cmp::{Eq, Ord};
use num::from_int; use num::Num::from_int;
pub trait NumExt: Eq Ord Num {} pub trait NumExt: Eq Ord Num {}

View file

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use cmp::{Eq, Ord}; use cmp::{Eq, Ord};
use num::from_int; use num::Num::from_int;
pub trait NumExt: Eq Num {} pub trait NumExt: Eq Num {}

View file

@ -26,7 +26,7 @@ impl S: MyNum {
impl S: NumExt { } impl S: NumExt { }
fn greater_than_one<T:NumExt>() -> T { from_int(1) } fn greater_than_one<T:NumExt>() -> T { MyNum::from_int(1) }
fn main() { fn main() {
let v: S = greater_than_one(); let v: S = greater_than_one();

View file

@ -30,7 +30,7 @@ impl S: MyNum {
impl S: NumExt { } impl S: NumExt { }
fn greater_than_one<T:NumExt>() -> T { from_int(1) } fn greater_than_one<T:NumExt>() -> T { MyNum::from_int(1) }
fn main() { fn main() {
let v: S = greater_than_one(); let v: S = greater_than_one();

View file

@ -37,6 +37,6 @@ mod base {
} }
fn main() { fn main() {
let f: base::Foo = base::new::<base::Foo, base::Foo>(); let f: base::Foo = base::HasNew::new::<base::Foo, base::Foo>();
let b: base::Bar = base::new::<base::Bar, base::Bar>(); let b: base::Bar = base::HasNew::new::<base::Bar, base::Bar>();
} }

View file

@ -37,9 +37,9 @@ enum ColorTree {
impl ColorTree : Equal { impl ColorTree : Equal {
static fn isEq(a: ColorTree, b: ColorTree) -> bool { static fn isEq(a: ColorTree, b: ColorTree) -> bool {
match (a, b) { match (a, b) {
(leaf(x), leaf(y)) => { isEq(x, y) } (leaf(x), leaf(y)) => { Equal::isEq(x, y) }
(branch(l1, r1), branch(l2, r2)) => { (branch(l1, r1), branch(l2, r2)) => {
isEq(*l1, *l2) && isEq(*r1, *r2) Equal::isEq(*l1, *l2) && Equal::isEq(*r1, *r2)
} }
_ => { false } _ => { false }
} }
@ -47,18 +47,18 @@ impl ColorTree : Equal {
} }
fn main() { fn main() {
assert isEq(cyan, cyan); assert Equal::isEq(cyan, cyan);
assert isEq(magenta, magenta); assert Equal::isEq(magenta, magenta);
assert !isEq(cyan, yellow); assert !Equal::isEq(cyan, yellow);
assert !isEq(magenta, cyan); assert !Equal::isEq(magenta, cyan);
assert isEq(leaf(cyan), leaf(cyan)); assert Equal::isEq(leaf(cyan), leaf(cyan));
assert !isEq(leaf(cyan), leaf(yellow)); assert !Equal::isEq(leaf(cyan), leaf(yellow));
assert isEq(branch(@leaf(magenta), @leaf(cyan)), assert Equal::isEq(branch(@leaf(magenta), @leaf(cyan)),
branch(@leaf(magenta), @leaf(cyan))); branch(@leaf(magenta), @leaf(cyan)));
assert !isEq(branch(@leaf(magenta), @leaf(cyan)), assert !Equal::isEq(branch(@leaf(magenta), @leaf(cyan)),
branch(@leaf(magenta), @leaf(magenta))); branch(@leaf(magenta), @leaf(magenta)));
log(error, "Assertions all succeeded!"); log(error, "Assertions all succeeded!");