@@ -110,8 +110,6 @@ trait QuotesAndSplices {
110
110
def typedSplicePattern (tree : untpd.SplicePattern , pt : Type )(using Context ): Tree = {
111
111
record(" typedSplicePattern" )
112
112
if isFullyDefined(pt, ForceDegree .flipBottom) then
113
- def patternOuterContext (ctx : Context ): Context =
114
- if (ctx.mode.is(Mode .QuotedPattern )) patternOuterContext(ctx.outer) else ctx
115
113
val typedArgs = withMode(Mode .InQuotePatternHoasArgs ) {
116
114
tree.args.map {
117
115
case arg : untpd.Ident =>
@@ -125,8 +123,7 @@ trait QuotesAndSplices {
125
123
report.error(" References to `var`s cannot be used in higher-order pattern" , arg.srcPos)
126
124
val argTypes = typedArgs.map(_.tpe.widenTermRefExpr)
127
125
val patType = if tree.args.isEmpty then pt else defn.FunctionOf (argTypes, pt)
128
- val pat = typedPattern(tree.body, defn.QuotedExprClass .typeRef.appliedTo(patType))(
129
- using spliceContext.retractMode(Mode .QuotedPattern ).addMode(Mode .Pattern ).withOwner(patternOuterContext(ctx).owner))
126
+ val pat = typedPattern(tree.body, defn.QuotedExprClass .typeRef.appliedTo(patType))(using quotePatternSpliceContext)
130
127
val baseType = pat.tpe.baseType(defn.QuotedExprClass )
131
128
val argType = if baseType.exists then baseType.argTypesHi.head else defn.NothingType
132
129
untpd.cpy.SplicePattern (tree)(pat, typedArgs).withType(pt)
@@ -166,14 +163,27 @@ trait QuotesAndSplices {
166
163
val typeSymInfo = pt match
167
164
case pt : TypeBounds => pt
168
165
case _ => TypeBounds .empty
166
+
167
+ def warnOnInferredBounds (typeSym : Symbol ) =
168
+ if ! (typeSymInfo =:= TypeBounds .empty) && ! (typeSym.info <:< typeSymInfo) then
169
+ val (openQuote, closeQuote) = if isInQuotedExprPattern then (" '{" , " }" ) else (" '[" , " ]" )
170
+ if isInQuotedTypePattern then // TODO remove this branch once SIP-53 is non-experimental
171
+ report.warning(
172
+ em """ Ignored bound $typeSymInfo
173
+ |
174
+ |This kind of pattern will be supported with SIP-53.
175
+ |SIP-53: https://docs.scala-lang.org/sips/quote-pattern-type-variable-syntax.html
176
+ | """ , tree.srcPos)
177
+ else
178
+ report.warning(em " Ignored bound $typeSymInfo\n\n Consider defining bounds explicitly: \n $openQuote $typeSym${typeSym.info & typeSymInfo}; ... $closeQuote" , tree.srcPos)
179
+
169
180
getQuotedPatternTypeVariable(tree.name.asTypeName) match
170
181
case Some (typeSym) =>
171
182
checkExperimentalFeature(
172
183
" support for multiple references to the same type (without backticks) in quoted type patterns (SIP-53)" ,
173
184
tree.srcPos,
174
185
" \n\n SIP-53: https://docs.scala-lang.org/sips/quote-pattern-type-variable-syntax.html" )
175
- if ! (typeSymInfo =:= TypeBounds .empty) && ! (typeSym.info <:< typeSymInfo) then
176
- report.warning(em " Ignored bound $typeSymInfo\n\n Consider defining bounds explicitly `'{ $typeSym${typeSym.info & typeSymInfo}; ... }` " , tree.srcPos)
186
+ warnOnInferredBounds(typeSym)
177
187
ref(typeSym)
178
188
case None =>
179
189
def spliceOwner (ctx : Context ): Symbol =
@@ -454,7 +464,7 @@ trait QuotesAndSplices {
454
464
" \n\n SIP-53: https://docs.scala-lang.org/sips/quote-pattern-type-variable-syntax.html" )
455
465
456
466
val (typeTypeVariables, patternCtx) =
457
- val quoteCtx = quotePatternContext()
467
+ val quoteCtx = quotePatternContext(quoted.isType )
458
468
if untpdTypeVariables.isEmpty then (Nil , quoteCtx)
459
469
else typedBlockStats(untpdTypeVariables)(using quoteCtx)
460
470
@@ -536,20 +546,49 @@ trait QuotesAndSplices {
536
546
object QuotesAndSplices {
537
547
import tpd ._
538
548
549
+ private enum QuotePattenKind :
550
+ case Expr , Type
551
+
539
552
/** Key for mapping from quoted pattern type variable names into their symbol */
540
553
private val TypeVariableKey = new Property .Key [collection.mutable.Map [TypeName , Symbol ]]
541
554
555
+ /** Key that track in which kind of quote pattern we are */
556
+ private val QuotePattenKindKey = new Property .Key [QuotePattenKind ]
557
+
542
558
/** Get the symbol for the quoted pattern type variable if it exists */
543
559
def getQuotedPatternTypeVariable (name : TypeName )(using Context ): Option [Symbol ] =
544
560
ctx.property(TypeVariableKey ).get.get(name)
545
561
546
- /** Get the symbol for the quoted pattern type variable if it exists */
562
+ /** Get the symbol for the quoted pattern type variable if it exists */
547
563
def addQuotedPatternTypeVariable (sym : Symbol )(using Context ): Unit =
548
564
ctx.property(TypeVariableKey ).get.update(sym.name.asTypeName, sym)
549
565
550
- /** Context used to type the contents of a quoted */
551
- def quotePatternContext ()(using Context ): Context =
566
+ /** Is the current context in a quoted expression pattern?
567
+ * But not in the splice of a quoted expression pattern.
568
+ */
569
+ def isInQuotedExprPattern (using Context ): Boolean =
570
+ ctx.property(QuotePattenKindKey ).contains(QuotePattenKind .Expr )
571
+
572
+ /** Is the current context in a quoted type pattern?
573
+ * But not in the splice of a quoted type pattern.
574
+ */
575
+ def isInQuotedTypePattern (using Context ): Boolean =
576
+ ctx.property(QuotePattenKindKey ).contains(QuotePattenKind .Type )
577
+
578
+ /** Context used to type the contents of a quote pattern */
579
+ def quotePatternContext (isTypePattern : Boolean )(using Context ): Context =
552
580
quoteContext.fresh.setNewScope
553
581
.addMode(Mode .QuotedPattern ).retractMode(Mode .Pattern )
582
+ .addMode(Mode .QuotedPattern ).retractMode(Mode .Pattern ) // TODO do we need Mode.QuotedPattern?
554
583
.setProperty(TypeVariableKey , collection.mutable.Map .empty)
584
+ .setProperty(QuotePattenKindKey , if isTypePattern then QuotePattenKind .Type else QuotePattenKind .Expr )
585
+
586
+ /** Context used to type the contents of a quote pattern splice */
587
+ def quotePatternSpliceContext (using Context ): Context =
588
+ def patternOuterContext (ctx : Context ): Context =
589
+ if ctx.mode.is(Mode .QuotedPattern ) then patternOuterContext(ctx.outer) else ctx
590
+ spliceContext
591
+ .retractMode(Mode .QuotedPattern ).addMode(Mode .Pattern )
592
+ .dropProperty(QuotePattenKindKey )
593
+ .withOwner(patternOuterContext(ctx).owner)
555
594
}
0 commit comments