Skip to content

Fix check experimental inline references #15147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import ast.tpd

class CrossVersionChecks extends MiniPhase:
import tpd.*
import CrossVersionChecks.*

override def phaseName: String = CrossVersionChecks.name

Expand All @@ -27,7 +28,7 @@ class CrossVersionChecks extends MiniPhase:
// arbitrarily choose one as more important than the other.
private def checkUndesiredProperties(sym: Symbol, pos: SrcPos)(using Context): Unit =
checkDeprecated(sym, pos)
checkExperimental(sym, pos)
checkExperimentalRef(sym, pos)
checkSinceAnnot(sym, pos)

val xMigrationValue = ctx.settings.Xmigration.value
Expand Down Expand Up @@ -69,10 +70,6 @@ class CrossVersionChecks extends MiniPhase:
val since = annot.argumentConstant(1).map(" since " + _.stringValue).getOrElse("")
report.deprecationWarning(s"${sym.showLocated} is deprecated${since}${msg}", pos)

private def checkExperimental(sym: Symbol, pos: SrcPos)(using Context): Unit =
if sym.isExperimental && !ctx.owner.isInExperimentalScope then
Feature.checkExperimentalDef(sym, pos)

private def checkExperimentalSignature(sym: Symbol, pos: SrcPos)(using Context): Unit =
class Checker extends TypeTraverser:
def traverse(tp: Type): Unit =
Expand Down Expand Up @@ -192,11 +189,11 @@ class CrossVersionChecks extends MiniPhase:
tpe.foreachPart {
case TypeRef(_, sym: Symbol) =>
checkDeprecated(sym, tree.srcPos)
checkExperimental(sym, tree.srcPos)
checkExperimentalRef(sym, tree.srcPos)
checkSinceAnnot(sym, tree.srcPos)
case TermRef(_, sym: Symbol) =>
checkDeprecated(sym, tree.srcPos)
checkExperimental(sym, tree.srcPos)
checkExperimentalRef(sym, tree.srcPos)
checkSinceAnnot(sym, tree.srcPos)
case _ =>
}
Expand All @@ -214,3 +211,10 @@ end CrossVersionChecks
object CrossVersionChecks:
val name: String = "crossVersionChecks"
val description: String = "check issues related to deprecated and experimental"

/** Check that a reference to an experimental definition with symbol `sym` is only
* used in an experimental scope
*/
def checkExperimentalRef(sym: Symbol, pos: SrcPos)(using Context): Unit =
if sym.isExperimental && !ctx.owner.isInExperimentalScope then
Feature.checkExperimentalDef(sym, pos)
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import ErrorReporting.errorTree
import dotty.tools.dotc.util.{SimpleIdentityMap, SimpleIdentitySet, SourceFile, SourcePosition, SrcPos}
import dotty.tools.dotc.parsing.Parsers.Parser
import Nullables._
import transform.{PostTyper, Inlining}
import transform.{PostTyper, Inlining, CrossVersionChecks}

import collection.mutable
import reporting.trace
Expand Down Expand Up @@ -102,8 +102,7 @@ object Inliner {
if (tree.symbol == defn.CompiletimeTesting_typeChecks) return Intrinsics.typeChecks(tree)
if (tree.symbol == defn.CompiletimeTesting_typeCheckErrors) return Intrinsics.typeCheckErrors(tree)

if tree.symbol.isExperimental then
Feature.checkExperimentalDef(tree.symbol, tree)
CrossVersionChecks.checkExperimentalRef(tree.symbol, tree.srcPos)

if tree.symbol.isConstructor then return tree // error already reported for the inline constructor definition

Expand Down
15 changes: 15 additions & 0 deletions tests/pos-custom-args/no-experimental/i15133a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.annotation.experimental

@experimental
inline def foo: Any = ???

@experimental
object Test {
val x = foo

def bar() = {
foo
}

foo
}
13 changes: 13 additions & 0 deletions tests/pos-custom-args/no-experimental/i15133b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import scala.annotation.experimental

@experimental
inline def foo: Any = ???

object Test {
@experimental val x = foo

@experimental
def bar() = {
foo
}
}