Skip to content

Commit a45d3e5

Browse files
committed
unifies handling of T's in various analyses of Foo[T]'s
1 parent ee646e9 commit a45d3e5

File tree

3 files changed

+50
-42
lines changed

3 files changed

+50
-42
lines changed

src/compiler/scala/reflect/macros/util/Helpers.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ trait Helpers {
5454
*
5555
* @see Metalevels.scala for more information and examples about metalevels
5656
*/
57-
def increaseMetalevel(pre: Type, tp: Type): Type = dealiasAndRewrap(tp) {
57+
def increaseMetalevel(pre: Type, tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) {
5858
case tp => typeRef(pre, MacroContextExprClass, List(tp))
5959
}
6060

@@ -64,8 +64,8 @@ trait Helpers {
6464
*
6565
* @see Metalevels.scala for more information and examples about metalevels
6666
*/
67-
def decreaseMetalevel(tp: Type): Type = dealiasAndRewrap(tp) {
67+
def decreaseMetalevel(tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) {
6868
case ExprClassOf(runtimeType) => runtimeType
69-
case _ => AnyClass.tpe // so that macro impls with rhs = ??? don't screw up our inference
69+
case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference
7070
}
7171
}

src/reflect/scala/reflect/internal/Definitions.scala

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -407,10 +407,6 @@ trait Definitions extends api.StandardDefinitions {
407407
lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe))
408408
lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe))
409409

410-
def dropByName(tp: Type): Type = tp match {
411-
case TypeRef(_, ByNameParamClass, arg :: Nil) => arg
412-
case _ => tp
413-
}
414410
def isByNameParamType(tp: Type) = tp.typeSymbol == ByNameParamClass
415411
def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass
416412
def isJavaRepeatedParamType(tp: Type) = tp.typeSymbol == JavaRepeatedParamClass
@@ -431,29 +427,15 @@ trait Definitions extends api.StandardDefinitions {
431427
case _ => false
432428
}
433429

434-
def repeatedToSingle(tp: Type): Type = tp match {
435-
case TypeRef(_, RepeatedParamClass, arg :: Nil) => arg
436-
case _ => tp
437-
}
438-
439-
def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match {
440-
case TypeRef(_, RepeatedParamClass, arg :: Nil) => seqType(arg)
441-
case _ => tp
442-
}
443-
444-
def seqToRepeated(tp: Type): Type = (tp baseType SeqClass) match {
445-
case TypeRef(_, SeqClass, arg :: Nil) => scalaRepeatedType(arg)
446-
case _ => tp
447-
}
448-
449-
def isReferenceArray(tp: Type) = tp match {
450-
case TypeRef(_, ArrayClass, arg :: Nil) => arg <:< AnyRefTpe
451-
case _ => false
452-
}
453-
def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match {
454-
case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == elem
455-
case _ => false
456-
}
430+
// wrapping and unwrapping
431+
def dropByName(tp: Type): Type = elementExtract(ByNameParamClass, tp) orElse tp
432+
def repeatedToSingle(tp: Type): Type = elementExtract(RepeatedParamClass, tp) orElse tp
433+
def repeatedToSeq(tp: Type): Type = elementTransform(RepeatedParamClass, tp)(seqType) orElse tp
434+
def seqToRepeated(tp: Type): Type = elementTransform(SeqClass, tp)(scalaRepeatedType) orElse tp
435+
def isReferenceArray(tp: Type) = elementTest(ArrayClass, tp)(_ <:< AnyRefTpe)
436+
def isArrayOfSymbol(tp: Type, elem: Symbol) = elementTest(ArrayClass, tp)(_.typeSymbol == elem)
437+
def elementType(container: Symbol, tp: Type): Type = elementExtract(container, tp)
438+
object ExprClassOf { def unapply(tp: Type): Option[Type] = elementExtractOption(ExprClass, tp) }
457439

