From cd969b8014502211fbf477133c5bf54e11beec0d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 16 Jul 2021 18:10:11 +0200 Subject: [PATCH] Remove extended experimental checking This PR makes @experimental behave analogously to @deprecated: if you refer to something that's experimental then the compiler version must be a snapshot release. I don't see a reason for more extensive rules. They are likely more damaging than helpful, as i13091 shows. Fixes #13091 --- .../dotty/tools/dotc/typer/RefChecks.scala | 41 ------------------- tests/pos/i13091.scala | 3 ++ 2 files changed, 3 insertions(+), 41 deletions(-) create mode 100644 tests/pos/i13091.scala diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index af33ca2ff5c2..8bc18f349e85 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -995,20 +995,6 @@ object RefChecks { then Feature.checkExperimentalDef(sym, pos) - private def checkExperimentalSignature(sym: Symbol, pos: SrcPos)(using Context): Unit = - val checker = new TypeTraverser: - def traverse(tp: Type): Unit = - if tp.typeSymbol.isExperimental then - Feature.checkExperimentalDef(tp.typeSymbol, pos) - else - traverseChildren(tp) - if !sym.owner.isExperimental && !pos.span.isSynthetic then // avoid double errors - checker.traverse(sym.info) - - private def checkExperimentalAnnots(sym: Symbol)(using Context): Unit = - for annot <- sym.annotations if annot.symbol.isExperimental && annot.tree.span.exists do - Feature.checkExperimentalDef(annot.symbol, annot.tree) - /** If @migration is present (indicating that the symbol has changed semantics between versions), * emit a warning. */ @@ -1221,16 +1207,6 @@ object RefChecks { f(variableName, variableOffset) end checkImplicitNotFoundAnnotation - - - /** Check that classes extending experimental classes or nested in experimental classes have the @experimental annotation. */ - private def checkExperimentalInheritance(cls: ClassSymbol)(using Context): Unit = - if !cls.hasAnnotation(defn.ExperimentalAnnot) then - cls.info.parents.find(_.typeSymbol.isExperimental) match - case Some(parent) => - report.error(em"extension of experimental ${parent.typeSymbol} must have @experimental annotation", cls.srcPos) - case _ => - end checkExperimentalInheritance } import RefChecks._ @@ -1287,8 +1263,6 @@ class RefChecks extends MiniPhase { thisPhase => override def transformValDef(tree: ValDef)(using Context): ValDef = { checkNoPrivateOverrides(tree) checkDeprecatedOvers(tree) - checkExperimentalAnnots(tree.symbol) - checkExperimentalSignature(tree.symbol, tree) val sym = tree.symbol if (sym.exists && sym.owner.isTerm) { tree.rhs match { @@ -1309,8 +1283,6 @@ class RefChecks extends MiniPhase { thisPhase => override def transformDefDef(tree: DefDef)(using Context): DefDef = { checkNoPrivateOverrides(tree) checkDeprecatedOvers(tree) - checkExperimentalAnnots(tree.symbol) - checkExperimentalSignature(tree.symbol, tree) checkImplicitNotFoundAnnotation.defDef(tree.symbol.denot) checkUnaryMethods(tree.symbol) tree @@ -1324,8 +1296,6 @@ class RefChecks extends MiniPhase { thisPhase => checkCompanionNameClashes(cls) checkAllOverrides(cls) checkImplicitNotFoundAnnotation.template(cls.classDenot) - checkExperimentalInheritance(cls) - checkExperimentalAnnots(cls) tree } catch { @@ -1370,17 +1340,6 @@ class RefChecks extends MiniPhase { thisPhase => } tree } - - override def transformTypeTree(tree: TypeTree)(using Context): TypeTree = { - checkExperimental(tree.symbol, tree.srcPos) - tree - } - - override def transformTypeDef(tree: TypeDef)(using Context): TypeDef = { - checkExperimental(tree.symbol, tree.srcPos) - checkExperimentalAnnots(tree.symbol) - tree - } } /* todo: rewrite and re-enable diff --git a/tests/pos/i13091.scala b/tests/pos/i13091.scala new file mode 100644 index 000000000000..3145e32a4068 --- /dev/null +++ b/tests/pos/i13091.scala @@ -0,0 +1,3 @@ +import annotation.experimental +@experimental trait Foo +val foo = new (Foo @experimental) {} \ No newline at end of file