@@ -5,6 +5,7 @@ package diagnostic
5
5
6
6
import dotc .core ._
7
7
import Contexts .Context , Decorators ._ , Symbols ._ , Names ._ , Types ._
8
+ import ast .untpd .{Modifiers , ModuleDef }
8
9
import util .{SourceFile , NoSource }
9
10
import util .{SourcePosition , NoSourcePosition }
10
11
import config .Settings .Setting
@@ -318,4 +319,86 @@ object messages {
318
319
| $code2
319
320
| """ .stripMargin
320
321
}
322
+
323
+ val implicitClassRestrictionsText =
324
+ """ For a full list of restrictions on implicit classes visit
325
+ |http://docs.scala-lang.org/overviews/core/implicit-classes.html""" .stripMargin
326
+
327
+ case class TopLevelImplicitClass (cdef : untpd.TypeDef )(implicit ctx : Context )
328
+ extends Message (10 ) {
329
+ val kind = " Syntax"
330
+
331
+ val msg = hl """ |An ${" implicit class" } may not be top-level """
332
+
333
+ val explanation = {
334
+ val TypeDef (name, impl @ Template (constr0, parents, self, _)) = cdef
335
+ val exampleArgs = constr0.vparamss(0 ).map(_.withMods(Modifiers ()).show).mkString(" , " )
336
+ val exampleBodyDefs = impl.body.map(_.show).mkString(" \n\n " )
337
+ val exampleBody = if (exampleBodyDefs == " <empty>" ) " " else s " { \n $exampleBodyDefs\n } "
338
+ hl """ |There may not be any method, member or object in scope with the same name as the
339
+ |implicit class and a case class automatically gets a companion object with the same name
340
+ |created by the compiler which would cause a naming conflict if it were allowed.
341
+ |
342
+ | $implicitClassRestrictionsText
343
+ |
344
+ |bodyDefs = ${impl.body.map(_.show)}
345
+ |
346
+ |To resolve the conflict declare ${cdef.name} inside of an ${" object" } then import the class
347
+ |from the object at the use site if needed, for example:
348
+ |
349
+ |object Implicits {
350
+ | implicit class ${cdef.name}( $exampleArgs) $exampleBody
351
+ |}
352
+ |
353
+ |import Implicits. ${cdef.name}""" .stripMargin
354
+ }
355
+ }
356
+
357
+ case class ImplicitCaseClass (cdef : untpd.TypeDef )(implicit ctx : Context )
358
+ extends Message (11 ) {
359
+ val kind = " Syntax"
360
+
361
+ val msg = hl """ |A ${" case class" } may not be defined as ${" implicit" }"""
362
+
363
+ val explanation =
364
+ hl """ |implicit classes may not be case classes. Instead use a plain class:
365
+ | example: implicit class ${cdef.name}...
366
+ |
367
+ | $implicitClassRestrictionsText""" .stripMargin
368
+ }
369
+
370
+ case class ObjectMayNotHaveSelfType (mdef : untpd.ModuleDef )(implicit ctx : Context )
371
+ extends Message (12 ) {
372
+ val kind = " Syntax"
373
+
374
+ val msg = hl """ | ${" objects" } must not have a ${" self type" }"""
375
+
376
+ val explanation = {
377
+ val ModuleDef (name, tmpl) = mdef
378
+ val ValDef (_, selfTpt, _) = tmpl.self
379
+ hl """ |objects must not have a ${" self type" }:
380
+ |
381
+ |Consider these alternative solutions:
382
+ | - Create a trait or a class instead of an object
383
+ | - Let the object extend a trait containing the self type:
384
+ | example: object $name extends ${selfTpt.show}""" .stripMargin
385
+ }
386
+ }
387
+
388
+ case class TupleTooLong (ts : List [untpd.Tree ])(implicit ctx : Context )
389
+ extends Message (13 ) {
390
+ import Definitions .MaxTupleArity
391
+ val kind = " Syntax"
392
+
393
+ val msg = hl """ |A ${" tuple" } cannot have more than ${MaxTupleArity } members """
394
+
395
+ val explanation = {
396
+ val members = ts.map(_.showSummary).grouped(MaxTupleArity )
397
+ val nestedRepresentation = members.map(_.mkString(" , " )).mkString(" )(" )
398
+ hl """ |This restriction will be removed in the future.
399
+ |Currently it is possible to use nested tuples when more than ${MaxTupleArity } are needed, for example:
400
+ |
401
+ | (( ${nestedRepresentation})) """ .stripMargin
402
+ }
403
+ }
321
404
}
0 commit comments