Skip to content

Commit

Permalink
code cleanup
Browse files Browse the repository at this point in the history
Summary:
- Util.getFunType always returns Some(...) (after we stopped supporting strict mode)
- changing API from `Option[FunType]` to `FunType` and deleting dead code

Reviewed By: VLanvin

Differential Revision: D62641540

fbshipit-source-id: 32aca1fc8760819155260057696503f9eb3dab5e
  • Loading branch information
ilya-klyuchnikov authored and facebook-github-bot committed Sep 16, 2024
1 parent 7af66a2 commit 931e328
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 129 deletions.
48 changes: 16 additions & 32 deletions eqwalizer/src/main/scala/com/whatsapp/eqwalizer/tc/Check.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,10 @@ final class Check(pipelineContext: PipelineContext) {
if (!subtype.subType(callTy, resTy))
diagnosticsInfo.add(ExpectedSubtype(expr.pos, expr, expected = resTy, got = callTy))
env1
} else
util.getFunType(module, id) match {
case Some(ft) =>
checkApply(funId, expr, freshen(ft), args, resTy, env)
case None =>
diagnosticsInfo.add(UnboundVar(expr.pos, id.toString))
env
}
} else {
val ft = util.getFunType(module, id)
checkApply(funId, expr, freshen(ft), args, resTy, env)
}
case DynRemoteFun(mod, name) =>
throw new IllegalStateException(s"unexpected $expr")
case dFun: DynRemoteFunArity =>
Expand All @@ -216,14 +212,10 @@ final class Check(pipelineContext: PipelineContext) {
if (!subtype.subType(callTy, resTy))
diagnosticsInfo.add(ExpectedSubtype(expr.pos, expr, expected = resTy, got = callTy))
env1
} else
util.getFunType(fqn) match {
case Some(ft) =>
checkApply(fqn, expr, freshen(ft), args, resTy, env)
case None =>
diagnosticsInfo.add(UnboundVar(expr.pos, fqn.toString))
env
}
} else {
val ft = util.getFunType(fqn)
checkApply(fqn, expr, freshen(ft), args, resTy, env)
}
case DynCall(l: Lambda, args) =>
val arity = lambdaArity(l)
val (argTys, env1) = elab.elabExprs(args, env)
Expand Down Expand Up @@ -268,24 +260,16 @@ final class Check(pipelineContext: PipelineContext) {
}
env2
case LocalFun(id) =>
util.getFunType(module, id) match {
case Some(ft) =>
val ft1 = freshen(ft)
if (!subtype.subType(ft1, resTy))
diagnosticsInfo.add(ExpectedSubtype(expr.pos, expr, expected = resTy, got = ft1))
case None =>
diagnosticsInfo.add(UnboundVar(expr.pos, id.toString))
}
val ft = util.getFunType(module, id)
val ft1 = freshen(ft)
if (!subtype.subType(ft1, resTy))
diagnosticsInfo.add(ExpectedSubtype(expr.pos, expr, expected = resTy, got = ft1))
env
case RemoteFun(fqn) =>
util.getFunType(fqn) match {
case Some(ft) =>
val ft1 = freshen(ft)
if (!subtype.subType(ft1, resTy))
diagnosticsInfo.add(ExpectedSubtype(expr.pos, expr, expected = resTy, got = ft1))
case None =>
diagnosticsInfo.add(UnboundVar(expr.pos, fqn.toString))
}
val ft = util.getFunType(fqn)
val ft1 = freshen(ft)
if (!subtype.subType(ft1, resTy))
diagnosticsInfo.add(ExpectedSubtype(expr.pos, expr, expected = resTy, got = ft1))
env
case lambda: Lambda =>
checkLambda(lambda, resTy, env)
Expand Down
62 changes: 22 additions & 40 deletions eqwalizer/src/main/scala/com/whatsapp/eqwalizer/tc/Elab.scala
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,16 @@ final class Elab(pipelineContext: PipelineContext) {
elabApplyCustom.elabCustom(funId, args, env, expr.pos)
} else if (elabApplyOverloaded.isOverloadedFun(funId)) {
elabApplyOverloaded.elabOverloaded(expr, funId, args, env)
} else
util.getFunType(module, id) match {
case Some(ft) =>
val (argTys, env1) = typeInfo.withoutLambdaTypeCollection {
elabExprs(args, env)
}
var resTy = elabApply.elabApply(check.freshen(ft), args, argTys, env1)
if (customReturn.isCustomReturn(funId))
resTy = customReturn.customizeResultType(funId, args, argTys, resTy)
(resTy, env1)
case None =>
diagnosticsInfo.add(UnboundVar(expr.pos, id.toString))
(DynamicType, env)
} else {
val ft = util.getFunType(module, id)
val (argTys, env1) = typeInfo.withoutLambdaTypeCollection {
elabExprs(args, env)
}
var resTy = elabApply.elabApply(check.freshen(ft), args, argTys, env1)
if (customReturn.isCustomReturn(funId))
resTy = customReturn.customizeResultType(funId, args, argTys, resTy)
(resTy, env1)
}
case DynCall(l: Lambda, args) =>
val arity = l.clauses.head.pats.size
val (argTys, env1) = elabExprs(args, env)
Expand Down Expand Up @@ -220,36 +216,22 @@ final class Elab(pipelineContext: PipelineContext) {
elabApplyCustom.elabCustom(fqn, args, env, expr.pos)
} else if (elabApplyOverloaded.isOverloadedFun(fqn)) {
elabApplyOverloaded.elabOverloaded(expr, fqn, args, env)
} else
util.getFunType(fqn) match {
case Some(ft) =>
val (argTys, env1) = typeInfo.withoutLambdaTypeCollection {
elabExprs(args, env)
}
var resTy = elabApply.elabApply(check.freshen(ft), args, argTys, env1)
if (customReturn.isCustomReturn(fqn))
resTy = customReturn.customizeResultType(fqn, args, argTys, resTy)
(resTy, env1)
case None =>
diagnosticsInfo.add(UnboundVar(expr.pos, fqn.toString))
(DynamicType, env)
} else {
val ft = util.getFunType(fqn)
val (argTys, env1) = typeInfo.withoutLambdaTypeCollection {
elabExprs(args, env)
}
case LocalFun(id) =>
util.getFunType(module, id) match {
case Some(ft) =>
(check.freshen(ft), env)
case None =>
diagnosticsInfo.add(UnboundVar(expr.pos, id.toString))
(DynamicType, env)
var resTy = elabApply.elabApply(check.freshen(ft), args, argTys, env1)
if (customReturn.isCustomReturn(fqn))
resTy = customReturn.customizeResultType(fqn, args, argTys, resTy)
(resTy, env1)
}
case LocalFun(id) =>
val ft = util.getFunType(module, id)
(check.freshen(ft), env)
case RemoteFun(fqn) =>
util.getFunType(fqn) match {
case Some(ft) =>
(check.freshen(ft), env)
case None =>
diagnosticsInfo.add(UnboundVar(expr.pos, fqn.toString))
(DynamicType, env)
}
val ft = util.getFunType(fqn)
(check.freshen(ft), env)
case lambda @ Lambda(clauses) =>
val arity = clauses.head.pats.length
val funType = FunType(Nil, List.fill(arity)(DynamicType), DynamicType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import scala.annotation.tailrec
import com.whatsapp.eqwalizer.ast.Exprs.{AtomLit, Cons, Expr, IntLit, Lambda, NilLit, Var}
import com.whatsapp.eqwalizer.ast.Types._
import com.whatsapp.eqwalizer.ast.{Exprs, Pos, RemoteId}
import com.whatsapp.eqwalizer.tc.TcDiagnostics.{ExpectedSubtype, IndexOutOfBounds, UnboundVar, UnboundRecord}
import com.whatsapp.eqwalizer.tc.TcDiagnostics.{ExpectedSubtype, IndexOutOfBounds, UnboundRecord}
import com.whatsapp.eqwalizer.ast.CompilerMacro

class ElabApplyCustom(pipelineContext: PipelineContext) {
Expand Down Expand Up @@ -77,57 +77,52 @@ class ElabApplyCustom(pipelineContext: PipelineContext) {
val (argTys, env1) = elab.elabExprs(args, env)
remoteId match {
case fqn @ RemoteId("file", "open", 2) =>
util.getFunType(fqn) match {
case Some(ft) =>
val resTy = elabApply.elabApply(check.freshen(ft), args, argTys, env1)
val resTyPrecise = {
val modeArg = args(1)
def collectModes(expr: Expr): List[Option[String]] = {
expr match {
case NilLit() =>
Nil
case Cons(AtomLit(s), t) =>
Some(s) :: collectModes(t)
case Cons(Exprs.Tuple(List(AtomLit(s), _)), t) =>
Some(s) :: collectModes(t)
case _ =>
List(None)
}
}
val modes = collectModes(modeArg)
if (modes.forall(_.isDefined)) {
val literalModes = modes.flatten
val fd = literalModes.contains("raw") || literalModes.contains("ram")
val deviceT =
if (fd)
RemoteType(RemoteId("file", "fd", 0), List())
else
PidType
UnionType(
Set(
TupleType(List(AtomLitType("ok"), deviceT)),
TupleType(
List(
AtomLitType("error"),
UnionType(
Set(
RemoteType(RemoteId("file", "posix", 0), List()),
AtomLitType("badarg"),
AtomLitType("system_limit"),
)
),
val ft = util.getFunType(fqn)
val resTy = elabApply.elabApply(check.freshen(ft), args, argTys, env1)
val resTyPrecise = {
val modeArg = args(1)
def collectModes(expr: Expr): List[Option[String]] = {
expr match {
case NilLit() =>
Nil
case Cons(AtomLit(s), t) =>
Some(s) :: collectModes(t)
case Cons(Exprs.Tuple(List(AtomLit(s), _)), t) =>
Some(s) :: collectModes(t)
case _ =>
List(None)
}
}
val modes = collectModes(modeArg)
if (modes.forall(_.isDefined)) {
val literalModes = modes.flatten
val fd = literalModes.contains("raw") || literalModes.contains("ram")
val deviceT =
if (fd)
RemoteType(RemoteId("file", "fd", 0), List())
else
PidType
UnionType(
Set(
TupleType(List(AtomLitType("ok"), deviceT)),
TupleType(
List(
AtomLitType("error"),
UnionType(
Set(
RemoteType(RemoteId("file", "posix", 0), List()),
AtomLitType("badarg"),
AtomLitType("system_limit"),
)
),
)
)
} else
resTy
}
(resTyPrecise, env1)
case None =>
diagnosticsInfo.add(UnboundVar(callPos, fqn.toString))
(DynamicType, env)
),
)
)
} else
resTy
}
(resTyPrecise, env1)
case RemoteId("lists", "filtermap", 2) =>
val List(funArg, collection) = args
val List(funArgTy, collectionTy) = argTys
Expand Down Expand Up @@ -366,7 +361,7 @@ class ElabApplyCustom(pipelineContext: PipelineContext) {
val resTy = narrow.adjustMapType(mapCoercedTy, AtomLitType(keyAtom), valTy)
(resTy, env1)
case _ =>
val ft = util.getFunType(fqn).get
val ft = util.getFunType(fqn)
val resTy = elabApply.elabApply(ft, args, argTys, env1)
(resTy, env1)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ object TcDiagnostics {
def errorName = "not_enough_info_to_branch"
override def erroneousExpr: Option[Expr] = Some(expr)
}
case class IgnoredOverloadedSpec(pos: Pos) extends TypeError {
override val msg: String = s"dynamic() -> dynamic() is used"
def errorName = "not_enough_info_to_branch"
override def erroneousExpr: Option[Expr] = None
}
case class LambdaArityMismatch(pos: Pos, expr: Expr, lambdaArity: Int, argsArity: Int) extends TypeError {
override val msg: String = s"fun with arity $lambdaArity used as fun with $argsArity arguments"
def errorName = "fun_arity_mismatch"
Expand Down
16 changes: 8 additions & 8 deletions eqwalizer/src/main/scala/com/whatsapp/eqwalizer/tc/Util.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Util(pipelineContext: PipelineContext) {
RemoteId(hostModule, id.name, id.arity)
}

def getFunType(module: String, id: Id): Option[FunType] =
def getFunType(module: String, id: Id): FunType =
getFunType(globalFunId(module, id))

private def typeAndGetRecord(module: String, name: String): Option[RecDeclTyped] =
Expand Down Expand Up @@ -57,13 +57,13 @@ class Util(pipelineContext: PipelineContext) {
RecFieldTyped(f.name, tp, f.defaultValue, f.refinable)
}

def getFunType(fqn: RemoteId): Option[FunType] = {
val funType = DbApi.getSpec(fqn.module, Id(fqn.name, fqn.arity)).map(_.ty)
if (funType.isEmpty) {
val arity = fqn.arity
Some(FunType(Nil, List.fill(arity)(DynamicType), DynamicType))
} else {
funType
def getFunType(fqn: RemoteId): FunType = {
DbApi.getSpec(fqn.module, Id(fqn.name, fqn.arity)).map(_.ty) match {
case Some(funType) =>
funType
case None =>
val arity = fqn.arity
FunType(Nil, List.fill(arity)(DynamicType), DynamicType)
}
}

Expand Down

0 comments on commit 931e328

Please sign in to comment.