Skip to content

Commit eeabada

Browse files
committed
Merge #247: fix: realising of built-in types, hard-coded aliases
887c681 fix: add whitespace after comma in `Either` display (Volodymyr Herashchenko) 0f54d67 feat: add check for redefining built-in types (Volodymyr Herashchenko) ec45a2d fix: remove hardcoded built-ins (Volodymyr Herashchenko) Pull request description: Closes #235 and partially closes #202. There are 3 small and separate fixes: 1) Remove hard-coded built-in aliases from the parser, so all alias checking is in `types.rs` 2) Adds check for redefining built-in aliases and types in `TypeAlias` parsing function. It uses the same logic as the first fix, so I included it here. 3) Fix small typo within `TypeInner` display function -- there are missing whitespace after comma inside `Either` type. You can see this issue in [this PR](BlockstreamResearch/simplicity-lang-org@ab0365c#diff-45c93d101716efcb5e6e71fbdca58e55488f9b0c15f1ac2f01c9af1b1b39f44eR2936) for `simplicitiy-lang-org`. It's a small enough change that I thought I could include it here. Would be happy to split this up if needed. ACKs for top commit: apoelstra: ACK 887c681; successfully ran local tests delta1: ACK 887c681; tested locally Tree-SHA512: c30a6be4221727d0518e1d0b9559b83783b1834c9b002cfc51c81414209fac924f4fb9786c1ad4ec3057a2572c42ce9b88ac0b2f238b614beec5be68142c28f1
2 parents 8c5ac11 + 887c681 commit eeabada

File tree

3 files changed

+73
-22
lines changed

3 files changed

+73
-22
lines changed

