Skip to content
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

NullPointerException with type lambda + match type #20546

Closed
aherlihy opened this issue Jun 10, 2024 · 2 comments · Fixed by #20553
Closed

NullPointerException with type lambda + match type #20546

aherlihy opened this issue Jun 10, 2024 · 2 comments · Fixed by #20553
Assignees
Labels
area:experimental:named-tuples Issues tied to the named tuples feature. area:typer itype:bug itype:crash regression This worked in a previous version but doesn't anymore
Milestone

Comments

@aherlihy
Copy link
Contributor

aherlihy commented Jun 10, 2024

There is very likely some type-level bug in this code, but even so it should probably not crash with a null pointer

Compiler version

3.5.0-RC1-bin-SNAPSHOT-git-b10d64e

Minimized code

package repro

import NamedTuple.{NamedTuple, AnyNamedTuple}

type And[X <: Boolean, Y <: Boolean] <: Boolean = (X, Y) match
  case (true, true) => true
  case _ => false
type AndLambda = [X <: Boolean, Y <: Boolean] =>> And[X, Y]

trait Expr2[Result, Scalar <: Boolean]:
  type StripScalar[E] = E match
    case Expr2[_, s] => s

  type AllScalar[A <: AnyNamedTuple] = Tuple.Fold[Tuple.Map[NamedTuple.DropNames[A], StripScalar], true, AndLambda]

Output (click arrow to expand)

