@@ -13,13 +13,14 @@ import util.{Property, SourceFile, SourcePosition, SrcPos, Chars}
13
13
import config .{Feature , Config }
14
14
import config .Feature .{sourceVersion , migrateTo3 , enabled }
15
15
import config .SourceVersion .*
16
- import collection .mutable
17
16
import reporting .*
18
17
import printing .Formatting .hl
19
18
import config .Printers
20
19
import parsing .Parsers
20
+ import dotty .tools .dotc .util .chaining .*
21
21
22
22
import scala .annotation .{unchecked as _ , * }, internal .sharable
23
+ import scala .collection .mutable , mutable .ListBuffer
23
24
24
25
object desugar {
25
26
import untpd .*
@@ -1343,7 +1344,7 @@ object desugar {
1343
1344
)).withSpan(tree.span)
1344
1345
end makePolyFunctionType
1345
1346
1346
- /** Invent a name for an anonympus given of type or template `impl`. */
1347
+ /** Invent a name for an anonymous given of type or template `impl`. */
1347
1348
def inventGivenName (impl : Tree )(using Context ): SimpleName =
1348
1349
val str = impl match
1349
1350
case impl : Template =>
@@ -2044,33 +2045,35 @@ object desugar {
2044
2045
makeCaseLambda(CaseDef (gen.pat, EmptyTree , body) :: Nil , matchCheckMode)
2045
2046
}
2046
2047
2047
- def hasGivenBind (pat : Tree ): Boolean = pat.existsSubTree {
2048
- case pat @ Bind (_, pat1 ) => pat.mods.is(Given )
2048
+ def hasGivenBind (pat : Tree ): Boolean = pat.existsSubTree:
2049
+ case pat @ Bind (_, _ ) => pat.mods.is(Given )
2049
2050
case _ => false
2050
- }
2051
2051
2052
2052
/** Does this pattern define any given bindings */
2053
2053
def isNestedGivenPattern (pat : Tree ): Boolean = pat match
2054
- case pat @ Bind (_, pat1 ) => hasGivenBind(pat1 )
2054
+ case Bind (_, pat ) => hasGivenBind(pat )
2055
2055
case _ => hasGivenBind(pat)
2056
2056
2057
2057
/** If `pat` is not an Identifier, a Typed(Ident, _), or a Bind, wrap
2058
2058
* it in a Bind with a fresh name. Return the transformed pattern, and the identifier
2059
2059
* that refers to the bound variable for the pattern. Wildcard Binds are
2060
2060
* also replaced by Binds with fresh names.
2061
2061
*/
2062
- def makeIdPat (pat : Tree ): (Tree , Ident ) = pat match {
2063
- case bind @ Bind (name, pat1) =>
2064
- if name == nme.WILDCARD then
2065
- val name = UniqueName .fresh()
2066
- (cpy.Bind (pat)(name, pat1).withMods(bind.mods), Ident (name))
2067
- else (pat, Ident (name))
2062
+ def makeIdPat (pat : Tree ): (Tree , Ident ) = pat match
2063
+ case bind @ Bind (nme.WILDCARD , pat) =>
2064
+ val name = UniqueName .fresh()
2065
+ cpy.Bind (pat)(name, pat)
2066
+ .withMods(bind.mods)
2067
+ .withSpan(bind.span)
2068
+ .withAttachment(PatternVar , ())
2069
+ ->
2070
+ Ident (name)
2071
+ case Bind (name, _) => (pat, Ident (name))
2068
2072
case id : Ident if isVarPattern(id) && id.name != nme.WILDCARD => (id, id)
2069
2073
case Typed (id : Ident , _) if isVarPattern(id) && id.name != nme.WILDCARD => (pat, id)
2070
2074
case _ =>
2071
2075
val name = UniqueName .fresh()
2072
2076
(Bind (name, pat), Ident (name))
2073
- }
2074
2077
2075
2078
/** Make a pattern filter:
2076
2079
* rhs.withFilter { case pat => true case _ => false }
@@ -2173,36 +2176,44 @@ object desugar {
2173
2176
case (gen : GenFrom ) :: (rest @ (GenFrom (_, _, _) :: _)) =>
2174
2177
val cont = makeFor(mapName, flatMapName, rest, body)
2175
2178
Apply (rhsSelect(gen, flatMapName), makeLambda(gen, cont))
2176
- case (gen : GenFrom ) :: rest
2177
- if sourceVersion.enablesBetterFors
2178
- && rest.dropWhile(_.isInstanceOf [GenAlias ]).headOption.forall(e => e.isInstanceOf [GenFrom ]) // possible aliases followed by a generator or end of for
2179
- && ! rest.takeWhile(_.isInstanceOf [GenAlias ]).exists(a => isNestedGivenPattern(a.asInstanceOf [GenAlias ].pat)) =>
2180
- val cont = makeFor(mapName, flatMapName, rest, body)
2181
- val selectName =
2182
- if rest.exists(_.isInstanceOf [GenFrom ]) then flatMapName
2183
- else mapName
2184
- val aply = Apply (rhsSelect(gen, selectName), makeLambda(gen, cont))
2185
- markTrailingMap(aply, gen, selectName)
2186
- aply
2187
- case (gen : GenFrom ) :: (rest @ GenAlias (_, _) :: _) =>
2188
- val (valeqs, rest1) = rest.span(_.isInstanceOf [GenAlias ])
2189
- val pats = valeqs map { case GenAlias (pat, _) => pat }
2190
- val rhss = valeqs map { case GenAlias (_, rhs) => rhs }
2191
- val (defpat0, id0) = makeIdPat(gen.pat)
2192
- val (defpats, ids) = (pats map makeIdPat).unzip
2193
- val pdefs = valeqs.lazyZip(defpats).lazyZip(rhss).map { (valeq, defpat, rhs) =>
2194
- val mods = defpat match
2195
- case defTree : DefTree => defTree.mods
2196
- case _ => Modifiers ()
2197
- makePatDef(valeq, mods, defpat, rhs)
2198
- }
2199
- val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom (defpat0, gen.expr, gen.checkMode) :: Nil , Block (pdefs, makeTuple(id0 :: ids).withAttachment(ForArtifact , ())))
2200
- val allpats = gen.pat :: pats
2201
- val vfrom1 = GenFrom (makeTuple(allpats), rhs1, GenCheckMode .Ignore )
2202
- makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
2179
+ case (gen : GenFrom ) :: (tail @ GenAlias (_, _) :: _) =>
2180
+ val (valeqs, suffix) = tail.span(_.isInstanceOf [GenAlias ])
2181
+ // possible aliases followed by a generator or end of for, when betterFors.
2182
+ // exclude value definitions with a given pattern (given T = x)
2183
+ val better = sourceVersion.enablesBetterFors
2184
+ && suffix.headOption.forall(_.isInstanceOf [GenFrom ])
2185
+ && ! valeqs.exists(a => isNestedGivenPattern(a.asInstanceOf [GenAlias ].pat))
2186
+ if better then
2187
+ val cont = makeFor(mapName, flatMapName, enums = tail, body)
2188
+ val selectName =
2189
+ if suffix.exists(_.isInstanceOf [GenFrom ]) then flatMapName
2190
+ else mapName
2191
+ Apply (rhsSelect(gen, selectName), makeLambda(gen, cont))
2192
+ .tap(markTrailingMap(_, gen, selectName))
2193
+ else
2194
+ val pats = valeqs.map { case GenAlias (pat, _) => pat }
2195
+ val rhss = valeqs.map { case GenAlias (_, rhs) => rhs }
2196
+ val (defpat0, id0) = makeIdPat(gen.pat)
2197
+ val (defpats, ids) = pats.map(makeIdPat).unzip
2198
+ val pdefs = valeqs.lazyZip(defpats).lazyZip(rhss).map { (valeq, defpat, rhs) =>
2199
+ val mods = defpat match
2200
+ case defTree : DefTree => defTree.mods
2201
+ case _ => Modifiers ()
2202
+ makePatDef(valeq, mods, defpat, rhs)
2203
+ }
2204
+ val rhs1 =
2205
+ val enums = GenFrom (defpat0, gen.expr, gen.checkMode) :: Nil
2206
+ val body = Block (pdefs, makeTuple(id0 :: ids).withAttachment(ForArtifact , ()))
2207
+ makeFor(nme.map, nme.flatMap, enums, body)
2208
+ val allpats = gen.pat :: pats
2209
+ val vfrom1 = GenFrom (makeTuple(allpats), rhs1, GenCheckMode .Ignore )
2210
+ makeFor(mapName, flatMapName, enums = vfrom1 :: suffix, body)
2211
+ end if
2203
2212
case (gen : GenFrom ) :: test :: rest =>
2204
- val filtered = Apply (rhsSelect(gen, nme.withFilter), makeLambda(gen, test))
2205
- val genFrom = GenFrom (gen.pat, filtered, if sourceVersion.enablesBetterFors then GenCheckMode .Filtered else GenCheckMode .Ignore )
2213
+ val genFrom =
2214
+ val filtered = Apply (rhsSelect(gen, nme.withFilter), makeLambda(gen, test))
2215
+ val mode = if sourceVersion.enablesBetterFors then GenCheckMode .Filtered else GenCheckMode .Ignore
2216
+ GenFrom (gen.pat, filtered, mode)
2206
2217
makeFor(mapName, flatMapName, genFrom :: rest, body)
2207
2218
case GenAlias (_, _) :: _ if sourceVersion.enablesBetterFors =>
2208
2219
val (valeqs, rest) = enums.span(_.isInstanceOf [GenAlias ])
@@ -2396,7 +2407,7 @@ object desugar {
2396
2407
* without duplicates
2397
2408
*/
2398
2409
private def getVariables (tree : Tree , shouldAddGiven : Context ?=> Bind => Boolean )(using Context ): List [VarInfo ] = {
2399
- val buf = mutable. ListBuffer [VarInfo ]()
2410
+ val buf = ListBuffer .empty [VarInfo ]
2400
2411
def seenName (name : Name ) = buf exists (_._1.name == name)
2401
2412
def add (named : NameTree , t : Tree ): Unit =
2402
2413
if (! seenName(named.name) && named.name.isTermName) buf += ((named, t))
0 commit comments