Skip to content

Commit c864e11

Browse files
committed
Merge pull request #1000 from dotty-staging/fix-#241
Fix #241
2 parents 6fc069f + 7e8f401 commit c864e11

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1181
-878
lines changed

Diff for: src/dotty/tools/dotc/ast/Desugar.scala

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ object desugar {
2121
/** Info of a variable in a pattern: The named tree and its type */
2222
private type VarInfo = (NameTree, Tree)
2323

24+
/** Names of methods that are added unconditionally to case classes */
25+
def isDesugaredCaseClassMethodName(name: Name)(implicit ctx: Context) =
26+
name == nme.isDefined ||
27+
name == nme.copy ||
28+
name == nme.productArity ||
29+
name.isSelectorName
30+
2431
// ----- DerivedTypeTrees -----------------------------------
2532

2633
class SetterParamTree extends DerivedTypeTree {

Diff for: src/dotty/tools/dotc/ast/tpd.scala

+16-9
Original file line numberDiff line numberDiff line change
@@ -845,15 +845,22 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
845845
def applyOverloaded(receiver: Tree, method: TermName, args: List[Tree], targs: List[Type], expectedType: Type, isAnnotConstructor: Boolean = false)(implicit ctx: Context): Tree = {
846846
val typer = ctx.typer
847847
val proto = new FunProtoTyped(args, expectedType, typer)
848-
val alts = receiver.tpe.member(method).alternatives.map(_.termRef)
849-
850-
val alternatives = ctx.typer.resolveOverloaded(alts, proto, Nil)
851-
assert(alternatives.size == 1,
852-
i"multiple overloads available for $method on ${receiver.tpe.widenDealias} with targs: $targs, args: $args and expectedType: $expectedType." +
853-
i" isAnnotConstructor = $isAnnotConstructor.\n" +
854-
i"alternatives: $alternatives") // this is parsed from bytecode tree. there's nothing user can do about it
855-
856-
val selected = alternatives.head
848+
val denot = receiver.tpe.member(method)
849+
assert(denot.exists, i"no member $receiver . $method, members = ${receiver.tpe.decls}")
850+
val selected =
851+
if (denot.isOverloaded) {
852+
val allAlts = denot.alternatives.map(_.termRef)
853+
val alternatives =
854+
ctx.typer.resolveOverloaded(allAlts, proto, Nil)
855+
assert(alternatives.size == 1,
856+
i"${if (alternatives.isEmpty) "no" else "multiple"} overloads available for " +
857+
i"$method on ${receiver.tpe.widenDealias} with targs: $targs, args: $args and expectedType: $expectedType." +
858+
i" isAnnotConstructor = $isAnnotConstructor.\n" +
859+
i"all alternatives: ${allAlts.map(_.symbol.showDcl).mkString(", ")}\n" +
860+
i"matching alternatives: ${alternatives.map(_.symbol.showDcl).mkString(", ")}.") // this is parsed from bytecode tree. there's nothing user can do about it
861+
alternatives.head
862+
}
863+
else denot.asSingleDenotation.termRef
857864
val fun = receiver
858865
.select(TermRef.withSig(receiver.tpe, selected.termSymbol.asTerm))
859866
.appliedToTypes(targs)

Diff for: src/dotty/tools/dotc/config/Printers.scala

+9-9
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ object Printers {
2222
val implicitsDetailed: Printer = noPrinter
2323
val subtyping: Printer = noPrinter
2424
val unapp: Printer = noPrinter
25-
val gadts = noPrinter
26-
val hk = noPrinter
27-
val variances = noPrinter
28-
val incremental = noPrinter
29-
val config = noPrinter
30-
val transforms = noPrinter
31-
val completions = noPrinter
32-
val cyclicErrors = noPrinter
33-
val pickling = noPrinter
25+
val gadts: Printer = noPrinter
26+
val hk: Printer = noPrinter
27+
val variances: Printer = noPrinter
28+
val incremental: Printer = noPrinter
29+
val config: Printer = noPrinter
30+
val transforms: Printer = noPrinter
31+
val completions: Printer = noPrinter
32+
val cyclicErrors: Printer = noPrinter
33+
val pickling: Printer = noPrinter
3434
}

Diff for: src/dotty/tools/dotc/core/ConstraintHandling.scala

+10
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,16 @@ trait ConstraintHandling {
232232
}
233233
}
234234

235+
/** Instantiate `param` to `tp` if the constraint stays satisfiable */
236+
protected def tryInstantiate(param: PolyParam, tp: Type): Boolean = {
237+
val saved = constraint
238+
constraint =
239+
if (addConstraint(param, tp, fromBelow = true) &&
240+
addConstraint(param, tp, fromBelow = false)) constraint.replace(param, tp)
241+
else saved
242+
constraint ne saved
243+
}
244+
235245
/** Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated */
236246
def checkPropagated(msg: => String)(result: Boolean): Boolean = {
237247
if (Config.checkConstraintsPropagated && result && addConstraintInvocations == 0) {

Diff for: src/dotty/tools/dotc/core/Definitions.scala

+11-5
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,12 @@ class Definitions {
588588
name.startsWith(prefix) && name.drop(prefix.length).forall(_.isDigit)
589589
}
590590

591+
def isBottomClass(cls: Symbol) = cls == NothingClass || cls == NullClass
592+
def isBottomType(tp: Type) = tp match {
593+
case tp: TypeRef => isBottomClass(tp.symbol)
594+
case _ => false
595+
}
596+
591597
def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
592598
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)
593599
def isTupleClass(cls: Symbol) = isVarArityClass(cls, tpnme.Tuple)
@@ -642,9 +648,9 @@ class Definitions {
642648
* to be the type parameters of a higher-kided type). This is a class symbol that
643649
* would be generated by the following schema.
644650
*
645-
* class LambdaXYZ extends Object with P1 with ... with Pn {
646-
* type v_1 $hk$Arg0; ...; type v_N $hk$ArgN;
647-
* type Apply
651+
* trait LambdaXYZ extends Object with P1 with ... with Pn {
652+
* type v_1 hk$0; ...; type v_N hk$N;
653+
* type +$Apply
648654
* }
649655
*
650656
* Here:
@@ -669,7 +675,7 @@ class Definitions {
669675
val cls = denot.asClass.classSymbol
670676
val paramDecls = newScope
671677
for (i <- 0 until vcs.length)
672-
newTypeParam(cls, tpnme.LambdaArgName(i), varianceFlags(vcs(i)), paramDecls)
678+
newTypeParam(cls, tpnme.hkArg(i), varianceFlags(vcs(i)), paramDecls)
673679
newTypeField(cls, tpnme.hkApply, Covariant, paramDecls)
674680
val parentTraitRefs =
675681
for (i <- 0 until vcs.length if vcs(i) != 0)
@@ -679,7 +685,7 @@ class Definitions {
679685
}
680686
}
681687

682-
val traitName = tpnme.LambdaTraitName(vcs)
688+
val traitName = tpnme.hkLambda(vcs)
683689

684690
def createTrait = {
685691
val cls = newClassSymbol(

Diff for: src/dotty/tools/dotc/core/Denotations.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ object Denotations {
324324
info1 // follow Scala2 linearization -
325325
// compare with way merge is performed in SymDenotation#computeMembersNamed
326326
else
327-
throw new MergeError(s"${ex.getMessage} as members of type ${pre.show}")
327+
throw new MergeError(s"${ex.getMessage} as members of type ${pre.show}", ex.tp1, ex.tp2)
328328
}
329329
new JointRefDenotation(sym, jointInfo, denot1.validFor & denot2.validFor)
330330
}

Diff for: src/dotty/tools/dotc/core/Flags.scala

+10-5
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,12 @@ object Flags {
306306
/** A case parameter accessor */
307307
final val CaseAccessor = termFlag(25, "<caseaccessor>")
308308

309-
/** An type parameter which is an alias for some other (non-visible) type parameter */
310-
final val TypeArgument = typeFlag(25, "<type-param-inst>")
309+
/** A binding for a type parameter of a base class or trait.
310+
* TODO: Replace with combination of isType, ExpandedName, and Override?
311+
*/
312+
final val BaseTypeArg = typeFlag(25, "<basetypearg>")
311313

312-
final val CaseAccessorOrTypeArgument = CaseAccessor.toCommonFlags
314+
final val CaseAccessorOrBaseTypeArg = CaseAccessor.toCommonFlags
313315

314316
/** A super accessor */
315317
final val SuperAccessor = termFlag(26, "<superaccessor>")
@@ -446,7 +448,7 @@ object Flags {
446448
final val FromStartFlags =
447449
AccessFlags | Module | Package | Deferred | Final | MethodOrHKCommon | Param | ParamAccessor | Scala2ExistentialCommon |
448450
InSuperCall | Touched | JavaStatic | CovariantOrOuter | ContravariantOrLabel | ExpandedName | AccessorOrSealed |
449-
CaseAccessorOrTypeArgument | Fresh | Frozen | Erroneous | ImplicitCommon | Permanent |
451+
CaseAccessorOrBaseTypeArg | Fresh | Frozen | Erroneous | ImplicitCommon | Permanent |
450452
LazyOrTrait | SuperAccessorOrScala2x | SelfNameOrImplClass
451453

452454
assert(FromStartFlags.isTermFlags && FromStartFlags.isTypeFlags)
@@ -545,7 +547,7 @@ object Flags {
545547
final val TypeParamOrAccessor = TypeParam | TypeParamAccessor
546548

547549
/** If symbol of a type alias has these flags, prefer the alias */
548-
final val AliasPreferred = TypeParam | TypeArgument | ExpandedName
550+
final val AliasPreferred = TypeParam | BaseTypeArg | ExpandedName
549551

550552
/** A covariant type parameter instance */
551553
final val LocalCovariant = allOf(Local, Covariant)
@@ -583,6 +585,9 @@ object Flags {
583585
/** A private[this] parameter accessor */
584586
final val PrivateLocalParamAccessor = allOf(Private, Local, ParamAccessor)
585587

588+
/** A parameter forwarder */
589+
final val ParamForwarder = allOf(Method, Stable, ParamAccessor)
590+
586591
/** A private[this] parameter */
587592
final val PrivateLocalParam = allOf(Private, Local, Param)
588593

Diff for: src/dotty/tools/dotc/core/NameOps.scala

+10-6
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ object NameOps {
8181
def isScala2LocalSuffix = name.endsWith(" ")
8282
def isModuleVarName(name: Name): Boolean =
8383
name.stripAnonNumberSuffix endsWith MODULE_VAR_SUFFIX
84+
def isSelectorName = name.startsWith(" ") && name.tail.forall(_.isDigit)
8485

8586
/** Is name a variable name? */
8687
def isVariableName: Boolean = name.length > 0 && {
@@ -99,19 +100,22 @@ object NameOps {
99100
}
100101

101102
/** Is this the name of a higher-kinded type parameter of a Lambda? */
102-
def isLambdaArgName =
103+
def isHkArgName =
103104
name.length > 0 &&
104-
name.head == tpnme.LAMBDA_ARG_PREFIXhead &&
105-
name.startsWith(tpnme.LAMBDA_ARG_PREFIX) && {
106-
val digits = name.drop(tpnme.LAMBDA_ARG_PREFIX.length)
105+
name.head == tpnme.hkArgPrefixHead &&
106+
name.startsWith(tpnme.hkArgPrefix) && {
107+
val digits = name.drop(tpnme.hkArgPrefixLength)
107108
digits.length <= 4 && digits.forall(_.isDigit)
108109
}
109110

110111
/** The index of the higher-kinded type parameter with this name.
111112
* Pre: isLambdaArgName.
112113
*/
113-
def LambdaArgIndex: Int =
114-
name.drop(tpnme.LAMBDA_ARG_PREFIX.length).toString.toInt
114+
def hkArgIndex: Int =
115+
name.drop(tpnme.hkArgPrefixLength).toString.toInt
116+
117+
def isLambdaTraitName(implicit ctx: Context): Boolean =
118+
name.startsWith(tpnme.hkLambdaPrefix)
115119

116120
/** If the name ends with $nn where nn are
117121
* all digits, strip the $ and the digits.

Diff for: src/dotty/tools/dotc/core/StdNames.scala

+10-10
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,6 @@ object StdNames {
173173
final val WILDCARD_STAR: N = "_*"
174174
final val REIFY_TREECREATOR_PREFIX: N = "$treecreator"
175175
final val REIFY_TYPECREATOR_PREFIX: N = "$typecreator"
176-
final val LAMBDA_ARG_PREFIX: N = "hk$"
177-
final val LAMBDA_ARG_PREFIXhead: Char = LAMBDA_ARG_PREFIX.head
178176

179177
final val AbstractFunction: N = "AbstractFunction"
180178
final val Any: N = "Any"
@@ -314,15 +312,13 @@ object StdNames {
314312

315313
val AnnotatedType: N = "AnnotatedType"
316314
val AppliedTypeTree: N = "AppliedTypeTree"
317-
val hkApply: N = "$apply"
318315
val ArrayAnnotArg: N = "ArrayAnnotArg"
319316
val Constant: N = "Constant"
320317
val ConstantType: N = "ConstantType"
321318
val ExistentialTypeTree: N = "ExistentialTypeTree"
322319
val Flag : N = "Flag"
323320
val Ident: N = "Ident"
324321
val Import: N = "Import"
325-
val LambdaPrefix: N = "Lambda$"
326322
val Literal: N = "Literal"
327323
val LiteralAnnotArg: N = "LiteralAnnotArg"
328324
val Modifiers: N = "Modifiers"
@@ -530,9 +526,14 @@ object StdNames {
530526
val nothingRuntimeClass: N = "scala.runtime.Nothing$"
531527
val nullRuntimeClass: N = "scala.runtime.Null$"
532528

533-
534529
val synthSwitch: N = "$synthSwitch"
535530

531+
val hkApply: N = "$Apply"
532+
val hkArgPrefix: N = "$hk"
533+
val hkLambdaPrefix: N = "Lambda$"
534+
val hkArgPrefixHead: Char = hkArgPrefix.head
535+
val hkArgPrefixLength: Int = hkArgPrefix.length
536+
536537
// unencoded operators
537538
object raw {
538539
final val AMP : N = "&"
@@ -742,14 +743,13 @@ object StdNames {
742743
def syntheticTypeParamNames(num: Int): List[TypeName] =
743744
(0 until num).map(syntheticTypeParamName)(breakOut)
744745

745-
def LambdaTraitName(vcs: List[Int]): TypeName = LambdaPrefix ++ vcs.map(varianceSuffix).mkString
746-
def LambdaArgName(n: Int) = LAMBDA_ARG_PREFIX ++ n.toString
747-
748-
final val Conforms = encode("<:<")
746+
def hkLambda(vcs: List[Int]): TypeName = hkLambdaPrefix ++ vcs.map(varianceSuffix).mkString
747+
def hkArg(n: Int): TypeName = hkArgPrefix ++ n.toString
749748

750749
def varianceSuffix(v: Int): Char = varianceSuffixes.charAt(v + 1)
751-
752750
val varianceSuffixes = "NIP"
751+
752+
final val Conforms = encode("<:<")
753753
}
754754

755755
abstract class JavaNames[N <: Name] extends DefinedNames[N] {

Diff for: src/dotty/tools/dotc/core/SymDenotations.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ object SymDenotations {
167167
completions.println(i"${" " * indent}completing ${if (isType) "type" else "val"} $name")
168168
indent += 1
169169
}
170-
indent += 1
171170
if (myFlags is Touched) throw CyclicReference(this)
172171
myFlags |= Touched
173172

@@ -446,7 +445,7 @@ object SymDenotations {
446445

447446
/** is this symbol a trait representing a type lambda? */
448447
final def isLambdaTrait(implicit ctx: Context): Boolean =
449-
isClass && name.startsWith(tpnme.LambdaPrefix) && owner == defn.ScalaPackageClass
448+
isClass && name.startsWith(tpnme.hkLambdaPrefix) && owner == defn.ScalaPackageClass
450449

451450
/** Is this symbol a package object or its module class? */
452451
def isPackageObject(implicit ctx: Context): Boolean = {

Diff for: src/dotty/tools/dotc/core/Symbols.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ object Symbols {
368368

369369
type ThisName <: Name
370370

371-
//assert(_id != 30214)
371+
//assert(id != 4285)
372372

373373
/** The last denotation of this symbol */
374374
private[this] var lastDenot: SymDenotation = _

0 commit comments

Comments
 (0)