iter 22-tidy.5.2: parse_const rejects duplicate doc/type/body clauses

This commit is contained in:
2026-05-10 04:31:08 +02:00
parent 9592478971
commit 3fd17827bf
+97 -3
View File
@@ -686,9 +686,45 @@ impl<'a> Parser<'a> {
let mut value: Option<Term> = None;
loop {
match self.peek_head_ident() {
Some("doc") => doc = Some(self.parse_doc()?),
Some("type") => ty = Some(self.parse_type_attr()?),
Some("body") => value = Some(self.parse_body_attr()?),
Some("doc") => {
if doc.is_some() {
let pos = self.peek().map(|t| t.span.start).unwrap_or(0);
return Err(ParseError::Production {
production: "const-def",
message: format!(
"const `{name}` has duplicate `(doc ...)` clause"
),
pos,
});
}
doc = Some(self.parse_doc()?);
}
Some("type") => {
if ty.is_some() {
let pos = self.peek().map(|t| t.span.start).unwrap_or(0);
return Err(ParseError::Production {
production: "const-def",
message: format!(
"const `{name}` has duplicate `(type ...)` clause"
),
pos,
});
}
ty = Some(self.parse_type_attr()?);
}
Some("body") => {
if value.is_some() {
let pos = self.peek().map(|t| t.span.start).unwrap_or(0);
return Err(ParseError::Production {
production: "const-def",
message: format!(
"const `{name}` has duplicate `(body ...)` clause"
),
pos,
});
}
value = Some(self.parse_body_attr()?);
}
Some(other) => {
let pos = self.peek().map(|t| t.span.start).unwrap_or(0);
return Err(ParseError::Production {
@@ -2393,4 +2429,62 @@ mod tests {
"expected duplicate-body diagnostic, got: {msg}"
);
}
#[test]
fn parse_const_rejects_duplicate_doc_clause() {
let err = parse(
r#"
(module m
(const c
(doc "first")
(doc "second")
(type (con Int))
(body 42)))
"#,
)
.unwrap_err();
let msg = format!("{err:?}");
assert!(
msg.contains("const `c` has duplicate `(doc ...)` clause"),
"expected duplicate-doc diagnostic, got: {msg}"
);
}
#[test]
fn parse_const_rejects_duplicate_type_clause() {
let err = parse(
r#"
(module m
(const c
(type (con Int))
(type (con Int))
(body 42)))
"#,
)
.unwrap_err();
let msg = format!("{err:?}");
assert!(
msg.contains("const `c` has duplicate `(type ...)` clause"),
"expected duplicate-type diagnostic, got: {msg}"
);
}
#[test]
fn parse_const_rejects_duplicate_body_clause() {
let err = parse(
r#"
(module m
(const c
(type (con Int))
(body 1)
(body 2)))
"#,
)
.unwrap_err();
let msg = format!("{err:?}");
assert!(
msg.contains("const `c` has duplicate `(body ...)` clause"),
"expected duplicate-body diagnostic, got: {msg}"
);
}
}