iter 22-tidy.4: pin lockstep invariant + tighten module doc
This commit is contained in:
@@ -3,27 +3,24 @@
|
||||
//! constructor?" Every typecheck and codegen site that gates
|
||||
//! behaviour on the primitive set goes through this module.
|
||||
//!
|
||||
//! Adding a primitive: append to BOTH functions below; the four
|
||||
//! consumers compile-fail-loudly if the predicate is forgotten
|
||||
//! (the failure is a missed branch, not a panic), but
|
||||
//! `primitive_surface_name` will silently return `None` for the
|
||||
//! new name unless its `match` is extended too. Keep the two
|
||||
//! functions in lockstep.
|
||||
//! Adding a primitive: append to BOTH functions below. The lockstep
|
||||
//! invariant ([`is_primitive_name`] is `true` iff
|
||||
//! [`primitive_surface_name`] is `Some`) is pinned by the unit test
|
||||
//! at the bottom of this file — extending only one of the two
|
||||
//! fails the test before the bug reaches a consumer.
|
||||
|
||||
/// Returns `true` iff `name` is one of the built-in zero-arity
|
||||
/// primitive type constructors. Cross-crate predicate consumed by
|
||||
/// `ailang-check` (`linearity::is_heap_type`, `lib::check_type_well_formed`,
|
||||
/// `lib::qualify_local_types`) and `ailang-codegen`
|
||||
/// (`subst::qualify_local_types_codegen`).
|
||||
/// primitive type constructors. Cross-crate predicate used by
|
||||
/// typecheck-time well-formedness gating, the heap-type filter,
|
||||
/// the local-type qualifier, and the codegen substitution path.
|
||||
pub fn is_primitive_name(name: &str) -> bool {
|
||||
matches!(name, "Int" | "Bool" | "Str" | "Unit")
|
||||
}
|
||||
|
||||
/// Returns the static-lifetime surface name iff `name` is a
|
||||
/// primitive. Used by `mono::primitive_surface_name` to embed the
|
||||
/// human-readable form in monomorphised symbol names; the static
|
||||
/// lifetime is what makes the symbol-builder's `&'static str`
|
||||
/// signature work.
|
||||
/// primitive. Used by the mono pass to embed the human-readable
|
||||
/// form in monomorphised symbol names; the static lifetime is what
|
||||
/// makes the symbol-builder's `&'static str` signature work.
|
||||
pub fn primitive_surface_name(name: &str) -> Option<&'static str> {
|
||||
match name {
|
||||
"Int" => Some("Int"),
|
||||
@@ -33,3 +30,23 @@ pub fn primitive_surface_name(name: &str) -> Option<&'static str> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// The two functions must agree on which names are primitive:
|
||||
/// `is_primitive_name(n)` true iff `primitive_surface_name(n)`
|
||||
/// is `Some`. The list of names tested mirrors the literal set
|
||||
/// inside both functions plus a sample non-primitive.
|
||||
#[test]
|
||||
fn predicate_and_surface_name_agree() {
|
||||
for name in ["Int", "Bool", "Str", "Unit", "List", "Foo", "", "int"] {
|
||||
assert_eq!(
|
||||
is_primitive_name(name),
|
||||
primitive_surface_name(name).is_some(),
|
||||
"lockstep violation for {name:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user