diff --git a/compiler/src/dotty/tools/dotc/Driver.scala b/compiler/src/dotty/tools/dotc/Driver.scala index 924a9162bdb9..b1089b066cdb 100644 --- a/compiler/src/dotty/tools/dotc/Driver.scala +++ b/compiler/src/dotty/tools/dotc/Driver.scala @@ -72,22 +72,21 @@ class Driver { // Resolve classpath and class names of tasty files val (classPaths, classNames) = fileNames0.flatMap { name => val path = Paths.get(name) - if (name.endsWith(".jar")) { + if (name.endsWith(".jar")) new dotty.tools.io.Jar(File(name)).toList.collect { case e if e.getName.endsWith(".tasty") => (name, e.getName.stripSuffix(".tasty").replace("/", ".")) } - } else if (!name.endsWith(".tasty")) ("", name) :: Nil - else if (Files.exists(path)) { + else if (Files.exists(path)) TastyFileUtil.getClassName(path) match { case Some(res) => res:: Nil case _ => ctx0.error(s"Could not load classname from $name.") ("", name) :: Nil } - } else { + else { ctx0.error(s"File $name does not exist.") ("", name) :: Nil } diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index ec3df458b67b..fbdacce2e28b 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -454,8 +454,9 @@ object desugar { if (isCaseClass) ctx.error(CaseClassMissingParamList(cdef), namePos) ListOfNil - } else if (isCaseClass && originalVparamss.head.exists(_.mods.isOneOf(GivenOrImplicit))) { - ctx.error("Case classes should have a non-implicit parameter list", namePos) + } + else if (isCaseClass && originalVparamss.head.exists(_.mods.isOneOf(GivenOrImplicit))) { + ctx.error("Case classes should have a non-implicit parameter list", namePos) ListOfNil } else originalVparamss.nestedMap(toDefParam(_, keepAnnotations = false)) @@ -717,12 +718,11 @@ object desugar { } else if (companionMembers.nonEmpty || companionDerived.nonEmpty || isEnum) companionDefs(anyRef, companionMembers) - else if (isValueClass) { + else if (isValueClass) impl.constr.vparamss match { case (_ :: Nil) :: _ => companionDefs(anyRef, Nil) case _ => Nil // error will be emitted in typer } - } else Nil enumCompanionRef match { @@ -1133,12 +1133,11 @@ object desugar { case tree: MemberDef => var tested: MemberDef = tree def fail(msg: String) = ctx.error(msg, tree.sourcePos) - def checkApplicable(flag: Flag, test: MemberDefTest): Unit = { + def checkApplicable(flag: Flag, test: MemberDefTest): Unit = if (tested.mods.is(flag) && !test.applyOrElse(tree, (md: MemberDef) => false)) { fail(i"modifier `${flag.flagsString}` is not allowed for this definition") tested = tested.withMods(tested.mods.withoutFlags(flag)) } - } checkApplicable(Opaque, legalOpaque) tested case _ => diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index e23e899a91b9..333a4caf49d3 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -42,7 +42,8 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] => if (param.info.isRepeatedParam) { for (arg <- args) f(param, arg) true - } else args match { + } + else args match { case Nil => false case arg :: args1 => f(param, args.head) diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 6b7c92b6d09e..fad5cfc14811 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -1468,7 +1468,7 @@ object Trees { case _ => foldMoreCases(x, tree) } - } + } def foldMoreCases(x: X, tree: Tree)(implicit ctx: Context): X = { assert(ctx.reporter.errorsReported || ctx.mode.is(Mode.Interactive), tree) diff --git a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala index 0195da7a4f6c..de3673501a59 100644 --- a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala +++ b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala @@ -107,7 +107,8 @@ class CheckRealizable(implicit ctx: Context) { if (tp.info.isStable && tpInfoRealizable == Realizable) { sym.setFlag(StableRealizable) Realizable - } else r + } + else r } } case _: SingletonType | NoPrefix => diff --git a/compiler/src/dotty/tools/dotc/core/Comments.scala b/compiler/src/dotty/tools/dotc/core/Comments.scala index d14fcb34ab7f..0a1a1071c866 100644 --- a/compiler/src/dotty/tools/dotc/core/Comments.scala +++ b/compiler/src/dotty/tools/dotc/core/Comments.scala @@ -371,9 +371,8 @@ object Comments { superComment(sym) foreach { sc => val superSections = tagIndex(sc) replaceWith(sc.substring(3, startTag(sc, superSections))) - for (sec @ (start, end) <- superSections) { + for (sec @ (start, end) <- superSections) if (!isMovable(sc, sec)) out append sc.substring(start, end) - } } case "" => idx += 1 case vname => diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala index 163ebe4a0639..a2678ce98189 100644 --- a/compiler/src/dotty/tools/dotc/core/Names.scala +++ b/compiler/src/dotty/tools/dotc/core/Names.scala @@ -390,7 +390,7 @@ object Names { override def toString: String = if (length == 0) "" else { - if (Config.checkBackendNames) { + if (Config.checkBackendNames) if (!toStringOK) { // We print the stacktrace instead of doing an assert directly, // because asserts are caught in exception handlers which might @@ -400,7 +400,6 @@ object Names { Thread.dumpStack() assert(false) } - } new String(chrs, start, length) } diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index 20de65ec0949..e578d5f0032e 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -484,12 +484,11 @@ class OrderingConstraint(private val boundsMap: ParamBounds, def foreachTypeVar(op: TypeVar => Unit): Unit = boundsMap.foreachBinding { (poly, entries) => - for (i <- 0 until paramCount(entries)) { + for (i <- 0 until paramCount(entries)) typeVar(entries, i) match { case tv: TypeVar if !tv.inst.exists => op(tv) case _ => } - } } def & (other: Constraint, otherHasErrors: Boolean)(implicit ctx: Context): OrderingConstraint = { diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 9563015a09f3..be885758046e 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -86,18 +86,19 @@ trait SymDenotations { this: Context => else { implicit val ctx = this val initial = denot.initial - if ((initial ne denot) || ctx.phaseId != initial.validFor.firstPhaseId) { + if ((initial ne denot) || ctx.phaseId != initial.validFor.firstPhaseId) ctx.withPhase(initial.validFor.firstPhaseId).traceInvalid(initial) - } else try { + else try { val owner = denot.owner.denot if (!traceInvalid(owner)) explainSym("owner is invalid") else if (!owner.isClass || owner.isRefinementClass || denot.isSelfSym) true else if (owner.unforcedDecls.lookupAll(denot.name) contains denot.symbol) true else explainSym(s"decls of ${show(owner)} are ${owner.unforcedDecls.lookupAll(denot.name).toList}, do not contain ${denot.symbol}") - } catch { + } + catch { case ex: StaleSymbol => explainSym(s"$ex was thrown") } - } + } case _ => explain("denotation is not a SymDenotation") } diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 89bb068edff3..6c5239293db0 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -466,7 +466,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w case _ => val cls2 = tp2.symbol - if (cls2.isClass) { + if (cls2.isClass) if (cls2.typeParams.isEmpty) { if (cls2 eq AnyKindClass) return true if (tp1.isRef(NothingClass)) return true @@ -485,7 +485,6 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w } else if (tp1.isLambdaSub && !tp1.isRef(AnyKindClass)) return recur(tp1, EtaExpansion(cls2.typeRef)) - } fourthTry } diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index a51d27311e26..15c3537de67c 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -68,7 +68,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object. case pre: SuperType => toPrefix(pre.thistpe, cls, thiscls) case _ => if (thiscls.derivesFrom(cls) && pre.baseType(thiscls).exists) - if (variance <= 0 && !isLegalPrefix(pre)) { + if (variance <= 0 && !isLegalPrefix(pre)) if (variance < 0) { approximated = true defn.NothingType @@ -80,7 +80,6 @@ trait TypeOps { this: Context => // TODO: Make standalone object. // is not possible, then `expandBounds` will end up being // called which we override to set the `approximated` flag. range(defn.NothingType, pre) - } else pre else if ((pre.termSymbol is Package) && !(thiscls is Package)) toPrefix(pre.select(nme.PACKAGE), cls, thiscls) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index d1aaf780ccdd..eae0aa9cd8cb 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -646,9 +646,8 @@ object Types { else tp rt.opened = true try go(rt.parent).mapInfo(_.substRecThis(rt, pre)) - finally { + finally if (!rt.openedTwice) rt.opened = false - } } def goRefined(tp: RefinedType) = { @@ -1359,11 +1358,10 @@ object Types { case tp @ AppliedType(tycon, args) if tycon.typeSymbol.isClass => tycon.parents.map(_.subst(tycon.typeSymbol.typeParams, args)) case tp: TypeRef => - if (tp.info.isInstanceOf[TempClassInfo]) { + if (tp.info.isInstanceOf[TempClassInfo]) tp.recomputeDenot() // We usually should have `!tp.info.isInstanceOf[TempClassInfo]` here, but // this can be falsified for code with illegal cyclic references. See neg/i7107.scala. - } tp.info.parents case tp: TypeProxy => tp.superType.parents @@ -2104,9 +2102,9 @@ object Types { try { ctx.pendingUnderlying += this op - } finally { - ctx.pendingUnderlying -= this } + finally + ctx.pendingUnderlying -= this } finally ctx.base.underlyingRecursions -= 1 @@ -4768,7 +4766,7 @@ object Types { case _ => tp.derivedRefinedType(parent, tp.refinedName, info) } - } + } override protected def derivedRecType(tp: RecType, parent: Type): Type = if (parent eq tp.parent) tp @@ -4802,7 +4800,7 @@ object Types { case Range(tyconLo, tyconHi) => range(derivedAppliedType(tp, tyconLo, args), derivedAppliedType(tp, tyconHi, args)) case _ => - if (args.exists(isRange)) { + if (args.exists(isRange)) if (variance > 0) tp.derivedAppliedType(tycon, args.map(rangeToBounds)) else { val loBuf, hiBuf = new mutable.ListBuffer[Type] @@ -4834,7 +4832,6 @@ object Types { else range(defn.NothingType, defn.AnyType) // TODO: can we give a better bound than `topType`? } - } else tp.derivedAppliedType(tycon, args) } diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index e69c2cae6bae..8f7e382b3c6e 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -655,6 +655,7 @@ object Parsers { } def needsBraces(t: Any): Boolean = t match { + case Match(EmptyTree, _) => true case Block(stats, expr) => stats.nonEmpty || needsBraces(expr) case expr: Tree => @@ -712,8 +713,9 @@ object Parsers { val (startOpening, endOpening) = startingElimRegion(colonRequired) val isOutermost = in.currentRegion.isOutermost def allBraces(r: Region): Boolean = r match { + case r: Indented => r.isOutermost || allBraces(r.enclosing) case r: InBraces => allBraces(r.enclosing) - case _ => r.isOutermost + case _ => false } var canRewrite = allBraces(in.currentRegion) && // test (1) !testChars(in.lastOffset - 3, " =>") // test(6) @@ -1843,7 +1845,7 @@ object Parsers { def matchExpr(t: Tree, start: Offset, mkMatch: (Tree, List[CaseDef]) => Match) = indentRegion(MATCH) { atSpan(start, in.skipToken()) { - inBracesOrIndented(mkMatch(t, caseClauses(caseClause))) + mkMatch(t, inBracesOrIndented(caseClauses(caseClause))) } } diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 2de86ab1d550..0304fe7ccdd3 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -742,12 +742,11 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { def tparamsText[T >: Untyped](params: List[Tree[T]]): Text = "[" ~ toText(params, ", ") ~ "]" provided params.nonEmpty - def addVparamssText[T >: Untyped](leading: Text, vparamss: List[List[ValDef[T]]]): Text = { + def addVparamssText[T >: Untyped](leading: Text, vparamss: List[List[ValDef[T]]]): Text = vparamss.foldLeft(leading)((txt, params) => txt ~ (Str(" given ") provided params.nonEmpty && params.head.mods.is(Given)) ~ paramsText(params)) - } protected def valDefToText[T >: Untyped](tree: ValDef[T]): Text = { import untpd.{modsDeco => _} dclTextOr(tree) { diff --git a/compiler/src/dotty/tools/dotc/reporting/trace.scala b/compiler/src/dotty/tools/dotc/reporting/trace.scala index 02e75d55e0de..bf85dc8de82d 100644 --- a/compiler/src/dotty/tools/dotc/reporting/trace.scala +++ b/compiler/src/dotty/tools/dotc/reporting/trace.scala @@ -91,13 +91,12 @@ abstract class TraceSyntax { if (ctx.mode.is(Mode.Printing)) op else { var finalized = false - def finalize(result: Any, note: String) = { + def finalize(result: Any, note: String) = if (!finalized) { ctx.base.indent -= 1 log(s"${ctx.base.indentTab * ctx.base.indent}${trailing(result)}$note") finalized = true } - } try { log(s"${ctx.base.indentTab * ctx.base.indent}$leading") ctx.base.indent += 1 diff --git a/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala b/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala index 9c26de87d227..37eebce9ac55 100644 --- a/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala +++ b/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala @@ -82,9 +82,8 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisPhase = */ def refClass(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): Symbol = { val refMap = if (isVolatile) refInfo.volatileRefClass else refInfo.refClass - if (cls.isClass) { + if (cls.isClass) refMap.getOrElse(cls, refMap(defn.ObjectClass)) - } else refMap(defn.ObjectClass) } @@ -108,7 +107,8 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisPhase = cpy.ValDef(vdef)( rhs = boxMethod(nme.create).appliedTo(vdef.rhs), tpt = TypeTree(vble.info).withSpan(vdef.tpt.span)) - } else vdef + } + else vdef } override def transformIdent(id: Ident)(implicit ctx: Context): Tree = { diff --git a/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala b/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala index d0f36a185150..140940820553 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala @@ -55,12 +55,12 @@ class CheckReentrant extends MiniPhase { finally indent -= 1 } - def addVars(cls: ClassSymbol)(implicit ctx: Context): Unit = { + def addVars(cls: ClassSymbol)(implicit ctx: Context): Unit = if (!seen.contains(cls) && !isIgnored(cls)) { seen += cls scanning(cls) { - for (sym <- cls.classInfo.decls) { - if (sym.isTerm && !sym.isSetter && !isIgnored(sym)) { + for (sym <- cls.classInfo.decls) + if (sym.isTerm && !sym.isSetter && !isIgnored(sym)) if (sym.is(Mutable)) { ctx.error( i"""possible data race involving globally reachable ${sym.showLocated}: ${sym.info} @@ -71,13 +71,10 @@ class CheckReentrant extends MiniPhase { scanning(sym) { sym.info.widenExpr.classSymbols.foreach(addVars) } - } - } for (parent <- cls.classInfo.classParents) addVars(parent.classSymbol.asClass) } } - } override def transformTemplate(tree: Template)(implicit ctx: Context): Tree = { if (ctx.settings.YcheckReentrant.value && tree.symbol.owner.isStaticOwner) diff --git a/compiler/src/dotty/tools/dotc/transform/Constructors.scala b/compiler/src/dotty/tools/dotc/transform/Constructors.scala index a7671194f574..49e3c4805d67 100644 --- a/compiler/src/dotty/tools/dotc/transform/Constructors.scala +++ b/compiler/src/dotty/tools/dotc/transform/Constructors.scala @@ -74,7 +74,7 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase = } else retain() case _ => retain() - } + } } } @@ -159,14 +159,12 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase = if (noDirectRefsFrom(tree)) tree else super.transform(tree) } - def apply(tree: Tree, prevOwner: Symbol)(implicit ctx: Context): Tree = { + def apply(tree: Tree, prevOwner: Symbol)(implicit ctx: Context): Tree = transform(tree).changeOwnerAfter(prevOwner, constr.symbol, thisPhase) - } } - def isRetained(acc: Symbol) = { + def isRetained(acc: Symbol) = !mightBeDropped(acc) || retainedPrivateVals(acc) - } val constrStats, clsStats = new mutable.ListBuffer[Tree] @@ -223,7 +221,8 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase = if (!isRetained(acc)) { dropped += acc Nil - } else { + } + else { if (acc.hasAnnotation(defn.TransientParamAnnot)) ctx.error(em"transient parameter $acc is retained as field in class ${acc.owner}", acc.sourcePos) val target = if (acc.is(Method)) acc.field else acc @@ -250,7 +249,6 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase = cls.copy( info = clsInfo.derivedClassInfo( decls = clsInfo.decls.filteredScope(!dropped.contains(_)))) - // TODO: this happens to work only because Constructors is the last phase in group } diff --git a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala index 5aa109bbb9a6..dcb680e77b7d 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -54,7 +54,8 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase => if (paramTypes.nonEmpty && paramTypes.last.isRepeatedParam) { val last = paramTypes.last.underlyingIfRepeated(tp.isJavaMethod) paramTypes.init :+ last - } else paramTypes + } + else paramTypes tp.derivedLambdaType(paramNames, paramTypes1, resultType1) case tp: PolyType => tp.derivedLambdaType(tp.paramNames, tp.paramInfos, elimRepeated(tp.resultType)) diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index f71818aabeaa..27e903e488e0 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -54,9 +54,8 @@ class Erasure extends Phase with DenotTransformer { // After erasure, all former Any members are now Object members val ClassInfo(pre, _, ps, decls, selfInfo) = ref.info val extendedScope = decls.cloneScope - for (decl <- defn.AnyClass.classInfo.decls) { + for (decl <- defn.AnyClass.classInfo.decls) if (!decl.isConstructor) extendedScope.enter(decl) - } ref.copySymDenotation( info = transformInfo(ref.symbol, ClassInfo(pre, defn.ObjectClass, ps, extendedScope, selfInfo)) diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala b/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala index 04f2cf02e90e..d026a805144f 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala @@ -39,23 +39,20 @@ class ExpandPrivate extends MiniPhase with IdentityDenotTransformer { thisPhase override def changesMembers: Boolean = true // the phase introduces new members with mangled names - override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = { + override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match { case t: DefDef => val sym = t.symbol - def hasWeakerAccess(other: Symbol) = { + def hasWeakerAccess(other: Symbol) = // public > protected > /* default */ > private if (sym.is(Private)) other.is(Private) else if (sym.is(Protected)) other.isOneOf(Protected | Private) else true // sym is public - } val fail = sym.allOverriddenSymbols.findSymbol(x => !hasWeakerAccess(x)) - if (fail.exists) { + if (fail.exists) assert(false, i"${sym.showFullName}: ${sym.info} has weaker access than superclass method ${fail.showFullName}: ${fail.info}") - } case _ => } - } private def isVCPrivateParamAccessor(d: SymDenotation)(implicit ctx: Context) = d.isTerm && d.isAllOf(PrivateParamAccessor) && isDerivedValueClass(d.owner) diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 432dbc4b5db3..86b15800f548 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -80,7 +80,7 @@ class ExplicitOuter extends MiniPhase with InfoTransformer { thisPhase => if (clsHasOuter || cls.mixins.exists(needsOuterIfReferenced)) { val newDefs = new mutable.ListBuffer[Tree] - if (clsHasOuter) { + if (clsHasOuter) if (isTrait) newDefs += DefDef(outerAccessor(cls).asTerm, EmptyTree) else { @@ -88,22 +88,19 @@ class ExplicitOuter extends MiniPhase with InfoTransformer { thisPhase => newDefs += ValDef(outerParamAcc, EmptyTree) newDefs += DefDef(outerAccessor(cls).asTerm, ref(outerParamAcc)) } - } - for (parentTrait <- cls.mixins) { + for (parentTrait <- cls.mixins) if (needsOuterIfReferenced(parentTrait)) { val parentTp = cls.denot.thisType.baseType(parentTrait) val outerAccImpl = newOuterAccessor(cls, parentTrait).enteredAfter(thisPhase) newDefs += DefDef(outerAccImpl, singleton(fixThis(outerPrefix(parentTp)))) } - } val parents1 = for (parent <- impl.parents) yield { val parentCls = parent.tpe.classSymbol.asClass - if (parentCls.is(Trait)) { + if (parentCls.is(Trait)) parent - } else parent match { // ensure class parent is a constructor case parent: TypeTree => New(parent.tpe, Nil).withSpan(impl.span) case _ => parent diff --git a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala index e62ca5079ff3..c6b53b158123 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala @@ -108,10 +108,9 @@ class ExtensionMethods extends MiniPhase with DenotTransformer with FullParamete } // Drop the Local flag from all private[this] and protected[this] members // that will be moved to the companion object. - if (ref.is(Local) && isDerivedValueClass(ref.owner)) { + if (ref.is(Local) && isDerivedValueClass(ref.owner)) if (ref1 ne ref) ref1.resetFlag(Local) else ref1 = ref1.copySymDenotation(initFlags = ref1.flags &~ Local) - } ref1 case _ => ref.info match { @@ -145,13 +144,13 @@ class ExtensionMethods extends MiniPhase with DenotTransformer with FullParamete // TODO: this is state and should be per-run // todo: check that when transformation finished map is empty - override def transformTemplate(tree: tpd.Template)(implicit ctx: Context): tpd.Tree = { - if (isDerivedValueClass(ctx.owner)) { + override def transformTemplate(tree: tpd.Template)(implicit ctx: Context): tpd.Tree = + if (isDerivedValueClass(ctx.owner)) /* This is currently redundant since value classes may not wrap over other value classes anyway. checkNonCyclic(ctx.owner.pos, Set(), ctx.owner) */ tree - } else if (ctx.owner.isStaticOwner) { + else if (ctx.owner.isStaticOwner) extensionDefs remove tree.symbol.owner match { case Some(defns) if defns.nonEmpty => cpy.Template(tree)(body = tree.body ++ @@ -159,10 +158,9 @@ class ExtensionMethods extends MiniPhase with DenotTransformer with FullParamete case _ => tree } - } else tree - } + else tree - override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = { + override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = if (isMethodWithExtension(tree.symbol)) { val origMeth = tree.symbol val origClass = ctx.owner.asClass @@ -173,8 +171,8 @@ class ExtensionMethods extends MiniPhase with DenotTransformer with FullParamete val store = extensionDefs.getOrElseUpdate(staticClass, new mutable.ListBuffer[Tree]) store += fullyParameterizedDef(extensionMeth, tree) cpy.DefDef(tree)(rhs = forwarder(extensionMeth, tree)) - } else tree - } + } + else tree } object ExtensionMethods { diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala index 2fc953cfdad2..18a31b12cbf2 100644 --- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -47,7 +47,7 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => override protected def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym.isClass - override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = { + override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match { case Select(qual, name) if !name.is(OuterSelectName) && tree.symbol.exists => assert( @@ -59,7 +59,6 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => assert(false, i"illegal tree: $tree") case _ => } - } /** Reorder statements so that module classes always come after their companion classes */ private def reorderAndComplete(stats: List[Tree])(implicit ctx: Context): List[Tree] = { @@ -78,7 +77,8 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => singleClassDefs -= stat.name.stripModuleClassSuffix val stats1r = reorder(stats1, Nil) pushOnTop(revPrefix, if (moduleClassDefs contains stat.name) stat :: stats1r else stats1r) - } else { + } + else reorder( stats1, moduleClassDefs remove stat.name.moduleClassName match { @@ -89,7 +89,6 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => stat :: revPrefix } ) - } case stat :: stats1 => reorder(stats1, stat :: revPrefix) case Nil => revPrefix.reverse } @@ -98,9 +97,8 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => } /** eliminate self in Template */ - override def transformTemplate(impl: Template)(implicit ctx: Context): Tree = { + override def transformTemplate(impl: Template)(implicit ctx: Context): Tree = cpy.Template(impl)(self = EmptyValDef) - } override def transformDefDef(ddef: DefDef)(implicit ctx: Context): Tree = { val meth = ddef.symbol.asTerm @@ -109,8 +107,8 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => polyDefDef(meth, _ => _ => ref(defn.Sys_error.termRef).withSpan(ddef.span) .appliedTo(Literal(Constant(s"native method stub")))) - } + else ddef } diff --git a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala index 1b15b4adfe97..513e08ccf258 100644 --- a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala +++ b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala @@ -79,13 +79,12 @@ object GenericSignatures { boundsSig(hiBounds(param.paramInfo.bounds)) } - def polyParamSig(tparams: List[LambdaParam]): Unit = { + def polyParamSig(tparams: List[LambdaParam]): Unit = if (tparams.nonEmpty) { builder.append('<') tparams.foreach(paramSig) builder.append('>') } - } def typeParamSig(name: Name): Unit = { builder.append(ClassfileConstants.TVAR_TAG) @@ -270,7 +269,7 @@ object GenericSignatures { jsig(intersectionDominator(tp1 :: tp2 :: Nil), primitiveOK = primitiveOK) case ci: ClassInfo => - def polyParamSig(tparams: List[TypeParamInfo]): Unit = { + def polyParamSig(tparams: List[TypeParamInfo]): Unit = if (tparams.nonEmpty) { builder.append('<') tparams.foreach { tp => @@ -279,7 +278,6 @@ object GenericSignatures { } builder.append('>') } - } val tParams = tp.typeParams if (toplevel) polyParamSig(tParams) superSig(ci.typeSymbol, ci.parents) diff --git a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala index 910086b23712..a53d3bc9b368 100644 --- a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala +++ b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala @@ -92,7 +92,7 @@ object LambdaLift { /** Set `liftedOwner(sym)` to `owner` if `owner` is more deeply nested * than the previous value of `liftedowner(sym)`. */ - def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context): Unit = { + def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context): Unit = if (sym.maybeOwner.isTerm && owner.isProperlyContainedIn(liftedOwner(sym)) && owner != sym) { @@ -100,7 +100,6 @@ object LambdaLift { changedLiftedOwner = true liftedOwner(sym) = owner } - } /** Mark symbol `sym` as being free in `enclosure`, unless `sym` is defined * in `enclosure` or there is an intermediate class properly containing `enclosure` @@ -156,17 +155,15 @@ object LambdaLift { else if (enclosure.isConstructor) markFree(sym, enclosure.owner.enclosure) else markFree(sym, enclosure.enclosure) if (intermediate.exists) narrowLiftedOwner(enclosure, intermediate) - if (!intermediate.isRealClass || enclosure.isConstructor) { + if (!intermediate.isRealClass || enclosure.isConstructor) // Constructors and methods nested inside traits get the free variables // of the enclosing trait or class. // Conversely, local traits do not get free variables. - if (!enclosure.is(Trait)) { + if (!enclosure.is(Trait)) if (symSet(free, enclosure).add(sym)) { changedFreeVars = true ctx.log(i"$sym is free in $enclosure") } - } - } if (intermediate.isRealClass) intermediate else if (enclosure.isRealClass) enclosure else if (intermediate.isClass) intermediate @@ -203,10 +200,9 @@ object LambdaLift { tree match { case tree: Ident => - if (isLocal(sym)) { + if (isLocal(sym)) if (sym is Method) markCalled(sym, enclosure) else if (sym.isTerm) markFree(sym, enclosure) - } def captureImplicitThis(x: Type): Unit = x match { case tr@TermRef(x, _) if (!tr.termSymbol.isStatic) => captureImplicitThis(x) @@ -361,10 +357,9 @@ object LambdaLift { initFlags = initFlags, info = liftedInfo(local)).installAfter(thisPhase) } - for (local <- free.keys) { + for (local <- free.keys) if (!liftedOwner.contains(local)) local.copySymDenotation(info = liftedInfo(local)).installAfter(thisPhase) - } } // initialization diff --git a/compiler/src/dotty/tools/dotc/transform/LinkScala2Impls.scala b/compiler/src/dotty/tools/dotc/transform/LinkScala2Impls.scala index 62d055e60e3c..d97d51142012 100644 --- a/compiler/src/dotty/tools/dotc/transform/LinkScala2Impls.scala +++ b/compiler/src/dotty/tools/dotc/transform/LinkScala2Impls.scala @@ -56,10 +56,9 @@ class LinkScala2Impls extends MiniPhase with IdentityDenotTransformer { thisPhas info = staticInfo(mold.info) ) } - for (sym <- mixin.info.decls) { + for (sym <- mixin.info.decls) if (needsMixinForwarder(sym) || sym.isConstructor || sym.isGetter && sym.is(Lazy) || sym.is(Method, butNot = Deferred)) newImpl(sym.asTerm).enteredAfter(thisPhase) - } // The trait is now fully augmented so the flag isn't needed anymore. mixin.resetFlag(Scala2xPartiallyAugmented) } diff --git a/compiler/src/dotty/tools/dotc/transform/Memoize.scala b/compiler/src/dotty/tools/dotc/transform/Memoize.scala index 65263544c3ab..98b9a0c532da 100644 --- a/compiler/src/dotty/tools/dotc/transform/Memoize.scala +++ b/compiler/src/dotty/tools/dotc/transform/Memoize.scala @@ -105,7 +105,7 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase => val NoFieldNeeded = Lazy | Deferred | JavaDefined | (if (ctx.settings.YnoInline.value) EmptyFlags else Inline) - def erasedBottomTree(sym: Symbol) = { + def erasedBottomTree(sym: Symbol) = if (sym eq defn.NothingClass) Throw(nullLiteral) else if (sym eq defn.NullClass) nullLiteral else if (sym eq defn.BoxedUnitClass) ref(defn.BoxedUnit_UNIT) @@ -113,7 +113,6 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase => assert(false, s"$sym has no erased bottom tree") EmptyTree } - } if (sym.is(Accessor, butNot = NoFieldNeeded)) { val field = sym.field.orElse(newField).asTerm @@ -136,7 +135,8 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase => addAnnotations(fieldDef.denot) removeAnnotations(sym) Thicket(fieldDef, getterDef) - } else if (sym.isSetter) { + } + else if (sym.isSetter) { if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs } // This is intended as an assertion field.setFlag(Mutable) // Necessary for vals mixed in from Scala2 traits val initializer = diff --git a/compiler/src/dotty/tools/dotc/transform/Mixin.scala b/compiler/src/dotty/tools/dotc/transform/Mixin.scala index 9e20dd13abd1..2dd7af23f804 100644 --- a/compiler/src/dotty/tools/dotc/transform/Mixin.scala +++ b/compiler/src/dotty/tools/dotc/transform/Mixin.scala @@ -200,10 +200,9 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase => else call :: Nil case None => if (baseCls.isAllOf(NoInitsTrait) || defn.NoInitClasses.contains(baseCls) || defn.isFunctionClass(baseCls)) Nil - else { + else //println(i"synth super call ${baseCls.primaryConstructor}: ${baseCls.primaryConstructor.info}") transformFollowingDeep(superRef(baseCls.primaryConstructor).appliedToNone) :: Nil - } } def wasOneOf(sym: Symbol, flags: FlagSet) = @@ -236,14 +235,13 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase => val rhs = if (wasOneOf(getter, ParamAccessor)) nextArgument() - else if (isScala2x) { + else if (isScala2x) if (getter.is(Lazy, butNot = Module)) initial else if (getter.is(Module)) New(getter.info.resultType, List(This(cls))) else Underscore(getter.info.resultType) - } else initial // transformFollowing call is needed to make memoize & lazy vals run diff --git a/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala b/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala index b89fef2aad1d..ba57008bb0a8 100644 --- a/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala +++ b/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala @@ -102,7 +102,7 @@ object OverridingPairs { * overriding = curEntry.sym */ private def nextOverriding(): Unit = { - @tailrec def loop(): Unit = { + @tailrec def loop(): Unit = if (curEntry ne null) { overriding = curEntry.sym if (visited.contains(overriding)) { @@ -110,7 +110,6 @@ object OverridingPairs { loop() } } - } loop() nextEntry = curEntry } @@ -120,7 +119,7 @@ object OverridingPairs { * overriding = overriding member of the pair, provided hasNext is true * overridden = overridden member of the pair, provided hasNext is true */ - @tailrec final def next(): Unit = { + @tailrec final def next(): Unit = if (nextEntry ne null) { nextEntry = decls.lookupNextEntry(nextEntry) if (nextEntry ne null) @@ -143,7 +142,6 @@ object OverridingPairs { } next() } - } nextOverriding() next() diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala index 589a9c523120..8a2e610b649b 100644 --- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -903,7 +903,7 @@ object PatternMatcher { case TypeTest(tpt, trusted) => i"TypeTest($tpt, trusted=$trusted)" case _ => test.toString } - def showPlan(plan: Plan): Unit = { + def showPlan(plan: Plan): Unit = if (!seen.contains(plan.id)) { seen += plan.id sb append s"\n${plan.id}: " @@ -929,7 +929,6 @@ object PatternMatcher { sb.append(tree.show) } } - } showPlan(plan) sb.toString } diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index 954d63d36c68..21e748ec594e 100644 --- a/compiler/src/dotty/tools/dotc/transform/Pickler.scala +++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala @@ -116,7 +116,7 @@ class Pickler extends Phase { } } - private def testSame(unpickled: String, previous: String, cls: ClassSymbol)(implicit ctx: Context) = { + private def testSame(unpickled: String, previous: String, cls: ClassSymbol)(implicit ctx: Context) = if (previous != unpickled) { output("before-pickling.txt", previous) output("after-pickling.txt", unpickled) @@ -124,5 +124,4 @@ class Pickler extends Phase { | | diff before-pickling.txt after-pickling.txt""".stripMargin) } - } } diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index a2fcdc4ee3e7..377ad8a63ceb 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -212,10 +212,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase } case tree: TypeApply => val tree1 @ TypeApply(fn, args) = normalizeTypeArgs(tree) - if (fn.symbol != defn.ChildAnnot.primaryConstructor) { + if (fn.symbol != defn.ChildAnnot.primaryConstructor) // Make an exception for ChildAnnot, which should really have AnyKind bounds Checking.checkBounds(args, fn.tpe.widen.asInstanceOf[PolyType]) - } fn match { case sel: Select => val args1 = transform(args) @@ -243,13 +242,12 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase processMemberDef(superAcc.wrapDefDef(tree1)(super.transform(tree1).asInstanceOf[DefDef])) case tree: TypeDef => val sym = tree.symbol - if (sym.isClass) { + if (sym.isClass) // Add SourceFile annotation to top-level classes if (sym.owner.is(Package) && ctx.compilationUnit.source.exists && sym != defn.SourceFileAnnot) sym.addAnnotation(Annotation.makeSourceFile(ctx.compilationUnit.source.file.path)) - } processMemberDef(super.transform(tree)) case tree: New if isCheckable(tree) => Checking.checkInstantiable(tree.tpe, tree.posd) diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index bd1f48e1a45d..bbfc39bf603f 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -85,9 +85,8 @@ class ReifyQuotes extends MacroTransform { case _ => } - override def run(implicit ctx: Context): Unit = { + override def run(implicit ctx: Context): Unit = if (ctx.compilationUnit.needsStaging) super.run(freshStagingContext) - } protected def newTransformer(implicit ctx: Context): Transformer = new Transformer { override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = @@ -186,7 +185,7 @@ class ReifyQuotes extends MacroTransform { // Optimization: avoid the full conversion when capturing `x` // in '{ x } to '{ ${x$1} } and go directly to `x$1` capturers(body.symbol)(body) - case _=> + case _ => val (body1, splices) = nested(isQuote = true).splitQuote(body)(quoteContext) if (level == 0) { val body2 = @@ -194,9 +193,8 @@ class ReifyQuotes extends MacroTransform { else Inlined(Inliner.inlineCallTrace(ctx.owner, quote.sourcePos), Nil, body1) pickledQuote(body2, splices, body.tpe, isType).withSpan(quote.span) } - else { + else body - } } } @@ -213,7 +211,7 @@ class ReifyQuotes extends MacroTransform { .select(name).appliedToType(originalTp) .select("toExpr".toTermName).appliedTo(Literal(Constant(value))) - def pickleAsValue[T](value: T) = { + def pickleAsValue[T](value: T) = value match { case null => ref(defn.QuotedExprModule).select("nullExpr".toTermName) case _: Unit => ref(defn.QuotedExprModule).select("unitExpr".toTermName) @@ -227,7 +225,6 @@ class ReifyQuotes extends MacroTransform { case _: Char => liftedValue(value, "Liftable_Char_delegate".toTermName) case _: String => liftedValue(value, "Liftable_String_delegate".toTermName) } - } def pickleAsTasty() = { val meth = @@ -256,7 +253,7 @@ class ReifyQuotes extends MacroTransform { * and make a hole from these parts. Otherwise issue an error, unless we * are in the body of an inline method. */ - protected def transformSplice(body: Tree, splice: Tree)(implicit ctx: Context): Tree = { + protected def transformSplice(body: Tree, splice: Tree)(implicit ctx: Context): Tree = if (level > 1) { val body1 = nested(isQuote = false).transform(body)(spliceContext) splice match { @@ -276,7 +273,6 @@ class ReifyQuotes extends MacroTransform { if (splice.isType || outer.embedded.isLiftedSymbol(body.symbol)) hole else Inlined(EmptyTree, Nil, hole).withSpan(splice.span) } - } /** Transforms the contents of a nested splice * Assuming @@ -389,7 +385,7 @@ class ReifyQuotes extends MacroTransform { Hole(idx, splices).withType(tpe).asInstanceOf[Hole] } - override def transform(tree: Tree)(implicit ctx: Context): Tree = { + override def transform(tree: Tree)(implicit ctx: Context): Tree = if (tree.source != ctx.source && tree.source.exists) transform(tree)(ctx.withSource(tree.source)) else reporting.trace(i"Reifier.transform $tree at $level", show = true) { @@ -419,13 +415,11 @@ class ReifyQuotes extends MacroTransform { super.transform(tree) } } - } - private def liftList(list: List[Tree], tpe: Type)(implicit ctx: Context): Tree = { + private def liftList(list: List[Tree], tpe: Type)(implicit ctx: Context): Tree = list.foldRight[Tree](ref(defn.NilModule)) { (x, acc) => acc.select("::".toTermName).appliedToType(tpe).appliedTo(x) } - } } } diff --git a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala index b77b27fc305c..9330c524987d 100644 --- a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala +++ b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala @@ -49,7 +49,7 @@ class ResolveSuper extends MiniPhase with IdentityDenotTransformer { thisPhase = yield { util.Stats.record("super accessors") polyDefDef(mkForwarderSym(superAcc.asTerm), forwarderRhsFn(rebindSuper(cls, superAcc))) - } + } val overrides = mixins.flatMap(superAccessors) diff --git a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala index 39ef97865da7..bee4d38e2baf 100644 --- a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala +++ b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala @@ -96,7 +96,8 @@ class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisPh .withType(tree.tpe.asInstanceOf[NamedType].prefix.select(directMethod(tree.symbol))) } directQual(tree.qualifier) - } else tree + } + else tree /** Transform methods with implicit function type result according to rewrite rule (1) above */ override def transformDefDef(mdef: DefDef)(implicit ctx: Context): Tree = { diff --git a/compiler/src/dotty/tools/dotc/transform/Staging.scala b/compiler/src/dotty/tools/dotc/transform/Staging.scala index 6b9cc00ff23e..929a2a056fce 100644 --- a/compiler/src/dotty/tools/dotc/transform/Staging.scala +++ b/compiler/src/dotty/tools/dotc/transform/Staging.scala @@ -37,7 +37,7 @@ class Staging extends MacroTransform { override def allowsImplicitSearch: Boolean = true - override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = { + override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = if (ctx.phase <= ctx.reifyQuotesPhase) { // Recheck that PCP holds but do not heal any inconsistent types as they should already have been heald tree match { @@ -71,11 +71,9 @@ class Staging extends MacroTransform { // OK } } - } - override def run(implicit ctx: Context): Unit = { + override def run(implicit ctx: Context): Unit = if (ctx.compilationUnit.needsStaging) super.run(freshStagingContext) - } protected def newTransformer(implicit ctx: Context): Transformer = new Transformer { override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = diff --git a/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala b/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala index 81a980167303..ee1285281d1d 100644 --- a/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala +++ b/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala @@ -93,11 +93,10 @@ class SyntheticMembers(thisPhase: DenotTransformer) { val isEnumCase = clazz.derivesFrom(defn.EnumClass) && clazz != defn.EnumClass val symbolsToSynthesize: List[Symbol] = - if (clazz.is(Case)) { + if (clazz.is(Case)) if (clazz.is(Module)) caseModuleSymbols else if (isEnumCase) caseSymbols ++ enumCaseSymbols else caseSymbols - } else if (isEnumCase) enumCaseSymbols else if (isDerivedValueClass(clazz)) valueSymbols else Nil @@ -284,14 +283,13 @@ class SyntheticMembers(thisPhase: DenotTransformer) { * * else if either `T` or `U` are primitive, gets the `hashCode` method implemented by [[caseHashCodeBody]] */ - def chooseHashcode(implicit ctx: Context) = { + def chooseHashcode(implicit ctx: Context) = if (clazz.is(ModuleClass)) Literal(Constant(clazz.name.stripModuleClassSuffix.toString.hashCode)) else if (accessors.exists(_.info.finalResultType.classSymbol.isPrimitiveValueClass)) caseHashCodeBody else ref(defn.ScalaRuntime__hashCode).appliedTo(This(clazz)) - } /** The class * @@ -380,51 +378,51 @@ class SyntheticMembers(thisPhase: DenotTransformer) { Nil } - /** The class - * - * ``` - * case class C[T <: U](x: T, y: String*) - * ``` - * - * gets the `fromProduct` method: - * - * ``` - * def fromProduct(x$0: Product): MirroredMonoType = - * new C[U]( - * x$0.productElement(0).asInstanceOf[U], - * x$0.productElement(1).asInstanceOf[Seq[String]]: _*) - * ``` - * where - * ``` - * type MirroredMonoType = C[?] - * ``` - */ - def fromProductBody(caseClass: Symbol, param: Tree)(implicit ctx: Context): Tree = { - val (classRef, methTpe) = - caseClass.primaryConstructor.info match { - case tl: PolyType => - val (tl1, tpts) = constrained(tl, untpd.EmptyTree, alwaysAddTypeVars = true) - val targs = - for (tpt <- tpts) yield - tpt.tpe match { - case tvar: TypeVar => tvar.instantiate(fromBelow = false) - } - (caseClass.typeRef.appliedTo(targs), tl.instantiate(targs)) - case methTpe => - (caseClass.typeRef, methTpe) - } - methTpe match { - case methTpe: MethodType => - val elems = - for ((formal, idx) <- methTpe.paramInfos.zipWithIndex) yield { - val elem = - param.select(defn.Product_productElement).appliedTo(Literal(Constant(idx))) - .ensureConforms(formal.underlyingIfRepeated(isJava = false)) - if (formal.isRepeatedParam) ctx.typer.seqToRepeated(elem) else elem - } - New(classRef, elems) + /** The class + * + * ``` + * case class C[T <: U](x: T, y: String*) + * ``` + * + * gets the `fromProduct` method: + * + * ``` + * def fromProduct(x$0: Product): MirroredMonoType = + * new C[U]( + * x$0.productElement(0).asInstanceOf[U], + * x$0.productElement(1).asInstanceOf[Seq[String]]: _*) + * ``` + * where + * ``` + * type MirroredMonoType = C[?] + * ``` + */ + def fromProductBody(caseClass: Symbol, param: Tree)(implicit ctx: Context): Tree = { + val (classRef, methTpe) = + caseClass.primaryConstructor.info match { + case tl: PolyType => + val (tl1, tpts) = constrained(tl, untpd.EmptyTree, alwaysAddTypeVars = true) + val targs = + for (tpt <- tpts) yield + tpt.tpe match { + case tvar: TypeVar => tvar.instantiate(fromBelow = false) + } + (caseClass.typeRef.appliedTo(targs), tl.instantiate(targs)) + case methTpe => + (caseClass.typeRef, methTpe) } + methTpe match { + case methTpe: MethodType => + val elems = + for ((formal, idx) <- methTpe.paramInfos.zipWithIndex) yield { + val elem = + param.select(defn.Product_productElement).appliedTo(Literal(Constant(idx))) + .ensureConforms(formal.underlyingIfRepeated(isJava = false)) + if (formal.isRepeatedParam) ctx.typer.seqToRepeated(elem) else elem + } + New(classRef, elems) } + } /** For an enum T: * diff --git a/compiler/src/dotty/tools/dotc/transform/TailRec.scala b/compiler/src/dotty/tools/dotc/transform/TailRec.scala index 4f6d03f5e8db..6727ebe3d56d 100644 --- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala +++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala @@ -411,10 +411,9 @@ class TailRec extends MiniPhase { if (inTailPosition) tailPositionLabeledSyms += bind.symbol try cpy.Labeled(tree)(bind, transform(expr)) - finally { + finally if (inTailPosition) tailPositionLabeledSyms -= bind.symbol - } case Return(expr, from) => val fromSym = from.symbol diff --git a/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala b/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala index e1129dd04cde..1835012e8d7a 100644 --- a/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala +++ b/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala @@ -39,26 +39,26 @@ abstract class TransformByNameApply extends MiniPhase { thisPhase: DenotTransfor override def transformApply(tree: Apply)(implicit ctx: Context): Tree = trace(s"transforming ${tree.show} at phase ${ctx.phase}", show = true) { - def transformArg(arg: Tree, formal: Type): Tree = formal.dealias match { - case formalExpr: ExprType => - var argType = arg.tpe.widenIfUnstable - if (defn.isBottomType(argType)) argType = formal.widenExpr - def wrap(arg: Tree) = - ref(defn.cbnArg).appliedToType(argType).appliedTo(arg).withSpan(arg.span) - arg match { - case Apply(Select(qual, nme.apply), Nil) - if qual.tpe.derivesFrom(defn.FunctionClass(0)) && isPureExpr(qual) => - wrap(qual) - case _ => - if (isByNameRef(arg) || arg.symbol == defn.cbnArg) arg - else wrap(mkByNameClosure(arg, argType)) - } - case _ => - arg - } + def transformArg(arg: Tree, formal: Type): Tree = formal.dealias match { + case formalExpr: ExprType => + var argType = arg.tpe.widenIfUnstable + if (defn.isBottomType(argType)) argType = formal.widenExpr + def wrap(arg: Tree) = + ref(defn.cbnArg).appliedToType(argType).appliedTo(arg).withSpan(arg.span) + arg match { + case Apply(Select(qual, nme.apply), Nil) + if qual.tpe.derivesFrom(defn.FunctionClass(0)) && isPureExpr(qual) => + wrap(qual) + case _ => + if (isByNameRef(arg) || arg.symbol == defn.cbnArg) arg + else wrap(mkByNameClosure(arg, argType)) + } + case _ => + arg + } - val mt @ MethodType(_) = tree.fun.tpe.widen - val args1 = tree.args.zipWithConserve(mt.paramInfos)(transformArg) - cpy.Apply(tree)(tree.fun, args1) - } + val mt @ MethodType(_) = tree.fun.tpe.widen + val args1 = tree.args.zipWithConserve(mt.paramInfos)(transformArg) + cpy.Apply(tree)(tree.fun, args1) + } } diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index 70368d7c5ee4..f42011a3e261 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -87,12 +87,11 @@ class TreeChecker extends Phase with SymTransformer { def phaseName: String = "Ycheck" - def run(implicit ctx: Context): Unit = { + def run(implicit ctx: Context): Unit = if (ctx.settings.YtestPickler.value && ctx.phase.prev.isInstanceOf[Pickler]) ctx.echo("Skipping Ycheck after pickling with -Ytest-pickler, the returned tree contains stale symbols") else if (ctx.phase.prev.isCheckable) check(ctx.base.allPhases.toIndexedSeq, ctx) - } private def previousPhases(phases: List[Phase])(implicit ctx: Context): List[Phase] = phases match { case (phase: MegaPhase) :: phases1 => diff --git a/compiler/src/dotty/tools/dotc/transform/YCheckPositions.scala b/compiler/src/dotty/tools/dotc/transform/YCheckPositions.scala index 2a13e72a2fd4..525537e90fe3 100644 --- a/compiler/src/dotty/tools/dotc/transform/YCheckPositions.scala +++ b/compiler/src/dotty/tools/dotc/transform/YCheckPositions.scala @@ -27,12 +27,11 @@ class YCheckPositions extends Phases.Phase { // Check current context is correct assert(ctx.source == sources.head) - if (!tree.isEmpty && !tree.isInstanceOf[untpd.TypedSplice] && ctx.typerState.isGlobalCommittable) { + if (!tree.isEmpty && !tree.isInstanceOf[untpd.TypedSplice] && ctx.typerState.isGlobalCommittable) if (!tree.isType) { // TODO also check types, currently we do not add Inlined(EmptyTree, _, _) for types. We should. val currentSource = sources.head assert(tree.source == currentSource, i"wrong source set for $tree # ${tree.uniqueId} of ${tree.getClass}, set to ${tree.source} but context had $currentSource") } - } // Recursivlely check children while keeping track of current source tree match { diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 339556f62d2b..f92b15ee6fe5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1006,13 +1006,12 @@ trait Applications extends Compatibility { case typedFn => typedFn.tpe.widen match { case pt: PolyType => - if (typedArgs.length <= pt.paramInfos.length && !isNamed) { + if (typedArgs.length <= pt.paramInfos.length && !isNamed) if (typedFn.symbol == defn.Predef_classOf && typedArgs.nonEmpty) { val arg = typedArgs.head if (!arg.symbol.is(Module)) // Allow `classOf[Foo.type]` if `Foo` is an object checkClassType(arg.tpe, arg.sourcePos, traitReq = false, stablePrefixReq = false) } - } case _ => } def tryDynamicTypeApply(): Tree = typedFn match { @@ -1322,8 +1321,7 @@ trait Applications extends Compatibility { tp1.paramInfos.isEmpty && tp2.isInstanceOf[LambdaType] case tp1: PolyType => // (2) val nestedCtx = ctx.fresh.setExploreTyperState() - - { + locally { implicit val ctx = nestedCtx // Fully define the PolyType parameters so that the infos of the diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 7814881c8670..b3756a61613d 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -558,9 +558,8 @@ trait ImplicitRunInfo { } val comps = new TermRefSet - def addCompanion(pre: Type, companion: Symbol) = { + def addCompanion(pre: Type, companion: Symbol) = if (companion.exists && !companion.isAbsent()) comps += TermRef(pre, companion) - } def addPath(pre: Type): Unit = pre.dealias match { case pre: ThisType if pre.cls.is(Module) && pre.cls.isStaticOwner => @@ -735,12 +734,11 @@ trait Implicits { self: Typer => lazy val synthesizedTupleFunction: SpecialHandler = (formal, span) => implicit ctx => formal match { case AppliedType(_, funArgs @ fun :: tupled :: Nil) => - def functionTypeEqual(baseFun: Type, actualArgs: List[Type], actualRet: Type, expected: Type) = { + def functionTypeEqual(baseFun: Type, actualArgs: List[Type], actualRet: Type, expected: Type) = expected =:= defn.FunctionOf(actualArgs, actualRet, defn.isImplicitFunctionType(baseFun), defn.isErasedFunctionType(baseFun)) - } - val arity: Int = { + val arity: Int = if (defn.isErasedFunctionType(fun) || defn.isErasedFunctionType(fun)) -1 // TODO support? - else if (defn.isFunctionType(fun)) { + else if (defn.isFunctionType(fun)) // TupledFunction[(...) => R, ?] fun.dropDependentRefinement.dealias.argInfos match { case funArgs :+ funRet if functionTypeEqual(fun, defn.tupleType(funArgs) :: Nil, funRet, tupled) => @@ -748,7 +746,7 @@ trait Implicits { self: Typer => funArgs.size case _ => -1 } - } else if (defn.isFunctionType(tupled)) { + else if (defn.isFunctionType(tupled)) // TupledFunction[?, (...) => R] tupled.dropDependentRefinement.dealias.argInfos match { case tupledArgs :: funRet :: Nil => @@ -760,12 +758,9 @@ trait Implicits { self: Typer => } case _ => -1 } - } - else { + else // TupledFunction[?, ?] -1 - } - } if (arity == -1) EmptyTree else if (arity <= Definitions.MaxImplementedFunctionArity) @@ -1003,7 +998,7 @@ trait Implicits { self: Typer => assert(caseClass.is(Case)) if (caseClass.is(Module)) caseClass.sourceModule.termRef - else { + else caseClass.primaryConstructor.info match { case info: PolyType => // Compute the the full child type by solving the subtype constraint @@ -1031,7 +1026,6 @@ trait Implicits { self: Typer => case _ => caseClass.typeRef } - } case child => child.termRef } @@ -1054,7 +1048,8 @@ trait Implicits { self: Typer => if (cls.linkedClass.exists && !cls.is(Scala2x)) companionPath(mirroredType, span) else anonymousMirror(monoType, ExtendsSumMirror, span) mirrorRef.cast(mirrorType) - } else EmptyTree + } + else EmptyTree case _ => EmptyTree } } @@ -1109,10 +1104,9 @@ trait Implicits { self: Typer => } val base = baseWithRefinements(formal) val result = - if (base <:< formal.widenExpr) { + if (base <:< formal.widenExpr) // With the subtype test we enforce that the searched type `formal` is of the right form handler(base, span)(ctx) - } else EmptyTree result.orElse(trySpecialCases(rest)) case Nil => @@ -1303,9 +1297,9 @@ trait Implicits { self: Typer => if (argument.isEmpty) i"missing implicit parameter of type $pt after typer" else i"type error: ${argument.tpe} does not conform to $pt${err.whyNoMatchStr(argument.tpe, pt)}") val result0 = - try { + try new ImplicitSearch(pt, argument, span).bestImplicit(contextual = true) - } catch { + catch { case ce: CyclicReference => ce.inImplicitSearch = true throw ce @@ -1322,7 +1316,7 @@ trait Implicits { self: Typer => case result: SearchFailure if result.isAmbiguous => val deepPt = pt.deepenProto if (deepPt ne pt) inferImplicit(deepPt, argument, span) - else if (ctx.scala2Mode && !ctx.mode.is(Mode.OldOverloadingResolution)) { + else if (ctx.scala2Mode && !ctx.mode.is(Mode.OldOverloadingResolution)) inferImplicit(pt, argument, span)(ctx.addMode(Mode.OldOverloadingResolution)) match { case altResult: SearchSuccess => ctx.migrationWarning( @@ -1332,7 +1326,6 @@ trait Implicits { self: Typer => case _ => result } - } else result case NoMatchingImplicitsFailure => SearchFailure(new NoMatchingImplicits(pt, argument, ctx.typerState.constraint)) @@ -1402,9 +1395,9 @@ trait Implicits { self: Typer => ctx.error(em"ambiguous implicit: $generated is eligible both as an implicit conversion and as an extension method container") } result - } - else tryConversion } + else tryConversion + } if (ctx.reporter.hasErrors) { ctx.reporter.removeBufferedMessages SearchFailure { @@ -1497,7 +1490,7 @@ trait Implicits { self: Typer => * - otherwise add the failure to `rfailures` and continue testing the other candidates. */ def rank(pending: List[Candidate], found: SearchResult, rfailures: List[SearchFailure]): SearchResult = - pending match { + pending match { case cand :: remaining => negateIfNot(tryImplicit(cand, contextual)) match { case fail: SearchFailure => diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index dbf633f6095f..96aea1c65745 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -222,9 +222,7 @@ object Inliner { case _ => EmptyTree } - } - } } diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index b2585dc7e591..34be6ad819bf 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -22,9 +22,9 @@ import transform.TypeUtils._ import transform.SymUtils._ import reporting.diagnostic.messages._ -trait NamerContextOps { +trait NamerContextOps { this: Context => - + import NamerContextOps._ def typer: Typer = ctx.typeAssigner match { @@ -140,9 +140,8 @@ trait NamerContextOps { else (params.head.is(Given), params.head.is(Implicit), params.head.is(Erased)) val make = MethodType.companion(isJava = isJava, isContextual = isContextual, isImplicit = isImplicit, isErased = isErased) if (isJava) - for (param <- params) { + for (param <- params) if (param.info.isDirectRef(defn.ObjectClass)) param.info = defn.AnyType - } make.fromSymbols(params, resultType) } if (typeParams.nonEmpty) PolyType.fromParams(typeParams.asInstanceOf[List[TypeSymbol]], monotpe) @@ -760,7 +759,8 @@ class Namer { typer: Typer => try { val expr1 = typedAheadExpr(imp.expr, AnySelectionProto) ImportType(expr1) - } catch { + } + catch { case ex: CyclicReference => typr.println(s"error while completing ${imp.expr}") throw ex @@ -955,7 +955,7 @@ class Namer { typer: Typer => other => cls.derivesFrom(other.owner) && !other.is(Deferred)) match { case Some(other) => i"overrides ${other.showLocated}, which is already a member of $cls" case None => "" - } + } else "" } @@ -1022,8 +1022,10 @@ class Namer { typer: Typer => } def addForwardersExcept(seen: List[TermName], span: Span): Unit = - for (mbr <- path.tpe.membersBasedOnFlags( - required = EmptyFlags, excluded = PrivateOrSynthetic)) { + for { + mbr <- path.tpe.membersBasedOnFlags(required = EmptyFlags, excluded = PrivateOrSynthetic) + } + { val alias = mbr.name.toTermName if (!seen.contains(alias)) addForwarder(alias, mbr, span) } diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 8e2d0d949747..9e379c6f7367 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -313,10 +313,9 @@ object ProtoTypes { if (!args1.exists(arg => isUndefined(arg.tpe))) state.typedArgs = args1 args1 } - finally { + finally if (this.ctx.typerState.constraint ne prevConstraint) ctx.typerState.mergeConstraintWith(this.ctx.typerState) - } } /** Type single argument and remember the unadapted result in `myTypedArg`. diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 19eeca6d0fd3..c8e76126870b 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -665,11 +665,10 @@ object RefChecks { */ def checkCaseClassInheritanceInvariant() = for (caseCls <- clazz.info.baseClasses.tail.find(_.is(Case))) - for (baseCls <- caseCls.info.baseClasses.tail) { + for (baseCls <- caseCls.info.baseClasses.tail) if (baseCls.typeParams.exists(_.paramVariance != 0)) for (problem <- variantInheritanceProblems(baseCls, caseCls, "non-variant", "case ")) ctx.errorOrMigrationWarning(problem(), clazz.sourcePos) - } checkNoAbstractMembers() if (abstractErrors.isEmpty) checkNoAbstractDecls(clazz) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a7bf1dacee77..8e3adf71addb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -322,9 +322,8 @@ class Typer extends Namer else { // find import val outer = ctx.outer val curImport = ctx.importInfo - def updateUnimported() = { + def updateUnimported() = if (curImport.unimported.exists) unimported += curImport.unimported - } if (ctx.owner.is(Package) && curImport != null && curImport.isRootImport && previous.exists) previous // no more conflicts possible in this case else if (isPossibleImport(NamedImport) && (curImport ne outer.importInfo)) { diff --git a/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala b/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala index a456633f1bc5..b5d2b840c5e7 100644 --- a/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala +++ b/compiler/src/dotty/tools/dotc/util/SimpleIdentityMap.scala @@ -163,9 +163,8 @@ object SimpleIdentityMap { return { if (size == CompactifyThreshold) { var m: SimpleIdentityMap[K, V] = Empty[K] - for (j <- 0 until bindings.length by 2) { + for (j <- 0 until bindings.length by 2) if (j != i) m = m.updated(key(j), value(j)) - } m } else {