Repository: scalameta/scalameta (scala)

Issue:
Invariant failed when using this
Scalameta gives an error message including "invariant failed" (which I assume shouldn't happen and indicates a bug in Scalameta) on this (admittedly nonsensical) code:
```
class A
class B extends A:
  def this = this.f()
```
The message:
```
org.scalameta.invariants.InvariantFailedException: invariant failed:
when verifying paramss.!=(null).&&(paramss.nonEmpty)
found that paramss.nonEmpty is false
where paramss = List()
	at org.scalameta.invariants.InvariantFailedException$.raise(Exceptions.scala:19)
	at scala.meta.Ctor$Secondary$.internal$258(Trees.scala:460)
	at scala.meta.Ctor$Secondary$.apply(Trees.scala:460)
	at scala.meta.internal.parsers.ScalametaParser.secondaryCtorRest(ScalametaParser.scala:4736)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$secondaryCtor$1(ScalametaParser.scala:4706)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.secondaryCtor(ScalametaParser.scala:4700)
	at scala.meta.internal.parsers.ScalametaParser.funDefOrDclOrExtensionOrSecondaryCtor(ScalametaParser.scala:4351)
	at scala.meta.internal.parsers.ScalametaParser.defOrDclOrSecondaryCtor(ScalametaParser.scala:4187)
	at scala.meta.internal.parsers.ScalametaParser.nonLocalDefOrDcl(ScalametaParser.scala:4172)
	at scala.meta.internal.parsers.ScalametaParser$$anonfun$templateStat$1$1.applyOrElse(ScalametaParser.scala:5120)
	at scala.meta.internal.parsers.ScalametaParser$$anonfun$templateStat$1$1.applyOrElse(ScalametaParser.scala:5114)
	at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:35)
	at scala.meta.internal.parsers.ScalametaParser.statSeq(ScalametaParser.scala:5057)
	at scala.meta.internal.parsers.ScalametaParser.templateStats(ScalametaParser.scala:5130)
	at scala.meta.internal.parsers.ScalametaParser.templateStatSeq(ScalametaParser.scala:5110)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$templateBodyOpt$1(ScalametaParser.scala:4964)
	at scala.meta.internal.parsers.ScalametaParser.indented(ScalametaParser.scala:815)
	at scala.meta.internal.parsers.ScalametaParser.templateBodyOpt(ScalametaParser.scala:4964)
	at scala.meta.internal.parsers.ScalametaParser.template(ScalametaParser.scala:4887)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$template$1(ScalametaParser.scala:4906)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.template(ScalametaParser.scala:4891)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$templateOpt$1(ScalametaParser.scala:4931)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.templateOpt(ScalametaParser.scala:4923)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$classDef$1(ScalametaParser.scala:4620)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.classDef(ScalametaParser.scala:4596)
	at scala.meta.internal.parsers.ScalametaParser.tmplDef(ScalametaParser.scala:4552)
	at scala.meta.internal.parsers.ScalametaParser.defOrDclOrSecondaryCtor(ScalametaParser.scala:4201)
	at scala.meta.internal.parsers.ScalametaParser.nonLocalDefOrDcl(ScalametaParser.scala:4172)
	at scala.meta.internal.parsers.ScalametaParser$$anonfun$templateStat$1$1.applyOrElse(ScalametaParser.scala:5120)
	at scala.meta.internal.parsers.ScalametaParser$$anonfun$templateStat$1$1.applyOrElse(ScalametaParser.scala:5114)
	at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:35)
	at scala.meta.internal.parsers.ScalametaParser.statSeq(ScalametaParser.scala:5057)
	at scala.meta.internal.parsers.ScalametaParser.templateStats(ScalametaParser.scala:5130)
	at scala.meta.internal.parsers.ScalametaParser.templateStatSeq(ScalametaParser.scala:5110)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$templateBody$1(ScalametaParser.scala:4945)
	at scala.meta.internal.parsers.ScalametaParser.inBraces(ScalametaParser.scala:800)
	at scala.meta.internal.parsers.ScalametaParser.templateBody(ScalametaParser.scala:4945)
	at scala.meta.internal.parsers.ScalametaParser.templateBodyOpt(ScalametaParser.scala:4953)
	at scala.meta.internal.parsers.ScalametaParser.template(ScalametaParser.scala:4887)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$template$1(ScalametaParser.scala:4906)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.template(ScalametaParser.scala:4891)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$templateOpt$1(ScalametaParser.scala:4931)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.templateOpt(ScalametaParser.scala:4923)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$objectDef$1(ScalametaParser.scala:4682)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.objectDef(ScalametaParser.scala:4674)
	at scala.meta.internal.parsers.ScalametaParser.tmplDef(ScalametaParser.scala:4558)
	at scala.meta.internal.parsers.ScalametaParser.topLevelTmplDef(ScalametaParser.scala:4540)
	at scala.meta.internal.parsers.ScalametaParser$$anonfun$topStat$1.applyOrElse(ScalametaParser.scala:5079)
	at scala.meta.internal.parsers.ScalametaParser$$anonfun$topStat$1.applyOrElse(ScalametaParser.scala:5067)
	at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:35)
	at scala.meta.internal.parsers.ScalametaParser.statSeq(ScalametaParser.scala:5057)
	at scala.meta.internal.parsers.ScalametaParser.topStatSeq(ScalametaParser.scala:5066)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$batchSource$1(ScalametaParser.scala:5297)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.batchSource(ScalametaParser.scala:5256)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$source$1(ScalametaParser.scala:5239)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.source(ScalametaParser.scala:5238)
	at scala.meta.internal.parsers.ScalametaParser.entrypointSource(ScalametaParser.scala:5244)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$parseSource$2(ScalametaParser.scala:143)
	at scala.meta.internal.parsers.ScalametaParser.parseRule(ScalametaParser.scala:53)
	at scala.meta.internal.parsers.ScalametaParser.parseSource(ScalametaParser.scala:143)
	at scala.meta.parsers.Parse$.$anonfun$parseSource$1(Parse.scala:29)
	at scala.meta.internal.parsers.ScalametaParser$$anon$264.apply(ScalametaParser.scala:5308)
	at scala.meta.parsers.Api$XtensionParseDialectInput.parse(Api.scala:25)
	at scala.meta.parsers.Api$XtensionParseInputLike.parse(Api.scala:14)
	at com.olegych.scastie.instrumentation.Instrument$.apply(Instrument.scala:199)
	at com.olegych.scastie.instrumentation.InstrumentedInputs$.apply(InstrumentedInputs.scala:23)
	at com.olegych.scastie.sbt.SbtProcess$$anonfun$4.applyOrElse(SbtProcess.scala:191)
	at com.olegych.scastie.sbt.SbtProcess$$anonfun$4.applyOrElse(SbtProcess.scala:177)
	at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:35)
	at akka.actor.FSM.processEvent(FSM.scala:707)
	at akka.actor.FSM.processEvent$(FSM.scala:704)
	at com.olegych.scastie.sbt.SbtProcess.processEvent(SbtProcess.scala:64)
	at akka.actor.FSM.akka$actor$FSM$$processMsg(FSM.scala:701)
	at akka.actor.FSM$$anonfun$receive$1.applyOrElse(FSM.scala:695)
	at akka.actor.Actor.aroundReceive(Actor.scala:539)
	at akka.actor.Actor.aroundReceive$(Actor.scala:537)
	at com.olegych.scastie.sbt.SbtProcess.aroundReceive(SbtProcess.scala:64)
	at akka.actor.ActorCell.receiveMessage(ActorCell.scala:614)
	at akka.actor.ActorCell.invoke(ActorCell.scala:583)
	at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:268)
	at akka.dispatch.Mailbox.run(Mailbox.scala:229)
	at akka.dispatch.Mailbox.exec(Mailbox.scala:241)
	at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
	at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
	at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
	at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
```

Pull request:
Fixes https://github.com/scalameta/scalameta/issues/2531

Patch:
diff --git a/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScalametaParser.scala b/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScalametaParser.scala
index 91bca25f1c..b8ca7c9f77 100644
--- a/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScalametaParser.scala
+++ b/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScalametaParser.scala
@@ -4740,8 +4740,12 @@ class ScalametaParser(input: Input)(implicit dialect: Dialect) { parser =>
     rejectMod[Mod.Sealed](mods, Messages.InvalidSealed)
     val name = atPos(in.tokenPos, in.tokenPos)(Name.Anonymous())
     accept[KwThis]
-    val paramss = paramClauses(ownerIsType = true)
-    secondaryCtorRest(mods, name, paramss)
+    if (token.isNot[LeftParen]) {
+      syntaxError("auxiliary constructor needs non-implicit parameter list", at = token.pos)
+    } else {
+      val paramss = paramClauses(ownerIsType = true)
+      secondaryCtorRest(mods, name, paramss)
+    }
   }
 
   def quasiquoteCtor(): Ctor = autoPos {


Test patch:
diff --git a/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/MinorDottySuite.scala b/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/MinorDottySuite.scala
index 3604bf9987..21027ecba8 100644
--- a/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/MinorDottySuite.scala
+++ b/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/MinorDottySuite.scala
@@ -203,6 +203,15 @@ class MinorDottySuite extends BaseDottySuite {
     )
   }
 
+  test("no-params") {
+    runTestError[Stat](
+      """|class A
+         |class B extends A:
+         |  def this = this.f()""".stripMargin,
+      "auxiliary constructor needs non-implicit parameter list"
+    )
+  }
+
   test("trait-parameters-generic") {
     runTestAssert[Stat]("trait Foo[T](bar: T)")(
       Defn.Trait(Nil, pname("Foo"), List(pparam("T")), ctorp(List(tparam("bar", "T"))), tpl(Nil))