@@ -554,9 +554,7 @@ trait Implicits { self: Typer =>
554
554
}
555
555
556
556
/** Find an implicit argument for parameter `formal`.
557
- * @param error An error handler that gets an error message parameter
558
- * which is itself parameterized by another string,
559
- * indicating where the implicit parameter is needed
557
+ * Return a failure as a SearchFailureType in the type of the returned tree.
560
558
*/
561
559
def inferImplicitArg (formal : Type , pos : Position )(implicit ctx : Context ): Tree = {
562
560
@@ -583,6 +581,81 @@ trait Implicits { self: Typer =>
583
581
EmptyTree
584
582
}
585
583
584
+ def synthesizedTypeTag (tpe : Type )(implicit ctx : Context ): Tree = {
585
+ var ok = true
586
+
587
+ def toParamSyms (tpe : LambdaType ): List [Symbol { type ThisName = tpe.ThisName }] =
588
+ (tpe.paramNames, tpe.paramInfos).zipped.map((name, bounds) =>
589
+ ctx.newSymbol(ctx.owner, name, Param , bounds))
590
+
591
+ def toTreeAndDefs (tpe : Type ): (List [TypeSymbol ], List [List [TermSymbol ]], Tree ) = tpe match {
592
+ case tpe : TypeLambda =>
593
+ val tsyms = toParamSyms(tpe)
594
+ val (Nil , vsymss, result) = toTreeAndDefs(tpe.resultType.substParams(tpe, tsyms.map(_.typeRef)))
595
+ (tsyms, vsymss, result)
596
+ case tpe : TermLambda =>
597
+ val vsyms = toParamSyms(tpe)
598
+ val (Nil , vsymss, result) = toTreeAndDefs(tpe.resultType.substParams(tpe, vsyms.map(_.termRef)))
599
+ (Nil , vsyms :: vsymss, result)
600
+ case _ =>
601
+ (Nil , Nil , toTree(tpe))
602
+ }
603
+
604
+ def refinedToTree (tpe : Type , refinements : List [Tree ], refineCls : ClassSymbol ): Tree = tpe.stripTypeVar match {
605
+ case RefinedType (parent, rname, rinfo) =>
606
+ val isMethod = rinfo.isInstanceOf [MethodOrPoly ]
607
+ val sym = ctx.newSymbol(refineCls, rname, if (isMethod) Method else EmptyFlags , rinfo)
608
+ val refinement = rname match {
609
+ case rname : TypeName =>
610
+ TypeDef (sym.asType)
611
+ case rname : TermName =>
612
+ if (isMethod) {
613
+ val (tparams, vparamss, resTpt) = toTreeAndDefs(rinfo.asInstanceOf [MethodOrPoly ])
614
+ DefDef (sym.asTerm, tparams, vparamss, resTpt.tpe, EmptyTree )
615
+ }
616
+ else ValDef (sym.asTerm)
617
+ }
618
+ refinedToTree(parent, refinement :: refinements, refineCls)
619
+ case _ =>
620
+ RefinedTypeTree (toTree(tpe), refinements, refineCls)
621
+ }
622
+
623
+ def toTree (tpe : Type ): Tree = tpe.stripTypeVar match {
624
+ case tpe @ TypeRef (NoPrefix , _) =>
625
+ val tag = inferImplicitArg(defn.QuotedTypeType .appliedTo(tpe), pos)
626
+ ok &= ! tag.tpe.isInstanceOf [SearchFailureType ]
627
+ tag.select(defn.QuotedType_~ )
628
+ case tpe : NamedType =>
629
+ ref(tpe)
630
+ case tpe : SingletonType =>
631
+ singleton(tpe)
632
+ case AppliedType (tycon, args) =>
633
+ AppliedTypeTree (toTree(tycon), args.map(toTree))
634
+ case AndType (l, r) =>
635
+ AndTypeTree (toTree(l), toTree(r))
636
+ case OrType (l, r) =>
637
+ OrTypeTree (toTree(l), toTree(r))
638
+ case tp : HKTypeLambda =>
639
+ val tsyms = toParamSyms(tp)
640
+ toTree(tp.resType.substParams(tp, tsyms.map(_.typeRef)))
641
+ case tpe : RecType =>
642
+ refinedToTree(tpe.parent, Nil , ctx.newRefinedClassSymbol())
643
+ case tpe : RefinedType =>
644
+ refinedToTree(tpe, Nil , ctx.newRefinedClassSymbol())
645
+ case TypeAlias (alias) =>
646
+ val aliasTree = toTree(alias)
647
+ TypeBoundsTree (aliasTree, aliasTree)
648
+ case TypeBounds (lo, hi) =>
649
+ TypeBoundsTree (toTree(lo), toTree(hi))
650
+ case _ =>
651
+ EmptyTree
652
+ }
653
+
654
+ val tag = toTree(tpe)
655
+ if (ok) ref(defn.typeQuoteMethod).appliedToTypeTrees(tag :: Nil )
656
+ else EmptyTree
657
+ }
658
+
586
659
/** If `formal` is of the form Eq[T, U], where no `Eq` instance exists for
587
660
* either `T` or `U`, synthesize `Eq.eqAny[T, U]` as solution.
588
661
*/
@@ -645,6 +718,8 @@ trait Implicits { self: Typer =>
645
718
tree
646
719
else if (formalValue.isRef(defn.ClassTagClass ))
647
720
synthesizedClassTag(formalValue).orElse(tree)
721
+ else if (formalValue.isRef(defn.QuotedTypeClass ))
722
+ synthesizedTypeTag(formalValue).orElse(tree)
648
723
else if (formalValue.isRef(defn.EqClass ))
649
724
synthesizedEq(formalValue).orElse(tree)
650
725
else
0 commit comments