Skip to content

Commit

Permalink
more checks of overloaded specs
Browse files Browse the repository at this point in the history
Summary: - if we cannot select a single sub-spec, - "unionize" types of parameters and check obvious cases when arguments are of wrong types

Reviewed By: VLanvin

Differential Revision: D63639932

fbshipit-source-id: c01c5f0ab0e61e0d8171739ed92e4207cd76665f
  • Loading branch information
ilya-klyuchnikov authored and facebook-github-bot committed Oct 2, 2024
1 parent 8fcae04 commit 0c099bb
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 0 deletions.
2 changes: 2 additions & 0 deletions eqwalizer/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ eqwalizer {
custom_maps_merge = ${?EQWALIZER_CUSTOM_MAPS_MERGE}
ignored_overloaded_spec = false
ignored_overloaded_spec = ${?EQWALIZER_IGNORED_OVERLOADED_SPEC}
overloaded_spec_domain_check = false
overloaded_spec_domain_check = ${?EQWALIZER_OVERLOADED_SPEC_DOMAIN_CHECK}
}
2 changes: 2 additions & 0 deletions eqwalizer/src/main/scala/com/whatsapp/eqwalizer/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ package object eqwalizer {
mode: Mode.Mode,
errorDepth: Int,
ignoredOverloadedSpec: Boolean,
overloadedSpecDomainCheck: Boolean,
)

lazy val config: Config = {
Expand All @@ -54,6 +55,7 @@ package object eqwalizer {
mode,
errorDepth = config.getInt("error_depth"),
ignoredOverloadedSpec = config.getBoolean("ignored_overloaded_spec"),
overloadedSpecDomainCheck = config.getBoolean("overloaded_spec_domain_check"),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,28 @@ class ElabApplyOverloaded(pipelineContext: PipelineContext) {
case _ =>
if (pipelineCtx.overloadedSpecDynamicResult && typeInfo.isCollect)
diagnosticsInfo.add(NoSpecialType(expr.pos, expr, argTys))
if (pipelineContext.overloadedSpecDomainCheck)
toFunType(depFunSpec).foreach(ft => elabApply.elabApply(check.freshen(ft), args, argTys, env1))
(DynamicType, env1)
}
}

def isOverloadedFun(remoteId: RemoteId): Boolean =
util.getOverloadedSpec(remoteId).isDefined

private def toFunType(depFunSpec: OverloadedFunSpec): Option[FunType] = {
// If a sub-spec has generic vars, - transforming it to a FunType is tricky in general case.
// Skipping overloaded specs with generic vars for now (for simplicity).
if (depFunSpec.tys.forall(_.forall.isEmpty)) {
val result = depFunSpec.tys.reduce { (acc, elem) =>
val argTys = acc.argTys.zip(elem.argTys).map { case (t1, t2) => subtype.join(t1, t2) }
FunType(Nil, argTys, DynamicType)
}
Some(result)
} else
None
}

private def mightOverlap(t1: Type, t2: Type): Boolean = {
val approxMeet = narrow.meet(t1, t2)
!subtype.subType(approxMeet, NoneType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,6 @@ package object tc {
val overloadedSpecDynamicResult: Boolean = config.overloadedSpecDynamicResult
val customMapsMerge: Boolean = config.customMapsMerge
val ignoredOverloadedSpec: Boolean = config.ignoredOverloadedSpec
val overloadedSpecDomainCheck: Boolean = config.overloadedSpecDomainCheck
}
}

0 comments on commit 0c099bb

Please sign in to comment.