Skip to content

Commit 964792d

Browse files
Merge pull request #7015 from dotty-staging/fix-#7013
Fix #7013: Check PCP for all class references
2 parents ec51eb0 + e58a160 commit 964792d

File tree

4 files changed

+42
-15
lines changed

4 files changed

+42
-15
lines changed

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

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,12 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
138138
/** Is a reference to a class but not `this.type` */
139139
def isClassRef = sym.isClass && !tp.isInstanceOf[ThisType]
140140

141-
if (sym.exists && !sym.isStaticOwner && !isClassRef && !levelOK(sym))
141+
if (!sym.exists || levelOK(sym))
142+
None
143+
else if (!sym.isStaticOwner && !isClassRef)
142144
tryHeal(sym, tp, pos)
145+
else if (!sym.owner.isStaticOwner) // non-top level class reference that is phase inconsistent
146+
levelError(sym, tp, pos, "")
143147
else
144148
None
145149
}
@@ -170,17 +174,6 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
170174
* to be added to the "inconsistent phase" message.
171175
*/
172176
protected def tryHeal(sym: Symbol, tp: Type, pos: SourcePosition)(implicit ctx: Context): Option[Tree] = {
173-
def levelError(errMsg: String) = {
174-
def symStr =
175-
if (!tp.isInstanceOf[ThisType]) sym.show
176-
else if (sym.is(ModuleClass)) sym.sourceModule.show
177-
else i"${sym.name}.this"
178-
ctx.error(
179-
em"""access to $symStr from wrong staging level:
180-
| - the definition is at level ${levelOf(sym).getOrElse(0)},
181-
| - but the access is at level $level.$errMsg""", pos)
182-
None
183-
}
184177
tp match {
185178
case tp: TypeRef =>
186179
if (level == -1) {
@@ -193,19 +186,33 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
193186
case _: TermRef =>
194187
Some(tag.select(tpnme.splice))
195188
case _: SearchFailureType =>
196-
levelError(i"""
189+
levelError(sym, tp, pos,
190+
i"""
197191
|
198192
| The access would be accepted with the right type tag, but
199193
| ${ctx.typer.missingArgMsg(tag, reqType, "")}""")
200194
case _ =>
201-
levelError(i"""
195+
levelError(sym, tp, pos,
196+
i"""
202197
|
203198
| The access would be accepted with an implict $reqType""")
204199
}
205200
}
206201
case _ =>
207-
levelError("")
202+
levelError(sym, tp, pos, "")
208203
}
209204
}
210205

206+
private def levelError(sym: Symbol, tp: Type, pos: SourcePosition, errMsg: String) given Context = {
207+
def symStr =
208+
if (!tp.isInstanceOf[ThisType]) sym.show
209+
else if (sym.is(ModuleClass)) sym.sourceModule.show
210+
else i"${sym.name}.this"
211+
the[Context].error(
212+
em"""access to $symStr from wrong staging level:
213+
| - the definition is at level ${levelOf(sym).getOrElse(0)},
214+
| - but the access is at level $level.$errMsg""", pos)
215+
None
216+
}
217+
211218
}

tests/neg/i7013.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import quoted._
2+
3+
def foo() given QuoteContext = {
4+
class C
5+
'[C] // error
6+
}

tests/neg/i7013b.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import quoted._
2+
3+
class Foo {
4+
class Bar
5+
def foo() given QuoteContext = {
6+
'[Bar] // error
7+
}
8+
}

tests/neg/i7013c.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import quoted._
2+
3+
def foo() given QuoteContext = {
4+
type C
5+
'[C] // error
6+
}

0 commit comments

Comments
 (0)