iter 23.3.3: prelude — class Ord a extends Eq + Ord Int/Bool/Str instances
This commit is contained in:
@@ -956,6 +956,45 @@ mod tests {
|
||||
eq_instance_types.contains(&"Str"),
|
||||
"prelude must contain `instance Eq Str`; saw Eq instances on: {eq_instance_types:?}"
|
||||
);
|
||||
|
||||
// Iter 23.3: prelude also ships the `Ord` class plus three
|
||||
// primitive instances (Ord Int, Ord Bool, Ord Str). Ord
|
||||
// extends Eq (Decision 11 single-superclass closure), so its
|
||||
// shape is the same as Eq's instance set; the loader uses the
|
||||
// superclass walk to verify the Eq instances exist.
|
||||
assert!(
|
||||
prelude.defs.iter().any(|d| matches!(
|
||||
d,
|
||||
crate::ast::Def::Class(c) if c.name == "Ord"
|
||||
)),
|
||||
"prelude must contain Ord class def"
|
||||
);
|
||||
let ord_instance_types: Vec<&str> = prelude
|
||||
.defs
|
||||
.iter()
|
||||
.filter_map(|d| match d {
|
||||
crate::ast::Def::Instance(i) if i.class == "Ord" => {
|
||||
if let crate::ast::Type::Con { name, .. } = &i.type_ {
|
||||
Some(name.as_str())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
assert!(
|
||||
ord_instance_types.contains(&"Int"),
|
||||
"prelude must contain `instance Ord Int`; saw: {ord_instance_types:?}"
|
||||
);
|
||||
assert!(
|
||||
ord_instance_types.contains(&"Bool"),
|
||||
"prelude must contain `instance Ord Bool`; saw: {ord_instance_types:?}"
|
||||
);
|
||||
assert!(
|
||||
ord_instance_types.contains(&"Str"),
|
||||
"prelude must contain `instance Ord Str`; saw: {ord_instance_types:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -118,6 +118,106 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "Ord",
|
||||
"param": "a",
|
||||
"superclass": { "class": "Eq", "type": "a" },
|
||||
"doc": "Total ordering. Ships in milestone 23 alongside Eq. `compare x y` returns LT, EQ, or GT (the three-ctor Ordering ADT also in the prelude). Decision 11's single-superclass closure requires `instance Eq T` for every `instance Ord T` — the three Ord instances below pair with the three Eq instances shipped in iter 23.2.3.",
|
||||
"methods": [
|
||||
{
|
||||
"name": "compare",
|
||||
"type": {
|
||||
"k": "fn",
|
||||
"params": [
|
||||
{ "k": "var", "name": "a" },
|
||||
{ "k": "var", "name": "a" }
|
||||
],
|
||||
"param_modes": ["borrow", "borrow"],
|
||||
"ret": { "k": "con", "name": "Ordering" },
|
||||
"effects": []
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "Ord",
|
||||
"type": { "k": "con", "name": "Int" },
|
||||
"doc": "Ord Int. The lambda body shape is a placeholder for round-trip stability; the codegen intercept `try_emit_primitive_instance_body::\"compare__Int\"` emits a three-way `icmp slt` / `icmp eq` branch ladder constructing LT / EQ / GT.",
|
||||
"methods": [
|
||||
{
|
||||
"name": "compare",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["x", "y"],
|
||||
"paramTypes": [
|
||||
{ "k": "var", "name": "a" },
|
||||
{ "k": "var", "name": "a" }
|
||||
],
|
||||
"retType": { "k": "con", "name": "Ordering" },
|
||||
"body": {
|
||||
"t": "ctor",
|
||||
"type": "Ordering",
|
||||
"ctor": "EQ",
|
||||
"args": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "Ord",
|
||||
"type": { "k": "con", "name": "Bool" },
|
||||
"doc": "Ord Bool. Body lowered via `try_emit_primitive_instance_body::\"compare__Bool\"` — `icmp ult i1` LT-test, `icmp eq i1` EQ-test, GT default.",
|
||||
"methods": [
|
||||
{
|
||||
"name": "compare",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["x", "y"],
|
||||
"paramTypes": [
|
||||
{ "k": "var", "name": "a" },
|
||||
{ "k": "var", "name": "a" }
|
||||
],
|
||||
"retType": { "k": "con", "name": "Ordering" },
|
||||
"body": {
|
||||
"t": "ctor",
|
||||
"type": "Ordering",
|
||||
"ctor": "EQ",
|
||||
"args": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "instance",
|
||||
"class": "Ord",
|
||||
"type": { "k": "con", "name": "Str" },
|
||||
"doc": "Ord Str. Body lowered via `try_emit_primitive_instance_body::\"compare__Str\"` — `call i32 @ail_str_compare(ptr, ptr)` then branch on slt-0 / eq-0 against the normalised {-1, 0, +1} return.",
|
||||
"methods": [
|
||||
{
|
||||
"name": "compare",
|
||||
"body": {
|
||||
"t": "lam",
|
||||
"params": ["x", "y"],
|
||||
"paramTypes": [
|
||||
{ "k": "var", "name": "a" },
|
||||
{ "k": "var", "name": "a" }
|
||||
],
|
||||
"retType": { "k": "con", "name": "Ordering" },
|
||||
"body": {
|
||||
"t": "ctor",
|
||||
"type": "Ordering",
|
||||
"ctor": "EQ",
|
||||
"args": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user