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

Literal null match error in ill-formed summon #16861

Closed
nicolasstucki opened this issue Feb 9, 2023 · 10 comments · Fixed by #16887
Closed

Literal null match error in ill-formed summon #16861

nicolasstucki opened this issue Feb 9, 2023 · 10 comments · Fixed by #16887
Assignees
Labels
area:implicits related to implicits itype:bug itype:crash regression This worked in a previous version but doesn't anymore
Milestone

Comments

@nicolasstucki
Copy link
Contributor

Compiler version

3.3.0-RC2

Minimized code

import scala.quoted.*
trait Foo
object Foo:
  inline given foo[T <: Foo]: T = summon[Type.of[T]]

Output (click arrow to expand)

Exception in thread "main" scala.MatchError: Literal(Constant(null)) (of class dotty.tools.dotc.ast.Trees$Literal) while compiling tests/pos-macros/i15685.scala
scala.MatchError: Literal(Constant(null)) (of class dotty.tools.dotc.ast.Trees$Literal)
        at dotty.tools.dotc.ast.tpd$.TypeApply(tpd.scala:55)
        at dotty.tools.dotc.ast.tpd$TreeOps$.appliedToTypeTrees$extension(tpd.scala:973)
        at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4122)
        at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3457)
        at dotty.tools.dotc.typer.ProtoTypes$FunProto.typedArg(ProtoTypes.scala:497)
        at dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:897)
        at dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:897)
        at dotty.tools.dotc.typer.Applications$Application.addTyped$1(Applications.scala:589)
        at dotty.tools.dotc.typer.Applications$Application.matchArgs(Applications.scala:653)
        at dotty.tools.dotc.typer.Applications$Application.init(Applications.scala:492)
        at dotty.tools.dotc.typer.Applications$TypedApply.<init>(Applications.scala:779)
        at dotty.tools.dotc.typer.Applications$ApplyToUntyped.<init>(Applications.scala:896)
        at dotty.tools.dotc.typer.Applications.ApplyTo(Applications.scala:1126)
        at dotty.tools.dotc.typer.Applications.ApplyTo$(Applications.scala:352)
        at dotty.tools.dotc.typer.Typer.ApplyTo(Typer.scala:115)
        at dotty.tools.dotc.typer.Applications.simpleApply$1(Applications.scala:969)
        at dotty.tools.dotc.typer.Applications.realApply$1$$anonfun$2(Applications.scala:1052)
        at dotty.tools.dotc.typer.Typer.tryEither(Typer.scala:3220)
        at dotty.tools.dotc.typer.Applications.realApply$1(Applications.scala:1063)
        at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:1101)
        at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:352)
        at dotty.tools.dotc.typer.Typer.typedApply(Typer.scala:115)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2950)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3013)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3080)
        at dotty.tools.dotc.typer.Implicits.tryConversion$1(Implicits.scala:1124)
        at dotty.tools.dotc.typer.Implicits.typedImplicit(Implicits.scala:1155)
        at dotty.tools.dotc.typer.Implicits.typedImplicit$(Implicits.scala:806)
        at dotty.tools.dotc.typer.Typer.typedImplicit(Typer.scala:115)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.tryImplicit(Implicits.scala:1227)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.rank$1(Implicits.scala:1326)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1496)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1524)
        at dotty.tools.dotc.typer.Implicits$ImplicitSearch.bestImplicit(Implicits.scala:1557)
        at dotty.tools.dotc.typer.Implicits.inferImplicit(Implicits.scala:1048)
        at dotty.tools.dotc.typer.Implicits.inferImplicit$(Implicits.scala:806)
        at dotty.tools.dotc.typer.Typer.inferImplicit(Typer.scala:115)
        at dotty.tools.dotc.typer.Implicits.inferView(Implicits.scala:844)
        at dotty.tools.dotc.typer.Implicits.inferView$(Implicits.scala:806)
        at dotty.tools.dotc.typer.Typer.inferView(Typer.scala:115)
        at dotty.tools.dotc.typer.Implicits.viewExists(Implicits.scala:819)
        at dotty.tools.dotc.typer.Implicits.viewExists$(Implicits.scala:806)
        at dotty.tools.dotc.typer.Typer.viewExists(Typer.scala:115)
        at dotty.tools.dotc.typer.Implicits.ignoredConvertibleImplicits$1$$anonfun$3(Implicits.scala:948)
        at scala.collection.Iterator$$anon$6.hasNext(Iterator.scala:479)
        at scala.collection.Iterator.isEmpty(Iterator.scala:466)
        at scala.collection.Iterator.isEmpty$(Iterator.scala:466)
        at scala.collection.AbstractIterator.isEmpty(Iterator.scala:1300)
        at scala.collection.View$Filter.isEmpty(View.scala:146)
        at scala.collection.IterableOnceOps.nonEmpty(IterableOnce.scala:833)
        at scala.collection.IterableOnceOps.nonEmpty$(IterableOnce.scala:833)
        at scala.collection.AbstractIterable.nonEmpty(Iterable.scala:933)
        at dotty.tools.dotc.reporting.MissingImplicitArgument.noChainConversionsNote$1(messages.scala:2750)
        at dotty.tools.dotc.reporting.MissingImplicitArgument.msgPostscript$$anonfun$4(messages.scala:2758)
        at scala.Option.orElse(Option.scala:477)
        at dotty.tools.dotc.reporting.MissingImplicitArgument.msgPostscript(messages.scala:2758)
        at dotty.tools.dotc.reporting.Message.message$$anonfun$1(Message.scala:345)
        at dotty.tools.dotc.reporting.Message.inMessageContext(Message.scala:341)
        at dotty.tools.dotc.reporting.Message.message(Message.scala:345)
        at dotty.tools.dotc.reporting.Message.isNonSensical(Message.scala:322)
        at dotty.tools.dotc.reporting.HideNonSensicalMessages.isHidden(HideNonSensicalMessages.scala:16)
        at dotty.tools.dotc.reporting.HideNonSensicalMessages.isHidden$(HideNonSensicalMessages.scala:10)
        at dotty.tools.dotc.reporting.AbstractReporter.isHidden(AbstractReporter.scala:8)
        at dotty.tools.dotc.reporting.Reporter.issueUnconfigured(Reporter.scala:156)
        at dotty.tools.dotc.reporting.Reporter.go$1(Reporter.scala:181)
        at dotty.tools.dotc.reporting.Reporter.issueIfNotSuppressed(Reporter.scala:200)
        at dotty.tools.dotc.reporting.Reporter.report(Reporter.scala:203)
        at dotty.tools.dotc.report$.error(report.scala:69)
        at dotty.tools.dotc.typer.Typer.issueErrors$1$$anonfun$1(Typer.scala:3678)
        at scala.runtime.function.JProcedure3.apply(JProcedure3.java:15)
        at scala.runtime.function.JProcedure3.apply(JProcedure3.java:10)
        at scala.collection.LazyZip3.foreach(LazyZipOps.scala:248)
        at dotty.tools.dotc.typer.Typer.issueErrors$1(Typer.scala:3680)
        at dotty.tools.dotc.typer.Typer.addImplicitArgs$1(Typer.scala:3702)
        at dotty.tools.dotc.typer.Typer.adaptNoArgsImplicitMethod$1(Typer.scala:3719)
        at dotty.tools.dotc.typer.Typer.adaptNoArgs$1(Typer.scala:3908)
        at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4135)
        at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3457)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3080)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3084)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3196)
        at dotty.tools.dotc.typer.Typer.$anonfun$50(Typer.scala:2404)
        at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:249)
        at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2404)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2926)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3012)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3080)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3084)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3106)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3152)
        at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2584)
        at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:2938)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2942)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3012)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3080)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3084)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3106)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3152)
        at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2714)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2983)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3013)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3080)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3084)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3196)
        at dotty.tools.dotc.typer.TyperPhase.typeCheck$$anonfun$1(TyperPhase.scala:44)
        at dotty.tools.dotc.typer.TyperPhase.typeCheck$$anonfun$adapted$1(TyperPhase.scala:54)
        at scala.Function0.apply$mcV$sp(Function0.scala:42)
        at dotty.tools.dotc.core.Phases$Phase.monitor(Phases.scala:437)
        at dotty.tools.dotc.typer.TyperPhase.typeCheck(TyperPhase.scala:54)
        at dotty.tools.dotc.typer.TyperPhase.runOn$$anonfun$3(TyperPhase.scala:88)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.typer.TyperPhase.runOn(TyperPhase.scala:88)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:247)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1321)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:263)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:271)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:280)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:280)
        at dotty.tools.dotc.Run.compileSources(Run.scala:195)
        at dotty.tools.dotc.Run.compile(Run.scala:179)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:35)
        at dotty.tools.dotc.Driver.process(Driver.scala:195)
        at dotty.tools.dotc.Driver.process(Driver.scala:163)
        at dotty.tools.dotc.Driver.process(Driver.scala:175)
        at dotty.tools.dotc.Driver.main(Driver.scala:205)
        at dotty.tools.dotc.Main.main(Main.scala)
