Skip to content

Fix #3015: exhaustivity check on top of native apply #3074

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

Closed
wants to merge 106 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
fb7ffe2
Introduce AppliedType
odersky Jul 21, 2017
a060095
Adapt operations in Types
odersky Jul 21, 2017
fb08d5f
Move givenSelfType to ClassSymbol
odersky Jul 22, 2017
dabeeca
Handle AppliedTypes
odersky Jul 23, 2017
a16f5fc
Introduce TypeArgRef
odersky Jul 26, 2017
14ef226
Various fixes
odersky Jul 28, 2017
0fdfd30
More fixes
odersky Jul 28, 2017
e4b9c30
Fix stray brace
odersky Jul 29, 2017
d563cdf
Fix typing of _* arguments
odersky Jul 30, 2017
9c3b90d
Fix rebase breakage
odersky Aug 16, 2017
70a6bcc
Fix debug output to make it more stable
odersky Aug 16, 2017
235ef90
Fix Stackoverflow in asSeenFrom
odersky Aug 16, 2017
62f612c
Make newScheme non-final
odersky Aug 16, 2017
69226cd
Partially revert change in TypeApplications#Reducer
odersky Aug 16, 2017
e675fee
Use atVariance for new cases in TypeMaps and TypeAccumulators
odersky Aug 16, 2017
684773a
Fix bounds propagation
odersky Aug 17, 2017
5d0fe46
Fix variance in avoidParams
odersky Aug 17, 2017
3f8ee89
Fix isSubArg
odersky Aug 17, 2017
b8f8b44
Avoid infinite expansion in normaizeWildcardArgs
odersky Aug 17, 2017
7e4f591
Handle parameters from base classes of package objects
odersky Aug 17, 2017
b9b1bcd
More fixes
odersky Aug 18, 2017
6cd44c8
Fix #536 again
odersky Aug 18, 2017
c0649b9
Adapt ClassTypeParamCreationFlags to new scheme
odersky Aug 18, 2017
08de872
Fix TypeArgRef and argForParam
odersky Aug 18, 2017
a225978
Add capture conversion
odersky Aug 18, 2017
306d36c
Fix ExpandSAMs
odersky Aug 18, 2017
68d6ddb
Fix implicit scope computation
odersky Aug 18, 2017
fa2d7dd
Refine typeMismatchMsg
odersky Aug 19, 2017
442047b
Generalize argForParam
odersky Aug 19, 2017
c53e432
Check that class type parameters are only referenced via their this-t…
odersky Aug 20, 2017
9b56fec
Check that class type parameters are only referenced via their this-t…
odersky Aug 20, 2017
78786e6
Fix illegal select in VCInlineMethods
odersky Aug 20, 2017
5ef7907
Fix classBound
odersky Aug 21, 2017
5bb3c6e
Fix t8280
odersky Aug 21, 2017
d7a871a
Adapt flip in Applications to new scheme
odersky Aug 21, 2017
2c123ed
Fix type of outer accessor
odersky Aug 21, 2017
ee66d9c
Fix computation of implicit scope
odersky Aug 22, 2017
cd100c1
Fix problem in isSubArg
odersky Aug 22, 2017
bbd8f35
Fix instantiatability checking
odersky Aug 23, 2017
f71be3a
Adapt tpd.ClassDef and tpd.AnonClass to new scheme
odersky Aug 23, 2017
6629f41
Change capture conversion
odersky Aug 23, 2017
e89ada9
Fix variances for wildcard arguments in TypeMaps and TypeAccumulators
odersky Aug 23, 2017
86a94b1
Avoid cyclic reference in normalizeWildcardArgs
odersky Aug 23, 2017
3c0e5b5
Fix SuperAccessors
odersky Aug 23, 2017
8fbd356
Fix possible hole in constraint handling
odersky Aug 24, 2017
17e977e
Fix
odersky Aug 24, 2017
a59dcde
Fix printing of TypeBounds
odersky Aug 24, 2017
48fb509
Refine Space#refine to handle AppliedTypes
odersky Aug 24, 2017
36d0938
Fix implicit selection for views
odersky Aug 25, 2017
2a3778f
Fix sigName for AppliedType
odersky Aug 26, 2017
86f05a0
Handle Java raw types in isSubType
odersky Aug 27, 2017
0375832
Don't check variances when comparing type lambdas in Scala2 mode
odersky Aug 27, 2017
484bacc
Don't try to simplify & / | types written as types
odersky Aug 27, 2017
3c6da89
Hash-cons applied types in their own table
odersky Aug 27, 2017
f989fe3
Make ParamRefs unique types.
odersky Aug 27, 2017
8453797
Refine statistics
odersky Aug 27, 2017
3cdb005
Make ParamRefs unique types.
odersky Aug 28, 2017
217aeb4
Make bound types be uniquely created by their binders
odersky Aug 28, 2017
947e5f1
More detailed stats
odersky Aug 29, 2017
858e7c0
Fix base type computation
odersky Aug 29, 2017
413c8cb
Fix tests
odersky Aug 29, 2017
ea065c1
Temporarily disable pattern-matching exhaustivity tests
odersky Aug 29, 2017
ed1d565
Temporarily weaken double definition check
odersky Aug 29, 2017
1eaa0ce
Temporarily existentials test to pending
odersky Aug 29, 2017
50ae64d
Ensure type correctness of repeated arguments
odersky Aug 30, 2017
04570bd
Update "good bounds" checks
odersky Aug 30, 2017
db8b355
Exclude mixin forwarders from double definition checks
odersky Aug 31, 2017
dd0eadc
Adapt superclass inference to new scheme
odersky Aug 31, 2017
62826be
Avoid inifinite loop when comparing & types with class types
odersky Aug 31, 2017
e13a7c7
Fix rebase breakage
odersky Aug 31, 2017
a25f6de
Handle TypeArgRefs in UserfacingPrinter
odersky Aug 31, 2017
fe0ccdd
Fix imports and add explanations in Space
odersky Aug 31, 2017
35015eb
Eliminate Config switches
odersky Aug 31, 2017
8dd5a69
Get rid of parentRefs and associated operations
odersky Aug 31, 2017
d76e72e
Re-normalize parents methods
odersky Aug 31, 2017
f3ddbb1
Fix rebase breakage, drop old UserfacingPrinter
odersky Aug 31, 2017
7f0efca
Use adaptHkVariances when comparing type arguments
odersky Aug 31, 2017
2851099
Re-apply change to printing TypeArgRefs in UserfacingPrinter
odersky Aug 31, 2017
738e321
Fix script check file
odersky Aug 31, 2017
33d0dc6
Drop HKApply
odersky Aug 31, 2017
ee7c3f9
Make baseTypeOf more robust
odersky Aug 31, 2017
bc776ae
Drop uniqueRefinedType and uniqueTypeAlias
odersky Aug 31, 2017
ba29e51
Drop variance in TypeAlias
odersky Aug 31, 2017
9552235
Fix equals for TypeAlias
odersky Aug 31, 2017
fa7551a
Adapt homogenizeArgs to new scheme
odersky Sep 1, 2017
445d9f4
Drop AnyAppliedType
odersky Sep 1, 2017
1aa05e0
Fix printing of infix types
odersky Sep 1, 2017
3440567
Drop TypeParamAccessor
odersky Sep 1, 2017
ba12831
Drop BaseTypeArg flag
odersky Sep 1, 2017
bd1ad22
Drop withoutArgs
odersky Sep 1, 2017
634378c
Drop ClassDenotation.appliedRef and ClassInfo.typeRef
odersky Sep 1, 2017
e2703d3
Reorder and clean up erasure and sigName
odersky Sep 1, 2017
5fed255
More cleanups and removals of now redundant code
odersky Sep 2, 2017
6491ef2
Better implementation of mapArgs
odersky Sep 2, 2017
933c677
Specialize hash-consing of WithFixedSym types
odersky Sep 3, 2017
656ba92
Avoid creating unnecessary new lists in mapArgs
odersky Sep 4, 2017
9aafa1d
Drop unused RefType and ClassRef
odersky Sep 6, 2017
778f4d1
Remove unused code
odersky Sep 6, 2017
c003228
Reverted: Refine Space#refine to handle AppliedTypes
odersky Sep 4, 2017
410d0cf
Disable exhaustivity test
odersky Sep 6, 2017
7b81aee
reenable exhaustivity check
liufengyun Sep 7, 2017
6e50ab3
fix #3015: use type inference to type child classes
liufengyun Sep 7, 2017
7a49c8c
make exhaustivity check work on native apply
liufengyun Sep 7, 2017
2953cab
change var to val
liufengyun Sep 7, 2017
3bd360c
remove uselss expose
liufengyun Sep 7, 2017
33efe0f
enable disabled test
liufengyun Sep 7, 2017
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
21 changes: 11 additions & 10 deletions compiler/src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class Run(comp: Compiler, ictx: Context) {
compileUnits()(ctx)
}

