Skip to content

Commit e27005a

Browse files
committed
Flag inferred terms containing skolems as errors
They would crash in the pickler otherwise.
1 parent f8b1c98 commit e27005a

File tree

5 files changed

+56
-1
lines changed

5 files changed

+56
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
150150
UnknownNamedEnclosingClassOrObjectID,
151151
IllegalCyclicTypeReferenceID,
152152
MissingTypeParameterInTypeAppID,
153-
UNUSED_ImplicitTypesCanOnlyBeFunctionTypesID,
153+
SkolemInInferredID,
154154
ErasedTypesCanOnlyBeFunctionTypesID,
155155
CaseClassMissingNonImplicitParamListID,
156156
EnumerationsShouldNotBeEmptyID,

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,24 @@ import transform.SymUtils._
12441244
|""".stripMargin
12451245
}
12461246

1247+
class SkolemInInferred(tree: tpd.Tree, pt: Type, argument: tpd.Tree)(using Context)
1248+
extends TypeMsg(SkolemInInferredID):
1249+
private def argStr =
1250+
if argument.isEmpty then ""
1251+
else i" from argument of type ${argument.tpe.widen}"
1252+
def msg =
1253+
em"""Failure to generate given instance for type $pt$argStr)
1254+
|
1255+
|I found: $tree
1256+
|But the part corresponding to `<skolem>` is not a reference that can be generated.
1257+
|This might be because resolution yielded as given instance a function that is not known to be pure."""
1258+
def explain =
1259+
em"""The part of given resolution that corresponds to `<skolem>` produced a term that
1260+
|is not a stable reference. Therefore a given instance could not be generated.
1261+
|
1262+
|To trouble-shoot the problem, try to supply an explicit expression instead of
1263+
|relying on implicit search at this point."""
1264+
12471265
class SuperQualMustBeParent(qual: untpd.Ident, cls: ClassSymbol)(using Context)
12481266
extends ReferenceMsg(SuperQualMustBeParentID) {
12491267
def msg = em"""|$qual does not name a parent of $cls"""

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,19 @@ trait Implicits:
917917
implicits.println(i"Eql witness found for $ltp / $rtp: $res: ${res.tpe}")
918918
}
919919

920+
object hasSkolem extends TreeAccumulator[Boolean]:
921+
def apply(x: Boolean, tree: Tree)(using Context): Boolean =
922+
x || {
923+
tree match
924+
case tree: Ident => tree.symbol.isSkolem
925+
case Select(qual, _) => apply(x, qual)
926+
case Apply(fn, _) => apply(x, fn)
927+
case TypeApply(fn, _) => apply(x, fn)
928+
case tree: Applications.IntegratedTypeArgs => apply(x, tree.app)
929+
case _: This => false
930+
case _ => foldOver(x, tree)
931+
}
932+
920933
/** Find an implicit parameter or conversion.
921934
* @param pt The expected type of the parameter or conversion.
922935
* @param argument If an implicit conversion is searched, the argument to which
@@ -940,6 +953,8 @@ trait Implicits:
940953
case result: SearchSuccess =>
941954
result.tstate.commit()
942955
ctx.gadt.restore(result.gstate)
956+
if hasSkolem(false, result.tree) then
957+
report.error(SkolemInInferred(result.tree, pt, argument), ctx.source.atSpan(span))
943958
implicits.println(i"success: $result")
944959
implicits.println(i"committing ${result.tstate.constraint} yielding ${ctx.typerState.constraint} in ${ctx.typerState}")
945960
result

tests/neg/i8623.check

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- [E142] Type Error: tests/neg/i8623.scala:11:2 -----------------------------------------------------------------------
2+
11 | unseal.pos // error
3+
| ^^^^^^
4+
| Failure to generate given instance for type ?{ pos: ? } from argument of type ?1.tasty.Tree)
5+
|
6+
| I found: <skolem>.tasty.pos(unseal(given_QC[Any]))
7+
| But the part corresponding to `<skolem>` is not a reference that can be generated.
8+
| This might be because resolution yielded as given instance a function that is not known to be pure.
9+
10+
longer explanation available when compiling with `-explain`

tests/neg/i8623.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
trait QC:
3+
object tasty:
4+
type Tree
5+
extension (tree: Tree)
6+
def pos: Tree = ???
7+
8+
def test =
9+
given [T] as QC = ???
10+
def unseal(using qctx: QC): qctx.tasty.Tree = ???
11+
unseal.pos // error
12+

0 commit comments

Comments
 (0)