Skip to content

Commit ea71a5f

Browse files
clean up code
1 parent 783189d commit ea71a5f

File tree

2 files changed

+46
-27
lines changed

2 files changed

+46
-27
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,7 @@ class Definitions {
958958
def TupleClass(using Context): ClassSymbol = TupleTypeRef.symbol.asClass
959959
@tu lazy val Tuple_cons: Symbol = TupleClass.requiredMethod("*:")
960960
@tu lazy val TupleModule: Symbol = requiredModule("scala.Tuple")
961+
@tu lazy val Tuple_Elem: Symbol = TupleModule.requiredType("Elem")
961962
@tu lazy val EmptyTupleClass: Symbol = requiredClass("scala.EmptyTuple")
962963
@tu lazy val EmptyTupleModule: Symbol = requiredModule("scala.EmptyTuple")
963964
@tu lazy val NonEmptyTupleTypeRef: TypeRef = requiredClassRef("scala.NonEmptyTuple")
@@ -1270,6 +1271,32 @@ class Definitions {
12701271
else None
12711272
}
12721273

1274+
// Pattern matcher of tuple selectors at the type level
1275+
// Matches Tuple.Elem[x, constant] and x._1.type
1276+
object TupleSelectorOf:
1277+
def unapply(tp: Type)(using Context): Option[(Type, Int)] =
1278+
if tp.isRef(Tuple_Elem) then
1279+
// get the arg infos for tuple elem
1280+
tp.argInfos match
1281+
case tupleType :: ConstantType(c) :: Nil
1282+
if c.isIntRange && (isTupleNType(tupleType) || tupleType.isRef(PairClass)) =>
1283+
Some((tupleType, c.intValue))
1284+
// we should probably report an error here, but its probably handled elsewhere
1285+
case _ => None
1286+
else
1287+
tp.dealias match
1288+
// very explicitly ONLY check for isTupleNType
1289+
// pair class doesn't have selector fields
1290+
case TermRef(tupleType, field) if isTupleNType(tupleType) =>
1291+
field match
1292+
case name: SimpleName =>
1293+
name.toString match
1294+
case s"_$id" =>
1295+
id.toIntOption.map(it => (tupleType, it - 1))
1296+
case _ => None
1297+
case _ => None
1298+
case _ => None
1299+
12731300
object ArrayOf {
12741301
def apply(elem: Type)(using Context): Type =
12751302
if (ctx.erasedTypes) JavaArrayType(elem)
@@ -1473,7 +1500,7 @@ class Definitions {
14731500
def patchStdLibClass(denot: ClassDenotation)(using Context): Unit =
14741501
// Do not patch the stdlib files if we explicitly disable it
14751502
// This is only to be used during the migration of the stdlib
1476-
if ctx.settings.YnoStdlibPatches.value then
1503+
if ctx.settings.YnoStdlibPatches.value then
14771504
return
14781505

14791506
def patch2(denot: ClassDenotation, patchCls: Symbol): Unit =

compiler/src/dotty/tools/dotc/typer/Synthesizer.scala

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -108,43 +108,37 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
108108
case AppliedType(_, funArgs @ fun :: tupled :: Nil) =>
109109
def doesFunctionTupleInto(baseFun: Type, actualArgs: List[Type],
110110
actualRet: Type, tupled: Type) =
111-
tupled.dealias =:= constructDependentTupleType(actualArgs, actualRet, defn.isContextFunctionType(baseFun))
111+
tupled =:= constructDependentTupleType(actualArgs, actualRet, defn.isContextFunctionType(baseFun))
112112
def doesFunctionUntupleTo(baseFun: Type, actualArgs: List[Type],
113113
actualRet: Type, untupled: Type) =
114-
untupled.dealias =:= untupleDependentTupleType(actualArgs, actualRet, defn.isContextFunctionType(baseFun))
114+
untupled =:= untupleDependentTupleType(actualArgs, actualRet, defn.isContextFunctionType(baseFun))
115115

116116
def functionTypeEqual(baseFun: Type, actualArgs: List[Type],
117117
actualRet: Type, expected: Type) =
118-
expected.dealias =:= defn.FunctionNOf(actualArgs, actualRet, defn.isContextFunctionType(baseFun))
118+
expected =:= defn.FunctionNOf(actualArgs, actualRet, defn.isContextFunctionType(baseFun))
119119
def untupleDependentTupleType(args: List[Type], ret: Type, contextual: Boolean): Type =
120120
val methodKind = if contextual then ContextualMethodType else MethodType
121121

122-
123-
val p = methodKind(args.indices.map(nme.syntheticParamName).toList)(
122+
val arity = args.length
123+
methodKind(args.indices.map(nme.syntheticParamName).toList)(
124124
mt => args,
125125
mt =>
126126
val tpeMap = new TypeMap:
127127
def apply(tp: Type): Type =
128128
tp match
129-
case TermRef(TermParamRef(_, paramNum), name) =>
130-
name match
131-
case x: TermName =>
132-
x.toString match
133-
// hack upon hack upon hack
134-
// please make there be a reverse map so i dont have to do this : (
135-
case s"_$id" =>
136-
mt.paramRefs(id.toInt)
137-
case _ => ???
138-
case _ => ???
129+
case defn.TupleSelectorOf(TermParamRef(_, paramNum), fieldNum) =>
130+
if fieldNum >= arity then
131+
NoType
132+
else
133+
mt.paramRefs(fieldNum)
139134
case _ => mapOver(tp)
140135
tpeMap(ret)
141136
)
142-
p
143137

144138
def constructDependentTupleType(args: List[Type], ret: Type, contextual: Boolean): Type =
145139
val methodKind = if contextual then ContextualMethodType else MethodType
146140

147-
val p = methodKind(List(nme.syntheticParamName(0)))(
141+
methodKind(List(nme.syntheticParamName(0)))(
148142
mt => List(defn.tupleType(args)),
149143
mt =>
150144
val tpeMap = new TypeMap:
@@ -156,35 +150,33 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
156150
mapOver(tp)
157151
tpeMap(ret)
158152
).toFunctionType()
159-
p
160-
val dealiasedFun = fun.dealias
161-
val dealiasedTupled = tupled.dealias
153+
162154
val arity: Int =
163155
if defn.isFunctionNType(fun) then
164156
// TupledFunction[(...) => R, ?]
165157
// dont use functionArgInfos it dealiases and drops dependents
166158

167-
dealiasedFun match
168-
case defn.RefinedFunctionOf(method: MethodType) if doesFunctionTupleInto(dealiasedFun, method.paramInfos, method.resType, dealiasedTupled) =>
159+
fun.dealias match
160+
case defn.RefinedFunctionOf(method: MethodType) if doesFunctionTupleInto(fun, method.paramInfos, method.resType, tupled) =>
169161
method.paramInfos.size
170162
// poly types are unsupported
171163
case defn.RefinedFunctionOf(_) => -1
172164
case _ =>
173165
fun.functionArgInfos match
174166
case funArgs :+ funRet
175-
if functionTypeEqual(dealiasedFun, defn.tupleType(funArgs) :: Nil, funRet, dealiasedTupled) =>
167+
if functionTypeEqual(fun, defn.tupleType(funArgs) :: Nil, funRet, tupled) =>
176168
// TupledFunction[(...funArgs...) => funRet, ?]
177169
funArgs.size
178170
case _ => -1
179171
else if defn.isFunctionNType(tupled) then
180172
// TupledFunction[?, (...) => R]
181-
dealiasedTupled match
173+
tupled.dealias match
182174
case defn.RefinedFunctionOf(method: MethodType) =>
183175
method.argInfos match
184176
case tupledArgs :: funRet :: Nil =>
185177
// TupledFunction[?, ((...)) => R]
186178
tupledArgs.tupleElementTypes match
187-
case Some(args) if doesFunctionUntupleTo(dealiasedTupled, args, funRet, dealiasedFun) =>
179+
case Some(args) if doesFunctionUntupleTo(tupled, args, funRet, fun) =>
188180
args.size
189181
case _ => -1
190182
case _ => -1
@@ -193,7 +185,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
193185
case tupledArgs :: funRet :: Nil =>
194186
// TupledFunction[?, ((...)) => R]
195187
tupledArgs.tupleElementTypes match
196-
case Some(args) if functionTypeEqual(dealiasedTupled, args, funRet, dealiasedFun) =>
188+
case Some(args) if functionTypeEqual(tupled, args, funRet, fun) =>
197189
args.size
198190
case _ => -1
199191
case _ => -1

0 commit comments

Comments
 (0)