protected def compileUnits()(implicit ctx: Context) = Stats.monitorHeartBeat {
protected def compileUnits()(implicit ctx: Context) = Stats.maybeMonitored {
ctx.checkSingleThreaded()

// If testing pickler, make sure to stop after pickling phase:
Expand All @@ -118,17 +118,18 @@ class Run(comp: Compiler, ictx: Context) {
ctx.usePhases(phases)
var lastPrintedTree: PrintedTree = NoPrintedTree
for (phase <- ctx.allPhases)
if (phase.isRunnable) {
val start = System.currentTimeMillis
units = phase.runOn(units)
if (ctx.settings.Xprint.value.containsPhase(phase)) {
for (unit <- units) {
lastPrintedTree =
printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
if (phase.isRunnable)
Stats.trackTime(s"$phase ms ") {
val start = System.currentTimeMillis
units = phase.runOn(units)
if (ctx.settings.Xprint.value.containsPhase(phase)) {
for (unit <- units) {
lastPrintedTree =
printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
}
}
ctx.informTime(s"$phase ", start)
}
ctx.informTime(s"$phase ", start)
}
if (!ctx.reporter.hasErrors) Rewrites.writeBack()
for (unit <- units)
Stats.record("retained typed trees at end", unit.tpdTree.treeSize)
Expand Down
25 changes: 4 additions & 21 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package ast
import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
import Decorators._
import Decorators._, transform.SymUtils._
import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
import language.higherKinds
import typer.FrontEnd
Expand Down Expand Up @@ -70,7 +70,7 @@ object desugar {
def apply(tp: Type) = tp match {
case tp: NamedType if tp.symbol.exists && (tp.symbol.owner eq originalOwner) =>
val defctx = ctx.outersIterator.dropWhile(_.scope eq ctx.scope).next()
var local = defctx.denotNamed(tp.name).suchThat(_ is ParamOrAccessor).symbol
var local = defctx.denotNamed(tp.name).suchThat(_.isParamOrAccessor).symbol
if (local.exists) (defctx.owner.thisType select local).dealias
else {
def msg =
Expand Down Expand Up @@ -238,23 +238,6 @@ object desugar {
Nil
}

/** Fill in empty type bounds with Nothing/Any. Expand private local type parameters as follows:
*
* class C[v T]
* ==>
* class C { type v C$T; type v T = C$T }
*/
def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = {
if (tdef.mods is PrivateLocalParam) {
val tparam = cpy.TypeDef(tdef)(name = tdef.name.expandedName(ctx.owner))
.withMods(tdef.mods &~ PrivateLocal)
val alias = cpy.TypeDef(tdef)(rhs = refOfDef(tparam))
.withMods(tdef.mods & VarianceFlags | PrivateLocalParamAccessor | Synthetic)
Thicket(tparam, alias)
}
else tdef
}

@sharable private val synthetic = Modifiers(Synthetic)

private def toDefParam(tparam: TypeDef): TypeDef =
Expand Down Expand Up @@ -696,7 +679,7 @@ object desugar {

def defTree(tree: Tree)(implicit ctx: Context): Tree = tree match {
case tree: ValDef => valDef(tree)
case tree: TypeDef => if (tree.isClassDef) classDef(tree) else typeDef(tree)
case tree: TypeDef => if (tree.isClassDef) classDef(tree) else tree
case tree: DefDef => defDef(tree)
case tree: ModuleDef => moduleDef(tree)
case tree: PatDef => patDef(tree)
Expand Down Expand Up @@ -1132,7 +1115,7 @@ object desugar {
*/
def refinedTypeToClass(parent: tpd.Tree, refinements: List[Tree])(implicit ctx: Context): TypeDef = {
def stripToCore(tp: Type): List[Type] = tp match {
case tp: RefinedType if tp.argInfos.nonEmpty => tp :: Nil // parameterized class type
case tp: AppliedType => tp :: Nil
case tp: TypeRef if tp.symbol.isClass => tp :: Nil // monomorphic class type
case tp: TypeProxy => stripToCore(tp.underlying)
case AndType(tp1, tp2) => stripToCore(tp1) ::: stripToCore(tp2)
Expand Down
13 changes: 7 additions & 6 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
ta.assignType(untpd.TypeDef(sym.name, TypeTree(sym.info)), sym)

def ClassDef(cls: ClassSymbol, constr: DefDef, body: List[Tree], superArgs: List[Tree] = Nil)(implicit ctx: Context): TypeDef = {
val firstParentRef :: otherParentRefs = cls.info.parents
val firstParent = cls.typeRef.baseTypeWithArgs(firstParentRef.symbol)
val firstParent :: otherParents = cls.info.parents
val superRef =
if (cls is Trait) TypeTree(firstParent)
else {
Expand All @@ -229,7 +228,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
val constr = firstParent.decl(nme.CONSTRUCTOR).suchThat(constr => isApplicable(constr.info))
New(firstParent, constr.symbol.asTerm, superArgs)
}
val parents = superRef :: otherParentRefs.map(TypeTree(_))
val parents = superRef :: otherParents.map(TypeTree(_))

val selfType =
if (cls.classInfo.selfInfo ne NoType) ValDef(ctx.newSelfSym(cls))
Expand Down Expand Up @@ -305,7 +304,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
true
case pre: ThisType =>
pre.cls.isStaticOwner ||
tp.symbol.is(ParamOrAccessor) && !pre.cls.is(Trait) && ctx.owner.enclosingClass == pre.cls
tp.symbol.isParamOrAccessor && !pre.cls.is(Trait) && ctx.owner.enclosingClass == pre.cls
// was ctx.owner.enclosingClass.derivesFrom(pre.cls) which was not tight enough
// and was spuriously triggered in case inner class would inherit from outer one
// eg anonymous TypeMap inside TypeMap.andThen
Expand Down Expand Up @@ -381,7 +380,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
/** new C(args), calling given constructor `constr` of C */
def New(tp: Type, constr: TermSymbol, args: List[Tree])(implicit ctx: Context): Apply = {
val targs = tp.argTypes
val tycon = tp.withoutArgs(targs)
val tycon = tp.typeConstructor
New(tycon)
.select(TermRef.withSig(tycon, constr))
.appliedToTypes(targs)
Expand Down Expand Up @@ -698,8 +697,10 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
*/
def select(sym: Symbol)(implicit ctx: Context): Select = {
val tp =
if (sym.isType)
if (sym.isType) {
assert(!sym.is(TypeParam))
TypeRef(tree.tpe, sym.name.asTypeName)
}
else
TermRef.withSigAndDenot(tree.tpe, sym.name.asTermName,
sym.signature, sym.denot.asSeenFrom(tree.tpe))
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
(tycon, targs)
case TypedSplice(AppliedTypeTree(tycon, targs)) =>
(TypedSplice(tycon), targs map (TypedSplice(_)))
case TypedSplice(tpt1: Tree) =>
case TypedSplice(tpt1: tpd.Tree) =>
val tycon = tpt1.tpe.typeConstructor
val argTypes = tpt1.tpe.argTypesLo
val tycon = tpt1.tpe.withoutArgs(argTypes)
def wrap(tpe: Type) = TypeTree(tpe) withPos tpt.pos
(wrap(tycon), argTypes map wrap)
case _ =>
Expand Down
20 changes: 10 additions & 10 deletions compiler/src/dotty/tools/dotc/config/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,12 @@ object Config {
/** If this flag is set, take the fast path when comparing same-named type-aliases and types */
final val fastPathForRefinedSubtype = true

/** If this flag is set, `TypeOps.normalizeToClassRefs` will insert forwarders
* for type parameters of base classes. This is an optimization, which avoids
* long alias chains. We should not rely on the optimization, though. So changing
* the flag to false can be used for checking that everything works OK without it.
*/
final val forwardTypeParams = true

/** If this flag is set, and we compute `T1 { X = S1 }` & `T2 { X = S2 }` as a new
* upper bound of a constrained parameter, try to align the refinements by computing
/** If this flag is set, and we compute `T1[X1]` & `T2[X2]` as a new
* upper bound of a constrained parameter, try to align the arguments by computing
* `S1 =:= S2` (which might instantiate type parameters).
* This rule is contentious because it cuts the constraint set.
*
* For more info, see the comment in `TypeComparer#distributeAnd`.
* For more info, see the comment in `TypeComparer#glbArgs`.
*/
final val alignArgsInAnd = true

Expand All @@ -113,6 +106,13 @@ object Config {
*/
final val checkTypeRefCycles = false

/** If this flag is set, it is checked that class type parameters are
* only references with NoPrefix or ThisTypes as prefixes. This option
* is usally disabled, because there are still some legitimate cases where
* this can arise (e.g. for pos/Map.scala, in LambdaType.integrate).
*/
final val checkTypeParamRefs = false

/** The recursion depth for showing a summarized string */
final val summarizeDepth = 2

Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ class ScalaSettings extends Settings.SettingGroup {
val Ycheck = PhasesSetting("-Ycheck", "Check the tree at the end of")
val YcheckMods = BooleanSetting("-Ycheck-mods", "Check that symbols and their defining trees have modifiers in sync")
val debug = BooleanSetting("-Ydebug", "Increase the quantity of debugging output.")
val debugAlias = BooleanSetting("-Ydebug-alias", "Never follow alias when printing types")
val debugTrace = BooleanSetting("-Ydebug-trace", "Trace core operations")
val debugFlags = BooleanSetting("-Ydebug-flags", "Print all flags of definitions")
val debugNames = BooleanSetting("-Ydebug-names", "Show internal representation of names")
Expand All @@ -87,7 +86,8 @@ class ScalaSettings extends Settings.SettingGroup {
val YmethodInfer = BooleanSetting("-Yinfer-argument-types", "Infer types for arguments of overriden methods.")
val YtraceContextCreation = BooleanSetting("-Ytrace-context-creation", "Store stack trace of context creations.")
val YshowSuppressedErrors = BooleanSetting("-Yshow-suppressed-errors", "Also show follow-on errors and warnings that are normally supressed.")
val Yheartbeat = BooleanSetting("-Yheartbeat", "show heartbeat stack trace of compiler operations.")
val YdetailedStats = BooleanSetting("-Ydetailed-stats", "show detailed internal compiler stats (needs Stats.enabled to be set to true).")
val Yheartbeat = BooleanSetting("-Ydetailed-stats", "show heartbeat stack trace of compiler operations (needs Stats.enabled to be set to true).")
val Yprintpos = BooleanSetting("-Yprintpos", "show tree positions.")
val YnoDeepSubtypes = BooleanSetting("-Yno-deep-subtypes", "throw an exception on deep subtyping call stacks.")
val YnoPatmatOpt = BooleanSetting("-Yno-patmat-opt", "disable all pattern matching optimizations.")
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Annotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ object Annotations {

private def resolveConstructor(atp: Type, args:List[Tree])(implicit ctx: Context): Tree = {
val targs = atp.argTypes
tpd.applyOverloaded(New(atp withoutArgs targs), nme.CONSTRUCTOR, args, targs, atp, isAnnotConstructor = true)
tpd.applyOverloaded(New(atp.typeConstructor), nme.CONSTRUCTOR, args, targs, atp, isAnnotConstructor = true)
}

def applyResolve(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation = {
Expand Down
42 changes: 33 additions & 9 deletions compiler/src/dotty/tools/dotc/core/CheckRealizable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ object CheckRealizable {
class HasProblemBounds(typ: SingleDenotation)(implicit ctx: Context)
extends Realizability(i" has a member $typ with possibly conflicting bounds ${typ.info.bounds.lo} <: ... <: ${typ.info.bounds.hi}")

class HasProblemBaseArg(typ: Type, argBounds: TypeBounds)(implicit ctx: Context)
extends Realizability(i" has a base type $typ with possibly conflicting parameter bounds ${argBounds.lo} <: ... <: ${argBounds.hi}")

class HasProblemBase(base1: Type, base2: Type)(implicit ctx: Context)
extends Realizability(i" has conflicting base types $base1 and $base2")

class HasProblemField(fld: SingleDenotation, problem: Realizability)(implicit ctx: Context)
extends Realizability(i" has a member $fld which is not a legal path\n since ${fld.symbol.name}: ${fld.info}${problem.msg}")

Expand Down Expand Up @@ -89,18 +95,36 @@ class CheckRealizable(implicit ctx: Context) {
else boundsRealizability(tp).andAlso(memberRealizability(tp))
}

/** `Realizable` if `tp` has good bounds, a `HasProblemBounds` instance
* pointing to a bad bounds member otherwise.
/** `Realizable` if `tp` has good bounds, a `HasProblem...` instance
* pointing to a bad bounds member otherwise. "Has good bounds" means:
*
* - all type members have good bounds
* - all base types are class types, and if their arguments are wildcards
* they have good bounds.
*/
private def boundsRealizability(tp: Type) = {
def hasBadBounds(mbr: SingleDenotation) = {
val bounds = mbr.info.bounds
!(bounds.lo <:< bounds.hi)
}
tp.nonClassTypeMembers.find(hasBadBounds) match {
case Some(mbr) => new HasProblemBounds(mbr)
case _ => Realizable
val mbrProblems =
for {
mbr <- tp.nonClassTypeMembers
if !(mbr.info.loBound <:< mbr.info.hiBound)
}
yield new HasProblemBounds(mbr)

def baseTypeProblems(base: Type) = base match {
case AndType(base1, base2) =>
new HasProblemBase(base1, base2) :: Nil
case base =>
base.argInfos.collect {
case bounds @ TypeBounds(lo, hi) if !(lo <:< hi) =>
new HasProblemBaseArg(base, bounds)
}
}
val baseProblems =
tp.baseClasses.map(_.baseTypeOf(tp)).flatMap(baseTypeProblems)

(((Realizable: Realizability)
/: mbrProblems)(_ andAlso _)
/: baseProblems)(_ andAlso _)
}

/** `Realizable` if all of `tp`'s non-struct fields have realizable types,
Expand Down
26 changes: 21 additions & 5 deletions compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Types._, Contexts._, Symbols._
import Decorators._
import config.Config
import config.Printers.{constr, typr}
import TypeApplications.EtaExpansion
import TypeApplications.{EtaExpansion, TypeParamInfo}
import collection.mutable

/** Methods for adding constraints and solving them.
Expand Down Expand Up @@ -194,9 +194,15 @@ trait ConstraintHandling {
final def approximation(param: TypeParamRef, fromBelow: Boolean): Type = {
val avoidParam = new TypeMap {
override def stopAtStatic = true
def avoidInArg(arg: Type, formal: TypeParamInfo): Type =
if (param.occursIn(arg)) TypeBounds.empty else arg
def apply(tp: Type) = mapOver {
tp match {
case tp: RefinedType if param occursIn tp.refinedInfo => tp.parent
case tp @ AppliedType(tycon, args) =>
tp.derivedAppliedType(tycon,
args.zipWithConserve(tycon.typeParams)(avoidInArg))
case tp: RefinedType if param occursIn tp.refinedInfo =>
tp.parent
case tp: WildcardType =>
val bounds = tp.optBounds.orElse(TypeBounds.empty).bounds
// Try to instantiate the wildcard to a type that is known to conform to it.
Expand Down Expand Up @@ -306,7 +312,12 @@ trait ConstraintHandling {
/** The current bounds of type parameter `param` */
final def bounds(param: TypeParamRef): TypeBounds = {
val e = constraint.entry(param)
if (e.exists) e.bounds else param.binder.paramInfos(param.paramNum)
if (e.exists) e.bounds
else {
val pinfos = param.binder.paramInfos
if (pinfos != null) pinfos(param.paramNum) // pinfos == null happens in pos/i536.scala
else TypeBounds.empty
}
}

/** Add type lambda `tl`, possibly with type variables `tvars`, to current constraint
Expand All @@ -318,7 +329,7 @@ trait ConstraintHandling {
checkPropagated(i"initialized $tl") {
constraint = constraint.add(tl, tvars)
tl.paramNames.indices.forall { i =>
val param = TypeParamRef(tl, i)
val param = tl.paramRefs(i)
val bounds = constraint.nonParamBounds(param)
val lower = constraint.lower(param)
val upper = constraint.upper(param)
Expand Down Expand Up @@ -376,7 +387,12 @@ trait ConstraintHandling {
else tp

def addParamBound(bound: TypeParamRef) =
if (fromBelow) addLess(bound, param) else addLess(param, bound)
constraint.entry(param) match {
case _: TypeBounds =>
if (fromBelow) addLess(bound, param) else addLess(param, bound)
case tp =>
if (fromBelow) isSubType(bound, tp) else isSubType(tp, bound)
}

/** Drop all constrained parameters that occur at the toplevel in `bound` and
* handle them by `addLess` calls.
Expand Down
17 changes: 8 additions & 9 deletions compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import NameOps._
import Uniques._
import SymDenotations._
import Comments._
import Flags.ParamAccessor
import util.Positions._
import ast.Trees._
import ast.untpd
Expand Down Expand Up @@ -335,7 +334,7 @@ object Contexts {
* from constructor parameters to class parameter accessors.
*/
def superCallContext: Context = {
val locals = newScopeWith(owner.asClass.paramAccessors: _*)
val locals = newScopeWith(owner.typeParams ++ owner.asClass.paramAccessors: _*)
superOrThisCallContext(owner.primaryConstructor, locals)
}

Expand Down Expand Up @@ -604,20 +603,20 @@ object Contexts {
override def hash(x: Type): Int = x.hash
}

/** A table for hash consing unique refined types */
private[dotc] val uniqueRefinedTypes = new RefinedUniques
/** A table for hash consing unique applied types */
private[dotc] val uniqueAppliedTypes = new AppliedUniques

/** A table for hash consing unique named types */
private[core] val uniqueNamedTypes = new NamedTypeUniques

/** A table for hash consing unique type bounds */
private[core] val uniqueTypeAliases = new TypeAliasUniques
/** A table for hash consing unique symbolic named types */
private[core] val uniqueWithFixedSyms = new WithFixedSymUniques

private def uniqueSets = Map(
"uniques" -> uniques,
"uniqueRefinedTypes" -> uniqueRefinedTypes,
"uniqueNamedTypes" -> uniqueNamedTypes,
"uniqueTypeAliases" -> uniqueTypeAliases)
"uniqueAppliedTypes" -> uniqueAppliedTypes,
"uniqueWithFixedSyms" -> uniqueWithFixedSyms,
"uniqueNamedTypes" -> uniqueNamedTypes)

/** A map that associates label and size of all uniques sets */
def uniquesSizes: Map[String, Int] = uniqueSets.mapValues(_.size)
Expand Down
Loading