Skip to content

Commit 9c73c96

Browse files
committed
Merge pull request #38 from odersky/fix/#34-pathresolvers
Fix/#34 pathresolvers
2 parents 7004c22 + f3dacf9 commit 9c73c96

12 files changed

+94
-33
lines changed

src/dotty/tools/dotc/ast/CheckTrees.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ object CheckTrees {
135135
check(finalizer.isTerm)
136136
check(handler.isTerm)
137137
check(handler.tpe derivesFrom defn.FunctionClass(1))
138-
check(handler.tpe.baseTypeArgs(defn.FunctionClass(1)).head <:< defn.ThrowableType)
138+
check(handler.tpe.baseArgInfos(defn.FunctionClass(1)).head <:< defn.ThrowableType)
139139
case Throw(expr) =>
140140
check(expr.isValue)
141141
check(expr.tpe.derivesFrom(defn.ThrowableClass))
@@ -210,9 +210,9 @@ object CheckTrees {
210210
check(args.isEmpty)
211211
else {
212212
check(rtp isRef defn.OptionClass)
213-
val normArgs = rtp.typeArgs match {
213+
val normArgs = rtp.argTypesHi match {
214214
case optionArg :: Nil =>
215-
optionArg.typeArgs match {
215+
optionArg.argTypesHi match {
216216
case Nil =>
217217
optionArg :: Nil
218218
case tupleArgs if defn.isTupleType(optionArg) =>

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
336336

337337
/** new C(args) */
338338
def New(tp: Type, args: List[Tree])(implicit ctx: Context): Apply = {
339-
val targs = tp.typeArgs
339+
val targs = tp.argTypes
340340
Apply(
341341
Select(
342342
New(tp withoutArgs targs),

src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ object untpd extends Trees.Instance[Untyped] with TreeInfo[Untyped] {
124124
case TypedSplice(AppliedTypeTree(tycon, targs)) =>
125125
(TypedSplice(tycon), targs map TypedSplice)
126126
case TypedSplice(tpt1: Tree) =>
127-
val argTypes = tpt1.tpe.typeArgs
127+
val argTypes = tpt1.tpe.argTypes
128128
val tycon = tpt1.tpe.withoutArgs(argTypes)
129129
def wrap(tpe: Type) = TypeTree(tpe) withPos tpt.pos
130130
(wrap(tycon), argTypes map wrap)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ class Definitions {
286286
def unapply(ft: Type): Option[(List[Type], Type)] = { // Dotty deviation: Type annotation needed because inferred type
287287
// is Some[(List[Type], Type)] | None, which is not a legal unapply type.
288288
val tsym = ft.typeSymbol
289-
lazy val targs = ft.typeArgs
289+
lazy val targs = ft.argInfos
290290
if ((FunctionClasses contains tsym) &&
291291
(targs.length - 1 <= MaxFunctionArity) &&
292292
(FunctionClass(targs.length - 1) == tsym)) Some((targs.init, targs.last)) // Dotty deviation: no auto-tupling
@@ -317,7 +317,7 @@ class Definitions {
317317
lazy val RootImports = List[Symbol](JavaLangPackageVal, ScalaPackageVal, ScalaPredefModule, DottyPredefModule)
318318

319319
def isTupleType(tp: Type) = {
320-
val arity = tp.dealias.typeArgs.length
320+
val arity = tp.dealias.argInfos.length
321321
arity <= MaxTupleArity && (tp isRef TupleClass(arity))
322322
}
323323

@@ -329,7 +329,7 @@ class Definitions {
329329
0 <= arity && arity <= MaxFunctionArity && (tp isRef FunctionClass(arity))
330330
}
331331

332-
def functionArity(tp: Type) = tp.dealias.typeArgs.length - 1
332+
def functionArity(tp: Type) = tp.dealias.argInfos.length - 1
333333

334334
// ----- Higher kinds machinery ------------------------------------------
335335

src/dotty/tools/dotc/core/TypeApplications.scala

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,29 @@ import Flags._
1212
import util.Positions.Position
1313
import collection.mutable
1414

15+
object TypeApplications {
16+
17+
/** Assert type is not a TypeBounds instance and return it unchanged */
18+
val noBounds = (tp: Type) => tp match {
19+
case tp: TypeBounds => throw new AssertionError("no TypeBounds allowed")
20+
case _ => tp
21+
}
22+
23+
/** If `tp` is a TypeBounds instance return its lower bound else return `tp` */
24+
val boundsToLo = (tp: Type) => tp match {
25+
case tp: TypeBounds => tp.lo
26+
case _ => tp
27+
}
28+
29+
/** If `tp` is a TypeBounds instance return its upper bound else return `tp` */
30+
val boundsToHi = (tp: Type) => tp match {
31+
case tp: TypeBounds => tp.hi
32+
case _ => tp
33+
}
34+
}
35+
36+
import TypeApplications._
37+
1538
/** A decorator that provides methods for modeling type application */
1639
class TypeApplications(val self: Type) extends AnyVal {
1740

@@ -135,24 +158,43 @@ class TypeApplications(val self: Type) extends AnyVal {
135158
else TypeAlias(self, v)
136159
}
137160

138-
/** The type arguments of the base type instance wrt `base` of this type */
139-
final def baseTypeArgs(base: Symbol)(implicit ctx: Context): List[Type] =
161+
/** The type arguments of this type's base type instance wrt.`base`.
162+
* Existential types in arguments are returned as TypeBounds instances.
163+
*/
164+
final def baseArgInfos(base: Symbol)(implicit ctx: Context): List[Type] =
140165
if (self derivesFrom base)
141-
base.typeParams map (param => self.member(param.name).info.argType(param))
166+
base.typeParams map (param => self.member(param.name).info.argInfo(param))
142167
else
143168
Nil
144169

170+
/** The type arguments of this type's base type instance wrt.`base`.
171+
* Existential types in arguments are disallowed.
172+
*/
173+
final def baseArgTypes(base: Symbol)(implicit ctx: Context): List[Type] = baseArgInfos(base) mapConserve noBounds
174+
175+
/** The type arguments of this type's base type instance wrt.`base`.
176+
* Existential types in arguments are approximanted by their lower bound.
177+
*/
178+
final def baseArgTypesLo(base: Symbol)(implicit ctx: Context): List[Type] = baseArgInfos(base) mapConserve boundsToLo
179+
180+
/** The type arguments of this type's base type instance wrt.`base`.
181+
* Existential types in arguments are approximanted by their upper bound.
182+
*/
183+
final def baseArgTypesHi(base: Symbol)(implicit ctx: Context): List[Type] = baseArgInfos(base) mapConserve boundsToHi
184+
145185
/** The first type argument of the base type instance wrt `base` of this type */
146-
final def firstBaseTypeArg(base: Symbol)(implicit ctx: Context): Type = base.typeParams match {
186+
final def firstBaseArgInfo(base: Symbol)(implicit ctx: Context): Type = base.typeParams match {
147187
case param :: _ if self derivesFrom base =>
148-
self.member(param.name).info.argType(param)
188+
self.member(param.name).info.argInfo(param)
149189
case _ =>
150190
NoType
151191
}
152192

153-
/** The base type including all type arguments of this type */
193+
/** The base type including all type arguments of this type.
194+
* Existential types in arguments are returned as TypeBounds instances.
195+
*/
154196
final def baseTypeWithArgs(base: Symbol)(implicit ctx: Context): Type =
155-
self.baseTypeRef(base).appliedTo(baseTypeArgs(base))
197+
self.baseTypeRef(base).appliedTo(baseArgInfos(base))
156198

157199
/** Translate a type of the form From[T] to To[T], keep other types as they are.
158200
* `from` and `to` must be static classes, both with one type parameter, and the same variance.
@@ -163,9 +205,10 @@ class TypeApplications(val self: Type) extends AnyVal {
163205
else self
164206

165207
/** If this is an encoding of a (partially) applied type, return its arguments,
166-
* otherwise return Nil
208+
* otherwise return Nil.
209+
* Existential types in arguments are returned as TypeBounds instances.
167210
*/
168-
final def typeArgs(implicit ctx: Context): List[Type] = {
211+
final def argInfos(implicit ctx: Context): List[Type] = {
169212
var tparams: List[TypeSymbol] = null
170213
def recur(tp: Type, refineCount: Int): mutable.ListBuffer[Type] = tp.stripTypeVar match {
171214
case tp @ RefinedType(tycon, name) =>
@@ -175,7 +218,7 @@ class TypeApplications(val self: Type) extends AnyVal {
175218
if (tparams == null) tparams = tycon.typeParams
176219
if (buf.size < tparams.length) {
177220
val tparam = tparams(buf.size)
178-
if (name == tparam.name) buf += tp.refinedInfo.argType(tparam)
221+
if (name == tparam.name) buf += tp.refinedInfo.argInfo(tparam)
179222
else null
180223
} else null
181224
}
@@ -187,6 +230,15 @@ class TypeApplications(val self: Type) extends AnyVal {
187230
if (buf == null) Nil else buf.toList
188231
}
189232

233+
/** Argument types where existential types in arguments are disallowed */
234+
def argTypes(implicit ctx: Context) = argInfos mapConserve noBounds
235+
236+
/** Argument types where existential types in arguments are approximated by their lower bound */
237+
def argTypesLo(implicit ctx: Context) = argInfos mapConserve boundsToLo
238+
239+
/** Argument types where existential types in arguments are approximated by their upper bound */
240+
def argTypesHi(implicit ctx: Context) = argInfos mapConserve boundsToHi
241+
190242
/** The core type without any type arguments.
191243
* @param `typeArgs` must be the type arguments of this type.
192244
*/
@@ -201,7 +253,7 @@ class TypeApplications(val self: Type) extends AnyVal {
201253
/** If this is the image of a type argument to type parameter `tparam`,
202254
* recover the type argument, otherwise NoType.
203255
*/
204-
final def argType(tparam: Symbol)(implicit ctx: Context): Type = self match {
256+
final def argInfo(tparam: Symbol)(implicit ctx: Context): Type = self match {
205257
case TypeBounds(lo, hi) =>
206258
if (lo eq hi) hi
207259
else {
@@ -216,7 +268,7 @@ class TypeApplications(val self: Type) extends AnyVal {
216268

217269
/** The element type of a sequence or array */
218270
def elemType(implicit ctx: Context): Type =
219-
firstBaseTypeArg(defn.SeqClass) orElse firstBaseTypeArg(defn.ArrayClass)
271+
firstBaseArgInfo(defn.SeqClass) orElse firstBaseArgInfo(defn.ArrayClass)
220272

221273
/** If this type is of the normalized form Array[...[Array[T]...]
222274
* return the number of Array wrappers and T.
@@ -225,7 +277,7 @@ class TypeApplications(val self: Type) extends AnyVal {
225277
final def splitArray(implicit ctx: Context): (Int, Type) = {
226278
def recur(n: Int, tp: Type): (Int, Type) = tp.stripTypeVar match {
227279
case RefinedType(tycon, _) if tycon isRef defn.ArrayClass =>
228-
tp.typeArgs match {
280+
tp.argInfos match {
229281
case arg :: Nil => recur(n + 1, arg)
230282
case _ => (n, tp)
231283
}
@@ -274,7 +326,7 @@ class TypeApplications(val self: Type) extends AnyVal {
274326

275327
val correspondingParamName: Map[Symbol, TypeName] = {
276328
for {
277-
(tparam, targ: TypeRef) <- cls.typeParams zip typeArgs
329+
(tparam, targ: TypeRef) <- cls.typeParams zip argInfos
278330
if boundSyms contains targ.symbol
279331
} yield targ.symbol -> tparam.name
280332
}.toMap

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ class TypeComparer(initctx: Context) extends DotClass {
616616
*/
617617
def isSubTypeHK(tp1: Type, tp2: Type): Boolean = {
618618
val tparams = tp1.typeParams
619-
val hkArgs = tp2.typeArgs
619+
val hkArgs = tp2.argInfos
620620
(hkArgs.length == tparams.length) && {
621621
val base = tp1.narrow
622622
(tparams, hkArgs).zipped.forall { (tparam, hkArg) =>
@@ -752,7 +752,7 @@ class TypeComparer(initctx: Context) extends DotClass {
752752
/** The least upper bound of two types
753753
* @note We do not admit singleton types in or-types as lubs.
754754
*/
755-
def lub(tp1: Type, tp2: Type): Type =
755+
def lub(tp1: Type, tp2: Type): Type = /*>|>*/ ctx.traceIndented(s"lub(${tp1.show}, ${tp2.show})", typr, show = true) /*<|<*/ {
756756
if (tp1 eq tp2) tp1
757757
else if (!tp1.exists) tp1
758758
else if (!tp2.exists) tp2
@@ -772,6 +772,7 @@ class TypeComparer(initctx: Context) extends DotClass {
772772
}
773773
}
774774
}
775+
}
775776

776777
/** The least upper bound of a list of types */
777778
final def lub(tps: List[Type]): Type =

src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ object Types {
9696
else thissym eq sym
9797
case this1: RefinedType =>
9898
// make sure all refinements are type arguments
99-
this1.parent.isRef(sym) && this.typeArgs.nonEmpty
99+
this1.parent.isRef(sym) && this.argInfos.nonEmpty
100100
case _ =>
101101
false
102102
}

src/dotty/tools/dotc/core/pickling/UnPickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ object UnPickler {
7676
case tp @ MethodType(paramNames, paramTypes) =>
7777
val lastArg = paramTypes.last
7878
assert(lastArg isRef defn.ArrayClass)
79-
val elemtp0 :: Nil = lastArg.baseTypeArgs(defn.ArrayClass)
79+
val elemtp0 :: Nil = lastArg.baseArgInfos(defn.ArrayClass)
8080
val elemtp = elemtp0 match {
8181
case AndType(t1, t2) if t1.typeSymbol.isAbstractType && (t2 isRef defn.ObjectClass) =>
8282
t1 // drop intersection with Object for abstract types in varargs. UnCurry can handle them.

src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
9696
}
9797
tp match {
9898
case tp: RefinedType =>
99-
val args = tp.typeArgs
99+
val args = tp.argInfos
100100
if (args.nonEmpty) {
101101
val tycon = tp.unrefine
102102
val cls = tycon.typeSymbol

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import EtaExpansion._
2424
import collection.mutable
2525
import reflect.ClassTag
2626
import config.Printers._
27+
import TypeApplications._
2728
import language.implicitConversions
2829

2930
object Applications {
@@ -266,7 +267,7 @@ trait Applications extends Compatibility { self: Typer =>
266267
case arg :: Nil if isVarArg(arg) =>
267268
addTyped(arg, formal)
268269
case _ =>
269-
val elemFormal = formal.typeArgs.head
270+
val elemFormal = formal.argTypesLo.head
270271
args foreach (addTyped(_, elemFormal))
271272
makeVarArg(args.length, elemFormal)
272273
}
@@ -609,7 +610,7 @@ trait Applications extends Compatibility { self: Typer =>
609610
if (extractorMemberType(unapplyResult, nme.isDefined) isRef defn.BooleanClass) {
610611
if (getTp.exists)
611612
if (unapply.symbol.name == nme.unapplySeq) {
612-
val seqArg = getTp.firstBaseTypeArg(defn.SeqClass)
613+
val seqArg = boundsToHi(getTp.firstBaseArgInfo(defn.SeqClass))
613614
if (seqArg.exists) return args map Function.const(seqArg)
614615
}
615616
else return getSelectors(getTp)
@@ -683,6 +684,7 @@ trait Applications extends Compatibility { self: Typer =>
683684
}
684685

685686
var argTypes = unapplyArgs(unapplyApp.tpe)
687+
for (argType <- argTypes) assert(!argType.isInstanceOf[TypeBounds], unapplyApp.tpe.show)
686688
val bunchedArgs = argTypes match {
687689
case argType :: Nil if argType.isRepeatedParam => untpd.SeqLiteral(args) :: Nil
688690
case _ => args
@@ -770,7 +772,7 @@ trait Applications extends Compatibility { self: Typer =>
770772
val tparams = ctx.newTypeParams(alt1.symbol.owner, tp1.paramNames, EmptyFlags, bounds)
771773
isAsSpecific(alt1, tp1.instantiate(tparams map (_.typeRef)), alt2, tp2)
772774
case tp1: MethodType =>
773-
def repeatedToSingle(tp: Type) = if (tp.isRepeatedParam) tp.typeArgs.head else tp
775+
def repeatedToSingle(tp: Type) = if (tp.isRepeatedParam) tp.argTypesHi.head else tp
774776
isApplicable(alt2, tp1.paramTypes map repeatedToSingle, WildcardType) ||
775777
tp1.paramTypes.isEmpty && tp2.isInstanceOf[MethodOrPoly]
776778
case _ =>

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ class Typer extends Namer with Applications with Implicits {
438438
}
439439

440440
def typedPair(tree: untpd.Pair, pt: Type)(implicit ctx: Context) = track("typedPair") {
441-
val (leftProto, rightProto) = pt.typeArgs match {
441+
val (leftProto, rightProto) = pt.argTypesLo match {
442442
case l :: r :: Nil if pt isRef defn.PairClass => (l, r)
443443
case _ => (WildcardType, WildcardType)
444444
}
@@ -561,7 +561,7 @@ class Typer extends Namer with Applications with Implicits {
561561
val params = args.asInstanceOf[List[untpd.ValDef]]
562562
val (protoFormals, protoResult): (List[Type], Type) = pt match {
563563
case _ if defn.isFunctionType(pt) =>
564-
(pt.dealias.typeArgs.init, pt.dealias.typeArgs.last)
564+
(pt.dealias.argInfos.init, pt.dealias.argInfos.last)
565565
case SAMType(meth) =>
566566
val mt @ MethodType(_, paramTypes) = meth.info
567567
(paramTypes, mt.resultType)
@@ -750,7 +750,7 @@ class Typer extends Namer with Applications with Implicits {
750750
val expr1 = typed(tree.expr, pt)
751751
val handler1 = typed(tree.handler, defn.FunctionType(defn.ThrowableType :: Nil, pt))
752752
val finalizer1 = typed(tree.finalizer, defn.UnitType)
753-
val handlerTypeArgs = handler1.tpe.baseTypeArgs(defn.FunctionClass(1))
753+
val handlerTypeArgs = handler1.tpe.baseArgTypesHi(defn.FunctionClass(1))
754754
val ownType = if (handlerTypeArgs.nonEmpty) expr1.tpe | handlerTypeArgs(1) else expr1.tpe
755755
cpy.Try(tree, expr1, handler1, finalizer1) withType ownType
756756
}

test/dotc/tests.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,11 @@ class tests extends CompilerTest {
7171
"-Ylog:frontend",
7272
"-Xprompt"))
7373

74+
@Test def testIssue_34 = compileArgs(Array(
75+
dotcDir + "tools/dotc/config/Properties.scala",
76+
dotcDir + "tools/dotc/config/PathResolver.scala",
77+
"-Ylog:frontend",
78+
"-Xprompt"))
79+
7480
//@Test def dotc_compilercommand = compileFile(dotcDir + "tools/dotc/config/", "CompilerCommand")
7581
}

0 commit comments

Comments
 (0)