Skip to content

Commit d0aaa86

Browse files
committed
SI-8023 Address review comments around typedHigherKindedType
- Make `WildCardType` kind polymorphic - Factory methods for expected kinds. They are still just `Type`-s, though. - Check if the type parameter is initialized, rather than its owner. - Take advantage of these to cleanup `typedAppliedTypeTree` TODO: is this comment totally accurate? If so, should we refactor `Kind.FromParams(tparams)` to `Kind.Arity(tparams.length)`? // @m: kind-arity checking is done here and in adapt, // full kind-checking is in checkKindBounds (in Infer)
1 parent a89000b commit d0aaa86

File tree

3 files changed

+18
-18
lines changed

3 files changed

+18
-18
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3835,7 +3835,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
38353835
// as we don't know which alternative to choose... here we do
38363836
map2Conserve(args, tparams) {
38373837
//@M! the polytype denotes the expected kind
3838-
(arg, tparam) => typedHigherKindedType(arg, mode, GenPolyType(tparam.typeParams, AnyTpe))
3838+
(arg, tparam) => typedHigherKindedType(arg, mode, Kind.FromParams(tparam.typeParams))
38393839
}
38403840
} else // @M: there's probably something wrong when args.length != tparams.length... (triggered by bug #320)
38413841
// Martin, I'm using fake trees, because, if you use args or arg.map(typedType),
@@ -4880,20 +4880,17 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
48804880
if (sameLength(tparams, args)) {
48814881
// @M: kind-arity checking is done here and in adapt, full kind-checking is in checkKindBounds (in Infer)
48824882
val args1 = map2Conserve(args, tparams) { (arg, tparam) =>
4883-
//@M! the polytype denotes the expected kind
4884-
def pt = GenPolyType(tparam.typeParams, AnyTpe)
4885-
4886-
// if symbol hasn't been fully loaded, can't check kind-arity
4887-
// ... except, if we're in a pattern, where we can and must (SI-8023)
4888-
if (mode.typingPatternOrTypePat) {
4889-
tparam.initialize
4890-
typedHigherKindedType(arg, mode, pt)
4883+
def ptParams = Kind.FromParams(tparam.typeParams)
4884+
4885+
// if symbol hasn't been fully loaded, can't check kind-arity except when we're in a pattern,
4886+
// where we can (we can't take part in F-Bounds) and must (SI-8023)
4887+
val pt = if (mode.typingPatternOrTypePat) {
4888+
tparam.initialize; ptParams
48914889
}
4892-
else if (isComplete)
4893-
typedHigherKindedType(arg, mode, pt)
4894-
else
4895-
// This overload (without pt) allows type constructors, as we don't don't know the allowed kind.
4896-
typedHigherKindedType(arg, mode)
4890+
else if (isComplete) ptParams
4891+
else Kind.Wildcard
4892+
4893+
typedHigherKindedType(arg, mode, pt)
48974894
}
48984895
val argtypes = args1 map (_.tpe)
48994896

@@ -5080,8 +5077,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
50805077

50815078
// @M maybe the well-kindedness check should be done when checking the type arguments conform to the type parameters' bounds?
50825079
val args1 = if (sameLength(args, tparams)) map2Conserve(args, tparams) {
5083-
//@M! the polytype denotes the expected kind
5084-
(arg, tparam) => typedHigherKindedType(arg, mode, GenPolyType(tparam.typeParams, AnyTpe))
5080+
(arg, tparam) => typedHigherKindedType(arg, mode, Kind.FromParams(tparam.typeParams))
50855081
}
50865082
else {
50875083
//@M this branch is correctly hit for an overloaded polymorphic type. It also has to handle erroneous cases.
@@ -5451,9 +5447,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
54515447
/** Types a (fully parameterized) type tree */
54525448
def typedType(tree: Tree): Tree = typedType(tree, NOmode)
54535449

5454-
/** Types a higher-kinded type tree -- pt denotes the expected kind*/
5450+
/** Types a higher-kinded type tree -- pt denotes the expected kind and must be one of `Kind.WildCard` and `Kind.FromParams` */
54555451
def typedHigherKindedType(tree: Tree, mode: Mode, pt: Type): Tree =
5456-
if (pt.typeParams.isEmpty) typedType(tree, mode) // kind is known and it's *
5452+
if (pt != Kind.Wildcard && pt.typeParams.isEmpty) typedType(tree, mode) // kind is known and it's *
54575453
else context withinTypeConstructorAllowed typed(tree, NOmode, pt)
54585454

54595455
def typedHigherKindedType(tree: Tree, mode: Mode): Tree =

src/reflect/scala/reflect/internal/Kinds.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ trait Kinds {
326326
private[internal] object StringState {
327327
def empty: StringState = StringState(Seq())
328328
}
329+
def FromParams(tparams: List[Symbol]): Type = GenPolyType(tparams, AnyTpe)
330+
def Wildcard: Type = WildcardType
329331
}
330332
class ProperTypeKind(val bounds: TypeBounds) extends Kind {
331333
import Kind.StringState

test/files/pos/t8023b.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// this fails with naive attempts to fix SI-8023
2+
trait T[A <: T[A]]

0 commit comments

Comments
 (0)