Skip to content

Several type system fixes #4137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1466,7 +1466,7 @@ object SymDenotations {
val builder = new BaseDataBuilder
for (p <- classParents) {
if (p.typeSymbol.isClass) builder.addAll(p.typeSymbol.asClass.baseClasses)
else assert(ctx.mode.is(Mode.Interactive), s"$this has non-class parent: $p")
else assert(isRefinementClass || ctx.mode.is(Mode.Interactive), s"$this has non-class parent: $p")
}
(classSymbol :: builder.baseClasses, builder.baseClassSet)
}
Expand Down
58 changes: 28 additions & 30 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ object Types {
case tp: TypeRef =>
if (tp.symbol.isClass) tp
else tp.info match {
case TypeAlias(tp) => tp.dealias1(keepAnnots): @tailrec
case TypeAlias(alias) => alias.dealias1(keepAnnots): @tailrec
case _ => tp
}
case app @ AppliedType(tycon, args) =>
Expand Down Expand Up @@ -1967,37 +1967,35 @@ object Types {
def derivedSelect(prefix: Type)(implicit ctx: Context): Type =
if (prefix eq this.prefix) this
else if (prefix.isBottomType) prefix
else if (isType) {
val res =
if (currentSymbol.is(ClassTypeParam)) argForParam(prefix)
else prefix.lookupRefined(name)
if (res.exists) res
else if (Config.splitProjections)
prefix match {
case prefix: AndType =>
def isMissing(tp: Type) = tp match {
case tp: TypeRef => !tp.info.exists
case _ => false
}
val derived1 = derivedSelect(prefix.tp1)
val derived2 = derivedSelect(prefix.tp2)
return (
if (isMissing(derived1)) derived2
else if (isMissing(derived2)) derived1
else prefix.derivedAndType(derived1, derived2))
case prefix: OrType =>
val derived1 = derivedSelect(prefix.tp1)
val derived2 = derivedSelect(prefix.tp2)
return prefix.derivedOrType(derived1, derived2)
case _ =>
withPrefix(prefix)
}
else {
if (isType) {
val res =
if (currentSymbol.is(ClassTypeParam)) argForParam(prefix)
else prefix.lookupRefined(name)
if (res.exists) return res
if (Config.splitProjections)
prefix match {
case prefix: AndType =>
def isMissing(tp: Type) = tp match {
case tp: TypeRef => !tp.info.exists
case _ => false
}
val derived1 = derivedSelect(prefix.tp1)
val derived2 = derivedSelect(prefix.tp2)
return (
if (isMissing(derived1)) derived2
else if (isMissing(derived2)) derived1
else prefix.derivedAndType(derived1, derived2))
case prefix: OrType =>
val derived1 = derivedSelect(prefix.tp1)
val derived2 = derivedSelect(prefix.tp2)
return prefix.derivedOrType(derived1, derived2)
case _ =>
}
}
if (prefix.isInstanceOf[WildcardType]) WildcardType
else withPrefix(prefix)
}
else prefix match {
case _: WildcardType => WildcardType
case _ => withPrefix(prefix)
}

/** A reference like this one, but with the given symbol, if it exists */
final def withSym(sym: Symbol)(implicit ctx: Context): ThisType =
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ object ProtoTypes {
private def hasUnknownMembers(tp: Type)(implicit ctx: Context): Boolean = tp match {
case tp: TypeVar => !tp.isInstantiated
case tp: WildcardType => true
case NoType => true
case tp: TypeRef =>
val sym = tp.symbol
sym == defn.NothingClass ||
Expand All @@ -114,6 +115,7 @@ object ProtoTypes {
bound.isProvisional && hasUnknownMembers(bound)
}
}
case tp: AppliedType => hasUnknownMembers(tp.tycon) || hasUnknownMembers(tp.superType)
case tp: TypeProxy => hasUnknownMembers(tp.superType)
case _ => false
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,10 @@ object RefChecks {
if (autoOverride(member) ||
other.owner.is(JavaTrait) && ctx.testScala2Mode("`override' modifier required when a Java 8 default method is re-implemented", member.pos))
member.setFlag(Override)
else if (member.owner != clazz && other.owner != clazz && !(other.owner derivesFrom member.owner))
else if (member.isType && self.memberInfo(member) =:= self.memberInfo(other))
() // OK, don't complain about type aliases which are equal
else if (member.owner != clazz && other.owner != clazz &&
!(other.owner derivesFrom member.owner))
emitOverrideError(
clazz + " inherits conflicting members:\n "
+ infoStringWithLocation(other) + " and\n " + infoStringWithLocation(member)
Expand Down
26 changes: 26 additions & 0 deletions tests/neg/typeclass-encoding2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Used to crash with:
// assertion failed: class <refinement> has non-class parent
// Once that was fixed, another crash with:
// assertion failed: invalid prefix WildcardType(NoType)
object runtime1 {

trait TypeClass1[A] {
val common: TypeClassCommon1
type This[X] = common.This[X]
}

trait TypeClassCommon1 { self =>
type This[X]
type Instance[X] <: TypeClass1[X]
def inject[A](x: This[A]): Instance[A]// { val common: self.type }
}

trait Extension1[From[_], To[X] <: TypeClass1[X]] extends TypeClassCommon1 {
type This[X] = From[X]
type Instance[X] = To[X]
}

implicit def inject[A, From[_]](x: From[A])
(implicit ev: Extension1[From, _]): ev.Instance[A] { type This[X] = From[X] } =
ev.inject(x) // error: found: ev.To[A], required: ev.To[A]{This = From}
}
16 changes: 16 additions & 0 deletions tests/pos/this-types.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
trait A {
type A_This <: A
}
trait B extends A {
type A_This = B_This
type B_This <: B
}
trait C extends A {
type A_This = C_This
type C_This <: C
}
trait D extends B with C {
type B_This = D_This
type C_This = D_This
type D_This <: D
}
Loading