@nicolasstucki
Copy link
Contributor Author

Minimized

given foo[T]: Any = summon[bar]
def bar: Nothing = ???

@nicolasstucki
Copy link
Contributor Author

@WojciechMazur, this failure looks like one of the failures in the extended community build that you showed us. Is this the case, or am I misremembering?

@nicolasstucki
Copy link
Contributor Author

This does not crash in 3.2.2. It fails compilation with

[error] Test.scala:1:28: Not found: type bar
[error] given foo[T]: Any = summon[bar]
[error]                            ^^^

@nicolasstucki nicolasstucki added the regression This worked in a previous version but doesn't anymore label Feb 9, 2023
@nicolasstucki
Copy link
Contributor Author

Started in ebb616c

@WojciechMazur
Copy link
Contributor

@nicolasstucki yes, that seems to be exactly the same case as in these two projects:

Project Version Build URL Notes
marcinzh/turbolift 0.25.0 Open CB logs
zio/izumi-reflect 2.2.3 Open CB logs

odersky added a commit to dotty-staging/dotty that referenced this issue Feb 11, 2023
Harden tpd.Apply/TypeApply in case of errors to accept non-sensical terms as
functions.

Fixes scala#16861
@odersky
Copy link
Contributor

odersky commented Feb 11, 2023

