From c5430b0b7198a05ba783d3b84f9f78e05e6279ce Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 6 Dec 2021 10:25:10 +0100 Subject: [PATCH 1/2] Traverse the types to find undesired references Undesired references can be to deprecated or experimental terms or types. Fixes #14034 --- .../tools/backend/jvm/BTypesFromSymbols.scala | 2 +- .../src/dotty/tools/dotc/typer/RefChecks.scala | 15 ++++++++++++++- tests/neg-custom-args/deprecation/14034b.scala | 14 ++++++++++++++ tests/neg-custom-args/no-experimental/14034.scala | 12 ++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/neg-custom-args/deprecation/14034b.scala create mode 100644 tests/neg-custom-args/no-experimental/14034.scala diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 78dfd8e0a869..25a05077626a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -5,7 +5,7 @@ package jvm import scala.tools.asm import scala.annotation.threadUnsafe import scala.collection.mutable -import scala.collection.generic.Clearable +import scala.collection.mutable.Clearable import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.core.Contexts._ diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 4c20f5821ca4..b89205a1b666 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -1339,7 +1339,20 @@ class RefChecks extends MiniPhase { thisPhase => } override def transformTypeTree(tree: TypeTree)(using Context): TypeTree = { - checkExperimental(tree.symbol, tree.srcPos) + object CheckExperimental extends TypeTraverser { + def traverse(tp: Type): Unit = + tp match { + case tp: TypeRef => + checkDeprecated(tp.symbol, tree.srcPos) + checkExperimental(tp.symbol, tree.srcPos) + case tp: TermRef => + checkDeprecated(tp.symbol, tree.srcPos) + checkExperimental(tp.symbol, tree.srcPos) + case _ => + traverseChildren(tp) + } + } + CheckExperimental.traverse(tree.tpe) tree } diff --git a/tests/neg-custom-args/deprecation/14034b.scala b/tests/neg-custom-args/deprecation/14034b.scala new file mode 100644 index 000000000000..d22a945fe10d --- /dev/null +++ b/tests/neg-custom-args/deprecation/14034b.scala @@ -0,0 +1,14 @@ + +@deprecated trait Exp +@deprecated val exp = 1 + +def test1 = exp // error +def test2(a: Exp) = () // error + +type Foo0 = Exp // error +type Foo = Option[Exp] // error +type Bar = Option[exp.type] // error +type Baz = Exp | Int // error +type Quux = [X] =>> X match // error + case Exp => Int +type Quuz[A <: Exp] = Int // error diff --git a/tests/neg-custom-args/no-experimental/14034.scala b/tests/neg-custom-args/no-experimental/14034.scala new file mode 100644 index 000000000000..c0b4cc6899db --- /dev/null +++ b/tests/neg-custom-args/no-experimental/14034.scala @@ -0,0 +1,12 @@ +import annotation.experimental + +@experimental trait Exp +@experimental val exp = 1 + +type Foo0 = Exp // error +type Foo = Option[Exp] // error +type Bar = Option[exp.type] // error +type Baz = Exp | Int // error +type Quux = [X] =>> X match // error + case Exp => Int +type Quuz[A <: Exp] = Int // error From a1b7e17b37c9e802d244c89673cdfdc461be5fd3 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 10 Dec 2021 11:42:42 +0100 Subject: [PATCH 2/2] Use foreachPart --- .../dotty/tools/dotc/typer/RefChecks.scala | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index b89205a1b666..dcc4ac09d5ec 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -1339,20 +1339,16 @@ class RefChecks extends MiniPhase { thisPhase => } override def transformTypeTree(tree: TypeTree)(using Context): TypeTree = { - object CheckExperimental extends TypeTraverser { - def traverse(tp: Type): Unit = - tp match { - case tp: TypeRef => - checkDeprecated(tp.symbol, tree.srcPos) - checkExperimental(tp.symbol, tree.srcPos) - case tp: TermRef => - checkDeprecated(tp.symbol, tree.srcPos) - checkExperimental(tp.symbol, tree.srcPos) - case _ => - traverseChildren(tp) - } + val tpe = tree.tpe + tpe.foreachPart { + case TypeRef(_, sym: Symbol) => + checkDeprecated(sym, tree.srcPos) + checkExperimental(sym, tree.srcPos) + case TermRef(_, sym: Symbol) => + checkDeprecated(sym, tree.srcPos) + checkExperimental(sym, tree.srcPos) + case _ => } - CheckExperimental.traverse(tree.tpe) tree }