@@ -553,9 +553,7 @@ trait Implicits { self: Typer =>
553
553
}
554
554
555
555
/** Find an implicit argument for parameter `formal`.
556
- * @param error An error handler that gets an error message parameter
557
- * which is itself parameterized by another string,
558
- * indicating where the implicit parameter is needed
556
+ * Return a failure as a SearchFailureType in the type of the returned tree.
559
557
*/
560
558
def inferImplicitArg (formal : Type , pos : Position )(implicit ctx : Context ): Tree = {
561
559
@@ -582,6 +580,81 @@ trait Implicits { self: Typer =>
582
580
EmptyTree
583
581
}
584
582
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
+ }
602
+
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
+ }
621
+
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
+ }
652
+
653
+ val tag = toTree(tpe)
654
+ if (ok) ref(defn.typeQuoteMethod).appliedToTypeTrees(tag :: Nil )
655
+ else EmptyTree
656
+ }
657
+
585
658
/** If `formal` is of the form Eq[T, U], where no `Eq` instance exists for
586
659
* either `T` or `U`, synthesize `Eq.eqAny[T, U]` as solution.
587
660
*/
@@ -644,6 +717,8 @@ trait Implicits { self: Typer =>
644
717
tree
645
718
else if (formalValue.isRef(defn.ClassTagClass ))
646
719
synthesizedClassTag(formalValue).orElse(tree)
720
+ else if (formalValue.isRef(defn.QuotedTypeClass ))
721
+ synthesizedTypeTag(formalValue).orElse(tree)
647
722
else if (formalValue.isRef(defn.EqClass ))
648
723
synthesizedEq(formalValue).orElse(tree)
649
724
else
0 commit comments