3286117605
Ships class Show a where show : (a borrow) -> Str in the prelude
plus primitive Show Int / Bool / Str / Float instances. Each
instance body is a single-application lambda invoking the
corresponding runtime primitive (int_to_str, bool_to_str,
str_clone, float_to_str) — first prelude instance bodies to call
runtime primitives directly. Float is included in Show (unlike
Eq/Ord) because textual representation is well-defined modulo the
NaN-spelling caveat at DESIGN.md §Float semantics.
The 22b typeclass test corpus is migrated preemptively: 21 fixture
files and 6 consumer files (typeclass_22b{2,3}.rs +
hash.rs ct4 pin + workspace.rs iter22b1 tests + the
instance_present.prose.txt snapshot) rename class Show / show
to class TShow / tshow, analogous to the existing TEq/TOrd
convention. Migration runs before the prelude additions so the
workspace stays green throughout.
Three new tests pin the post-mono shape: show_mono_synthesis.rs
(existence of show__Int/Bool/Str/Float as Def::Fn entries in the
prelude post-mono module), show_dispatch_pin.rs (bare show and
tshow both Step-2 singletons workspace-globally),
mono_hash_stability.rs::primitive_show_mono_symbol_hashes_stay_bit_identical
(body hashes pinned for the 4 new mono symbols).
DESIGN.md §Prelude (built-in) classes drops Show from the
deferred-features list and appends a milestone-24 paragraph
naming the class signature + the 4 instances + the body shape.
print rewire stays deferred to iter 24.3.
Tests: 552 passed (was 548 + 4 new). bench/compile_check +
bench/cross_lang exit 0. bench/check exits 1 on the recurring
noise envelope per the conservative-call lineage.
72 lines
2.6 KiB
Rust
72 lines
2.6 KiB
Rust
//! Singleton dispatch pin for milestone 24.2's Show class.
|
|
//!
|
|
//! Asserts that with `prelude.Show` shipping `show` and a user `TShow`
|
|
//! shipping `tshow`, the bare method-name dispatcher resolves each via
|
|
//! Step-2 singleton (each method has exactly one candidate class globally).
|
|
|
|
use ailang_check::{build_check_env, check_workspace};
|
|
use ailang_core::workspace::load_workspace;
|
|
use std::path::PathBuf;
|
|
|
|
fn fixture_dir() -> PathBuf {
|
|
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
d.pop();
|
|
d.pop();
|
|
d.join("examples")
|
|
}
|
|
|
|
#[test]
|
|
fn bare_show_routes_to_prelude_show_via_singleton() {
|
|
// Workspace = auto-loaded prelude (containing class Show) plus a
|
|
// non-prelude entry that has zero `Show` declarations of its own.
|
|
// Asserts: env.method_to_candidate_classes["show"] == {"prelude.Show"}
|
|
// (a singleton), so Step-2 of resolve_method_dispatch resolves bare
|
|
// "show" without needing Steps 3-4.
|
|
let ws_path = fixture_dir().join("show_mono_pin_smoke.ail.json");
|
|
let ws = load_workspace(&ws_path).expect("workspace loads");
|
|
let diags = check_workspace(&ws);
|
|
assert!(diags.is_empty(), "typecheck diagnostics: {diags:#?}");
|
|
|
|
let env = build_check_env(&ws);
|
|
let candidates = env
|
|
.method_to_candidate_classes
|
|
.get("show")
|
|
.expect("method 'show' has candidates");
|
|
assert_eq!(
|
|
candidates.len(),
|
|
1,
|
|
"post-24.2-migration, 'show' has exactly one candidate class globally: got {candidates:?}"
|
|
);
|
|
assert!(
|
|
candidates.iter().any(|c| c == "prelude.Show"),
|
|
"candidates do not include prelude.Show: {candidates:?}"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn bare_tshow_routes_to_user_tshow_via_singleton() {
|
|
// Workspace = auto-loaded prelude + the migrated 22b1_dup_classmod
|
|
// (which now declares class TShow with method tshow).
|
|
// Asserts: env.method_to_candidate_classes["tshow"] has exactly one
|
|
// candidate (the user TShow), workspace-globally.
|
|
let ws_path = fixture_dir().join("test_22b1_dup_classmod.ail.json");
|
|
let ws = load_workspace(&ws_path).expect("workspace loads");
|
|
let diags = check_workspace(&ws);
|
|
assert!(diags.is_empty(), "typecheck diagnostics: {diags:#?}");
|
|
|
|
let env = build_check_env(&ws);
|
|
let candidates = env
|
|
.method_to_candidate_classes
|
|
.get("tshow")
|
|
.expect("method 'tshow' has candidates");
|
|
assert_eq!(
|
|
candidates.len(),
|
|
1,
|
|
"post-22b-migration, 'tshow' is owned by exactly one class globally: got {candidates:?}"
|
|
);
|
|
assert!(
|
|
candidates.iter().any(|c| c.ends_with(".TShow")),
|
|
"candidates do not include a *.TShow class: {candidates:?}"
|
|
);
|
|
}
|