458440
// collections classes
459441
lazy val ConsClass = requiredClass[scala.collection.immutable.::[_]]
@@ -512,13 +494,6 @@ trait Definitions extends api.StandardDefinitions {
512494
lazy val ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr))
513495
def ExprSplice = ExprClass.map(sym => getMemberMethod(sym, nme.splice))
514496
def ExprValue = ExprClass.map(sym => getMemberMethod(sym, nme.value))
515-
object ExprClassOf {
516-
def unapply(tpe: Type): Option[Type] = tpe.dealias match {
517-
case ExistentialType(_, underlying) => unapply(underlying)
518-
case TypeRef(_, ExprClass, t :: Nil) => Some(t)
519-
case _ => None
520-
}
521-
}
522497

523498
lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]]
524499
lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]]
@@ -707,11 +682,6 @@ trait Definitions extends api.StandardDefinitions {
707682
(sym eq PartialFunctionClass) || (sym eq AbstractPartialFunctionClass)
708683
}
709684

710-
def elementType(container: Symbol, tp: Type): Type = tp match {
711-
case TypeRef(_, `container`, arg :: Nil) => arg
712-
case _ => NoType
713-
}
714-
715685
def arrayType(arg: Type) = appliedType(ArrayClass, arg)
716686
def byNameType(arg: Type) = appliedType(ByNameParamClass, arg)
717687
def iteratorOfType(tp: Type) = appliedType(IteratorClass, tp)

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,6 +2436,7 @@ trait Types
24362436
else
24372437
super.prefixString
24382438
)
2439+
def copy(pre: Type = this.pre, sym: Symbol = this.sym, args: List[Type] = this.args) = TypeRef(pre, sym, args)
24392440
override def kind = "TypeRef"
24402441
}
24412442

@@ -3700,6 +3701,43 @@ trait Types
37003701
object unwrapToStableClass extends ClassUnwrapper(existential = false) { }
37013702
object unwrapWrapperTypes extends TypeUnwrapper(true, true, true, true) { }
37023703

3704+
def elementExtract(container: Symbol, tp: Type): Type = {
3705+
assert(!container.isAliasType, container)
3706+
unwrapWrapperTypes(tp baseType container).dealiasWiden match {
3707+
case TypeRef(_, `container`, arg :: Nil) => arg
3708+
case _ => NoType
3709+
}
3710+
}
3711+
def elementExtractOption(container: Symbol, tp: Type): Option[Type] = {
3712+
elementExtract(container, tp) match {
3713+
case NoType => None
3714+
case tp => Some(tp)
3715+
}
3716+
}
3717+
def elementTest(container: Symbol, tp: Type)(f: Type => Boolean): Boolean = {
3718+
elementExtract(container, tp) match {
3719+
case NoType => false
3720+
case tp => f(tp)
3721+
}
3722+
}
3723+
def elementTransform(container: Symbol, tp: Type)(f: Type => Type): Type = {
3724+
elementExtract(container, tp) match {
3725+
case NoType => NoType
3726+
case tp => f(tp)
3727+
}
3728+
}
3729+
3730+
def transparentShallowTransform(container: Symbol, tp: Type)(f: Type => Type): Type = {
3731+
def loop(tp: Type): Type = tp match {
3732+
case tp @ AnnotatedType(_, underlying, _) => tp.copy(underlying = loop(underlying))
3733+
case tp @ ExistentialType(_, underlying) => tp.copy(underlying = loop(underlying))
3734+
case tp @ PolyType(_, resultType) => tp.copy(resultType = loop(resultType))
3735+
case tp @ NullaryMethodType(resultType) => tp.copy(resultType = loop(resultType))
3736+
case tp => elementTransform(container, tp)(el => appliedType(container, f(el))).orElse(f(tp))
3737+
}
3738+
loop(tp)
3739+
}
3740+
37033741
/** Repack existential types, otherwise they sometimes get unpacked in the
37043742
* wrong location (type inference comes up with an unexpected skolem)
37053743
*/

0 commit comments

Comments
 (0)