Skip to content

Commit 666739b

Browse files
committed
restrict export wildcard from package
1 parent 31de5df commit 666739b

File tree

7 files changed

+49
-17
lines changed

7 files changed

+49
-17
lines changed

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -719,12 +719,29 @@ trait Checking {
719719
recur(pat, pt)
720720
}
721721

722-
/** Check that `path` is a legal prefix for an import or export clause */
723-
def checkLegalImportPath(path: Tree)(using Context): Unit = {
724-
checkStable(path.tpe, path.srcPos, "import prefix")
722+
private def checkLegalImportOrExportPath(path: Tree, kind: String)(using Context): Unit = {
723+
checkStable(path.tpe, path.srcPos, kind)
725724
if (!ctx.isAfterTyper) Checking.checkRealizable(path.tpe, path.srcPos)
726725
}
727726

727+
/** Check that `path` is a legal prefix for an import clause */
728+
def checkLegalImportPath(path: Tree)(using Context): Unit = {
729+
checkLegalImportOrExportPath(path, "import prefix")
730+
}
731+
732+
/** Check that `path` is a legal prefix for an export clause */
733+
def checkLegalExportPath(path: Tree, selectors: List[untpd.ImportSelector])(using Context): Unit =
734+
checkLegalImportOrExportPath(path, "export prefix")
735+
if
736+
selectors.exists(_.isWildcard)
737+
&& path.tpe.classSymbol.is(PackageClass)
738+
then
739+
// we restrict wildcard export from package as incremental compilation does not yet
740+
// register a dependency on "all members of a package" - see https://github.com/sbt/zinc/issues/226
741+
report.error(
742+
em"Implementation restriction: ${path.tpe.classSymbol} is not a valid prefix " +
743+
"for a wildcard export, as it is a package.", path.srcPos)
744+
728745
/** Check that `tp` is a class type.
729746
* Also, if `traitReq` is true, check that `tp` is a trait.
730747
* Also, if `stablePrefixReq` is true and phase is not after RefChecks,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ class Namer { typer: Typer =>
945945
val buf = new mutable.ListBuffer[tpd.MemberDef]
946946
val Export(expr, selectors) = exp
947947
val path = typedAheadExpr(expr, AnySelectionProto)
948-
checkLegalImportPath(path)
948+
checkLegalExportPath(path, selectors)
949949
lazy val wildcardBound = importBound(selectors, isGiven = false)
950950
lazy val givenBound = importBound(selectors, isGiven = true)
951951

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

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,29 +2235,26 @@ class Typer extends Namer
22352235
def localDummy(cls: ClassSymbol, impl: untpd.Template)(using Context): Symbol =
22362236
newLocalDummy(cls, impl.span)
22372237

2238-
inline def typedImportOrExport[T <: ImportOrExport[Untyped]](imp: T)(
2239-
inline mkTree: (Tree, List[untpd.ImportSelector]) => imp.ThisTree[Type])(using Context): imp.ThisTree[Type] = {
2240-
val expr1 = typedExpr(imp.expr, AnySelectionProto)
2241-
checkLegalImportPath(expr1)
2242-
val selectors1: List[untpd.ImportSelector] = imp.selectors.mapConserve { sel =>
2238+
inline private def typedSelectors(selectors: List[untpd.ImportSelector])(using Context): List[untpd.ImportSelector] =
2239+
selectors.mapConserve { sel =>
22432240
if sel.bound.isEmpty then sel
22442241
else cpy.ImportSelector(sel)(
22452242
sel.imported, sel.renamed, untpd.TypedSplice(typedType(sel.bound)))
22462243
.asInstanceOf[untpd.ImportSelector]
22472244
}
2248-
mkTree(expr1, selectors1)
2249-
}
22502245

22512246
def typedImport(imp: untpd.Import, sym: Symbol)(using Context): Import = {
2252-
typedImportOrExport(imp)((expr1, selectors1) =>
2253-
assignType(cpy.Import(imp)(expr1, selectors1), sym)
2254-
)
2247+
val expr1 = typedExpr(imp.expr, AnySelectionProto)
2248+
checkLegalImportPath(expr1)
2249+
val selectors1 = typedSelectors(imp.selectors)
2250+
assignType(cpy.Import(imp)(expr1, selectors1), sym)
22552251
}
22562252

22572253
def typedExport(exp: untpd.Export)(using Context): Export = {
2258-
typedImportOrExport(exp)((expr1, selectors1) =>
2259-
assignType(cpy.Export(exp)(expr1, selectors1))
2260-
)
2254+
val expr1 = typedExpr(exp.expr, AnySelectionProto)
2255+
// already called `checkLegalExportPath` in Namer
2256+
val selectors1 = typedSelectors(exp.selectors)
2257+
assignType(cpy.Export(exp)(expr1, selectors1))
22612258
}
22622259

22632260
def typedPackageDef(tree: untpd.PackageDef)(using Context): Tree =
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package defaults
2+
3+
given numerics.Ring[Int] = ???

tests/neg/package-export/enums.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package enums
2+
3+
def enumOrdinal[T](t: T): Int = t match
4+
case t: reflect.Enum => t.ordinal
5+
case t => -1
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package numerics
2+
3+
trait Ring[T]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package mylib
2+
3+
export numerics._ // error: package numerics is not a valid prefix for a wildcard export...
4+
5+
export defaults.{given Ring[Int]} // error: package defaults is not a valid prefix for a wildcard export...
6+
7+
export enums.enumOrdinal // ok, enums is a package but export is not wildcard

0 commit comments

Comments
 (0)