Skip to content

Commit e25d0fd

Browse files
committed
Keep directly imported idents - fix linting bug
1 parent c5adafc commit e25d0fd

File tree

6 files changed

+90
-43
lines changed

6 files changed

+90
-43
lines changed
Submodule specs2 updated 44 files
Submodule stdLib213 updated 653 files

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

Lines changed: 85 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,14 @@ import Nullables._
5252
import NullOpsDecorator._
5353
import cc.CheckCaptures
5454
import config.Config
55+
import java.io.File
5556

5657
import scala.annotation.constructorOnly
5758
import dotty.tools.dotc.rewrites.Rewrites
59+
import java.nio.file.Files
60+
import java.nio.file.Path
61+
import java.nio.file.Paths
62+
import java.nio.file.StandardOpenOption
5863

5964
object Typer {
6065

@@ -67,6 +72,32 @@ object Typer {
6772
def isImportPrec = this == NamedImport || this == WildImport
6873
}
6974

75+
76+
sealed trait TypeResolution:
77+
def result: Type
78+
def exists = result.exists
79+
def isError(using Context) = result.isError
80+
def prec: BindingPrec
81+
82+
import BindingPrec._
83+
case object NoTypeResolution extends TypeResolution:
84+
def result = NoType
85+
def prec = NothingBound
86+
87+
case class NamedImportedType(result: Type, from: ImportInfo) extends TypeResolution:
88+
def prec = NamedImport
89+
90+
case class WildImportedType(result: Type, from: ImportInfo) extends TypeResolution:
91+
def prec = WildImport
92+
93+
case class DefinitionType(result: Type) extends TypeResolution:
94+
def prec = Definition
95+
96+
case class PackageClauseType(result: Type) extends TypeResolution:
97+
def prec = PackageClause
98+
99+
100+
70101
/** Assert tree has a position, unless it is empty or a typed splice */
71102
def assertPositioned(tree: untpd.Tree)(using Context): Unit =
72103
if (!tree.isEmpty && !tree.isInstanceOf[untpd.TypedSplice] && ctx.typerState.isGlobalCommittable)
@@ -166,7 +197,22 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
166197
* a reference for `m` is searched. `null` in all other situations.
167198
*/
168199
def findRef(name: Name, pt: Type, required: FlagSet, excluded: FlagSet, pos: SrcPos,
169-
altImports: mutable.ListBuffer[TermRef] | Null = null)(using Context): Type = {
200+
altImports: mutable.ListBuffer[TermRef] | Null = null)(using Context): Type =
201+
findRefResolution(name, pt, required, excluded, pos, altImports).result
202+
203+
/** Find the type of an identifier with given `name` in given context `ctx`.
204+
* @param name the name of the identifier
205+
* @param pt the expected type
206+
* @param required flags the result's symbol must have
207+
* @param excluded flags the result's symbol must not have
208+
* @param pos indicates position to use for error reporting
209+
* @param altImports a ListBuffer in which alternative imported references are
210+
* collected in case `findRef` is called from an expansion of
211+
* an extension method, i.e. when `e.m` is expanded to `m(e)` and
212+
* a reference for `m` is searched. `null` in all other situations.
213+
*/
214+
def findRefResolution(name: Name, pt: Type, required: FlagSet, excluded: FlagSet, pos: SrcPos,
215+
altImports: mutable.ListBuffer[TermRef] | Null = null)(using Context): TypeResolution = {
170216
val refctx = ctx
171217
val noImports = ctx.mode.is(Mode.InPackageClauseName)
172218
def suppressErrors = excluded.is(ConstructorProxy)
@@ -211,7 +257,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
211257
* @param prevCtx The context of the previous denotation,
212258
* or else `NoContext` if nothing was found yet.
213259
*/
214-
def findRefRecur(previous: Type, prevPrec: BindingPrec, prevCtx: Context)(using Context): Type = {
260+
def findRefRecur(previous: TypeResolution, prevCtx: Context)(using Context): TypeResolution = {
215261
import BindingPrec._
216262

217263
/** Check that any previously found result from an inner context
@@ -223,18 +269,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
223269
* previous and new contexts do not have the same scope, we select
224270
* the previous (inner) definition. This models what scalac does.
225271
*/
226-
def checkNewOrShadowed(found: Type, newPrec: BindingPrec, scala2pkg: Boolean = false)(using Context): Type =
227-
if !previous.exists || TypeComparer.isSameRef(previous, found) then
272+
def checkNewOrShadowed(found: TypeResolution, scala2pkg: Boolean = false)(using Context): TypeResolution =
273+
if !previous.exists || TypeComparer.isSameRef(previous.result, found.result) then
228274
found
229275
else if (prevCtx.scope eq ctx.scope)
230-
&& (newPrec == Definition || newPrec == NamedImport && prevPrec == WildImport)
276+
&& (found.prec == Definition || found.prec == NamedImport && previous.prec == WildImport)
231277
then
232278
// special cases: definitions beat imports, and named imports beat
233279
// wildcard imports, provided both are in contexts with same scope
234280
found
235281
else
236282
if !scala2pkg && !previous.isError && !found.isError then
237-
fail(AmbiguousReference(name, newPrec, prevPrec, prevCtx))
283+
fail(AmbiguousReference(name, found.prec, previous.prec, prevCtx))
238284
previous
239285

240286
/** Assemble and check alternatives to an imported reference. This implies:
@@ -253,10 +299,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
253299
* @param prevCtx the context in which the reference was found
254300
* @param using_Context the outer context of `precCtx`
255301
*/
256-
def checkImportAlternatives(previous: Type, prevPrec: BindingPrec, prevCtx: Context)(using Context): Type =
302+
def checkImportAlternatives(previous: TypeResolution, prevCtx: Context)(using Context): TypeResolution =
257303

258304
def addAltImport(altImp: TermRef) =
259-
if !TypeComparer.isSameRef(previous, altImp)
305+
if !TypeComparer.isSameRef(previous.result, altImp)
260306
&& !altImports.uncheckedNN.exists(TypeComparer.isSameRef(_, altImp))
261307
then
262308
altImports.uncheckedNN += altImp
@@ -265,22 +311,22 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
265311
val curImport = ctx.importInfo.uncheckedNN
266312
namedImportRef(curImport) match
267313
case altImp: TermRef =>
268-
if prevPrec == WildImport then
314+
if previous.prec == WildImport then
269315
// Discard all previously found references and continue with `altImp`
270316
altImports.clear()
271-
checkImportAlternatives(altImp, NamedImport, ctx)(using ctx.outer)
317+
checkImportAlternatives(NamedImportedType(altImp, curImport), ctx)(using ctx.outer)
272318
else
273319
addAltImport(altImp)
274-
checkImportAlternatives(previous, prevPrec, prevCtx)(using ctx.outer)
320+
checkImportAlternatives(previous, prevCtx)(using ctx.outer)
275321
case _ =>
276-
if prevPrec == WildImport then
322+
if previous.prec == WildImport then
277323
wildImportRef(curImport) match
278324
case altImp: TermRef => addAltImport(altImp)
279325
case _ =>
280-
checkImportAlternatives(previous, prevPrec, prevCtx)(using ctx.outer)
326+
checkImportAlternatives(previous, prevCtx)(using ctx.outer)
281327
else
282-
val found = findRefRecur(previous, prevPrec, prevCtx)
283-
if found eq previous then checkNewOrShadowed(found, prevPrec)(using prevCtx)
328+
val found = findRefRecur(previous, prevCtx)
329+
if found eq previous then checkNewOrShadowed(previous)(using prevCtx)
284330
else found
285331
end checkImportAlternatives
286332

@@ -369,12 +415,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
369415
/** Would import of kind `prec` be not shadowed by a nested higher-precedence definition? */
370416
def isPossibleImport(prec: BindingPrec)(using Context) =
371417
!noImports &&
372-
(prevPrec.ordinal < prec.ordinal || prevPrec == prec && (prevCtx.scope eq ctx.scope))
418+
(previous.prec.ordinal < prec.ordinal || previous.prec == prec && (prevCtx.scope eq ctx.scope))
373419

374-
@tailrec def loop(lastCtx: Context)(using Context): Type =
420+
@tailrec def loop(lastCtx: Context)(using Context): TypeResolution =
375421
if (ctx.scope eq EmptyScope) previous
376422
else {
377-
var result: Type = NoType
423+
var result: TypeResolution = NoTypeResolution
378424
val curOwner = ctx.owner
379425

380426
/** Is curOwner a package object that should be skipped?
@@ -469,19 +515,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
469515
effectiveOwner.thisType.select(name, defDenot)
470516
}
471517
if !curOwner.is(Package) || isDefinedInCurrentUnit(defDenot) then
472-
result = checkNewOrShadowed(found, Definition) // no need to go further out, we found highest prec entry
518+
result = checkNewOrShadowed(DefinitionType(found)) // no need to go further out, we found highest prec entry
473519
found match
474520
case found: NamedType
475521
if curOwner.isClass && isInherited(found.denot) && !ctx.compilationUnit.isJava =>
476522
checkNoOuterDefs(found.denot, ctx, ctx)
477523
case _ =>
478524
else
479525
if migrateTo3 && !foundUnderScala2.exists then
480-
foundUnderScala2 = checkNewOrShadowed(found, Definition, scala2pkg = true)
526+
foundUnderScala2 = checkNewOrShadowed(DefinitionType(found), scala2pkg = true).result
481527
if (defDenot.symbol.is(Package))
482-
result = checkNewOrShadowed(previous orElse found, PackageClause)
483-
else if (prevPrec.ordinal < PackageClause.ordinal)
484-
result = findRefRecur(found, PackageClause, ctx)(using ctx.outer)
528+
result = checkNewOrShadowed(PackageClauseType(previous.result orElse found))
529+
else if (previous.prec.ordinal < PackageClause.ordinal)
530+
result = findRefRecur(PackageClauseType(found), ctx)(using ctx.outer)
485531
}
486532

487533
if result.exists then result
@@ -493,13 +539,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
493539
if (curOwner.is(Package) && curImport != null && curImport.isRootImport && previous.exists)
494540
previous // no more conflicts possible in this case
495541
else if (isPossibleImport(NamedImport) && (curImport nen outer.importInfo)) {
496-
val namedImp = namedImportRef(curImport.uncheckedNN)
542+
val curImportNN = curImport.uncheckedNN
543+
val namedImp = namedImportRef(curImportNN)
497544
if (namedImp.exists)
498-
checkImportAlternatives(namedImp, NamedImport, ctx)(using outer)
545+
checkImportAlternatives(NamedImportedType(namedImp, curImportNN), ctx)(using outer)
499546
else if (isPossibleImport(WildImport) && !curImport.nn.importSym.isCompleting) {
500-
val wildImp = wildImportRef(curImport.uncheckedNN)
547+
val wildImp = wildImportRef(curImportNN)
501548
if (wildImp.exists)
502-
checkImportAlternatives(wildImp, WildImport, ctx)(using outer)
549+
checkImportAlternatives(WildImportedType(wildImp, curImportNN), ctx)(using outer)
503550
else {
504551
updateUnimported()
505552
loop(ctx)(using outer)
@@ -518,7 +565,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
518565
loop(NoContext)
519566
}
520567

521-
findRefRecur(NoType, BindingPrec.NothingBound, NoContext)
568+
findRefRecur(NoTypeResolution, NoContext)
522569
}
523570

524571
/** If `tree`'s type is a `TermRef` identified by flow typing to be non-null, then
@@ -573,20 +620,20 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
573620
checkLegalValue(tree2, pt)
574621
return tree2
575622

576-
val rawType =
623+
val (rawType, directlyImported) =
577624
val saved1 = unimported
578625
val saved2 = foundUnderScala2
579626
unimported = Set.empty
580627
foundUnderScala2 = NoType
581628
try
582-
val found = findRef(name, pt, EmptyFlags, EmptyFlags, tree.srcPos)
583-
if foundUnderScala2.exists && !(foundUnderScala2 =:= found) then
629+
val found = findRefResolution(name, pt, EmptyFlags, EmptyFlags, tree.srcPos)
630+
if foundUnderScala2.exists && !(foundUnderScala2 =:= found.result) then
584631
report.migrationWarning(
585632
em"""Name resolution will change.
586633
| currently selected : $foundUnderScala2
587-
| in the future, without -source 3.0-migration: $found""", tree.srcPos)
588-
foundUnderScala2
589-
else found
634+
| in the future, without -source 3.0-migration: ${found.result}""", tree.srcPos)
635+
(foundUnderScala2, false)
636+
else (found.result, found.prec == BindingPrec.NamedImport)
590637
finally
591638
unimported = saved1
592639
foundUnderScala2 = saved2
@@ -618,10 +665,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
618665
case _ =>
619666
ownType
620667

621-
def setType(ownType: Type): Tree =
668+
def setType(ownType: Type, directlyImported: Boolean): Tree =
622669
val checkedType = checkNotShadowed(ownType)
623670
val tree1 = checkedType match
624-
case checkedType: NamedType if !prefixIsElidable(checkedType) =>
671+
case checkedType: NamedType if !prefixIsElidable(checkedType) && !directlyImported =>
625672
ref(checkedType).withSpan(tree.span)
626673
case _ =>
627674
tree.withType(checkedType)
@@ -649,13 +696,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
649696
val selection = untpd.cpy.Select(tree)(qualifier, name)
650697
typed(selection, pt)
651698
else if rawType.exists then
652-
setType(ensureAccessible(rawType, superAccess = false, tree.srcPos))
699+
setType(ensureAccessible(rawType, superAccess = false, tree.srcPos), directlyImported)
653700
else if name == nme._scope then
654701
// gross hack to support current xml literals.
655702
// awaiting a better implicits based solution for library-supported xml
656703
ref(defn.XMLTopScopeModule.termRef)
657704
else if name.toTermName == nme.ERROR then
658-
setType(UnspecifiedErrorType)
705+
setType(UnspecifiedErrorType, false)
659706
else if ctx.owner.isConstructor && !ctx.owner.isPrimaryConstructor
660707
&& ctx.owner.owner.unforcedDecls.lookup(tree.name).exists
661708
then // we are in the arguments of a this(...) constructor call

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
291291
/** This callback is executed once the compilation of this test source finished */
292292
private final def onComplete(testSource: TestSource, reportersOrCrash: Try[Seq[TestReporter]], logger: LoggedRunnable): Unit =
293293
reportersOrCrash match {
294-
case TryFailure(exn) => onFailure(testSource, Nil, logger, Some(s"Fatal compiler crash when compiling: ${testSource.title}:\n${exn.getMessage}${exn.getStackTrace.map("\n\tat " + _).mkString}"))
294+
case TryFailure(exn) => onFailure(testSource, Nil, logger, Some(s"Fatal compiler crash when compiling: ${testSource.title}:\n ${exn.toString()} ${exn.getMessage}${exn.getStackTrace.map("\n\tat " + _).mkString}"))
295295
case TrySuccess(reporters) if !reporters.exists(_.skipped) =>
296296
maybeFailureMessage(testSource, reporters) match {
297297
case Some(msg) => onFailure(testSource, reporters, logger, Option(msg).filter(_.nonEmpty))

0 commit comments

Comments
 (0)