Support "records" in Podlang (#507)

* Support both integer and string keys in anchored keys

* Podlang parser support for records

* Validate record usage in Podlang

* Lower records to middleware

* Cross-module record imports

* Tidying

* Record entry name literal

* More tidying

* More tests, make sure qualified record literals are supported

* Use snake-case for record entry names

* Review feedback
This commit is contained in:
Rob Knight 2026-05-06 06:21:22 -07:00 committed by GitHub
parent 5e3ac9a101
commit e9e3241263
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 2020 additions and 198 deletions

View file

@ -286,6 +286,123 @@ fn render_validation_error(
"not allowed here",
)
}
ValidationError::DuplicateRecord {
name,
first_span,
second_span,
} => {
let title = format!("duplicate record definition: {}", name);
render_dual_span(
renderer,
source,
path,
&title,
first_span.as_ref(),
"first definition here",
second_span.as_ref(),
"duplicate definition",
)
}
ValidationError::RecordTooManyEntries {
name,
count,
max,
span,
} => {
let title = format!(
"record `{}` has {} entries, exceeding the limit of {}",
name, count, max
);
render_with_optional_span(
renderer,
source,
path,
&title,
span.as_ref(),
"too many entries",
)
}
ValidationError::DuplicateRecordEntry {
record,
entry,
span,
} => {
let title = format!("duplicate entry `{}` in record `{}`", entry, record);
render_with_optional_span(
renderer,
source,
path,
&title,
span.as_ref(),
"already declared",
)
}
ValidationError::UnknownRecord { name, span } => {
let title = format!("unknown record type: {}", name);
render_with_optional_span(
renderer,
source,
path,
&title,
span.as_ref(),
"no such record",
)
}
ValidationError::UnknownRecordEntry {
record,
entry,
span,
} => {
let title = format!("record `{}` has no entry `{}`", record, entry);
render_with_optional_span(
renderer,
source,
path,
&title,
span.as_ref(),
"unknown entry",
)
}
ValidationError::DuplicateLiteralRecordEntry {
record,
entry,
span,
} => {
let title = format!("duplicate entry `{}` in `{}` literal", entry, record);
render_with_optional_span(
renderer,
source,
path,
&title,
span.as_ref(),
"already given",
)
}
ValidationError::BracketAccessOnTypedWildcard {
wildcard,
record,
span,
} => {
let title = format!(
"bracket access on `{}` (typed as record `{}`); use `{}.entry` instead",
wildcard, record, wildcard
);
render_with_optional_span(
renderer,
source,
path,
&title,
span.as_ref(),
"string-key access on integer-keyed record",
)
}
}
}