iter 22-tidy.5.2: parse_const rejects duplicate doc/type/body clauses
This commit is contained in:
@@ -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}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user