@@ -1943,23 +1943,29 @@ class Typer extends Namer
19431943 val exprPt = pt.baseType(defn.QuotedExprClass )
19441944 val quotedPt = if (exprPt.exists) exprPt.argTypesHi.head else defn.AnyType
19451945 val quoted1 = typedExpr(quoted, quotedPt)(quoteContext.addMode(Mode .QuotedPattern ))
1946- val (shape, splices) = splitQuotePattern(quoted1)
1947- val typeBindings = splices.collect {
1948- case t if t.tpe.derivesFrom(defn.QuotedTypeClass ) =>
1949- t.tpe.widen.argTypesHi.head.typeSymbol
1950- }
1951- val inQuoteTypeBinding = typeBindings.map { sym =>
1952- ctx.newSymbol(sym.owner, (sym.name + " $$$" ).toTypeName, // TODO remove $$$, just there for debugging
1953- EmptyFlags , sym.info, coord = sym.coord)
1954- }
1955- val shape2 =
1956- seq(inQuoteTypeBinding.map(TypeDef ), shape.subst(typeBindings, inQuoteTypeBinding))
1946+ val (typeBindings, shape, splices) = splitQuotePattern(quoted1)
1947+ // val typeBindings = splices.collect {
1948+ // case t if t.tpe.derivesFrom(defn.QuotedTypeClass) =>
1949+ // t.tpe.widen.argTypesHi.head.typeSymbol
1950+ // }
1951+ // val inQuoteTypeBinding = typeBindings.map { sym =>
1952+ // ctx.newSymbol(sym.owner, (sym.name + "$$$").toTypeName, // TODO remove $$$, just there for debugging
1953+ // EmptyFlags, sym.info, coord = sym.coord)
1954+ // }
1955+ // val shape2 =
1956+ // seq(inQuoteTypeBinding.map(TypeDef), shape.subst(typeBindings, inQuoteTypeBinding))
1957+
1958+
19571959 val patType = defn.tupleType(splices.tpes.map(_.widen))
1960+
1961+ val typeBindingsTuple = tpd.tupleTypeTree(typeBindings)
1962+
19581963 val splicePat = typed(untpd.Tuple (splices.map(untpd.TypedSplice (_))).withSpan(quoted.span), patType)
1964+
19591965 UnApply (
1960- fun = ref(defn.InternalQuotedMatcher_unapplyR ).appliedToType( patType),
1966+ fun = ref(defn.InternalQuotedMatcher_unapplyR ).appliedToTypeTrees(typeBindingsTuple :: TypeTree ( patType) :: Nil ),
19611967 implicits =
1962- ref(defn.InternalQuoted_exprQuoteR ).appliedToType(shape.tpe).appliedTo(shape2 ) ::
1968+ ref(defn.InternalQuoted_exprQuoteR ).appliedToType(shape.tpe).appliedTo(shape ) ::
19631969 implicitArgTree(defn.TastyReflectionType , tree.span) :: Nil ,
19641970 patterns = splicePat :: Nil ,
19651971 proto = pt)
@@ -1969,8 +1975,22 @@ class Typer extends Namer
19691975 }
19701976 }
19711977
1972- def splitQuotePattern (quoted : Tree )(implicit ctx : Context ): (Tree , List [Tree ]) = {
1978+ def splitQuotePattern (quoted : Tree )(implicit ctx : Context ): (List [ Bind ], Tree , List [Tree ]) = {
19731979 val ctx0 = ctx
1980+
1981+ val typeBindings : collection.mutable.Map [Symbol , Bind ] = collection.mutable.Map .empty
1982+ def replaceTypeBindings = new TypeMap {
1983+ def apply (tp : Type ): Type = tp match {
1984+ case tp : TypeRef if tp.typeSymbol.hasAnnotation(defn.InternalQuoted_patternBindHoleAnnot ) =>
1985+ val bindingBounds = TypeBounds .apply(defn.NothingType , defn.AnyType ) // TODO recover bounds
1986+ val sym = ctx.newPatternBoundSymbol((tp.name + " $" ).toTypeName, bindingBounds, quoted.span)
1987+ val bind = typeBindings.getOrElseUpdate(tp.typeSymbol,
1988+ Bind (sym, untpd.Ident (nme.WILDCARD ).withType(bindingBounds)).withSpan(quoted.span))
1989+ bind.symbol.typeRef
1990+ case _ => mapOver(tp)
1991+ }
1992+ }
1993+
19741994 object splitter extends tpd.TreeMap {
19751995 val patBuf = new mutable.ListBuffer [Tree ]
19761996 override def transform (tree : Tree )(implicit ctx : Context ) = tree match {
@@ -1981,8 +2001,18 @@ class Typer extends Namer
19812001 try patternHole(tree)
19822002 finally {
19832003 val patType = pat.tpe.widen
1984- val patType1 = patType.underlyingIfRepeated(isJava = false )
2004+ val patType1 = replaceTypeBindings( patType.underlyingIfRepeated(isJava = false ) )
19852005 val pat1 = if (patType eq patType1) pat else pat.withType(patType1)
2006+ println(" =-=-=-============-=-=-=----=-=-=" )
2007+ println(pat)
2008+ println(pat.symbol)
2009+ println(pat.symbol.info)
2010+ println()
2011+ println(pat1)
2012+ println(pat1.symbol)
2013+ println(pat1.symbol.info)
2014+ println()
2015+ println()
19862016 patBuf += pat1
19872017 }
19882018 case ddef : ValOrDefDef =>
@@ -2008,7 +2038,7 @@ class Typer extends Namer
20082038 }
20092039 }
20102040 val result = splitter.transform(quoted)
2011- (result, splitter.patBuf.toList)
2041+ (typeBindings.toList.map(_._2), result, splitter.patBuf.toList)
20122042 }
20132043
20142044 /** A hole the shape pattern of a quoted.Matcher.unapply, representing a splice */
@@ -2065,18 +2095,32 @@ class Typer extends Namer
20652095 case expr =>
20662096 if (ctx.mode.is(Mode .QuotedPattern ) && level == 1 ) {
20672097 if (isFullyDefined(pt, ForceDegree .all)) {
2098+ // TODO is this error still relevant here? probably not
20682099 ctx.error(i " Type must be fully defined. \n Consider annotating the splice using a type ascription: \n ( $tree: XYZ). " , tree.expr.sourcePos)
20692100 tree.withType(UnspecifiedErrorType )
20702101 } else {
2071- val bindingBounds = TypeBounds .apply(defn.NothingType , defn.AnyType )
2072- val sym = ctx.newPatternBoundSymbol(" ttt" .toTypeName, bindingBounds, expr.span)
2073- val bind = Bind (sym, untpd.Ident (nme.WILDCARD ).withType(bindingBounds)).withSpan(expr.span)
2102+ expr match {
2103+ case Ident (name) => typedIdent(untpd.Ident ((" $" + name).toTypeName), pt)
2104+ }
2105+
2106+ // println()
2107+ // println(expr)
2108+ // println()
2109+ // println()
2110+ // val bindingBounds = TypeBounds.apply(defn.NothingType, defn.AnyType)
2111+ // def getName(tree: untpd.Tree): TypeName = tree match {
2112+ // case tree: RefTree => ("$" + tree.name).toTypeName
2113+ // case tree: Typed => getName(tree.expr)
2114+ // }
2115+ // val sym = ctx.newPatternBoundSymbol(getName(expr), bindingBounds, expr.span)
2116+ // val bind = Bind(sym, untpd.Ident(nme.WILDCARD).withType(bindingBounds)).withSpan(expr.span)
2117+ //
2118+ // def spliceOwner(ctx: Context): Symbol =
2119+ // if (ctx.mode.is(Mode.QuotedPattern)) spliceOwner(ctx.outer) else ctx.owner
2120+ // val pat = typedPattern(tree.expr, defn.QuotedTypeType.appliedTo(sym.typeRef))(
2121+ // spliceContext.retractMode(Mode.QuotedPattern).withOwner(spliceOwner(ctx)))
2122+ // Splice(Typed(pat, AppliedTypeTree(TypeTree(defn.QuotedTypeType), bind :: Nil)))
20742123
2075- def spliceOwner (ctx : Context ): Symbol =
2076- if (ctx.mode.is(Mode .QuotedPattern )) spliceOwner(ctx.outer) else ctx.owner
2077- val pat = typedPattern(tree.expr, defn.QuotedTypeType .appliedTo(sym.typeRef))(
2078- spliceContext.retractMode(Mode .QuotedPattern ).withOwner(spliceOwner(ctx)))
2079- Splice (Typed (pat, AppliedTypeTree (TypeTree (defn.QuotedTypeType ), bind :: Nil )))
20802124 }
20812125
20822126 } else {
0 commit comments