diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index edc1f89e5f62..49e65bbb0b1f 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -102,6 +102,7 @@ class ScalaSettings extends Settings.SettingGroup { val YplainPrinter = BooleanSetting("-Yplain-printer", "Pretty-print using a plain printer.") val YprintSyms = BooleanSetting("-Yprint-syms", "when printing trees print info in symbols instead of corresponding info in trees.") val YprintDebug = BooleanSetting("-Yprint-debug", "when printing trees, print some extra information useful for debugging.") + val YshowPrintErrors = BooleanSetting("-Yshow-print-errors", "don't suppress exceptions thrown during tree printing.") val YtestPickler = BooleanSetting("-Ytest-pickler", "self-test for pickling functionality; should be used with -Ystop-after:pickler") val YcheckReentrant = BooleanSetting("-Ycheck-reentrant", "check that compiled program does not contain vars that can be accessed from a global root.") val YkeepComments = BooleanSetting("-Ykeep-comments", "Keep comments when scanning source files.") diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 39e2e44506f8..e3bcd1e1fda0 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -67,7 +67,7 @@ class Definitions { enterTypeField(cls, name, flags | ClassTypeParamCreationFlags, scope) private def enterSyntheticTypeParam(cls: ClassSymbol, paramFlags: FlagSet, scope: MutableScope, suffix: String = "T0") = - enterTypeParam(cls, suffix.toTypeName.expandedName(cls), paramFlags, scope) + enterTypeParam(cls, suffix.toTypeName, paramFlags, scope) // NOTE: Ideally we would write `parentConstrs: => Type*` but SIP-24 is only // implemented in Dotty and not in Scala 2. diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index 8c2b1d431374..d39ca3f6a5c6 100644 --- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -6,7 +6,7 @@ import Names._ import NameOps._ import StdNames._ import util.DotClass -import tasty.TastyFormat._ +import NameTags._ import Decorators._ import Contexts.Context import collection.mutable @@ -358,7 +358,6 @@ object NameKinds { override def mkString(underlying: TermName, info: ThisInfo) = underlying.toString } val ExtMethName = new SuffixNameKind(EXTMETH, "$extension") - val ModuleVarName = new SuffixNameKind(OBJECTVAR, "$module") val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass") val ImplMethName = new SuffixNameKind(IMPLMETH, "$") val AdaptedClosureName = new SuffixNameKind(ADAPTEDCLOSURE, "$adapted") { override def definesNewName = true } diff --git a/compiler/src/dotty/tools/dotc/core/NameTags.scala b/compiler/src/dotty/tools/dotc/core/NameTags.scala new file mode 100644 index 000000000000..3afe715147b4 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/NameTags.scala @@ -0,0 +1,58 @@ +package dotty.tools +package dotc +package core + +import tasty.TastyFormat + +/** The possible tags of a NameKind */ +object NameTags extends TastyFormat.NameTags { + + final val FLATTENED = 5 // A flat name, generated by Flatten + + final val TRAITSETTER = 6 // A Scala-2 trait setter, generated by AugmentScala2Traits + + final val INITIALIZER = 24 // A mixin initializer method + + final val AVOIDCLASH = 25 // Adds a suffix to avoid a name clash; + // Used in FirstTransform for synthesized companion objects of classes + // if they would clash with another value. + + final val DIRECT = 26 // Used by ShortCutImplicits for the name of methods that + // implement implicit function result types directly. + + final val FIELD = 27 // Used by Memoize to tag the name of a class member field. + + final val EXTMETH = 28 // Used by ExtensionMethods for the name of an extension method + // implementing a value class method. + + final val ADAPTEDCLOSURE = 29 // Used in Erasure to adapt closures over primitive types. + + final val IMPLMETH = 30 // Used to define methods in implementation classes + // (can probably be removed). + + def nameTagToString(tag: Int): String = tag match { + case UTF8 => "UTF8" + case QUALIFIED => "QUALIFIED" + case FLATTENED => "FLATTENED" + case EXPANDED => "EXPANDED" + case EXPANDPREFIX => "EXPANDPREFIX" + case TRAITSETTER => "TRAITSETTER" + case UNIQUE => "UNIQUE" + case DEFAULTGETTER => "DEFAULTGETTER" + case VARIANT => "VARIANT" + case OUTERSELECT => "OUTERSELECT" + + case SUPERACCESSOR => "SUPERACCESSOR" + case PROTECTEDACCESSOR => "PROTECTEDACCESSOR" + case PROTECTEDSETTER => "PROTECTEDSETTER" + case INITIALIZER => "INITIALIZER" + case AVOIDCLASH => "AVOIDCLASH" + case DIRECT => "DIRECT" + case FIELD => "FIELD" + case EXTMETH => "EXTMETH" + case ADAPTEDCLOSURE => "ADAPTEDCLOSURE" + case OBJECTCLASS => "OBJECTCLASS" + + case SIGNED => "SIGNED" + } +} diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index ed79e79d652b..ce4f6dd72237 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -531,14 +531,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { case _ => isSubType(tp1.widenExpr, restpe2) } compareExpr - case tp2: TypeArgRef => - def sameTypeArgRef = tp1 match { - case tp1: TypeArgRef => - tp1.clsRef == tp2.clsRef && tp1.idx == tp2.idx && tp1.prefix =:= tp2.prefix - case _ => - false - } - sameTypeArgRef || isSubType(tp1, tp2.underlying.loBound) || fourthTry(tp1, tp2) case tp2 @ TypeBounds(lo2, hi2) => def compareTypeBounds = tp1 match { case tp1 @ TypeBounds(lo1, hi1) => @@ -609,8 +601,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { isNewSubType(tp1.parent, tp2) case tp1: RecType => isNewSubType(tp1.parent, tp2) - case tp1: TypeArgRef => - isSubType(tp1.underlying.hiBound, tp2) case tp1: HKTypeLambda => def compareHKLambda = tp1 match { case EtaExpansion(tycon1) => isSubType(tycon1, tp2) @@ -833,7 +823,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { def compareCaptured(arg1: Type, arg2: Type): Boolean = arg1 match { case arg1: TypeBounds => - val captured = TypeArgRef.fromParam(tp1, tparam.asInstanceOf[TypeSymbol]) + val captured = TypeRef(tp1, tparam.asInstanceOf[TypeSymbol]) isSubArg(captured, arg2) case _ => false diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index f7e013cd38f6..59598d332803 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -182,6 +182,18 @@ object Types { loop(this) } + /** True iff `symd` is a denotation of a class type parameter and the reference + * ` . ` is an actual argument reference, i.e. `this` is different + * from the ThisType of `symd`'s owner. + */ + def isArgPrefixOf(symd: SymDenotation)(implicit ctx: Context) = + symd.is(ClassTypeParam) && { + this match { + case tp: ThisType => tp.cls ne symd.owner + case _ => true + } + } + /** Returns true if the type is a phantom type * - true if XYZ extends scala.Phantom and this type is upper bounded XYZ.Any * - false otherwise @@ -1659,6 +1671,8 @@ object Types { val symd = sym.lastKnownDenotation if (symd.validFor.runId != ctx.runId && !ctx.stillValid(symd)) finish(memberDenot(symd.initial.name, allowPrivate = false)) + else if (prefix.isArgPrefixOf(symd)) + finish(argDenot(sym.asType)) else if (infoDependsOnPrefix(symd, prefix)) finish(memberDenot(symd.initial.name, allowPrivate = symd.is(Private))) else @@ -1715,6 +1729,38 @@ object Types { private def memberDenot(prefix: Type, name: Name, allowPrivate: Boolean)(implicit ctx: Context): Denotation = if (allowPrivate) prefix.member(name) else prefix.nonPrivateMember(name) + private def argDenot(param: TypeSymbol)(implicit ctx: Context): Denotation = { + val cls = param.owner + val args = prefix.baseType(cls).argInfos + val typeParams = cls.typeParams + + def concretize(arg: Type, tparam: TypeSymbol) = arg match { + case arg: TypeBounds => TypeRef(prefix, tparam) + case arg => arg + } + val concretized = args.zipWithConserve(typeParams)(concretize) + + def rebase(arg: Type) = arg.subst(typeParams, concretized) + + val idx = typeParams.indexOf(param) + + assert(args.nonEmpty, + i"""bad parameter reference $this at ${ctx.phase} + |the parameter is ${param.showLocated} but the prefix $prefix + |does not define any corresponding arguments.""") + + val argInfo = args(idx) match { + case arg: TypeBounds => + val v = param.paramVariance + val pbounds = param.paramInfo + if (v > 0 && pbounds.loBound.dealias.isBottomType) TypeAlias(arg.hiBound & rebase(pbounds.hiBound)) + else if (v < 0 && pbounds.hiBound.dealias.isTopType) TypeAlias(arg.loBound | rebase(pbounds.loBound)) + else arg recoverable_& rebase(pbounds) + case arg => TypeAlias(arg) + } + param.derivedSingleDenotation(param, argInfo) + } + /** Reload denotation by computing the member with the reference's name as seen * from the reference's prefix. */ @@ -1838,7 +1884,7 @@ object Types { while (tparams.nonEmpty && args.nonEmpty) { if (tparams.head.eq(tparam)) return args.head match { - case _: TypeBounds => TypeArgRef(pre, cls.typeRef, idx) + case _: TypeBounds => TypeRef(pre, tparam) case arg => arg } tparams = tparams.tail @@ -1940,7 +1986,7 @@ object Types { else if (lastDenotation == null) NamedType(prefix, designator) else designator match { case sym: Symbol => - if (infoDependsOnPrefix(sym, prefix)) { + if (infoDependsOnPrefix(sym, prefix) && !prefix.isArgPrefixOf(sym)) { val candidate = reload() val falseOverride = sym.isClass && candidate.symbol.exists && candidate.symbol != symbol // A false override happens if we rebind an inner class to another type with the same name @@ -2079,7 +2125,12 @@ object Types { abstract case class ThisType(tref: TypeRef) extends CachedProxyType with SingletonType { def cls(implicit ctx: Context): ClassSymbol = tref.stableInRunSymbol.asClass override def underlying(implicit ctx: Context): Type = - if (ctx.erasedTypes) tref else cls.classInfo.selfType + if (ctx.erasedTypes) tref + else cls.info match { + case cinfo: ClassInfo => cinfo.selfType + case cinfo: ErrorType if ctx.mode.is(Mode.Interactive) => cinfo + // can happen in IDE if `cls` is stale + } override def computeHash = doHash(tref) @@ -3016,7 +3067,7 @@ object Types { final val Provisional: DependencyStatus = 4 // set if dependency status can still change due to type variable instantiations } - // ----- Type application: LambdaParam, AppliedType, TypeArgRef --------------------- + // ----- Type application: LambdaParam, AppliedType --------------------- /** The parameter of a type lambda */ case class LambdaParam(tl: TypeLambda, n: Int) extends ParamInfo { @@ -3094,70 +3145,6 @@ object Types { } } - /** A reference to wildcard argument `p.` - * where `p: C[... _ ...]` - */ - abstract case class TypeArgRef(prefix: Type, clsRef: TypeRef, idx: Int) extends CachedProxyType with ValueType { - assert(prefix.isInstanceOf[ValueType]) - assert(idx >= 0) - - private[this] var underlyingCache: Type = _ - private[this] var underlyingCachePeriod = Nowhere - - def computeUnderlying(implicit ctx: Context): Type = { - val cls = clsRef.symbol - val args = prefix.baseType(cls).argInfos - val typeParams = cls.typeParams - - val concretized = TypeArgRef.concretizeArgs(args, prefix, clsRef) - def rebase(arg: Type) = arg.subst(typeParams, concretized) - - val arg = args(idx) - val tparam = typeParams(idx) - val v = tparam.paramVariance - val pbounds = tparam.paramInfo - if (v > 0 && pbounds.loBound.dealias.isBottomType) arg.hiBound & rebase(pbounds.hiBound) - else if (v < 0 && pbounds.hiBound.dealias.isTopType) arg.loBound | rebase(pbounds.loBound) - else arg recoverable_& rebase(pbounds) - } - - override def underlying(implicit ctx: Context): Type = { - if (!ctx.hasSameBaseTypesAs(underlyingCachePeriod)) { - underlyingCache = computeUnderlying - underlyingCachePeriod = ctx.period - } - underlyingCache - } - - def derivedTypeArgRef(prefix: Type)(implicit ctx: Context): Type = - if (prefix eq this.prefix) this else TypeArgRef(prefix, clsRef, idx) - override def computeHash = doHash(idx, prefix, clsRef) - - override def eql(that: Type) = that match { - case that: TypeArgRef => prefix.eq(that.prefix) && clsRef.eq(that.clsRef) && idx == that.idx - case _ => false - } - } - - final class CachedTypeArgRef(prefix: Type, clsRef: TypeRef, idx: Int) extends TypeArgRef(prefix, clsRef, idx) - - object TypeArgRef { - def apply(prefix: Type, clsRef: TypeRef, idx: Int)(implicit ctx: Context) = - unique(new CachedTypeArgRef(prefix, clsRef, idx)) - def fromParam(prefix: Type, tparam: TypeSymbol)(implicit ctx: Context) = { - val cls = tparam.owner - apply(prefix, cls.typeRef, cls.typeParams.indexOf(tparam)) - } - - def concretizeArgs(args: List[Type], prefix: Type, clsRef: TypeRef)(implicit ctx: Context): List[Type] = { - def concretize(arg: Type, j: Int) = arg match { - case arg: TypeBounds => TypeArgRef(prefix, clsRef, j) - case arg => arg - } - args.zipWithConserve(args.indices.toList)(concretize) - } - } - // ----- BoundTypes: ParamRef, RecThis ---------------------------------------- abstract class BoundType extends CachedProxyType with ValueType { @@ -3758,13 +3745,7 @@ object Types { def apply(tp: Type): Type protected def derivedSelect(tp: NamedType, pre: Type): Type = - tp.derivedSelect(pre) match { - case tp: TypeArgRef if variance != 0 => - val tp1 = tp.underlying - if (variance > 0) tp1.hiBound else tp1.loBound - case tp => - tp - } + tp.derivedSelect(pre) protected def derivedRefinedType(tp: RefinedType, parent: Type, info: Type): Type = tp.derivedRefinedType(parent, tp.refinedName, info) protected def derivedRecType(tp: RecType, parent: Type): Type = @@ -3777,8 +3758,6 @@ object Types { tp.derivedSuperType(thistp, supertp) protected def derivedAppliedType(tp: AppliedType, tycon: Type, args: List[Type]): Type = tp.derivedAppliedType(tycon, args) - protected def derivedTypeArgRef(tp: TypeArgRef, prefix: Type): Type = - tp.derivedTypeArgRef(prefix) protected def derivedAndOrType(tp: AndOrType, tp1: Type, tp2: Type): Type = tp.derivedAndOrType(tp1, tp2) protected def derivedAnnotatedType(tp: AnnotatedType, underlying: Type, annot: Annotation): Type = @@ -3863,9 +3842,6 @@ object Types { } mapOverLambda - case tp @ TypeArgRef(prefix, _, _) => - derivedTypeArgRef(tp, atVariance(0)(this(prefix))) - case tp @ SuperType(thistp, supertp) => derivedSuperType(tp, this(thistp), this(supertp)) @@ -3989,27 +3965,39 @@ object Types { /** Try to widen a named type to its info relative to given prefix `pre`, where possible. * The possible cases are listed inline in the code. */ - def tryWiden(tp: NamedType, pre: Type): Type = - pre.member(tp.name) match { - case d: SingleDenotation => - d.info match { - case TypeAlias(alias) => - // if H#T = U, then for any x in L..H, x.T =:= U, - // hence we can replace with U under all variances - reapply(alias) - case TypeBounds(lo, hi) => - // If H#T = _ >: S <: U, then for any x in L..H, S <: x.T <: U, - // hence we can replace with S..U under all variances - range(atVariance(-variance)(reapply(lo)), reapply(hi)) - case info: SingletonType => - // if H#x: y.type, then for any x in L..H, x.type =:= y.type, - // hence we can replace with y.type under all variances - reapply(info) - case _ => - NoType - } - case _ => NoType - } + def tryWiden(tp: NamedType, pre: Type): Type = pre.member(tp.name) match { + case d: SingleDenotation => + d.info match { + case TypeAlias(alias) => + // if H#T = U, then for any x in L..H, x.T =:= U, + // hence we can replace with U under all variances + reapply(alias) + case TypeBounds(lo, hi) => + // If H#T = _ >: S <: U, then for any x in L..H, S <: x.T <: U, + // hence we can replace with S..U under all variances + range(atVariance(-variance)(reapply(lo)), reapply(hi)) + case info: SingletonType => + // if H#x: y.type, then for any x in L..H, x.type =:= y.type, + // hence we can replace with y.type under all variances + reapply(info) + case _ => + NoType + } + case _ => NoType + } + + /** Expand parameter reference corresponding to prefix `pre`; + * If the expansion is a wildcard parameter reference, convert its + * underlying bounds to a range, otherwise return the expansion. + */ + def expandParam(tp: NamedType, pre: Type) = tp.argForParam(pre) match { + case arg @ TypeRef(pre, _) if pre.isArgPrefixOf(arg.symbol) => + arg.info match { + case TypeBounds(lo, hi) => range(atVariance(-variance)(reapply(lo)), reapply(hi)) + case arg => reapply(arg) + } + case arg => reapply(arg) + } /** Derived selection. * @pre the (upper bound of) prefix `pre` has a member named `tp.name`. @@ -4019,7 +4007,7 @@ object Types { else pre match { case Range(preLo, preHi) => val forwarded = - if (tp.symbol.is(ClassTypeParam)) tp.argForParam(preHi) + if (tp.symbol.is(ClassTypeParam)) expandParam(tp, preHi) else tryWiden(tp, preHi) forwarded.orElse( range(super.derivedSelect(tp, preLo), super.derivedSelect(tp, preHi))) @@ -4122,14 +4110,6 @@ object Types { else range(lower(tp1) | lower(tp2), upper(tp1) | upper(tp2)) else tp.derivedAndOrType(tp1, tp2) - override protected def derivedTypeArgRef(tp: TypeArgRef, prefix: Type): Type = - if (isRange(prefix)) // TODO: explain - tp.underlying match { - case TypeBounds(lo, hi) => range(atVariance(-variance)(reapply(lo)), reapply(hi)) - case _ => range(tp.bottomType, tp.topType) - } - else tp.derivedTypeArgRef(prefix) - override protected def derivedAnnotatedType(tp: AnnotatedType, underlying: Type, annot: Annotation) = underlying match { case Range(lo, hi) => @@ -4265,9 +4245,6 @@ object Types { case tp: SkolemType => this(x, tp.info) - case tp @ TypeArgRef(prefix, _, _) => - atVariance(0)(this(x, prefix)) - case SuperType(thistp, supertp) => this(this(x, thistp), supertp) diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index c2298100e8ce..7909413e36fb 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -198,7 +198,7 @@ class ClassfileParser( var sym = classRoot.owner while (sym.isClass && !(sym is Flags.ModuleClass)) { for (tparam <- sym.typeParams) { - classTParams = classTParams.updated(tparam.name.unexpandedName, tparam) + classTParams = classTParams.updated(tparam.name, tparam) } sym = sym.owner } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index 1bb0163ffe0e..f2c8db08e2f4 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -31,26 +31,19 @@ Macro-format: Name = UTF8 Length UTF8-CodePoint* QUALIFIED Length qualified_NameRef selector_NameRef - FLATTENED Length qualified_NameRef selector_NameRef EXPANDED Length qualified_NameRef selector_NameRef - EXPANDEDPREFIX Length qualified_NameRef selector_NameRef - TRAITSETTER Length qualified_NameRef selector_NameRef + EXPANDPREFIX Length qualified_NameRef selector_NameRef + UNIQUE Length separator_NameRef uniqid_Nat underlying_NameRef? DEFAULTGETTER Length underlying_NameRef index_Nat VARIANT Length underlying_NameRef variance_Nat // 0: Contravariant, 1: Covariant - OUTERSELECT Length underlying_NameRef nhops_Nat // a reference to `nhops` selections, followed by `underlying` + OUTERSELECT Length underlying_NameRef nhops_Nat SUPERACCESSOR Length underlying_NameRef PROTECTEDACCESSOR Length underlying_NameRef PROTECTEDSETTER Length underlying_NameRef INITIALIZER Length underlying_NameRef - AVOIDCLASH Length underlying_NameRef - DIRECT Length underlying_NameRef - FIELD Length underlying_NameRef - EXTMETH Length underlying_NameRef - ADAPTEDCLOSURE Length underlying_NameRef - OBJECTVAR Length underlying_NameRef - OBJECTCLASS Length underlying_NameRef + SIGNED Length original_NameRef resultSig_NameRef paramSig_NameRef* NameRef = Nat // ordinal number of name in name table, starting from 1. @@ -168,7 +161,6 @@ Standard-Section: "ASTs" TopLevelStat* // for type-variables defined in a type pattern BYNAMEtype underlying_Type PARAMtype Length binder_ASTref paramNum_Nat - TYPEARGtype Length prefix_Type clsRef_Type idx_Nat POLYtype Length result_Type NamesTypes METHODtype Length result_Type NamesTypes // needed for refinements TYPELAMBDAtype Length result_Type NamesTypes // variance encoded in front of name: +/-/(nothing) @@ -177,10 +169,10 @@ Standard-Section: "ASTs" TopLevelStat* NameType = paramName_NameRef typeOrBounds_ASTRef Modifier = PRIVATE - INTERNAL // package private + INTERNAL // package private PROTECTED - PRIVATEqualified qualifier_Type // will be dropped - PROTECTEDqualified qualifier_Type // will be dropped + PRIVATEqualified qualifier_Type // to be dropped(?) + PROTECTEDqualified qualifier_Type // to be dropped(?) ABSTRACT FINAL SEALED @@ -188,31 +180,32 @@ Standard-Section: "ASTs" TopLevelStat* IMPLICIT LAZY OVERRIDE - INLINE // macro - STATIC // mapped to static Java member - OBJECT // an object or its class - TRAIT // a trait - LOCAL // private[this] or protected[this] - SYNTHETIC // generated by Scala compiler - ARTIFACT // to be tagged Java Synthetic - MUTABLE // a var - LABEL // method generated as a label - FIELDaccessor // getter or setter - CASEaccessor // getter for case class param - COVARIANT // type param marked “+” - CONTRAVARIANT // type param marked “-” - SCALA2X // Imported from Scala2.x - DEFAULTparameterized // Method with default params - STABLE // Method that is assumed to be stable + INLINE // macro + STATIC // mapped to static Java member + OBJECT // an object or its class + TRAIT // a trait + LOCAL // private[this] or protected[this] + SYNTHETIC // generated by Scala compiler + ARTIFACT // to be tagged Java Synthetic + MUTABLE // a var + LABEL // method generated as a label + FIELDaccessor // getter or setter + CASEaccessor // getter for case class param + COVARIANT // type parameter marked “+” + CONTRAVARIANT // type parameter marked “-” + SCALA2X // Imported from Scala2.x + DEFAULTparameterized // Method with default parameters + STABLE // Method that is assumed to be stable Annotation + Annotation = ANNOTATION Length tycon_Type fullAnnotation_Term Note: Tree tags are grouped into 5 categories that determine what follows, and thus allow to compute the size of the tagged tree in a generic way. - Category 1 (tags 0-63) : tag - Category 2 (tags 64-95) : tag Nat - Category 3 (tags 96-111) : tag AST - Category 4 (tags 112-127): tag Nat AST + Category 1 (tags 1-49) : tag + Category 2 (tags 50-79) : tag Nat + Category 3 (tags 80-109) : tag AST + Category 4 (tags 110-127): tag Nat AST Category 5 (tags 128-255): tag Length Standard Section: "Positions" Assoc* @@ -231,38 +224,48 @@ Standard Section: "Positions" Assoc* object TastyFormat { final val header = Array(0x5C, 0xA1, 0xAB, 0x1F) - val MajorVersion = 1 - val MinorVersion = 1 - - // Name tags - - final val UTF8 = 1 - final val QUALIFIED = 2 - final val FLATTENED = 3 - final val EXPANDED = 4 - final val EXPANDPREFIX = 5 - final val TRAITSETTER = 6 - final val UNIQUE = 10 - final val DEFAULTGETTER = 11 - final val VARIANT = 12 - final val OUTERSELECT = 13 - - final val SUPERACCESSOR = 20 - final val PROTECTEDACCESSOR = 21 - final val PROTECTEDSETTER = 22 - final val INITIALIZER = 23 - final val AVOIDCLASH = 30 - final val DIRECT = 31 - final val FIELD = 32 - final val EXTMETH = 33 - final val ADAPTEDCLOSURE = 34 - final val OBJECTVAR = 39 - final val OBJECTCLASS = 40 - - final val SIGNED = 63 - - final val firstInternalTag = 64 - final val IMPLMETH = 64 + val MajorVersion = 2 + val MinorVersion = 0 + + /** Tags used to serialize names */ + class NameTags { + final val UTF8 = 1 // A simple name in UTF8 encoding. + + final val QUALIFIED = 2 // A fully qualified name `.`. + + final val EXPANDED = 3 // An expanded name `$$`, + // used by Scala-2 for private names. + + final val EXPANDPREFIX = 4 // An expansion prefix `$`, + // used by Scala-2 for private names. + + final val UNIQUE = 10 // A unique name `$` where `` + // is used only once for each ``. + + final val DEFAULTGETTER = 11 // The name `$default$` + // of a default getter that returns a default argument. + + final val VARIANT = 12 // A name `+` o `-` indicating + // a co- or contra-variant parameter of a type lambda. + + final val OUTERSELECT = 13 // A name `_outer`, used by the inliner to indicate an + // outer accessor that will be filled in by ExplicitOuter. + // indicates the number of hops needed to select the outer field. + + final val SUPERACCESSOR = 20 // The name of a super accessor `super$name` created by SuperAccesors. + + final val PROTECTEDACCESSOR = 21 // The name of a protected accessor `protected$` created by SuperAccesors. + + final val PROTECTEDSETTER = 22 // The name of a protected setter `protected$set` created by SuperAccesors. + // This is a dubious encoding for its risk for ambiguity. + // It is kept for Scala-2 compatibility. + + final val OBJECTCLASS = 23 // The name of an object class (or: module class) `$`. + + final val SIGNED = 63 // A pair of a name and a signature, used to idenitfy + // possibly overloaded methods. + } + object NameTags extends NameTags // AST tags // Cat. 1: tag @@ -300,51 +303,51 @@ object TastyFormat { // Cat. 2: tag Nat - final val SHARED = 64 - final val TERMREFdirect = 65 - final val TYPEREFdirect = 66 - final val TERMREFpkg = 67 - final val TYPEREFpkg = 68 - final val RECthis = 69 - final val BYTEconst = 70 - final val SHORTconst = 71 - final val CHARconst = 72 - final val INTconst = 73 - final val LONGconst = 74 - final val FLOATconst = 75 - final val DOUBLEconst = 76 - final val STRINGconst = 77 - final val IMPORTED = 78 - final val RENAMED = 79 - final val SYMBOLconst = 80 + final val SHARED = 50 + final val TERMREFdirect = 51 + final val TYPEREFdirect = 52 + final val TERMREFpkg = 53 + final val TYPEREFpkg = 54 + final val RECthis = 55 + final val BYTEconst = 56 + final val SHORTconst = 57 + final val CHARconst = 58 + final val INTconst = 59 + final val LONGconst = 60 + final val FLOATconst = 61 + final val DOUBLEconst = 62 + final val STRINGconst = 63 + final val IMPORTED = 64 + final val RENAMED = 65 + final val SYMBOLconst = 66 // Cat. 3: tag AST - final val THIS = 96 - final val QUALTHIS = 97 - final val CLASSconst = 98 - final val ENUMconst = 99 - final val BYNAMEtype = 100 - final val BYNAMEtpt = 101 - final val NEW = 102 - final val IMPLICITarg = 103 - final val PRIVATEqualified = 104 - final val PROTECTEDqualified = 105 - final val RECtype = 106 - final val TYPEALIAS = 107 - final val SINGLETONtpt = 108 + final val THIS = 80 + final val QUALTHIS = 81 + final val CLASSconst = 82 + final val ENUMconst = 83 + final val BYNAMEtype = 84 + final val BYNAMEtpt = 85 + final val NEW = 86 + final val IMPLICITarg = 87 + final val PRIVATEqualified = 88 + final val PROTECTEDqualified = 89 + final val RECtype = 90 + final val TYPEALIAS = 91 + final val SINGLETONtpt = 92 // Cat. 4: tag Nat AST - final val IDENT = 112 - final val IDENTtpt = 113 - final val SELECT = 114 - final val SELECTtpt = 115 - final val TERMREFsymbol = 116 - final val TERMREF = 117 - final val TYPEREFsymbol = 118 - final val TYPEREF = 119 - final val SELFDEF = 120 + final val IDENT = 110 + final val IDENTtpt = 111 + final val SELECT = 112 + final val SELECTtpt = 113 + final val TERMREFsymbol = 114 + final val TERMREF = 115 + final val TYPEREFsymbol = 116 + final val TYPEREF = 117 + final val SELFDEF = 118 // Cat. 5: tag Length ... @@ -355,48 +358,47 @@ object TastyFormat { final val IMPORT = 132 final val TYPEPARAM = 133 final val PARAMS = 134 - final val PARAM = 136 - final val APPLY = 137 - final val TYPEAPPLY = 138 - final val TYPED = 139 - final val NAMEDARG = 140 - final val ASSIGN = 141 - final val BLOCK = 142 - final val IF = 143 - final val LAMBDA = 144 - final val MATCH = 145 - final val RETURN = 146 - final val TRY = 147 - final val INLINED = 148 - final val REPEATED = 149 - final val BIND = 150 - final val ALTERNATIVE = 151 - final val UNAPPLY = 152 - final val ANNOTATEDtype = 153 - final val ANNOTATEDtpt = 154 - final val CASEDEF = 155 - final val TEMPLATE = 156 - final val SUPER = 157 - final val SUPERtype = 158 - final val REFINEDtype = 159 - final val REFINEDtpt = 160 - final val APPLIEDtype = 161 - final val APPLIEDtpt = 162 - final val TYPEBOUNDS = 163 - final val TYPEBOUNDStpt = 164 - final val ANDtype = 166 - final val ANDtpt = 167 - final val ORtype = 168 - final val ORtpt = 169 - final val METHODtype = 170 - final val POLYtype = 171 - final val TYPELAMBDAtype = 172 - final val LAMBDAtpt = 173 - final val PARAMtype = 174 - final val ANNOTATION = 175 - final val TYPEARGtype = 176 - final val TERMREFin = 177 - final val TYPEREFin = 178 + final val PARAM = 135 + final val APPLY = 136 + final val TYPEAPPLY = 137 + final val TYPED = 138 + final val NAMEDARG = 139 + final val ASSIGN = 140 + final val BLOCK = 141 + final val IF = 142 + final val LAMBDA = 143 + final val MATCH = 144 + final val RETURN = 145 + final val TRY = 146 + final val INLINED = 147 + final val REPEATED = 148 + final val BIND = 149 + final val ALTERNATIVE = 150 + final val UNAPPLY = 151 + final val ANNOTATEDtype = 152 + final val ANNOTATEDtpt = 153 + final val CASEDEF = 154 + final val TEMPLATE = 155 + final val SUPER = 156 + final val SUPERtype = 157 + final val REFINEDtype = 158 + final val REFINEDtpt = 159 + final val APPLIEDtype = 160 + final val APPLIEDtpt = 161 + final val TYPEBOUNDS = 162 + final val TYPEBOUNDStpt = 163 + final val ANDtype = 164 + final val ANDtpt = 165 + final val ORtype = 166 + final val ORtpt = 167 + final val METHODtype = 168 + final val POLYtype = 169 + final val TYPELAMBDAtype = 170 + final val LAMBDAtpt = 171 + final val PARAMtype = 172 + final val ANNOTATION = 173 + final val TERMREFin = 174 + final val TYPEREFin = 175 final val firstSimpleTreeTag = UNITconst final val firstNatTreeTag = SHARED @@ -455,33 +457,6 @@ object TastyFormat { case _ => false } - def nameTagToString(tag: Int): String = tag match { - case UTF8 => "UTF8" - case QUALIFIED => "QUALIFIED" - case FLATTENED => "FLATTENED" - case EXPANDED => "EXPANDED" - case EXPANDPREFIX => "EXPANDPREFIX" - case TRAITSETTER => "TRAITSETTER" - case UNIQUE => "UNIQUE" - case DEFAULTGETTER => "DEFAULTGETTER" - case VARIANT => "VARIANT" - case OUTERSELECT => "OUTERSELECT" - - case SUPERACCESSOR => "SUPERACCESSOR" - case PROTECTEDACCESSOR => "PROTECTEDACCESSOR" - case PROTECTEDSETTER => "PROTECTEDSETTER" - case INITIALIZER => "INITIALIZER" - case AVOIDCLASH => "AVOIDCLASH" - case DIRECT => "DIRECT" - case FIELD => "FIELD" - case EXTMETH => "EXTMETH" - case ADAPTEDCLOSURE => "ADAPTEDCLOSURE" - case OBJECTVAR => "OBJECTVAR" - case OBJECTCLASS => "OBJECTCLASS" - - case SIGNED => "SIGNED" - } - def astTagToString(tag: Int): String = tag match { case UNITconst => "UNITconst" case FALSEconst => "FALSEconst" @@ -580,7 +555,6 @@ object TastyFormat { case SYMBOLconst => "SYMBOLconst" case SINGLETONtpt => "SINGLETONtpt" case SUPERtype => "SUPERtype" - case TYPEARGtype => "TYPEARGtype" case TERMREFin => "TERMREFin" case TYPEREFin => "TYPEREFin" case REFINEDtype => "REFINEDtype" diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala index 9bbb7c83a510..87b074054ce7 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala @@ -4,6 +4,7 @@ package tasty import scala.collection.mutable import TastyFormat._ +import TastyFormat.NameTags._ import TastyBuffer.NameRef import Names.{Name, TermName, termName, EmptyTermName} import NameKinds._ @@ -49,7 +50,7 @@ class TastyUnpickler(reader: TastyReader) { case UTF8 => goto(end) termName(bytes, start.index, length) - case QUALIFIED | FLATTENED | EXPANDED | EXPANDPREFIX => + case QUALIFIED | EXPANDED | EXPANDPREFIX => qualifiedNameKindOfTag(tag)(readName(), readName().asSimpleName) case UNIQUE => val separator = readName().toString diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 53712e09a3d4..6986392c8e35 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -211,9 +211,6 @@ class TreePickler(pickler: TastyPickler) { case tpe: SuperType => writeByte(SUPERtype) withLength { pickleType(tpe.thistpe); pickleType(tpe.supertpe) } - case tpe: TypeArgRef => - writeByte(TYPEARGtype) - withLength { pickleType(tpe.prefix); pickleType(tpe.clsRef); writeNat(tpe.idx) } case tpe: RecThis => writeByte(RECthis) val binderAddr = pickledTypes.get(tpe.binder) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index bd7beccf0855..41a98c8edae9 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -235,7 +235,10 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi val name = readName().toTypeName val prefix = readType() val space = readType() - TypeRef(prefix, name, space.decl(name)) + space.decl(name) match { + case symd: SymDenotation if prefix.isArgPrefixOf(symd.symbol) => TypeRef(prefix, symd.symbol) + case _ => TypeRef(prefix, name, space.decl(name)) + } case REFINEDtype => var name: Name = readName() val parent = readType() @@ -256,8 +259,6 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi OrType(readType(), readType()) case SUPERtype => SuperType(readType(), readType()) - case TYPEARGtype => - TypeArgRef(readType(), readType().asInstanceOf[TypeRef], readNat()) case BIND => val sym = ctx.newSymbol(ctx.owner, readName().toTypeName, BindDefinedType, readType(), coord = coordAt(start)) @@ -766,20 +767,9 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi cls.setNoInitsFlags(fork.indexStats(end)) val constr = readIndexedDef().asInstanceOf[DefDef] - def mergeTypeParamsAndAliases(tparams: List[TypeDef], stats: List[Tree])(implicit ctx: Context): (List[Tree], List[Tree]) = - (tparams, stats) match { - case (tparam :: tparams1, (alias: TypeDef) :: stats1) - if tparam.name == alias.name.expandedName(cls) => - val (tas, stats2) = mergeTypeParamsAndAliases(tparams1, stats1) - (tparam :: alias :: tas, stats2) - case _ => - (tparams, stats) - } - val lazyStats = readLater(end, rdr => implicit ctx => { - val stats0 = rdr.readIndexedStats(localDummy, end) - val (tparamsAndAliases, stats) = mergeTypeParamsAndAliases(tparams, stats0) - tparamsAndAliases ++ vparams ++ stats + val stats = rdr.readIndexedStats(localDummy, end) + tparams ++ vparams ++ stats }) setPos(start, untpd.Template(constr, parents, self, lazyStats) diff --git a/compiler/src/dotty/tools/dotc/printing/Formatting.scala b/compiler/src/dotty/tools/dotc/printing/Formatting.scala index b8271ba19f25..887744e66d07 100644 --- a/compiler/src/dotty/tools/dotc/printing/Formatting.scala +++ b/compiler/src/dotty/tools/dotc/printing/Formatting.scala @@ -31,7 +31,9 @@ object Formatting { case arg: Showable => try arg.show catch { - case NonFatal(ex) if !ctx.mode.is(Mode.PrintShowExceptions) => + case NonFatal(ex) + if !ctx.mode.is(Mode.PrintShowExceptions) && + !ctx.settings.YshowPrintErrors.value => s"[cannot display due to $ex, raw string = $toString]" } case _ => arg.toString diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index 0b004f106e30..6cd933a48dc9 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -176,11 +176,6 @@ class PlainPrinter(_ctx: Context) extends Printer { "{" ~ selfRecName(openRecs.length) ~ " => " ~ toTextGlobal(tp.parent) ~ "}" } finally openRecs = openRecs.tail - case TypeArgRef(prefix, clsRef, idx) => - val cls = clsRef.symbol - val tparams = cls.typeParams - val paramName = if (tparams.length > idx) nameString(tparams(idx)) else "" - toTextPrefix(prefix) ~ s"" case AndType(tp1, tp2) => changePrec(AndPrec) { toText(tp1) ~ " & " ~ toText(tp2) } case OrType(tp1, tp2) => diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 3dabf69c2b67..279c3d7642b2 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -661,7 +661,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { if (tree.exists(!_.isEmpty)) encl(blockText(tree)) else "" override protected def ParamRefNameString(name: Name): String = - name.unexpandedName.invariantName.toString + name.invariantName.toString override protected def treatAsTypeParam(sym: Symbol): Boolean = sym is TypeParam diff --git a/compiler/src/dotty/tools/dotc/printing/UserFacingPrinter.scala b/compiler/src/dotty/tools/dotc/printing/UserFacingPrinter.scala index 344d8ced20db..9a00180017fe 100644 --- a/compiler/src/dotty/tools/dotc/printing/UserFacingPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/UserFacingPrinter.scala @@ -31,11 +31,6 @@ class UserFacingPrinter(_ctx: Context) extends RefinedPrinter(_ctx) { override def toText(const: Constant): Text = Str(const.value.toString) - override def argText(tp: Type): Text = tp match { - case arg: TypeArgRef => argText(arg.underlying) - case _ => super.argText(tp) - } - override def toText(tp: Type): Text = tp match { case ExprType(result) => ":" ~~ toText(result) case tp: ConstantType => toText(tp.value) diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala index 24d5da69afb0..d769d23ec535 100644 --- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala +++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala @@ -147,7 +147,6 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder new api.Annotated(tp, Array(marker)) private def marker(name: String) = new api.Annotation(new api.Constant(Constants.emptyType, name), Array()) - val typeArgRefMarker = marker("TypeArgRef") val orMarker = marker("Or") val byNameMarker = marker("ByName") @@ -478,9 +477,6 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder apiType(tp.ref) case tp: TypeVar => apiType(tp.underlying) - case TypeArgRef(prefix, clsRef, idx) => - val apiClsWithIdx = withMarker(apiType(clsRef), marker(idx.toString)) - withMarker(combineApiTypes(apiType(prefix), apiClsWithIdx), typeArgRefMarker) case _ => { ctx.warning(i"sbt-api: Unhandled type ${tp.getClass} : $tp") Constants.emptyType diff --git a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala index fbf48e6a15de..a950bf7c4f49 100644 --- a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala +++ b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala @@ -98,7 +98,7 @@ trait FullParameterization { case _ => (0, info) } val ctparams = if (abstractOverClass) clazz.typeParams else Nil - val ctnames = ctparams.map(_.name.unexpandedName) + val ctnames = ctparams.map(_.name) val ctvariances = ctparams.map(_.variance) /** The method result type */ diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index fe0fec988c75..801f654d7a57 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -520,26 +520,13 @@ trait TypeAssigner { tree.withType(proto) def assignType(tree: untpd.ValDef, sym: Symbol)(implicit ctx: Context) = - tree.withType(if (sym.exists) assertExists(symbolicIfNeeded(sym).orElse(sym.termRef)) else NoType) + tree.withType(if (sym.exists) assertExists(sym.termRef) else NoType) def assignType(tree: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = - tree.withType(symbolicIfNeeded(sym).orElse(sym.termRef)) + tree.withType(sym.termRef) def assignType(tree: untpd.TypeDef, sym: Symbol)(implicit ctx: Context) = - tree.withType(symbolicIfNeeded(sym).orElse(sym.typeRef)) - - private def symbolicIfNeeded(sym: Symbol)(implicit ctx: Context) = { // ??? can we drop this? - val owner = sym.owner - if (owner.isClass && owner.isCompleted && owner.asClass.givenSelfType.exists) - // In that case a simple typeRef/termWithWithSig could return a member of - // the self type, not the symbol itself. To avoid this, we make the reference - // symbolic. In general it seems to be faster to keep the non-symbolic - // reference, since there is less pressure on the uniqueness tables that way - // and less work to update all the different references. That's why symbolic references - // are only used if necessary. - NamedType(owner.thisType, sym) - else NoType - } + tree.withType(sym.typeRef) def assertExists(tp: Type) = { assert(tp != NoType); tp } diff --git a/compiler/test-resources/repl/i2554 b/compiler/test-resources/pending/repl/i2554 similarity index 100% rename from compiler/test-resources/repl/i2554 rename to compiler/test-resources/pending/repl/i2554 diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 617e62f04990..e79121c7fe6e 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -96,6 +96,7 @@ class CompilationTests extends ParallelTesting { compileFilesInDir("../tests/new", defaultOptions) + compileFilesInDir("../tests/pos-scala2", scala2Mode) + compileFilesInDir("../tests/pos", defaultOptions) + + compileFilesInDir("../tests/pos-no-optimise", defaultOptions) + compileFilesInDir("../tests/pos-deep-subtype", allowDeepSubtypes) + compileDir("../tests/pos/i1137-1", defaultOptions and "-Yemit-tasty") + compileFile( diff --git a/doc-tool/src/dotty/tools/dottydoc/model/factories.scala b/doc-tool/src/dotty/tools/dottydoc/model/factories.scala index b1f3e530ee55..a0609de9b5c5 100644 --- a/doc-tool/src/dotty/tools/dottydoc/model/factories.scala +++ b/doc-tool/src/dotty/tools/dottydoc/model/factories.scala @@ -120,9 +120,6 @@ object factories { case ref @ RefinedType(parent, rn, info) => expandTpe(parent) //FIXME: will be a refined HK, aka class Foo[X] { def bar: List[X] } or similar - - case ref: TypeArgRef => - expandTpe(ref.underlying) } expandTpe(t) diff --git a/tests/pos-from-tasty/i3598.scala b/tests/pos-from-tasty/i3598.scala new file mode 100644 index 000000000000..9e5c8c32e954 --- /dev/null +++ b/tests/pos-from-tasty/i3598.scala @@ -0,0 +1,4 @@ +class Foo[A] { + def baz(foo: Foo[_]): Unit = bar(foo) + def bar[A](foo: Foo[A]): A = ??? +} diff --git a/tests/pos/escapingRefs.scala b/tests/pos-no-optimise/escapingRefs.scala similarity index 89% rename from tests/pos/escapingRefs.scala rename to tests/pos-no-optimise/escapingRefs.scala index 1b1deb8dec75..190e99d97378 100644 --- a/tests/pos/escapingRefs.scala +++ b/tests/pos-no-optimise/escapingRefs.scala @@ -29,13 +29,13 @@ object Test { x } - val d: Foo[Int] = { +/* val d: Foo[Int] = { class Bar[B] extends Foo[B] new Bar[Int] } - +*/ val e: Foo[_] = { - class Bar[B] extends Foo[B] + class Bar[B11] extends Foo[B11] new Bar[Int]: Bar[_ <: Int] } } diff --git a/tests/pos/i2554.scala b/tests/pos/i2554.scala new file mode 100644 index 000000000000..f8a77019c3fd --- /dev/null +++ b/tests/pos/i2554.scala @@ -0,0 +1,18 @@ +object foo { + trait ShapeLevel + trait FlatShapeLevel extends ShapeLevel + trait ColumnsShapeLevel extends FlatShapeLevel + abstract class Shape[Level <: ShapeLevel, -Mixed, Unpacked, Packed] + object Shape extends TupleShapeImplicits + trait TupleShapeImplicits { + implicit final def tuple2Shape[Level <: ShapeLevel, M1,M2, U1,U2, P1,P2]( + implicit u1: Shape[_ <: Level, M1, U1, P1], u2: Shape[_ <: Level, M2, U2, P2]) + : Shape[Level, (M1,M2), (U1,U2), (P1,P2)] = ??? + } +} +object Test { + import foo._ + implicit val shape: Shape[_ <: FlatShapeLevel, Int, Int, _] = null + def hint = Shape.tuple2Shape(shape, shape) + val hint2: foo.Shape[foo.FlatShapeLevel, (Int, Int), (Int, Int), _] = hint +}