Skip to content

Commit

Permalink
Merge pull request #15270 from dwijnand/same-length
Browse files Browse the repository at this point in the history
  • Loading branch information
dwijnand authored Jun 7, 2022
2 parents 6508dfa + b199749 commit 76a0b29
Show file tree
Hide file tree
Showing 5 changed files with 8 additions and 17 deletions.
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Decorators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ object Decorators {
loop(xs, xs, 0)
end mapWithIndexConserve

/** True if two lists have the same length. Since calling length on linear sequences
* is Θ(n), it is an inadvisable way to test length equality. This method is Θ(n min m).
*/
final def hasSameLengthAs[U](ys: List[U]): Boolean = {
@tailrec def loop(xs: List[T], ys: List[U]): Boolean =
if (xs.isEmpty) ys.isEmpty
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ object Denotations {
case _ => NoType
case tp1: PolyType =>
tp2 match
case tp2: PolyType if sameLength(tp1.paramNames, tp2.paramNames) =>
case tp2: PolyType if tp1.paramNames.hasSameLengthAs(tp2.paramNames) =>
val resType = infoMeet(tp1.resType, tp2.resType.subst(tp2, tp1), safeIntersection)
if resType.exists then
tp1.derivedLambdaType(
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1943,7 +1943,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
case tp1: PolyType =>
tp2.widen match {
case tp2: PolyType =>
sameLength(tp1.paramNames, tp2.paramNames) &&
tp1.paramNames.hasSameLengthAs(tp2.paramNames) &&
matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
case _ =>
false
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ trait TypeAssigner {
def assignType(tree: untpd.Apply, fn: Tree, args: List[Tree])(using Context): Apply = {
val ownType = fn.tpe.widen match {
case fntpe: MethodType =>
if (sameLength(fntpe.paramInfos, args) || ctx.phase.prev.relaxedTyping)
if (fntpe.paramInfos.hasSameLengthAs(args) || ctx.phase.prev.relaxedTyping)
safeSubstMethodParams(fntpe, args.tpes)
else
errorType(i"wrong number of arguments at ${ctx.phase.prev} for $fntpe: ${fn.tpe}, expected: ${fntpe.paramInfos.length}, found: ${args.length}", tree.srcPos)
Expand Down Expand Up @@ -358,7 +358,7 @@ trait TypeAssigner {
if tp eq pt then pt.newLikeThis(pt.paramNames, pt.paramInfos, pt.resType)
else tp)
val argTypes = args.tpes.mapConserve(ensureFresh)
if (sameLength(argTypes, paramNames)) pt.instantiate(argTypes)
if (argTypes.hasSameLengthAs(paramNames)) pt.instantiate(argTypes)
else wrongNumberOfTypeArgs(fn.tpe, pt.typeParams, args, tree.srcPos)
}
}
Expand Down Expand Up @@ -474,7 +474,7 @@ trait TypeAssigner {
assert(!hasNamedArg(args) || ctx.reporter.errorsReported, tree)
val tparams = tycon.tpe.typeParams
val ownType =
if (sameLength(tparams, args))
if (tparams.hasSameLengthAs(args))
if (tycon.symbol == defn.andType) AndType(args(0).tpe, args(1).tpe)
else if (tycon.symbol == defn.orType) OrType(args(0).tpe, args(1).tpe, soft = false)
else tycon.tpe.appliedTo(args.tpes)
Expand Down
12 changes: 0 additions & 12 deletions compiler/src/dotty/tools/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,6 @@ package object tools {

val ListOfNil: List[Nil.type] = Nil :: Nil

/** True if two lists have the same length. Since calling length on linear sequences
* is O(n), it is an inadvisable way to test length equality.
*/
final def sameLength[T](xs: List[T], ys: List[T]): Boolean = xs match {
case _ :: xs1 =>
ys match {
case _ :: ys1 => sameLength(xs1, ys1)
case _ => false
}
case _ => ys.isEmpty
}

/** Throws an `UnsupportedOperationException` with the given method name. */
def unsupported(methodName: String): Nothing =
throw new UnsupportedOperationException(methodName)
Expand Down

0 comments on commit 76a0b29

Please sign in to comment.