Skip to content

Commit e8df9a0

Browse files
committed
Avoid SO in typetag search
1 parent f7bec70 commit e8df9a0

File tree

1 file changed

+95
-89
lines changed

1 file changed

+95
-89
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 95 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -560,99 +560,105 @@ trait Implicits { self: Typer =>
560560
/** If `formal` is of the form ClassTag[T], where `T` is a class type,
561561
* synthesize a class tag for `T`.
562562
*/
563-
def synthesizedClassTag(formal: Type)(implicit ctx: Context): Tree =
564-
formal.argInfos match {
565-
case arg :: Nil =>
566-
fullyDefinedType(arg, "ClassTag argument", pos) match {
567-
case defn.ArrayOf(elemTp) =>
568-
val etag = inferImplicitArg(defn.ClassTagType.appliedTo(elemTp), pos)
569-
if (etag.tpe.isError) EmptyTree else etag.select(nme.wrap)
570-
case tp if hasStableErasure(tp) && !defn.isBottomClass(tp.typeSymbol) =>
571-
ref(defn.ClassTagModule)
572-
.select(nme.apply)
573-
.appliedToType(tp)
574-
.appliedTo(clsOf(erasure(tp)))
575-
.withPos(pos)
576-
case tp =>
577-
EmptyTree
578-
}
579-
case _ =>
580-
EmptyTree
581-
}
563+
def synthesizedClassTag(formal: Type): Tree = formal.argInfos match {
564+
case arg :: Nil =>
565+
fullyDefinedType(arg, "ClassTag argument", pos) match {
566+
case defn.ArrayOf(elemTp) =>
567+
val etag = inferImplicitArg(defn.ClassTagType.appliedTo(elemTp), pos)
568+
if (etag.tpe.isError) EmptyTree else etag.select(nme.wrap)
569+
case tp if hasStableErasure(tp) && !defn.isBottomClass(tp.typeSymbol) =>
570+
ref(defn.ClassTagModule)
571+
.select(nme.apply)
572+
.appliedToType(tp)
573+
.appliedTo(clsOf(erasure(tp)))
574+
.withPos(pos)
575+
case tp =>
576+
EmptyTree
577+
}
578+
case _ =>
579+
EmptyTree
580+
}
582581

583-
def synthesizedTypeTag(tpe: Type)(implicit ctx: Context): Tree = {
584-
var ok = true
585-
586-
def toParamSyms(tpe: LambdaType): List[Symbol { type ThisName = tpe.ThisName }] =
587-
(tpe.paramNames, tpe.paramInfos).zipped.map((name, bounds) =>
588-
ctx.newSymbol(ctx.owner, name, Param, bounds))
589-
590-
def toTreeAndDefs(tpe: Type): (List[TypeSymbol], List[List[TermSymbol]], Tree) = tpe match {
591-
case tpe: TypeLambda =>
592-
val tsyms = toParamSyms(tpe)
593-
val (Nil, vsymss, result) = toTreeAndDefs(tpe.resultType.substParams(tpe, tsyms.map(_.typeRef)))
594-
(tsyms, vsymss, result)
595-
case tpe: TermLambda =>
596-
val vsyms = toParamSyms(tpe)
597-
val (Nil, vsymss, result) = toTreeAndDefs(tpe.resultType.substParams(tpe, vsyms.map(_.termRef)))
598-
(Nil, vsyms :: vsymss, result)
599-
case _ =>
600-
(Nil, Nil, toTree(tpe))
601-
}
582+
def synthesizedTypeTag(formal: Type): Tree = formal.argInfos match {
583+
case tpe :: Nil =>
584+
var ok = true
585+
586+
def toParamSyms(tpe: LambdaType): List[Symbol { type ThisName = tpe.ThisName }] =
587+
(tpe.paramNames, tpe.paramInfos).zipped.map((name, bounds) =>
588+
ctx.newSymbol(ctx.owner, name, Param, bounds))
589+
590+
def toTreeAndDefs(tpe: Type): (List[TypeSymbol], List[List[TermSymbol]], Tree) = tpe match {
591+
case tpe: TypeLambda =>
592+
val tsyms = toParamSyms(tpe)
593+
val (Nil, vsymss, result) = toTreeAndDefs(tpe.resultType.substParams(tpe, tsyms.map(_.typeRef)))
594+
(tsyms, vsymss, result)
595+
case tpe: TermLambda =>
596+
val vsyms = toParamSyms(tpe)
597+
val (Nil, vsymss, result) = toTreeAndDefs(tpe.resultType.substParams(tpe, vsyms.map(_.termRef)))
598+
(Nil, vsyms :: vsymss, result)
599+
case _ =>
600+
(Nil, Nil, toTree(tpe))
601+
}
602602

603-
def refinedToTree(tpe: Type, refinements: List[Tree], refineCls: ClassSymbol): Tree = tpe.stripTypeVar match {
604-
case RefinedType(parent, rname, rinfo) =>
605-
val isMethod = rinfo.isInstanceOf[MethodOrPoly]
606-
val sym = ctx.newSymbol(refineCls, rname, if (isMethod) Method else EmptyFlags, rinfo)
607-
val refinement = rname match {
608-
case rname: TypeName =>
609-
TypeDef(sym.asType)
610-
case rname: TermName =>
611-
if (isMethod) {
612-
val (tparams, vparamss, resTpt) = toTreeAndDefs(rinfo.asInstanceOf[MethodOrPoly])
613-
DefDef(sym.asTerm, tparams, vparamss, resTpt.tpe, EmptyTree)
614-
}
615-
else ValDef(sym.asTerm)
616-
}
617-
refinedToTree(parent, refinement :: refinements, refineCls)
618-
case _ =>
619-
RefinedTypeTree(toTree(tpe), refinements, refineCls)
620-
}
603+
def refinedToTree(tpe: Type, refinements: List[Tree], refineCls: ClassSymbol): Tree = tpe.stripTypeVar match {
604+
case RefinedType(parent, rname, rinfo) =>
605+
val isMethod = rinfo.isInstanceOf[MethodOrPoly]
606+
val sym = ctx.newSymbol(refineCls, rname, if (isMethod) Method else EmptyFlags, rinfo)
607+
val refinement = rname match {
608+
case rname: TypeName =>
609+
TypeDef(sym.asType)
610+
case rname: TermName =>
611+
if (isMethod) {
612+
val (tparams, vparamss, resTpt) = toTreeAndDefs(rinfo.asInstanceOf[MethodOrPoly])
613+
DefDef(sym.asTerm, tparams, vparamss, resTpt.tpe, EmptyTree)
614+
}
615+
else ValDef(sym.asTerm)
616+
}
617+
refinedToTree(parent, refinement :: refinements, refineCls)
618+
case _ =>
619+
RefinedTypeTree(toTree(tpe), refinements, refineCls)
620+
}
621621

622-
def toTree(tpe: Type): Tree = tpe.stripTypeVar match {
623-
case tpe @ TypeRef(NoPrefix, _) =>
624-
val tag = inferImplicitArg(defn.QuotedTypeType.appliedTo(tpe), pos)
625-
ok &= !tag.tpe.isInstanceOf[SearchFailureType]
626-
tag.select(defn.QuotedType_~)
627-
case tpe: NamedType =>
628-
ref(tpe)
629-
case tpe: SingletonType =>
630-
singleton(tpe)
631-
case AppliedType(tycon, args) =>
632-
AppliedTypeTree(toTree(tycon), args.map(toTree))
633-
case AndType(l, r) =>
634-
AndTypeTree(toTree(l), toTree(r))
635-
case OrType(l, r) =>
636-
OrTypeTree(toTree(l), toTree(r))
637-
case tp: HKTypeLambda =>
638-
val tsyms = toParamSyms(tp)
639-
toTree(tp.resType.substParams(tp, tsyms.map(_.typeRef)))
640-
case tpe: RecType =>
641-
refinedToTree(tpe.parent, Nil, ctx.newRefinedClassSymbol())
642-
case tpe: RefinedType =>
643-
refinedToTree(tpe, Nil, ctx.newRefinedClassSymbol())
644-
case TypeAlias(alias) =>
645-
val aliasTree = toTree(alias)
646-
TypeBoundsTree(aliasTree, aliasTree)
647-
case TypeBounds(lo, hi) =>
648-
TypeBoundsTree(toTree(lo), toTree(hi))
649-
case _ =>
650-
EmptyTree
651-
}
622+
def toTree(tpe: Type): Tree = tpe.stripTypeVar match {
623+
case tpe @ TypeRef(NoPrefix, _) =>
624+
inferImplicit(defn.QuotedTypeType.appliedTo(tpe), EmptyTree, pos) match {
625+
case SearchSuccess(tag, _, _) =>
626+
tag.select(defn.QuotedType_~)
627+
case _ =>
628+
ok = false
629+
EmptyTree
630+
}
631+
case tpe: NamedType =>
632+
ref(tpe)
633+
case tpe: SingletonType =>
634+
singleton(tpe)
635+
case AppliedType(tycon, args) =>
636+
AppliedTypeTree(toTree(tycon), args.map(toTree))
637+
case AndType(l, r) =>
638+
AndTypeTree(toTree(l), toTree(r))
639+
case OrType(l, r) =>
640+
OrTypeTree(toTree(l), toTree(r))
641+
case tp: HKTypeLambda =>
642+
val tsyms = toParamSyms(tp)
643+
toTree(tp.resType.substParams(tp, tsyms.map(_.typeRef)))
644+
case tpe: RecType =>
645+
refinedToTree(tpe.parent, Nil, ctx.newRefinedClassSymbol())
646+
case tpe: RefinedType =>
647+
refinedToTree(tpe, Nil, ctx.newRefinedClassSymbol())
648+
case TypeAlias(alias) =>
649+
val aliasTree = toTree(alias)
650+
TypeBoundsTree(aliasTree, aliasTree)
651+
case TypeBounds(lo, hi) =>
652+
TypeBoundsTree(toTree(lo), toTree(hi))
653+
case _ =>
654+
EmptyTree
655+
}
652656

653-
val tag = toTree(tpe)
654-
if (ok) ref(defn.typeQuoteMethod).appliedToTypeTrees(tag :: Nil)
655-
else EmptyTree
657+
val tag = toTree(tpe)
658+
if (ok) ref(defn.typeQuoteMethod).appliedToTypeTrees(tag :: Nil)
659+
else EmptyTree
660+
case _ =>
661+
EmptyTree
656662
}
657663

658664
/** If `formal` is of the form Eq[T, U], where no `Eq` instance exists for

0 commit comments

Comments
 (0)