I have a fix in #16887 where the crashes are avoided and these examples are now rejected. in particular I get for the original code fragment:

-- [E008] Not Found Error: i16861a.scala:4:46 ----------------------------------
4 |  inline given foo[T <: Foo]: T = summon[Type.of[Foo]] // error
  |                                         ^^^^^^^
  |                             type of is not a member of object quoted.Type
1 error found

But that error looks strange to me as well. I would have expected it to compile or at least give another error since of is clearly a member of quoted.Type. On the other hand, the Quotes given instance is missing, so that probably should be the error.

Kordyjan added a commit that referenced this issue Feb 16, 2023
Harden tpd.Apply/TypeApply in case of errors to accept non-sensical
terms as functions.

Fixes #16861
@Kordyjan Kordyjan added this to the 3.3.1 milestone Aug 1, 2023
@benhutchison
Copy link
Contributor

The "hardening" added in the fix for this issue is blowing up for me:

[info]                 tree: EmptyTree
[info]        tree position: :<unknown>
[info]            tree type: <notype>
[info]               symbol: val <none>
[info]            call site: package <root> in module class <root>
[info]
[info]   == Source file context for tree position ==
[info]
[error] ## Exception when compiling 1 sources to /Users/ben/trayda/modules/asset/target/scala-3.3.1/classes
[error] java.lang.AssertionError: assertion failed
[error] scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:11)
[error] dotty.tools.dotc.ast.tpd$.TypeApply(tpd.scala:60)
[error] dotty.tools.dotc.ast.tpd$TreeOps$.appliedToTypeTrees$extension(tpd.scala:985)
[error] dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4255)

I'm far from being able to minimize the issue. It occurred in an existing module with about 20 dependencies, and appeared after a refactor of some dependee modules.

What I would ask for is more context to help me narrow down where this originates in my code. The assert fails because an error was expected, but there is none:

  def Apply(fn: Tree, args: List[Tree])(using Context): Apply = fn match
    case Block(Nil, expr) =>
      Apply(expr, args)
    case _: RefTree | _: GenericApply | _: Inlined | _: Hole =>
      ta.assignType(untpd.Apply(fn, args), fn, args)
    case _ =>
      assert(ctx.reporter.errorsReported)
      ta.assignType(untpd.Apply(fn, args), fn, args)

If the assert also reported something about what/where fn actually was, that would give me a first clue about how to unpeel it. Otherwise I'm literally trial and error, moving code between compilation units and recompiling, just to determine what expression is triggering the crash.

@benhutchison
Copy link
Contributor

So as so often happens, the AssertionError mentioned above was associated with an underlying compile error, which unfortunately was then (from my POV at least) obscured by the assertion blowing up and preventing underlying errors from being reported.

The only usable diagnostic I had to go on was this output:

[info] exception occurred while typechecking /Users/ben/trayda/modules/asset/src/asset.scala

By splitting the code in asset.scala across two files, I could migrate code back and forth and use the above output to narrow down exactly what the offending line was. Turned out to be a missing implicit, an instance cats.Order[coulomb.DeltaQuantity[Long, U, V]], which when provided 1. resolved the crash and 2. made the code compile.

Can I plead for more informative/diagnostic info for all compiler crashes?

In industrial usage in a big, multi-layered codebase using libraries, truth is minimization of a crash can be extremely difficult. So it may well go unreported to dotty team; the issue templates request a minimized example as mandatory for crash reports.

As an early adopter of Scala 3, we users often will need to work-around, rather than fix, a compiler crash. Having context about what was going on at the crash point helps us to do this.

@odersky
Copy link
Contributor

odersky commented Oct 15, 2023

The "hardening" added in the fix for this issue is blowing up for me:

it would have blown up before as well, with a MatchError. But I see your point; we should either be more lenient, or give more info about what exactly went wrong.

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Oct 16, 2023
These are valid prefixes for a TypeApply in the same way they are for an
Apply.

See scala#16861 (comment)
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Oct 16, 2023
These are valid prefixes for a TypeApply in the same way they are for an
Apply.

See scala#16861 (comment)
@nicolasstucki
Copy link
Contributor Author

I opened #18700 to address this new issue.

nicolasstucki added a commit that referenced this issue Oct 20, 2023
<del>
These are valid prefixes for a TypeApply in the same way they are for an
Apply.

See
#16861 (comment)
</del>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:implicits related to implicits 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