diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index a7586f876435..77885417a443 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -88,9 +88,8 @@ object desugar { else { def msg = s"no matching symbol for ${tp.symbol.showLocated} in ${defctx.owner} / ${defctx.effectiveScope.toList}" - if (ctx.reporter.errorsReported) ErrorType(msg) - else throw new java.lang.Error(msg) - } + ErrorType(msg).assertingErrorsReported(msg) + } case _ => mapOver(tp) } diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index f67bfd228d0d..32235e35e904 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -769,28 +769,26 @@ object Trees { def genericEmptyTree[T >: Untyped]: Thicket[T] = theEmptyTree.asInstanceOf[Thicket[T]] def flatten[T >: Untyped](trees: List[Tree[T]]): List[Tree[T]] = { - var buf: ListBuffer[Tree[T]] = null - var xs = trees - while (!xs.isEmpty) { - xs.head match { - case Thicket(elems) => - if (buf == null) { - buf = new ListBuffer - var ys = trees - while (ys ne xs) { - buf += ys.head - ys = ys.tail + def recur(buf: ListBuffer[Tree[T]], remaining: List[Tree[T]]): ListBuffer[Tree[T]] = + remaining match { + case Thicket(elems) :: remaining1 => + var buf1 = buf + if (buf1 == null) { + buf1 = new ListBuffer[Tree[T]] + var scanned = trees + while (scanned `ne` remaining) { + buf1 += scanned.head + scanned = scanned.tail } } - for (elem <- elems) { - assert(!elem.isInstanceOf[Thicket[_]]) - buf += elem - } - case tree => + recur(recur(buf1, elems), remaining1) + case tree :: remaining1 => if (buf != null) buf += tree + recur(buf, remaining1) + case nil => + buf } - xs = xs.tail - } + val buf = recur(null, trees) if (buf != null) buf.toList else trees } diff --git a/compiler/src/dotty/tools/dotc/core/Constants.scala b/compiler/src/dotty/tools/dotc/core/Constants.scala index 4f013a088132..38cdac21d7fe 100644 --- a/compiler/src/dotty/tools/dotc/core/Constants.scala +++ b/compiler/src/dotty/tools/dotc/core/Constants.scala @@ -153,7 +153,8 @@ object Constants { */ def convertTo(pt: Type)(implicit ctx: Context): Constant = { def classBound(pt: Type): Type = pt.dealias.stripTypeVar match { - case tref: TypeRef if !tref.symbol.isClass => classBound(tref.info.bounds.lo) + case tref: TypeRef if !tref.symbol.isClass && tref.info.exists => + classBound(tref.info.bounds.lo) case param: TypeParamRef => ctx.typerState.constraint.entry(param) match { case TypeBounds(lo, hi) => diff --git a/compiler/src/dotty/tools/dotc/core/Decorators.scala b/compiler/src/dotty/tools/dotc/core/Decorators.scala index 9639e520d010..1417d15087a1 100644 --- a/compiler/src/dotty/tools/dotc/core/Decorators.scala +++ b/compiler/src/dotty/tools/dotc/core/Decorators.scala @@ -175,8 +175,16 @@ object Decorators { recur(enclosingInlineds, pos) } - implicit class reportingDeco[T](val x: T) extends AnyVal { + implicit class genericDeco[T](val x: T) extends AnyVal { def reporting(op: T => String): T = { println(op(x)); x } + def assertingErrorsReported(implicit ctx: Context): T = { + assert(ctx.reporter.errorsReported) + x + } + def assertingErrorsReported(msg: => String)(implicit ctx: Context): T = { + assert(ctx.reporter.errorsReported, msg) + x + } } implicit class StringInterpolators(val sc: StringContext) extends AnyVal { diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 995fd474d0bb..af680510de14 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1466,10 +1466,11 @@ object SymDenotations { if (classParents.isEmpty && !emptyParentsExpected) onBehalf.signalProvisional() val builder = new BaseDataBuilder - for (p <- classParents) { - if (p.typeSymbol.isClass) builder.addAll(p.typeSymbol.asClass.baseClasses) - else assert(isRefinementClass || ctx.mode.is(Mode.Interactive), s"$this has non-class parent: $p") - } + for (p <- classParents) + p.classSymbol match { + case pcls: ClassSymbol => builder.addAll(pcls.baseClasses) + case _ => assert(isRefinementClass || ctx.mode.is(Mode.Interactive), s"$this has non-class parent: $p") + } (classSymbol :: builder.baseClasses, builder.baseClassSet) } @@ -1598,7 +1599,7 @@ object SymDenotations { def collect(denots: PreDenotation, parents: List[Type]): PreDenotation = parents match { case p :: ps => val denots1 = collect(denots, ps) - p.typeSymbol.denot match { + p.classSymbol.denot match { case parentd: ClassDenotation => denots1 union parentd.nonPrivateMembersNamed(name) @@ -1747,7 +1748,7 @@ object SymDenotations { var names = Set[Name]() def maybeAdd(name: Name) = if (keepOnly(thisType, name)) names += name for (p <- classParents) - for (name <- p.typeSymbol.asClass.memberNames(keepOnly)) + for (name <- p.classSymbol.asClass.memberNames(keepOnly)) maybeAdd(name) val ownSyms = if (keepOnly eq implicitFilter) diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index d59c540432c3..1ff312dae475 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -140,7 +140,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object. val accu1 = if (accu exists (_ derivesFrom c)) accu else c :: accu if (cs == c.baseClasses) accu1 else dominators(rest, accu1) case Nil => // this case can happen because after erasure we do not have a top class anymore - assert(ctx.erasedTypes) + assert(ctx.erasedTypes || ctx.reporter.errorsReported) defn.ObjectClass :: Nil } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 19c645afb389..3de52cb16f87 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -142,9 +142,12 @@ object Types { /** Is this type a value type? */ final def isValueType: Boolean = this.isInstanceOf[ValueType] - /** Is the is value type or type lambda? */ + /** Is this a value type or a type lambda? */ final def isValueTypeOrLambda: Boolean = isValueType || this.isInstanceOf[TypeLambda] + /** Is this a value type or a wildcard? */ + final def isValueTypeOrWildcard: Boolean = isValueType || this.isInstanceOf[WildcardType] + /** Does this type denote a stable reference (i.e. singleton type)? */ final def isStable(implicit ctx: Context): Boolean = stripTypeVar match { case tp: TermRef => tp.termSymbol.isStable && tp.prefix.isStable || tp.info.isStable @@ -589,13 +592,14 @@ object Types { def goRefined(tp: RefinedType) = { val pdenot = go(tp.parent) + val pinfo = pdenot.info val rinfo = tp.refinedInfo - if (name.isTypeName) { // simplified case that runs more efficiently + if (name.isTypeName && !pinfo.isInstanceOf[ClassInfo]) { // simplified case that runs more efficiently val jointInfo = if (rinfo.isAlias) rinfo - else if (pdenot.info.isAlias) pdenot.info - else if (ctx.pendingMemberSearches.contains(name)) pdenot.info safe_& rinfo - else pdenot.info recoverable_& rinfo + else if (pinfo.isAlias) pinfo + else if (ctx.pendingMemberSearches.contains(name)) pinfo safe_& rinfo + else pinfo recoverable_& rinfo pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, jointInfo) } else { pdenot & ( @@ -1523,11 +1527,8 @@ object Types { /** A marker trait for types that can be types of values or prototypes of value types */ trait ValueTypeOrProto extends TermType - /** A marker trait for types that can be types of values or wildcards */ - trait ValueTypeOrWildcard extends TermType - /** A marker trait for types that can be types of values or that are higher-kinded */ - trait ValueType extends ValueTypeOrProto with ValueTypeOrWildcard + trait ValueType extends ValueTypeOrProto /** A marker trait for types that are guaranteed to contain only a * single non-null value (they might contain null in addition). @@ -2479,8 +2480,8 @@ object Types { object AndType { def apply(tp1: Type, tp2: Type)(implicit ctx: Context): AndType = { - assert(tp1.isInstanceOf[ValueTypeOrWildcard] && - tp2.isInstanceOf[ValueTypeOrWildcard], i"$tp1 & $tp2 / " + s"$tp1 & $tp2") + assert(tp1.isValueTypeOrWildcard && + tp2.isValueTypeOrWildcard, i"$tp1 & $tp2 / " + s"$tp1 & $tp2") unchecked(tp1, tp2) } @@ -2524,8 +2525,8 @@ object Types { myBaseClasses } - assert(tp1.isInstanceOf[ValueTypeOrWildcard] && - tp2.isInstanceOf[ValueTypeOrWildcard], s"$tp1 $tp2") + assert(tp1.isValueTypeOrWildcard && + tp2.isValueTypeOrWildcard, s"$tp1 $tp2") private[this] var myJoin: Type = _ private[this] var myJoinPeriod: Period = Nowhere @@ -3477,7 +3478,7 @@ object Types { if (selfTypeCache == null) selfTypeCache = { val given = cls.givenSelfType - if (!given.exists) appliedRef + if (!given.isValueType) appliedRef else if (cls is Module) given else if (ctx.erasedTypes) appliedRef else AndType(given, appliedRef) @@ -3756,7 +3757,7 @@ object Types { object TryDynamicCallType extends FlexType /** Wildcard type, possibly with bounds */ - abstract case class WildcardType(optBounds: Type) extends CachedGroundType with ValueTypeOrWildcard { + abstract case class WildcardType(optBounds: Type) extends CachedGroundType with TermType { def derivedWildcardType(optBounds: Type)(implicit ctx: Context) = if (optBounds eq this.optBounds) this else if (!optBounds.exists) WildcardType diff --git a/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala b/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala index cdb72fd429d8..c60d8edf04fc 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala @@ -82,7 +82,7 @@ class CheckReentrant extends MiniPhase { } } for (parent <- cls.classInfo.classParents) - addVars(parent.typeSymbol.asClass) + addVars(parent.classSymbol.asClass) } } } diff --git a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala index 944dc240491c..276e45a9eac8 100644 --- a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala +++ b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala @@ -53,7 +53,7 @@ object GenericSignatures { val validParents = if (isTraitSignature) // java is unthrilled about seeing interfaces inherit from classes - minParents filter (p => isInterfaceOrTrait(p.typeSymbol)) + minParents filter (p => isInterfaceOrTrait(p.classSymbol)) else minParents val ps = ensureClassAsFirstParent(validParents) @@ -329,11 +329,11 @@ object GenericSignatures { def isUnshadowed(psym: Symbol) = !(psyms exists (qsym => (psym ne qsym) && (qsym isSubClass psym))) val cs = parents.iterator.filter { p => // isUnshadowed is a bit expensive, so try classes first - val psym = p.typeSymbol + val psym = p.classSymbol psym.ensureCompleted() psym.isClass && !psym.is(Trait) && isUnshadowed(psym) } - (if (cs.hasNext) cs else parents.iterator.filter(p => isUnshadowed(p.typeSymbol))).next() + (if (cs.hasNext) cs else parents.iterator.filter(p => isUnshadowed(p.classSymbol))).next() } } } diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index a45942481a4f..01e66223d4e6 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -879,19 +879,25 @@ trait Applications extends Compatibility { self: Typer with Dynamic => */ def trySelectUnapply(qual: untpd.Tree)(fallBack: Tree => Tree): Tree = { // try first for non-overloaded, then for overloaded ocurrences - def tryWithName(name: TermName)(fallBack: Tree => Tree)(implicit ctx: Context): Tree = - tryEither { implicit ctx => - val specificProto = new UnapplyFunProto(selType, this) - typedExpr(untpd.Select(qual, name), specificProto) + def tryWithName(name: TermName)(fallBack: Tree => Tree)(implicit ctx: Context): Tree = { + def tryWithProto(pt: Type)(implicit ctx: Context) = { + val result = typedExpr(untpd.Select(qual, name), new UnapplyFunProto(pt, this)) + if (!result.symbol.exists || result.symbol.name == name) result + else notAnExtractor(result) + // It might be that the result of typedExpr is an `apply` selection or implicit conversion. + // Reject in this case. + } + tryEither { + implicit ctx => tryWithProto(selType) } { (sel, _) => - tryEither { implicit ctx => - val genericProto = new UnapplyFunProto(WildcardType, this) - typedExpr(untpd.Select(qual, name), genericProto) + tryEither { + implicit ctx => tryWithProto(WildcardType) } { (_, _) => fallBack(sel) } } + } // try first for unapply, then for unapplySeq tryWithName(nme.unapply) { sel => tryWithName(nme.unapplySeq)(_ => fallBack(sel)) // for backwards compatibility; will be dropped @@ -967,7 +973,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => case Apply(Apply(unapply, `dummyArg` :: Nil), args2) => assert(args2.nonEmpty); args2 case Apply(unapply, `dummyArg` :: Nil) => Nil case Inlined(u, _, _) => unapplyImplicits(u) - case _ => assert(ctx.reporter.errorsReported); Nil + case _ => Nil.assertingErrorsReported } var argTypes = unapplyArgs(unapplyApp.tpe, unapplyFn, args, tree.pos) diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 99c4116d8637..5990b102dac0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -449,7 +449,7 @@ trait ImplicitRunInfo { self: Run => comps += companion.asSeenFrom(pre, compSym.owner).asInstanceOf[TermRef] } def addParentScope(parent: Type): Unit = - iscopeRefs(tp.baseType(parent.typeSymbol)) foreach addRef + iscopeRefs(tp.baseType(parent.classSymbol)) foreach addRef val companion = cls.companionModule if (companion.exists) addRef(companion.termRef) cls.classParents foreach addParentScope diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index a231ff18f6e5..2d6ecae78fe4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -164,8 +164,8 @@ object NamerContextOps { /** Find moduleClass/sourceModule in effective scope */ private def findModuleBuddy(name: Name, scope: Scope)(implicit ctx: Context) = { val it = scope.lookupAll(name).filter(_ is Module) - assert(it.hasNext, s"no companion $name in $scope") - it.next() + if (it.hasNext) it.next() + else NoSymbol.assertingErrorsReported(s"no companion $name in $scope") } } @@ -918,8 +918,7 @@ class Namer { typer: Typer => fullyDefinedType(typedAheadExpr(parent).tpe, "class parent", parent.pos) } case _ => - assert(ctx.reporter.errorsReported) - UnspecifiedErrorType + UnspecifiedErrorType.assertingErrorsReported } } @@ -1033,8 +1032,9 @@ class Namer { typer: Typer => */ def moduleValSig(sym: Symbol)(implicit ctx: Context): Type = { val clsName = sym.name.moduleClassName - val cls = ctx.denotNamed(clsName) suchThat (_ is ModuleClass) - ctx.owner.thisType select (clsName, cls) + val cls = ctx.denotNamed(clsName).suchThat(_ is ModuleClass) + .orElse(ctx.newStubSymbol(ctx.owner, clsName).assertingErrorsReported) + ctx.owner.thisType.select(clsName, cls) } /** The type signature of a ValDef or DefDef diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index cc0c07c79266..5a32fcf19364 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -472,16 +472,18 @@ object ProtoTypes { } /** Create a new TypeVar that represents a dependent method parameter singleton */ - def newDepTypeVar(tp: Type)(implicit ctx: Context): TypeVar = + def newDepTypeVar(tp: Type)(implicit ctx: Context): TypeVar = { newTypeVar(TypeBounds.upper(AndType(tp.widenExpr, defn.SingletonClass.typeRef))) - + } /** The result type of `mt`, where all references to parameters of `mt` are * replaced by either wildcards (if typevarsMissContext) or TypeParamRefs. */ def resultTypeApprox(mt: MethodType)(implicit ctx: Context): Type = if (mt.isResultDependent) { def replacement(tp: Type) = - if (ctx.mode.is(Mode.TypevarsMissContext)) WildcardType else newDepTypeVar(tp) + if (ctx.mode.is(Mode.TypevarsMissContext) || + !tp.widenExpr.isValueTypeOrWildcard) WildcardType + else newDepTypeVar(tp) mt.resultType.substParams(mt, mt.paramInfos.map(replacement)) } else mt.resultType diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 0864fde2ff81..bec2403aff7d 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -103,7 +103,7 @@ object RefChecks { cls.pos) } for (parent <- cinfo.classParents) - checkSelfConforms(parent.typeSymbol.asClass, "illegal inheritance", "parent") + checkSelfConforms(parent.classSymbol.asClass, "illegal inheritance", "parent") for (reqd <- cinfo.cls.givenSelfType.classSymbols) checkSelfConforms(reqd, "missing requirement", "required") case _ => diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 6950934fb8f6..24ed19112fb6 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1447,7 +1447,9 @@ class Typer extends Namer assignType(cpy.TypeDef(tdef)(name, rhs1), sym) } - def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = track("typedClassDef") { + def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context): Tree = track("typedClassDef") { + if (!cls.info.isInstanceOf[ClassInfo]) return EmptyTree.assertingErrorsReported + val TypeDef(name, impl @ Template(constr, parents, self, _)) = cdef val superCtx = ctx.superCallContext @@ -1622,16 +1624,16 @@ class Typer extends Namer def typedPackageDef(tree: untpd.PackageDef)(implicit ctx: Context): Tree = track("typedPackageDef") { val pid1 = typedExpr(tree.pid, AnySelectionProto)(ctx.addMode(Mode.InPackageClauseName)) val pkg = pid1.symbol - - // Package will not exist if a duplicate type has already been entered, see - // `tests/neg/1708.scala`, else branch's error message should be supressed - if (pkg.exists) { - if (!pkg.is(Package)) ctx.error(PackageNameAlreadyDefined(pkg), tree.pos) - val packageCtx = ctx.packageContext(tree, pkg) - val stats1 = typedStats(tree.stats, pkg.moduleClass)(packageCtx) - cpy.PackageDef(tree)(pid1.asInstanceOf[RefTree], stats1) withType pkg.termRef + pid1 match { + case pid1: RefTree if pkg.exists => + if (!pkg.is(Package)) ctx.error(PackageNameAlreadyDefined(pkg), tree.pos) + val packageCtx = ctx.packageContext(tree, pkg) + val stats1 = typedStats(tree.stats, pkg.moduleClass)(packageCtx) + cpy.PackageDef(tree)(pid1, stats1).withType(pkg.termRef) + case _ => + // Package will not exist if a duplicate type has already been entered, see `tests/neg/1708.scala` + errorTree(tree, i"package ${tree.pid.name} does not exist") } - else errorTree(tree, i"package ${tree.pid.name} does not exist") } def typedAnnotated(tree: untpd.Annotated, pt: Type)(implicit ctx: Context): Tree = track("typedAnnotated") { diff --git a/tests/neg/bad-selftype.scala b/tests/neg/bad-selftype.scala new file mode 100644 index 000000000000..46a538d1f879 --- /dev/null +++ b/tests/neg/bad-selftype.scala @@ -0,0 +1,6 @@ +trait x0[T] { self: x0 => } // error + +trait x1[T] { self: (=> String) => } // error + +trait x2[T] { self: ([X] => X) => } // error + diff --git a/tests/neg/parser-stability-11.scala b/tests/neg/parser-stability-11.scala new file mode 100644 index 000000000000..ae9d6cde7b6a --- /dev/null +++ b/tests/neg/parser-stability-11.scala @@ -0,0 +1,5 @@ +package x0 { +case class x0 // error // error +} +package x0 +class x0 // error // error diff --git a/tests/neg/parser-stability-12.scala b/tests/neg/parser-stability-12.scala new file mode 100644 index 000000000000..956e80768cf5 --- /dev/null +++ b/tests/neg/parser-stability-12.scala @@ -0,0 +1,3 @@ +trait x0[] // error + trait x1[x1 <:x0] + extends x1[ // error diff --git a/tests/neg/parser-stability-14.scala b/tests/neg/parser-stability-14.scala new file mode 100644 index 000000000000..a34e8f9096d1 --- /dev/null +++ b/tests/neg/parser-stability-14.scala @@ -0,0 +1,4 @@ +object x0 { +{ +val x1 x0 // error +object x1 // error // error diff --git a/tests/neg/parser-stability-15.scala b/tests/neg/parser-stability-15.scala new file mode 100644 index 000000000000..89748da11dd6 --- /dev/null +++ b/tests/neg/parser-stability-15.scala @@ -0,0 +1,6 @@ +package x0 +class x0 { +def x1 = +x2 match // error +] // error +case x3[] => x0 // error // error // error // error diff --git a/tests/neg/parser-stability-16.scala b/tests/neg/parser-stability-16.scala new file mode 100644 index 000000000000..f6f6f19aa890 --- /dev/null +++ b/tests/neg/parser-stability-16.scala @@ -0,0 +1,5 @@ +class x0[x0] { + val x1 : x0 +} +trait x3 extends x0 { +x1 = 0 object // error // error diff --git a/tests/neg/parser-stability-17.scala b/tests/neg/parser-stability-17.scala new file mode 100644 index 000000000000..ff603a677378 --- /dev/null +++ b/tests/neg/parser-stability-17.scala @@ -0,0 +1,2 @@ +trait x0[] { x0: x0 => } // error // error + class x0[x1] extends x0[x0 x0] x2 x0 // error // error diff --git a/tests/neg/parser-stability-18.scala b/tests/neg/parser-stability-18.scala new file mode 100644 index 000000000000..3eefbbcbd333 --- /dev/null +++ b/tests/neg/parser-stability-18.scala @@ -0,0 +1,4 @@ +trait x0 { + class x1 (x1:x0 + { +type x1 <: List[x1 <: // error // error diff --git a/tests/neg/parser-stability-19.scala b/tests/neg/parser-stability-19.scala new file mode 100644 index 000000000000..306b9479a2e4 --- /dev/null +++ b/tests/neg/parser-stability-19.scala @@ -0,0 +1,4 @@ +object x0 { + case class x0[] // error // error + def x0( ) ] // error // error + def x0 ( x0:x0 ):x0.type = x1 x0 // error // error // error diff --git a/tests/neg/parser-stability-20.scala b/tests/neg/parser-stability-20.scala new file mode 100644 index 000000000000..bb1165042410 --- /dev/null +++ b/tests/neg/parser-stability-20.scala @@ -0,0 +1,5 @@ +object x0 { +def unapply= Array +x0 match +x0 // error +case x0( // error // error diff --git a/tests/neg/parser-stability-21.scala b/tests/neg/parser-stability-21.scala new file mode 100644 index 000000000000..97bbe74c6068 --- /dev/null +++ b/tests/neg/parser-stability-21.scala @@ -0,0 +1,2 @@ +class x0[x1[]] // error + extends x1[ // error // error diff --git a/tests/neg/parser-stability-22.scala b/tests/neg/parser-stability-22.scala new file mode 100644 index 000000000000..83e21b31816c --- /dev/null +++ b/tests/neg/parser-stability-22.scala @@ -0,0 +1,3 @@ +package x0.x0 {} +object x0 { + def x0 (implicit // error // error diff --git a/tests/pos/class-refinement.scala b/tests/pos/class-refinement.scala new file mode 100644 index 000000000000..a8a83fa20f00 --- /dev/null +++ b/tests/pos/class-refinement.scala @@ -0,0 +1,36 @@ +object Test { + + class C { + + class I + + } + + trait T + + val x: C { type I <: T } = ??? // direct refinement of class member + + val y: x.I = ??? + +} + +class B { + class C { + type I + } + trait T + + type CC <: C + + val x: CC { type I <: T } = ??? +} + +object Test2 extends B { + + class CC extends C { class I } + + val y: x.I = ??? // indirect refinement of class member + + +} +