fix(compiler): Throw an error when comparing an alias and a named type with the same name [LNG-231] (#946)

This commit is contained in:
Dima 2023-10-27 18:18:44 +07:00 committed by GitHub
parent 45ca7bbf3e
commit 38f77285f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 65 deletions

View File

@ -1,35 +1,6 @@
aqua A
alias Troll: u32
export bugLNG260
func test() -> i8:
MyAbility = Troll(f = "sf")
func create(a: i8) -> -> i8:
closureArrow = () -> i8:
<- a
<- closureArrow
func test() -> i8, i8:
arr1 <- create(1)
arr2 <- create(2)
<- arr1(), arr2()
func cmp(a: i32, b: i32, pred: i8 -> bool) -> bool:
result: ?bool
if a < b:
result <- pred(-1)
else:
if a == b:
result <- pred(0)
else:
result <- pred(1)
<- result!
func gt(a: i32, b: i32) -> bool:
pred = (ord: i8) -> bool:
<- ord > 0
<- cmp(a, b, pred)
func bugLNG260(a: i32, b: i32) -> bool:
<- gt(a, b)
<- 42

View File

@ -618,9 +618,6 @@ class ArrowInlinerSpec extends AnyFlatSpec with Matchers with Inside {
None
)
println("testFunc: ")
println(testFunc.body.show)
val model = ArrowInliner
.callArrow[InliningState](testFunc, CallModel(Nil, Nil))
.runA(InliningState())

View File

@ -6,27 +6,21 @@ import aqua.parser.lexer.PrefixToken.Op as PrefOp
import aqua.raw.value.*
import aqua.semantics.rules.abilities.AbilitiesAlgebra
import aqua.semantics.rules.names.NamesAlgebra
import aqua.semantics.rules.types.TypesAlgebra
import aqua.semantics.rules.report.ReportAlgebra
import aqua.semantics.rules.types.TypesAlgebra
import aqua.types.*
import cats.Monad
import cats.data.OptionT
import cats.data.Chain
import cats.data.{NonEmptyList, OptionT}
import cats.instances.list.*
import cats.syntax.applicative.*
import cats.syntax.apply.*
import cats.syntax.flatMap.*
import cats.syntax.functor.*
import cats.syntax.traverse.*
import cats.syntax.foldable.*
import cats.syntax.functor.*
import cats.syntax.option.*
import cats.instances.list.*
import cats.data.{NonEmptyList, NonEmptyMap}
import cats.data.OptionT
import cats.syntax.traverse.*
import scribe.Logging
import scala.collection.immutable.SortedMap
class ValuesAlgebra[S[_], Alg[_]: Monad](using
N: NamesAlgebra[S, Alg],
T: TypesAlgebra[S, Alg],
@ -119,7 +113,7 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](using
case dvt @ NamedValueToken(typeName, fields) =>
(for {
resolvedType <- OptionT(T.resolveType(typeName))
resolvedType <- OptionT(T.resolveNamedType(typeName))
// Report duplicate fields
_ <- OptionT.liftF(
reportNamedArgsDuplicates(fields)
@ -140,7 +134,6 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](using
ability.copy(fields = fieldsGivenTypes),
AbilityRaw(fieldsGiven, ability)
).some
case _ => none
}
)
(genType, genData) = generated

View File

@ -11,6 +11,8 @@ trait TypesAlgebra[S[_], Alg[_]] {
def resolveType(token: TypeToken[S]): Alg[Option[Type]]
def resolveNamedType(token: TypeToken[S]): Alg[Option[AbilityType | StructType]]
def getType(name: String): Alg[Option[Type]]
def resolveArrowDef(arrowDef: ArrowTypeToken[S]): Alg[Option[ArrowType]]

View File

@ -58,6 +58,12 @@ class TypesInterpreter[S[_], X](using
report.error(token, s"Unresolved type").as(None)
}
def resolveNamedType(token: TypeToken[S]): State[X, Option[AbilityType | StructType]] =
resolveType(token).flatMap(_.flatTraverse {
case t: (AbilityType | StructType) => Option(t).pure
case _ => report.error(token, "Type must be an ability or a data").as(None)
})
override def resolveArrowDef(arrowDef: ArrowTypeToken[S]): State[X, Option[ArrowType]] =
getState.map(TypesStateHelper.resolveArrowDef(arrowDef)).flatMap {
case Valid(TypeResolution(tt, tokens)) =>

View File

@ -1,29 +1,24 @@
package aqua.semantics
import aqua.parser.lexer.*
import aqua.raw.RawContext
import aqua.raw.value.*
import aqua.semantics.rules.ValuesAlgebra
import aqua.semantics.rules.abilities.{AbilitiesAlgebra, AbilitiesInterpreter, AbilitiesState}
import aqua.semantics.rules.names.{NamesAlgebra, NamesInterpreter, NamesState}
import aqua.semantics.rules.abilities.{AbilitiesAlgebra, AbilitiesInterpreter}
import aqua.semantics.rules.definitions.{DefinitionsAlgebra, DefinitionsInterpreter}
import aqua.semantics.rules.types.{TypesAlgebra, TypesInterpreter, TypesState}
import aqua.semantics.rules.locations.{DummyLocationsInterpreter, LocationsAlgebra}
import aqua.semantics.rules.mangler.{ManglerAlgebra, ManglerInterpreter}
import aqua.semantics.rules.names.{NamesAlgebra, NamesInterpreter, NamesState}
import aqua.semantics.rules.report.{ReportAlgebra, ReportInterpreter}
import aqua.raw.value.{ApplyBinaryOpRaw, LiteralRaw}
import aqua.raw.RawContext
import aqua.semantics.rules.types.{TypesAlgebra, TypesInterpreter}
import aqua.types.*
import aqua.parser.lexer.*
import aqua.raw.value.*
import aqua.parser.lexer.ValueToken.string
import cats.Id
import cats.data.{NonEmptyList, NonEmptyMap, State}
import monocle.syntax.all.*
import org.scalatest.Inside
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.Inside
import cats.Id
import cats.data.State
import cats.syntax.functor.*
import cats.syntax.comonad.*
import cats.data.NonEmptyMap
import monocle.syntax.all.*
import scala.collection.immutable.SortedMap
class ValuesAlgebraSpec extends AnyFlatSpec with Matchers with Inside {
@ -518,6 +513,30 @@ class ValuesAlgebraSpec extends AnyFlatSpec with Matchers with Inside {
}
}
it should "throw an error when comparing a struct type with a primitive alias" in {
val state = genState(
vars = Map("SomeName" -> LiteralType.string)
)
val token = NamedValueToken[Id](
NamedTypeToken[Id]("SomeName"),
NonEmptyList.of(
NamedArg.Full(Name("f1"), LiteralToken[Id]("1", LiteralType.number)),
NamedArg.Full(Name("f2"), LiteralToken[Id]("2", LiteralType.number))
)
)
val alg = algebra()
val (st, res) = alg
.valueToRaw(token)
.run(state)
.value
res shouldBe None
st.errors.exists(_.isInstanceOf[RulesViolated[Id]]) shouldBe true
}
it should "forbid collections with abilities or arrows" in {
val ability = variable("ab")
val abilityType = AbilityType("Ab", NonEmptyMap.of("field" -> ScalarType.i8))