src/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ pub enum Error {
429429
IntegerOutOfBounds(UIntType),
430430
UndefinedVariable(Identifier),
431431
RedefinedAlias(AliasName),
432+
RedefinedAliasAsBuiltin(AliasName),
432433
UndefinedAlias(AliasName),
433434
VariableReuseInPattern(Identifier),
434435
WitnessReused(WitnessName),
@@ -551,6 +552,10 @@ impl fmt::Display for Error {
551552
f,
552553
"Type alias `{identifier}` was defined multiple times"
553554
),
555+
Error::RedefinedAliasAsBuiltin(identifier) => write!(
556+
f,
557+
"Type alias `{identifier}` is already exists as built-in alias"
558+
),
554559
Error::UndefinedAlias(identifier) => write!(
555560
f,
556561
"Type alias `{identifier}` is not defined"

src/parse.rs

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::str::{
2626
AliasName, Binary, Decimal, FunctionName, Hexadecimal, Identifier, JetName, ModuleName,
2727
WitnessName,
2828
};
29-
use crate::types::{AliasedType, BuiltinAlias, TypeConstructible};
29+
use crate::types::{AliasedType, BuiltinAlias, TypeConstructible, UIntType};
3030

3131
/// A program is a sequence of items.
3232
#[derive(Clone, Debug)]
@@ -1002,26 +1002,17 @@ impl ChumskyParse for AliasedType {
10021002
I: ValueInput<'tokens, Token = Token<'src>, Span = Span>,
10031003
{
10041004
let atom = select! {
1005-
Token::Ident(ident) => {
1006-
match ident
1007-
{
1008-
"u1" => AliasedType::u1(),
1009-
"u2" => AliasedType::u2(),
1010-
"u4" => AliasedType::u4(),
1011-
"u8" => AliasedType::u8(),
1012-
"u16" => AliasedType::u16(),
1013-
"u32" => AliasedType::u32(),
1014-
"u64" => AliasedType::u64(),
1015-
"u128" => AliasedType::u128(),
1016-
"u256" => AliasedType::u256(),
1017-
"Ctx8" | "Pubkey" | "Message64" | "Message" | "Signature" | "Scalar" | "Fe" | "Gej"
1018-
| "Ge" | "Point" | "Height" | "Time" | "Distance" | "Duration" | "Lock" | "Outpoint"
1019-
| "Confidential1" | "ExplicitAsset" | "Asset1" | "ExplicitAmount" | "Amount1"
1020-
| "ExplicitNonce" | "Nonce" | "TokenAmount1" => AliasedType::builtin(BuiltinAlias::from_str(ident).unwrap()),
1021-
"bool" => AliasedType::boolean(),
1022-
_ => AliasedType::alias(AliasName::from_str_unchecked(ident)),
1005+
Token::Ident(ident) => {
1006+
if ident == "bool" {
1007+
AliasedType::boolean()
1008+
} else if let Ok(uint_type) = UIntType::from_str(ident) {
1009+
AliasedType::from(uint_type)
1010+
} else if let Ok(builtin) = BuiltinAlias::from_str(ident) {
1011+
AliasedType::builtin(builtin)
1012+
} else {
1013+
AliasedType::alias(AliasName::from_str_unchecked(ident))
1014+
}
10231015
}
1024-
},
10251016
};
10261017

10271018
let num = select! {
@@ -1461,7 +1452,25 @@ impl ChumskyParse for TypeAlias {
14611452
where
14621453
I: ValueInput<'tokens, Token = Token<'src>, Span = Span>,
14631454
{
1464-
let name = AliasName::parser().map_with(|name, e| (name, e.span()));
1455+
let name = AliasName::parser()
1456+
.validate(|name, e, emit| {
1457+
let ident = name.as_inner();
1458+
let known_type = if ident == "bool" {
1459+
Some(AliasedType::boolean())
1460+
} else if let Ok(uint_type) = UIntType::from_str(ident) {
1461+
Some(AliasedType::from(uint_type))
1462+
} else if let Ok(builtin) = BuiltinAlias::from_str(ident) {
1463+
Some(AliasedType::builtin(builtin))
1464+
} else {
1465+
None
1466+
};
1467+
1468+
if known_type.is_some() {
1469+
emit.emit(Error::RedefinedAliasAsBuiltin(name.clone()).with_span(e.span()));
1470+
}
1471+
name
1472+
})
1473+
.map_with(|name, e| (name, e.span()));
14651474

14661475
just(Token::Type)
14671476
.ignore_then(name)
@@ -2163,3 +2172,19 @@ impl crate::ArbitraryRec for Match {
21632172
})
21642173
}
21652174
}
2175+
2176+
#[cfg(test)]
2177+
mod test {
2178+
use super::*;
2179+
2180+
#[test]
2181+
fn test_reject_redefined_builtin_type() {
2182+
let ty = TypeAlias::parse_from_str("type Ctx8 = u32")
2183+
.expect_err("Redifining built-in alias should be rejected");
2184+
2185+
assert_eq!(
2186+
ty.error(),
2187+
&Error::RedefinedAliasAsBuiltin(AliasName::from_str_unchecked("Ctx8"))
2188+
);
2189+
}
2190+
}

src/types.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl<A> TypeInner<A> {
3737
match self {
3838
TypeInner::Either(_, _) => match n_children_yielded {
3939
0 => f.write_str("Either<"),
40-
1 => f.write_str(","),
40+
1 => f.write_str(", "),
4141
n => {
4242
debug_assert_eq!(n, 2);
4343
f.write_str(">")
@@ -193,6 +193,25 @@ impl fmt::Display for UIntType {
193193
}
194194
}
195195

196+
impl FromStr for UIntType {
197+
type Err = String;
198+
199+
fn from_str(s: &str) -> Result<Self, Self::Err> {
200+
match s {
201+
"u1" => Ok(UIntType::U1),
202+
"u2" => Ok(UIntType::U2),
203+
"u4" => Ok(UIntType::U4),
204+
"u8" => Ok(UIntType::U8),
205+
"u16" => Ok(UIntType::U16),
206+
"u32" => Ok(UIntType::U32),
207+
"u64" => Ok(UIntType::U64),
208+
"u128" => Ok(UIntType::U128),
209+
"u256" => Ok(UIntType::U256),
210+
_ => Err("Unknown integer type".to_string()),
211+
}
212+
}
213+
}
214+
196215
impl TryFrom<&StructuralType> for UIntType {
197216
type Error = ();
198217

@@ -1094,5 +1113,7 @@ mod tests {
10941113
assert_eq!("[(); 3]", &array.to_string());
10951114
let list = ResolvedType::list(ResolvedType::unit(), NonZeroPow2Usize::TWO);
10961115
assert_eq!("List<(), 2>", &list.to_string());
1116+
let either = ResolvedType::either(ResolvedType::unit(), ResolvedType::u32());
1117+
assert_eq!("Either<(), u32>", &either.to_string());
10971118
}
10981119
}

0 commit comments

Comments
 (0)