check: mode-strict-because suppression (iter 19b)
Closes the 19a/19a.1/19b arc. Corpus signal from 19a.1 (5/65
fixtures fire over-strict-mode, all deliberate RC codegen-test
fixtures) justified shipping the suppress mechanism end-to-end.
Schema: Suppress { code, because } on FnDef. Pre-19b hashes
bit-identical via skip_serializing_if. Typechecker drops matching
diagnostics; empty 'because' is Error severity; wrong codes are
silent no-ops (open-set registry).
Form-A: (suppress (code "...") (because "...")) clause, parser
+ printer round-trip clean. Form-B: '// @suppress <code>: <reason>'
above the doc string, lossless contract metadata.
5 RC fixtures migrated (.ail.json + .ailx + .prose.txt). Corpus
signal: 5/65 -> 0/65. Lint still fires on any future fn that's
accidentally over-strict without an authored reason.
Test counts: ailang-check 55->61, ailang-core 26->28, ailang-surface
21->26, ailang-prose 49->52, e2e 70 unchanged.
Known debt: .ailx comment headers lost on regen (ail render's
contract excludes comments); parse_suppress_attr accepts
duplicate code/because attrs without diagnose (bounded by canonical
print order).
This commit is contained in:
@@ -8,8 +8,8 @@
|
||||
//! per level. Comments are NOT emitted.
|
||||
|
||||
use ailang_core::ast::{
|
||||
Arm, ConstDef, Ctor, Def, FnDef, Import, Literal, Module, ParamMode, Pattern, Term, Type,
|
||||
TypeDef,
|
||||
Arm, ConstDef, Ctor, Def, FnDef, Import, Literal, Module, ParamMode, Pattern, Suppress, Term,
|
||||
Type, TypeDef,
|
||||
};
|
||||
|
||||
/// Print a module in form (A).
|
||||
@@ -153,6 +153,13 @@ fn write_fn_def(out: &mut String, fd: &FnDef, level: usize) {
|
||||
write_string_lit(out, doc);
|
||||
out.push(')');
|
||||
}
|
||||
// Iter 19b: emit one `(suppress ...)` clause per entry, after the
|
||||
// doc string and before the type. Round-trip stable: parser
|
||||
// re-reads each clause back into [`FnDef::suppress`].
|
||||
for s in &fd.suppress {
|
||||
out.push('\n');
|
||||
write_suppress(out, s, level + 1);
|
||||
}
|
||||
out.push('\n');
|
||||
indent(out, level + 1);
|
||||
out.push_str("(type ");
|
||||
@@ -174,6 +181,18 @@ fn write_fn_def(out: &mut String, fd: &FnDef, level: usize) {
|
||||
out.push(')');
|
||||
}
|
||||
|
||||
/// Iter 19b: print one `(suppress (code "<c>") (because "<r>"))`
|
||||
/// clause. Indentation matches the rest of the fn-def (one level
|
||||
/// deeper than the `(fn ...)` head).
|
||||
fn write_suppress(out: &mut String, s: &Suppress, level: usize) {
|
||||
indent(out, level);
|
||||
out.push_str("(suppress (code ");
|
||||
write_string_lit(out, &s.code);
|
||||
out.push_str(") (because ");
|
||||
write_string_lit(out, &s.because);
|
||||
out.push_str("))");
|
||||
}
|
||||
|
||||
fn write_const_def(out: &mut String, cd: &ConstDef, level: usize) {
|
||||
indent(out, level);
|
||||
out.push_str("(const ");
|
||||
|
||||
Reference in New Issue
Block a user