blob: 2ac7f041441e1521d9c9f2959b786e08cb976d28 (
plain) (
tree)
|
|
// See comment at end of file.
object Test {
abstract class Settings {}
abstract class Grist
{ self =>
type settingsType <: Settings
type moduleType <: Module {type settingsType = self.settingsType}
val module: moduleType
}
abstract class Tool
{ self =>
type settingsType <: Settings
type moduleType = Module { type settingsType = self.settingsType }
type gristType = Grist { type moduleType <: self.moduleType; type settingsType <: self.settingsType }
def inputGrist: List[gristType]
}
abstract class Module
{ self =>
type settingsType <: Settings
final type commonModuleType = Module {type settingsType = self.settingsType}
type selfType >: self.type <: commonModuleType
// BTW: if we use the commented out type decls, the code compiles successfully
// type gristType = Grist {type settingsType <: self.settingsType; type moduleType <: commonModuleType }
val tools: List[Tool {type settingsType = self.settingsType}]
protected def f: List[commonModuleType] =
{
val inputGrists = tools.flatMap(_.inputGrist)
// This produces an unhygienic closure for _.inputGrist.
// Pickling will log:
//
// [...] pickling reference to as yet undefined value _$1 in method $anonfun
//
// More info can be produced by uncommenting these two lines in
// Namer#valOrDefDefSig:
//
//println(i"lifting $rhsType over $paramss -> $hygienicType = ${tpt.tpe}")
//println(TypeComparer.explained { implicit ctx => hygienicType <:< tpt.tpe })
//
// Tracing the subtype statement (over 1600+ lines!) shows that the TypeComparer thinks that the
// following subtype judgement is true:
//
// Test.Grist{
// moduleType <: Test.Module{settingsType = Module.this.settingsType};
// settingsType <: Module.this.settingsType
// } <:< Test.Grist{moduleType <: _$1.moduleType; settingsType <: _$1.settingsType}
//
// Therefore, a type variable which has the second type as lower bound does not get
// the (hygienic) first type as new lower bound. Clearly something is wrong in the subtype
// derivation here. It would be important to figure out what.
???
// inputGrists.map(_.module)
}
}
}
|