Skip to content

Commit cc28c91

Browse files
committed
Add message to dummy capture paramter usages
1 parent 11fd151 commit cc28c91

File tree

8 files changed

+45
-9
lines changed

8 files changed

+45
-9
lines changed

compiler/src/dotty/tools/dotc/core/SymUtils.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ class SymUtils:
9090
def isContextBoundCompanion(using Context): Boolean =
9191
self.is(Synthetic) && self.infoOrCompleter.typeSymbol == defn.CBCompanion
9292

93+
def isDummyCaptureParam(using Context): Boolean =
94+
self.is(Synthetic) && self.is(CaptureParam) && !(self.isClass || self.is(Method))
95+
9396
/** Is this a case class for which a product mirror is generated?
9497
* Excluded are value classes, abstract classes and case classes with more than one
9598
* parameter section.

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
208208
case UnstableInlineAccessorID // errorNumber: 192
209209
case VolatileOnValID // errorNumber: 193
210210
case ExtensionNullifiedByMemberID // errorNumber: 194
211-
case ConstructorProxyNotValueID // errorNumber: 195
211+
case PhantomSymbolNotValueID // errorNumber: 195
212212
case ContextBoundCompanionNotValueID // errorNumber: 196
213213
case InlinedAnonClassWarningID // errorNumber: 197
214214
case UnusedSymbolID // errorNumber: 198

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3277,7 +3277,7 @@ extends SyntaxMsg(VolatileOnValID):
32773277
protected def explain(using Context): String = ""
32783278

32793279
class ConstructorProxyNotValue(sym: Symbol)(using Context)
3280-
extends TypeMsg(ConstructorProxyNotValueID):
3280+
extends TypeMsg(PhantomSymbolNotValueID):
32813281
protected def msg(using Context): String =
32823282
i"constructor proxy $sym cannot be used as a value"
32833283
protected def explain(using Context): String =
@@ -3292,7 +3292,7 @@ extends TypeMsg(ConstructorProxyNotValueID):
32923292
|but not as a stand-alone value."""
32933293

32943294
class ContextBoundCompanionNotValue(sym: Symbol)(using Context)
3295-
extends TypeMsg(ConstructorProxyNotValueID):
3295+
extends TypeMsg(PhantomSymbolNotValueID):
32963296
protected def msg(using Context): String =
32973297
i"context bound companion $sym cannot be used as a value"
32983298
protected def explain(using Context): String =
@@ -3311,6 +3311,22 @@ extends TypeMsg(ConstructorProxyNotValueID):
33113311
|companion value with the (term-)name `A`. However, these context bound companions
33123312
|are not values themselves, they can only be referred to in selections."""
33133313

3314+
class DummyCaptureParamNotValue(sym: Symbol)(using Context)
3315+
extends TypeMsg(PhantomSymbolNotValueID):
3316+
protected def msg(using Context): String =
3317+
i"dummy term capture parameter $sym cannot be used as a value"
3318+
protected def explain(using Context): String =
3319+
i"""A term capture parameter is a symbol made up by the compiler to represent a reference
3320+
|to a real capture parameter in capture sets. For instance, in
3321+
|
3322+
| class A:
3323+
| type C^
3324+
|
3325+
|there is just a type `A` declared but not a value `A`. Nevertheless, one can write
3326+
|the selection `(a: A).C` and use a a value, which works because the compiler created a
3327+
|term capture parameter for `C`. However, these term capture parameters are not real values,
3328+
|they can only be referred in capture sets."""
3329+
33143330
class UnusedSymbol(errorText: String, val actions: List[CodeAction] = Nil)(using Context)
33153331
extends Message(UnusedSymbolID):
33163332
def kind = MessageKind.UnusedSymbol
@@ -3518,7 +3534,7 @@ final class OnlyFullyDependentAppliedConstructorType()(using Context)
35183534
override protected def explain(using Context): String = ""
35193535

35203536
final class IllegalContextBounds(using Context) extends SyntaxMsg(IllegalContextBoundsID):
3521-
override protected def msg(using Context): String =
3537+
override protected def msg(using Context): String =
35223538
i"Context bounds are not allowed in this position"
35233539

35243540
override protected def explain(using Context): String = ""

compiler/src/dotty/tools/dotc/transform/Getters.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ class Getters extends MiniPhase with SymTransformer { thisPhase =>
8989
else d1 = d1.copySymDenotation(initFlags = d1.flags &~ Local)
9090
d1
9191
}
92-
private val NoGetterNeededFlags = Method | Param | JavaDefined | JavaStatic | CaptureParam
92+
93+
private val NoGetterNeededFlags = Method | Param | JavaDefined | JavaStatic | PhantomSymbol
9394

9495
val newSetters = util.HashSet[Symbol]()
9596

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,10 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
350350
def unusable(msg: Symbol => Message) =
351351
errorTree(tree, msg(tree.symbol))
352352
if tree.symbol.is(PhantomSymbol) then
353-
unusable(ConstructorProxyNotValue(_))
353+
if tree.symbol.isDummyCaptureParam then
354+
unusable(DummyCaptureParamNotValue(_))
355+
else
356+
unusable(ConstructorProxyNotValue(_))
354357
else if tree.symbol.isContextBoundCompanion then
355358
unusable(ContextBoundCompanionNotValue(_))
356359
else
@@ -707,7 +710,6 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
707710
case _ =>
708711
if parents1 ne info.parents then info.derivedClassInfo(declaredParents = parents1)
709712
else tp
710-
case _ if sym.is(PhantomSymbol) => NoType
711713
case _ => tp
712714

713715
private def argTypeOfCaseClassThatNeedsAbstractFunction1(sym: Symbol)(using Context): Option[List[Type]] =

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ object RefChecks {
434434
}
435435

436436
def emitOverrideError(fullmsg: Message) =
437-
if !(hasErrors && member.is(Synthetic) && member.is(Module) || member.is(PhantomSymbol)) then
437+
if !(hasErrors && member.is(Synthetic) && member.is(Module) || member.isDummyCaptureParam) then
438438
// suppress errors relating to synthetic companion objects if other override
439439
// errors (e.g. relating to the companion class) have already been reported.
440440
if (member.owner == clazz) report.error(fullmsg, member.srcPos)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
649649
*/
650650
def checkNotShadowed(ownType: Type): Type =
651651
ownType match
652-
case ownType: TermRef if ownType.symbol.is(PhantomSymbol) && !ctx.mode.is(Mode.InCaptureSet) =>
652+
case ownType: TermRef
653+
if ownType.symbol.is(PhantomSymbol)
654+
&& !(ctx.mode.is(Mode.InCaptureSet) && ownType.symbol.isDummyCaptureParam) =>
653655
findRef(name, pt, EmptyFlags, PhantomSymbol, tree.srcPos) match
654656
case shadowed: TermRef if !shadowed.symbol.maybeOwner.isEmptyPackage =>
655657
pt match
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- [E195] Type Error: tests/neg-custom-args/captures/check-dummy-symbol.scala:6:21 -------------------------------------
2+
6 |def f(a: A): a.C = a.C // error
3+
| ^^^
4+
| dummy term capture parameter value C cannot be used as a value
5+
|
6+
| longer explanation available when compiling with `-explain`
7+
-- [E195] Type Error: tests/neg-custom-args/captures/check-dummy-symbol.scala:7:15 -------------------------------------
8+
7 |def g[C^]: C = C // error
9+
| ^
10+
| dummy term capture parameter value C cannot be used as a value
11+
|
12+
| longer explanation available when compiling with `-explain`

0 commit comments

Comments
 (0)