Skip to content

Commit 97319fb

Browse files
authored
Merge pull request scala#5850 from lrytz/merge-2.12-to-2.13-apr-13
Merge 2.12 to 2.13
2 parents 6f0f162 + 5a78a23 commit 97319fb

File tree

5 files changed

+53
-22
lines changed

5 files changed

+53
-22
lines changed

src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,26 +146,26 @@ trait MethodSynthesis {
146146
// if there's no field symbol, the ValDef tree receives the getter symbol and thus is not a synthetic
147147
if (fieldSym != NoSymbol) {
148148
context.unit.synthetics(getterSym) = getter.derivedTree(getterSym)
149-
getterSym setInfo new namer.AccessorTypeCompleter(tree, tree.tpt.isEmpty, isBean = false, isSetter = false)
150-
} else getterSym setInfo new namer.ValTypeCompleter(tree)
149+
getterSym setInfo namer.accessorTypeCompleter(tree, tree.tpt.isEmpty, isBean = false, isSetter = false)
150+
} else getterSym setInfo namer.valTypeCompleter(tree)
151151

152152
enterInScope(getterSym)
153153

154154
if (getter.needsSetter) {
155155
val setter = Setter(tree)
156156
val setterSym = setter.createSym
157157
context.unit.synthetics(setterSym) = setter.derivedTree(setterSym)
158-
setterSym setInfo new namer.AccessorTypeCompleter(tree, tree.tpt.isEmpty, isBean = false, isSetter = true)
158+
setterSym setInfo namer.accessorTypeCompleter(tree, tree.tpt.isEmpty, isBean = false, isSetter = true)
159159
enterInScope(setterSym)
160160
}
161161

162162
// TODO: delay emitting the field to the fields phase (except for private[this] vals, which only get a field and no accessors)
163163
if (fieldSym != NoSymbol) {
164-
fieldSym setInfo new namer.ValTypeCompleter(tree)
164+
fieldSym setInfo namer.valTypeCompleter(tree)
165165
enterInScope(fieldSym)
166166
}
167167
} else {
168-
getterSym setInfo new namer.ValTypeCompleter(tree)
168+
getterSym setInfo namer.valTypeCompleter(tree)
169169
enterInScope(getterSym)
170170
}
171171

@@ -208,11 +208,11 @@ trait MethodSynthesis {
208208
sym
209209
}
210210

211-
val getterCompleter = new namer.AccessorTypeCompleter(tree, missingTpt, isBean = true, isSetter = false)
211+
val getterCompleter = namer.accessorTypeCompleter(tree, missingTpt, isBean = true, isSetter = false)
212212
enterInScope(deriveBeanAccessor(if (hasBeanProperty) "get" else "is") setInfo getterCompleter)
213213

214214
if (tree.mods.isMutable) {
215-
val setterCompleter = new namer.AccessorTypeCompleter(tree, missingTpt, isBean = true, isSetter = true)
215+
val setterCompleter = namer.accessorTypeCompleter(tree, missingTpt, isBean = true, isSetter = true)
216216
enterInScope(deriveBeanAccessor("set") setInfo setterCompleter)
217217
}
218218
}

src/compiler/scala/tools/nsc/typechecker/Namers.scala

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ trait Namers extends MethodSynthesis {
105105

106106
def enterValueParams(vparamss: List[List[ValDef]]): List[List[Symbol]] =
107107
mmap(vparamss) { param =>
108-
enterInScope(assignMemberSymbol(param, mask = ValueParameterFlags)) setInfo new MonoTypeCompleter(param)
108+
enterInScope(assignMemberSymbol(param, mask = ValueParameterFlags)) setInfo monoTypeCompleter(param)
109109
}
110110

111111
protected def owner = context.owner
@@ -337,10 +337,8 @@ trait Namers extends MethodSynthesis {
337337
}
338338
}
339339

340-
def createImportSymbol(tree: Import) = {
341-
val importNamer = namerOf(tree.symbol)
342-
NoSymbol.newImport(tree.pos) setInfo new importNamer.ImportTypeCompleter(tree)
343-
}
340+
def createImportSymbol(tree: Import) =
341+
NoSymbol.newImport(tree.pos) setInfo (namerOf(tree.symbol) importTypeCompleter tree)
344342

345343
/** All PackageClassInfoTypes come from here. */
346344
def createPackageSymbol(pos: Position, pid: RefTree): Symbol = {
@@ -430,8 +428,7 @@ trait Namers extends MethodSynthesis {
430428

431429
def enterModuleDef(tree: ModuleDef) = {
432430
val sym = enterModuleSymbol(tree)
433-
val mcsNamer = namerOf(sym)
434-
sym.moduleClass setInfo new mcsNamer.ModuleClassTypeCompleter(tree)
431+
sym.moduleClass setInfo namerOf(sym).moduleClassTypeCompleter(tree)
435432
sym setInfo completerOf(tree)
436433
validateCompanionDefs(tree)
437434
sym
@@ -667,7 +664,17 @@ trait Namers extends MethodSynthesis {
667664

668665
if (suppress) {
669666
sym setInfo ErrorType
667+
668+
// There are two ways in which we exclude the symbol from being added in typedStats::addSynthetics,
669+
// because we don't know when the completer runs with respect to this loop in addSynthetics
670+
// for (sym <- scope)
671+
// for (tree <- context.unit.synthetics.get(sym) if shouldAdd(sym)) {
672+
// if (!sym.initialize.hasFlag(IS_ERROR))
673+
// newStats += typedStat(tree)
674+
// If we're already in the loop, set the IS_ERROR flag and trigger the condition `sym.initialize.hasFlag(IS_ERROR)`
670675
sym setFlag IS_ERROR
676+
// Or, if we are not yet in the addSynthetics loop, we can just retract our symbol from the synthetics for this unit.
677+
companionContext.unit.synthetics -= sym
671678

672679
// Don't unlink in an error situation to generate less confusing error messages.
673680
// Ideally, our error reporting would distinguish overloaded from recursive user-defined apply methods without signature,
@@ -684,8 +691,7 @@ trait Namers extends MethodSynthesis {
684691
}
685692

686693
def completerOf(tree: MemberDef): TypeCompleter = {
687-
val treeNamer = namerOf(tree.symbol)
688-
val mono = new treeNamer.MonoTypeCompleter(tree)
694+
val mono = namerOf(tree.symbol) monoTypeCompleter tree
689695
val tparams = treeInfo.typeParameters(tree)
690696
if (tparams.isEmpty) mono
691697
else {
@@ -1081,7 +1087,7 @@ trait Namers extends MethodSynthesis {
10811087

10821088
val sym = (
10831089
if (hasType || hasName) {
1084-
owner.typeOfThis = if (hasType) new SelfTypeCompleter(tpt) else owner.tpe_*
1090+
owner.typeOfThis = if (hasType) selfTypeCompleter(tpt) else owner.tpe_*
10851091
val selfSym = owner.thisSym setPos self.pos
10861092
if (hasName) selfSym setName name else selfSym
10871093
}
@@ -1175,7 +1181,7 @@ trait Namers extends MethodSynthesis {
11751181
val res = GenPolyType(tparams0, resultType)
11761182
val pluginsTp = pluginsTypeSig(res, typer, cdef, WildcardType)
11771183

1178-
// Already assign the type to the class symbol (MonoTypeCompleter will do it again).
1184+
// Already assign the type to the class symbol (monoTypeCompleter will do it again).
11791185
// Allows isDerivedValueClass to look at the info.
11801186
clazz setInfo pluginsTp
11811187
if (clazz.isDerivedValueClass) {
@@ -1189,7 +1195,7 @@ trait Namers extends MethodSynthesis {
11891195

11901196
private def moduleSig(mdef: ModuleDef): Type = {
11911197
val moduleSym = mdef.symbol
1192-
// The info of both the module and the moduleClass symbols need to be assigned. MonoTypeCompleter assigns
1198+
// The info of both the module and the moduleClass symbols need to be assigned. monoTypeCompleter assigns
11931199
// the result of typeSig to the module symbol. The module class info is assigned here as a side-effect.
11941200
val result = templateSig(mdef.impl)
11951201
val pluginsTp = pluginsTypeSig(result, typer, mdef, WildcardType)
@@ -1589,7 +1595,7 @@ trait Namers extends MethodSynthesis {
15891595
// (a val's name ends in a " ", so can't compare to def)
15901596
val overridingSym = if (isGetter) vdef.symbol else vdef.symbol.getterIn(valOwner)
15911597

1592-
// We're called from an AccessorTypeCompleter, which is completing the info for the accessor's symbol,
1598+
// We're called from an accessorTypeCompleter, which is completing the info for the accessor's symbol,
15931599
// which may or may not be `vdef.symbol` (see isGetter above)
15941600
val overridden = safeNextOverriddenSymbol(overridingSym)
15951601

@@ -1732,7 +1738,7 @@ trait Namers extends MethodSynthesis {
17321738
}
17331739

17341740
/**
1735-
* TypeSig is invoked by MonoTypeCompleters. It returns the type of a definition which
1741+
* TypeSig is invoked by monoTypeCompleters. It returns the type of a definition which
17361742
* is then assigned to the corresponding symbol (typeSig itself does not need to assign
17371743
* the type to the symbol, but it can if necessary).
17381744
*/
@@ -1923,6 +1929,11 @@ trait Namers extends MethodSynthesis {
19231929
}
19241930
}
19251931

1932+
@deprecated("Instantiate TypeCompleterBase (for monomorphic, non-wrapping completer) or CompleterWrapper directly.", "2.12.2")
1933+
def mkTypeCompleter(t: Tree)(c: Symbol => Unit) = new TypeCompleterBase(t) {
1934+
def completeImpl(sym: Symbol) = c(sym)
1935+
}
1936+
19261937
// NOTE: only meant for monomorphic definitions,
19271938
// do not use to wrap existing completers (see CompleterWrapper for that)
19281939
abstract class TypeCompleterBase[T <: Tree](val tree: T) extends LockingTypeCompleter with FlagAgnosticCompleter

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3168,7 +3168,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
31683168
for (sym <- scope)
31693169
// OPT: shouldAdd is usually true. Call it here, rather than in the outer loop
31703170
for (tree <- context.unit.synthetics.get(sym) if shouldAdd(sym)) {
3171-
newStats += typedStat(tree) // might add even more synthetics to the scope
3171+
// if the completer set the IS_ERROR flag, retract the stat (currently only used by applyUnapplyMethodCompleter)
3172+
if (!sym.initialize.hasFlag(IS_ERROR))
3173+
newStats += typedStat(tree) // might add even more synthetics to the scope
31723174
context.unit.synthetics -= sym
31733175
}
31743176
// the type completer of a synthetic might add more synthetics. example: if the
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trait Companion[T] {
2+
def parse(value: String): Option[T]
3+
def apply(value: String): T = parse(value).get
4+
}

test/files/run/t10261/Test_2.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import scala.util.Try
2+
3+
object C extends Companion[C] {
4+
def parse(v: String) = if (v.nonEmpty) Some(new C(v)) else None
5+
}
6+
7+
case class C(value: String)
8+
9+
object Test {
10+
def main(args: Array[String]): Unit = {
11+
assert(Try{C("")}.isFailure, "Empty value should fail to parse") // check that parse is used to validate input
12+
assert(C("a").value == "a", "Unexpected value")
13+
}
14+
}

0 commit comments

Comments
 (0)