fix: disallow unknown type assignments and reads

This commit is contained in:
Gleb Koval 2025-02-07 00:23:41 +00:00
parent 277d2f66af
commit bc5f28ab52
Signed by: cyclane
GPG Key ID: 15E168A8B332382C
2 changed files with 28 additions and 9 deletions

View File

@ -99,12 +99,30 @@ object typeChecker {
) )
case Assign(lhs, rhs) => case Assign(lhs, rhs) =>
val lhsTy = checkValue(lhs, Constraint.Unconstrained) val lhsTy = checkValue(lhs, Constraint.Unconstrained)
checkValue(rhs, Constraint.Is(lhsTy, s"assignment must have type $lhsTy")) checkValue(rhs, Constraint.Is(lhsTy, s"assignment must have type $lhsTy")) match {
case Read(lhs) => case ? =>
checkValue( ctx.error(
lhs, Error.SemanticError(lhs.pos, "assignment with both sides of unknown type is illegal")
Constraint.IsEither(KnownType.Int, KnownType.Char, "read must be int or char")
) )
case _ => ()
}
case Read(lhs) =>
val lhsTy = checkValue(lhs, Constraint.Unconstrained)
lhsTy match {
case ? =>
ctx.error(
Error.SemanticError(lhs.pos, "cannot read into a destination with an unknown type")
)
case _ =>
lhsTy.satisfies(
Constraint.IsEither(
KnownType.Int,
KnownType.Char,
"read must be applied to an int or char"
),
lhs.pos
)
}
case Free(lhs) => case Free(lhs) =>
checkValue( checkValue(
lhs, lhs,
@ -193,7 +211,8 @@ object typeChecker {
elem, elem,
Constraint.Is(KnownType.Pair(?, ?), "fst must be applied to a pair") Constraint.Is(KnownType.Pair(?, ?), "fst must be applied to a pair")
) match { ) match {
case KnownType.Pair(left, _) => left.satisfies(constraint, elem.pos) case what @ KnownType.Pair(left, _) =>
left.satisfies(constraint, elem.pos)
case ? => ?.satisfies(constraint, elem.pos) case ? => ?.satisfies(constraint, elem.pos)
case _ => ctx.error(Error.InternalError(elem.pos, "fst must be applied to a pair")) case _ => ctx.error(Error.InternalError(elem.pos, "fst must be applied to a pair"))
} // satisfies constraint } // satisfies constraint

View File

@ -16,7 +16,7 @@ class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with Paral
(p.toString, List(200)) (p.toString, List(200))
} ++ } ++
allWaccFiles("wacc-examples/invalid/whack").map { p => allWaccFiles("wacc-examples/invalid/whack").map { p =>
(p.toString, List(0, 100, 200)) (p.toString, List(100, 200))
} }
// tests go here // tests go here
@ -82,7 +82,7 @@ class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with Paral
// "wacc-examples/invalid/semanticErr/variables", // "wacc-examples/invalid/semanticErr/variables",
// "wacc-examples/invalid/semanticErr/while", // "wacc-examples/invalid/semanticErr/while",
// invalid (whack) // invalid (whack)
"wacc-examples/invalid/whack" // "wacc-examples/invalid/whack"
// format: on // format: on
// format: on // format: on
).find(filename.contains).isDefined ).find(filename.contains).isDefined