[error] ## Exception when compiling 12 sources to /Users/anna/lamp/tyql/target/scala-3.5.0-RC1-bin-SNAPSHOT/classes
[error] java.lang.NullPointerException: Cannot invoke "dotty.tools.dotc.core.Types$Type.exists()" because the return value of "dotty.tools.dotc.core.Types$Type.underlyingMatchType(dotty.tools.dotc.core.Contexts$Context)" is null
[error] dotty.tools.dotc.core.Types$Type.isMatchAlias(Types.scala:483)
[error] dotty.tools.dotc.core.Types$AppliedType.tryMatchAlias$1(Types.scala:4672)
[error] dotty.tools.dotc.core.Types$AppliedType.tryNormalize(Types.scala:4687)
[error] dotty.tools.dotc.core.Types$LazyRef.tryNormalize(Types.scala:3244)
[error] dotty.tools.dotc.core.Types$Type.normalized(Types.scala:1547)
[error] dotty.tools.dotc.core.Types$.dotty$tools$dotc$core$Types$AppliedType$$_$tryMatchAlias$1$$anonfun$1$$anonfun$1(Types.scala:4675)
[error] scala.collection.immutable.List.map(List.scala:250)
[error] dotty.tools.dotc.core.Types$AppliedType.tryMatchAlias$1$$anonfun$1(Types.scala:4675)
[error] dotty.tools.dotc.core.MatchTypeTrace$.recurseWith(MatchTypeTrace.scala:88)
[error] dotty.tools.dotc.core.Types$AppliedType.tryMatchAlias$1(Types.scala:4683)
[error] dotty.tools.dotc.core.Types$AppliedType.tryNormalize(Types.scala:4687)
[error] dotty.tools.dotc.core.Types$Type.normalized(Types.scala:1547)
[error] dotty.tools.dotc.core.TypeApplications$.tryReduce$1(TypeApplications.scala:396)
[error] dotty.tools.dotc.core.TypeApplications$.appliedTo$extension(TypeApplications.scala:418)
[error] dotty.tools.dotc.core.Types$AppliedType.derivedAppliedType(Types.scala:4734)
[error] dotty.tools.dotc.core.Substituters$.substParams(Substituters.scala:160)
[error] dotty.tools.dotc.core.Substituters$.mapArgs$2(Substituters.scala:160)
[error] dotty.tools.dotc.core.Substituters$.mapArgs$2(Substituters.scala:160)
[error] dotty.tools.dotc.core.Substituters$.substParams(Substituters.scala:160)
[error] dotty.tools.dotc.core.Substituters$SubstParamsMap.apply(Substituters.scala:201)
[error] dotty.tools.dotc.core.Types$TypeMap.mapOverLambda(Types.scala:6230)
[error] dotty.tools.dotc.core.Types$TypeMap.mapOver(Types.scala:6261)
[error] dotty.tools.dotc.core.Substituters$.substParams(Substituters.scala:163)
[error] dotty.tools.dotc.core.Substituters$SubstParamsMap.apply(Substituters.scala:201)
[error] dotty.tools.dotc.core.Substituters$SubstParamsMap.apply(Substituters.scala:201)
[error] scala.collection.immutable.List.mapConserve(List.scala:472)
[error] dotty.tools.dotc.core.Types$TypeMap.mapOver(Types.scala:6339)
[error] dotty.tools.dotc.core.Substituters$.substParams(Substituters.scala:163)
[error] dotty.tools.dotc.core.Types$Type.substParams(Types.scala:1927)
[error] dotty.tools.dotc.core.Types$LambdaType.instantiate(Types.scala:3879)
[error] dotty.tools.dotc.core.Types$LambdaType.instantiate$(Types.scala:3840)
[error] dotty.tools.dotc.core.Types$HKLambda.instantiate(Types.scala:3917)
[error] dotty.tools.dotc.core.TypeApplications$.tryReduce$1(TypeApplications.scala:395)
[error] dotty.tools.dotc.core.TypeApplications$.appliedTo$extension(TypeApplications.scala:418)
[error] dotty.tools.dotc.core.TypeApplications$.applyIfParameterized$extension(TypeApplications.scala:444)
[error] dotty.tools.dotc.core.Types$AppliedType.superType(Types.scala:4637)
[error] dotty.tools.dotc.core.Types$AppliedType.underlyingMatchType(Types.scala:4666)
[error] dotty.tools.dotc.core.Types$Type.isMatchAlias(Types.scala:483)
[error] dotty.tools.dotc.core.Types$AppliedType.tryMatchAlias$1(Types.scala:4672)
[error] dotty.tools.dotc.core.Types$AppliedType.tryNormalize(Types.scala:4687)
[error] dotty.tools.dotc.core.Types$LazyRef.tryNormalize(Types.scala:3244)
[error] dotty.tools.dotc.core.Types$Type.normalized(Types.scala:1547)
[error] dotty.tools.dotc.core.Types$.dotty$tools$dotc$core$Types$AppliedType$$_$tryMatchAlias$1$$anonfun$1$$anonfun$1(Types.scala:4675)
[error] scala.collection.immutable.List.map(List.scala:250)
[error] dotty.tools.dotc.core.Types$AppliedType.tryMatchAlias$1$$anonfun$1(Types.scala:4675)
[error] dotty.tools.dotc.core.MatchTypeTrace$.recurseWith(MatchTypeTrace.scala:88)
[error] dotty.tools.dotc.core.Types$AppliedType.tryMatchAlias$1(Types.scala:4683)
[error] dotty.tools.dotc.core.Types$AppliedType.tryNormalize(Types.scala:4687)
[error] dotty.tools.dotc.core.Types$Type.normalized(Types.scala:1547)
[error] dotty.tools.dotc.core.TypeApplications$.tryReduce$1(TypeApplications.scala:396)
[error] dotty.tools.dotc.core.TypeApplications$.appliedTo$extension(TypeApplications.scala:418)
[error] dotty.tools.dotc.core.Types$AppliedType.derivedAppliedType(Types.scala:4734)
[error] dotty.tools.dotc.core.Substituters$.substParams(Substituters.scala:160)
[error] dotty.tools.dotc.core.Substituters$.mapArgs$2(Substituters.scala:160)
[error] dotty.tools.dotc.core.Substituters$.mapArgs$2(Substituters.scala:160)
[error] dotty.tools.dotc.core.Substituters$.substParams(Substituters.scala:160)
[error] dotty.tools.dotc.core.Substituters$SubstParamsMap.apply(Substituters.scala:201)
[error] dotty.tools.dotc.core.Types$TypeMap.mapOverLambda(Types.scala:6230)
[error] dotty.tools.dotc.core.Types$TypeMap.mapOver(Types.scala:6261)
[error] dotty.tools.dotc.core.Substituters$.substParams(Substituters.scala:163)
[error] dotty.tools.dotc.core.Substituters$SubstParamsMap.apply(Substituters.scala:201)
[error] dotty.tools.dotc.core.Substituters$SubstParamsMap.apply(Substituters.scala:201)
[error] scala.collection.immutable.List.mapConserve(List.scala:472)
[error] dotty.tools.dotc.core.Types$TypeMap.mapOver(Types.scala:6339)
[error] dotty.tools.dotc.core.Substituters$.substParams(Substituters.scala:163)
[error] dotty.tools.dotc.core.Types$Type.substParams(Types.scala:1927)
[error] dotty.tools.dotc.core.Types$LambdaType.instantiate(Types.scala:3879)
[error] dotty.tools.dotc.core.Types$LambdaType.instantiate$(Types.scala:3840)
[error] dotty.tools.dotc.core.Types$HKLambda.instantiate(Types.scala:3917)
[error] dotty.tools.dotc.core.TypeApplications$.tryReduce$1(TypeApplications.scala:395)
[error] dotty.tools.dotc.core.TypeApplications$.appliedTo$extension(TypeApplications.scala:418)
[error] dotty.tools.dotc.core.TypeApplications$.applyIfParameterized$extension(TypeApplications.scala:444)
[error] dotty.tools.dotc.core.Types$AppliedType.superType(Types.scala:4637)
[error] dotty.tools.dotc.core.Types$AppliedType.underlyingMatchType(Types.scala:4666)
[error] dotty.tools.dotc.core.Types$Type.isMatchAlias(Types.scala:483)
[error] dotty.tools.dotc.core.TypeOps$.simplify(TypeOps.scala:146)
[error] dotty.tools.dotc.core.Types$Type.simplified(Types.scala:2106)
[error] dotty.tools.dotc.typer.Typer.simplify(Typer.scala:3503)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3487)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3561)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3565)
[error] dotty.tools.dotc.typer.Typer.typedType(Typer.scala:3679)
[error] dotty.tools.dotc.typer.Namer.typedAheadType$$anonfun$1(Namer.scala:1744)
[error] dotty.tools.dotc.typer.Namer.typedAhead(Namer.scala:1737)
[error] dotty.tools.dotc.typer.Namer.typedAheadType(Namer.scala:1744)
[error] dotty.tools.dotc.typer.Namer$TypeDefCompleter.typeSig(Namer.scala:1073)
[error] dotty.tools.dotc.typer.Namer$Completer.completeInCreationContext(Namer.scala:974)
[error] dotty.tools.dotc.typer.Namer$Completer.complete(Namer.scala:850)
[error] dotty.tools.dotc.core.SymDenotations$SymDenotation.completeFrom(SymDenotations.scala:175)
[error] dotty.tools.dotc.core.Denotations$Denotation.completeInfo$1(Denotations.scala:190)
[error] dotty.tools.dotc.core.Denotations$Denotation.info(Denotations.scala:192)
[error] dotty.tools.dotc.core.SymDenotations$SymDenotation.ensureCompleted(SymDenotations.scala:393)
[error] dotty.tools.dotc.typer.Typer.retrieveSym(Typer.scala:3346)
[error] dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3371)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3483)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3561)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3565)
[error] dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3587)
[error] dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3633)
[error] dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:3081)
[error] dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3387)
[error] dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3391)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3483)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3561)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3565)
[error] dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3587)
[error] dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3633)
[error] dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:3214)
[error] dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3433)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3484)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3561)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:3565)
[error] dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3676)
[error] dotty.tools.dotc.typer.TyperPhase.typeCheck$$anonfun$1(TyperPhase.scala:47)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] dotty.tools.dotc.core.Phases$Phase.monitor(Phases.scala:503)
[error] dotty.tools.dotc.typer.TyperPhase.typeCheck(TyperPhase.scala:53)
[error] dotty.tools.dotc.typer.TyperPhase.$anonfun$4(TyperPhase.scala:99)
[error] scala.collection.Iterator$$anon$6.hasNext(Iterator.scala:479)
[error] scala.collection.Iterator$$anon$9.hasNext(Iterator.scala:583)
[error] scala.collection.immutable.List.prependedAll(List.scala:152)
[error] scala.collection.immutable.List$.from(List.scala:684)
[error] scala.collection.immutable.List$.from(List.scala:681)
[error] scala.collection.IterableOps$WithFilter.map(Iterable.scala:898)
[error] dotty.tools.dotc.typer.TyperPhase.runOn(TyperPhase.scala:98)
[error] dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:343)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
[error] dotty.tools.dotc.Run.runPhases$1(Run.scala:336)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:384)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:396)
[error] dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:396)
[error] dotty.tools.dotc.Run.compileSources(Run.scala:282)
[error] dotty.tools.dotc.Run.compile(Run.scala:267)
[error] dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
[error] dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:141)
[error] dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
[error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:193)
[error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
[error] sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:248)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:183)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:163)
[error] sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:163)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:211)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:534)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:534)
[error] sbt.internal.inc.Incremental$.$anonfun$apply$5(Incremental.scala:180)
[error] sbt.internal.inc.Incremental$.$anonfun$apply$5$adapted(Incremental.scala:178)
[error] sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:464)
[error] sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:116)
[error] sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56)
[error] sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52)
[error] sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:263)
[error] sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:419)
[error] sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:506)
[error] sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:406)
[error] sbt.internal.inc.Incremental$.apply(Incremental.scala:172)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:534)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:488)
[error] sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:425)
[error] sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137)
[error] sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:2371)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$2(Defaults.scala:2321)
[error] sbt.internal.server.BspCompileTask$.$anonfun$compute$1(BspCompileTask.scala:31)
[error] sbt.internal.io.Retry$.apply(Retry.scala:47)
[error] sbt.internal.io.Retry$.apply(Retry.scala:29)
[error] sbt.internal.io.Retry$.apply(Retry.scala:24)
[error] sbt.internal.server.BspCompileTask$.compute(BspCompileTask.scala:31)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:2319)
[error] scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:63)
[error] sbt.std.Transform$$anon$4.work(Transform.scala:69)
[error] sbt.Execute.$anonfun$submit$2(Execute.scala:283)
[error] sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:24)
[error] sbt.Execute.work(Execute.scala:292)
[error] sbt.Execute.$anonfun$submit$1(Execute.scala:283)
[error] sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error] sbt.CompletionService$$anon$2.call(CompletionService.scala:65)
[error] java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error] java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
[error] java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error] java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[error] java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[error] java.base/java.lang.Thread.run(Thread.java:833)
[error]
[error] stack trace is suppressed; run last Compile / compileIncremental for the full output
[error] (Compile / compileIncremental) java.lang.NullPointerException: Cannot invoke "dotty.tools.dotc.core.Types$Type.exists()" because the return value of "dotty.tools.dotc.core.Types$Type.underlyingMatchType(dotty.tools.dotc.core.Contexts$Context)" is null
[error] Total time: 0 s, completed Jun 10, 2024, 7:12:32 PM```
</details>
@aherlihy aherlihy added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label labels Jun 10, 2024
@noti0na1
Copy link
Member

noti0na1 commented Jun 10, 2024

Interesting, 3.4, 3.5.0-RC1, and 3.5.nightly actually produce different errors:

  • 3.4 and 3.3 produce a compiling error of "Recursion limit exceeded" due to potential illegal cyclic reference.
  • 3.5.0 has NPE at the result of underlyingMatchType
  • 3.5.1 nightly has NPE at the result of AppliedType.superType of underlyingMatchType

I saw some commits around #19871, may related to cachedSuper and cachedUnderlyingMatch I guess?

cc @EugeneFlesselle

@Gedochao Gedochao added area:typer regression This worked in a previous version but doesn't anymore and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jun 11, 2024
@Gedochao
Copy link
Contributor

Last non-crashing stable version: 3.4.2
Last non-crashing nightly: 3.5.0-RC1-bin-20240405-85672a0-NIGHTLY
First crashing nightly: 3.5.0-RC1-bin-20240408-1e8a653-NIGHTLY
Breaks for 3.5.1-RC1 and 3.5.1-RC1-bin-20240607-04ada79-NIGHTLY / current main branch, too.

IMO we should treat it as a regression.

@Gedochao Gedochao added the area:experimental:named-tuples Issues tied to the named tuples feature. label Jun 11, 2024
@EugeneFlesselle EugeneFlesselle self-assigned this Jun 11, 2024
EugeneFlesselle added a commit to dotty-staging/dotty that referenced this issue Jun 11, 2024
since cycles are possible when computing `AppliedType#superType`,
see tests/neg/i20546.scala for an example leading to an NPE.

We could use `ctx.period == validSuper && cachedSuper == null` as condition to detect cycles,
but they are already handled in `TypeApplications#appliedTo`, with a better error message.

We can update `AppliedType#validSuper` only after the computation is done to fix scala#20546
EugeneFlesselle added a commit that referenced this issue Jun 11, 2024
since cycles are possible when computing `AppliedType#superType`,
see tests/neg/i20546.scala for an example leading to an NPE.

We could use `ctx.period == validSuper && cachedSuper == null` as condition to detect cycles,
but they are already handled in `TypeApplications#appliedTo`, with a better error message.

We can update `AppliedType#validSuper` only after the computation is done to fix #20546
@Kordyjan Kordyjan added this to the 3.5.1 milestone Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:experimental:named-tuples Issues tied to the named tuples feature. area:typer itype:bug itype:crash regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants