diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index f3b6438a479d..a4f171ba7f9a 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -661,6 +661,8 @@ class Definitions { def GetterMetaAnnot(implicit ctx: Context) = GetterMetaAnnotType.symbol.asClass lazy val SetterMetaAnnotType = ctx.requiredClassRef("scala.annotation.meta.setter") def SetterMetaAnnot(implicit ctx: Context) = SetterMetaAnnotType.symbol.asClass + lazy val ShowAsInfixAnotType = ctx.requiredClassRef("scala.annotation.showAsInfix") + def ShowAsInfixAnnot(implicit ctx: Context) = ShowAsInfixAnotType.symbol.asClass // convenient one-parameter method types def methOfAny(tp: Type) = MethodType(List(AnyType), tp) diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index b8631fb517a4..fb0214e7b47d 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -126,8 +126,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { def isInfixType(tp: Type): Boolean = tp match { case AppliedType(tycon, args) => args.length == 2 && - !Character.isUnicodeIdentifierStart(tycon.typeSymbol.name.toString.head) - // TODO: Once we use the 2.12 stdlib, also check the @showAsInfix annotation + tycon.typeSymbol.getAnnotation(defn.ShowAsInfixAnnot).map(_.argumentConstant(0).forall(_.booleanValue)) + .getOrElse(!Character.isUnicodeIdentifierStart(tycon.typeSymbol.name.toString.head)) case _ => false } diff --git a/compiler/test-resources/type-printer/infix b/compiler/test-resources/type-printer/infix index 460bbd9a619d..e38fee3352c2 100644 --- a/compiler/test-resources/type-printer/infix +++ b/compiler/test-resources/type-printer/infix @@ -16,3 +16,12 @@ scala> def foo: (Int && String) &: Boolean = ??? def foo: (Int && String) &: Boolean scala> def foo: Int && (Boolean &: String) = ??? def foo: Int && (Boolean &: String) +scala> import scala.annotation.showAsInfix +scala> @scala.annotation.showAsInfix class Mappy[T,U] +// defined class Mappy +scala> def foo: Int Mappy (Boolean && String) = ??? +def foo: Int Mappy (Boolean && String) +scala> @scala.annotation.showAsInfix(false) class ||[T,U] +// defined class || +scala> def foo: Int || Boolean = ??? +def foo: ||[Int, Boolean]