diff --git a/community-build/community-projects/spire b/community-build/community-projects/spire index d60fe2c38848..993e8c8c7a8e 160000 --- a/community-build/community-projects/spire +++ b/community-build/community-projects/spire @@ -1 +1 @@ -Subproject commit d60fe2c38848ef193031c18eab3a14d3306b3761 +Subproject commit 993e8c8c7a8e55be943d63c07c8263c1021add2f diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index c360712999e2..dba0834c95e8 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -300,7 +300,12 @@ object desugar { // implicit resolution in Scala 3. val paramssNoContextBounds = - val iflag = if Feature.sourceVersion.isAtLeast(`future`) then Given else Implicit + val iflag = paramss.lastOption.flatMap(_.headOption) match + case Some(param) if param.mods.isOneOf(GivenOrImplicit) => + param.mods.flags & GivenOrImplicit + case _ => + if Feature.sourceVersion.isAtLeast(`3.6`) then Given + else Implicit val flags = if isPrimaryConstructor then iflag | LocalParamAccessor else iflag | Param mapParamss(paramss) { tparam => desugarContextBounds(tparam, evidenceParamBuf, flags, freshName, paramss) @@ -472,7 +477,14 @@ object desugar { case ValDefs(mparams) :: _ if mparams.exists(referencesBoundName) => params :: mparamss case ValDefs(mparams @ (mparam :: _)) :: Nil if mparam.mods.isOneOf(GivenOrImplicit) => - (params ++ mparams) :: Nil + val normParams = + if params.head.mods.flags.is(Given) != mparam.mods.flags.is(Given) then + params.map: param => + val normFlags = param.mods.flags &~ GivenOrImplicit | (mparam.mods.flags & (GivenOrImplicit)) + param.withMods(param.mods.withFlags(normFlags)) + .showing(i"ADAPTED PARAM $result ${result.mods.flags} for ${meth.name}") + else params + (normParams ++ mparams) :: Nil case mparams :: mparamss1 => mparams :: recur(mparamss1) case Nil => diff --git a/compiler/src/dotty/tools/dotc/util/Signatures.scala b/compiler/src/dotty/tools/dotc/util/Signatures.scala index 3f7d7dd39531..ae6bc583bae8 100644 --- a/compiler/src/dotty/tools/dotc/util/Signatures.scala +++ b/compiler/src/dotty/tools/dotc/util/Signatures.scala @@ -499,7 +499,7 @@ object Signatures { def isSyntheticEvidence(name: String) = name.startsWith(NameKinds.ContextBoundParamName.separator) - && symbol.paramSymss.flatten.find(_.name.show == name).exists(_.flags.is(Flags.Implicit)) + && symbol.paramSymss.flatten.find(_.name.show == name).exists(_.flags.isOneOf(Flags.GivenOrImplicit)) def toTypeParam(tpe: PolyType): List[Param] = val evidenceParams = (tpe.paramNamess.flatten zip tpe.paramInfoss.flatten).flatMap: diff --git a/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala b/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala index 19d603fcbb3b..a0dcb5276253 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala @@ -296,7 +296,7 @@ class ShortenedTypePrinter( val (methodParams, extParams) = splitExtensionParamss(gsym) val paramss = methodParams ++ extParams lazy val implicitParams: List[Symbol] = - paramss.flatMap(params => params.filter(p => p.is(Flags.Implicit))) + paramss.flatMap(params => params.filter(p => p.isOneOf(Flags.GivenOrImplicit))) lazy val implicitEvidenceParams: Set[Symbol] = implicitParams diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala index 8823f6cb4e5e..497b58b6ed2c 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala @@ -588,7 +588,8 @@ trait ClassLikeSupport: // `def foo[A: ClassTag] = 1`. // Scala spec states that `$` should not be used in names and behaviour may be undefiend in such case. // Documenting method slightly different then its definition is withing the 'undefiend behaviour'. - symbol.paramSymss.flatten.find(_.name == name).exists(_.flags.is(Flags.Implicit)) + symbol.paramSymss.flatten.find(_.name == name).exists(p => + p.flags.is(Flags.Given) || p.flags.is(Flags.Implicit)) def handlePolyType(memberInfo: MemberInfo, polyType: PolyType): MemberInfo = val typeParamList = MemberInfo.TypeParameterList(polyType.paramNames.zip(polyType.paramBounds).toMap) diff --git a/staging/test-resources/repl-staging/i6263 b/staging/test-resources/repl-staging/i6263 index 8d967c1c58ac..0df9a9893ae1 100644 --- a/staging/test-resources/repl-staging/i6263 +++ b/staging/test-resources/repl-staging/i6263 @@ -3,7 +3,7 @@ scala> import quoted.staging.{Compiler => StagingCompiler, _} scala> implicit def compiler: StagingCompiler = StagingCompiler.make(getClass.getClassLoader) def compiler: scala.quoted.staging.Compiler scala> def fn[T : Type](v : T) = println("ok") -def fn[T](v: T)(implicit evidence$1: scala.quoted.Type[T]): Unit +def fn[T](v: T)(using evidence$1: scala.quoted.Type[T]): Unit scala> withQuotes { fn("foo") } ok scala> withQuotes { fn((1,2)) } diff --git a/tests/neg/ctx-bounds-priority-migration.scala b/tests/neg/ctx-bounds-priority-migration.scala new file mode 100644 index 000000000000..8fc819c1e089 --- /dev/null +++ b/tests/neg/ctx-bounds-priority-migration.scala @@ -0,0 +1,13 @@ +//> using options -source 3.5 +trait Eq[A] +trait Order[A] extends Eq[A]: + def toOrdering: Ordering[A] + +def f[Element: Eq: Order] = summon[Eq[Element]].toOrdering // ok + +def Test() = + val eq: Eq[Int] = ??? + val ord: Order[Int] = ??? + f(eq, ord) // error + f(using eq, ord) // ok + diff --git a/tests/neg/ctx-bounds-priority.scala b/tests/neg/ctx-bounds-priority.scala new file mode 100644 index 000000000000..6594642d67c3 --- /dev/null +++ b/tests/neg/ctx-bounds-priority.scala @@ -0,0 +1,6 @@ +//> using options -source 3.6 +trait Eq[A] +trait Order[A] extends Eq[A]: + def toOrdering: Ordering[A] + +def Test[Element: Eq: Order] = summon[Eq[Element]].toOrdering // error diff --git a/tests/neg/i10901.check b/tests/neg/i10901.check index 4a8fa5db28bf..325cdccc6aab 100644 --- a/tests/neg/i10901.check +++ b/tests/neg/i10901.check @@ -1,23 +1,23 @@ -- [E008] Not Found Error: tests/neg/i10901.scala:45:38 ---------------------------------------------------------------- 45 | val pos1: Point2D[Int,Double] = x º y // error | ^^^ - | value º is not a member of object BugExp4Point2D.IntT. - | An extension method was tried, but could not be fully constructed: - | - | º(x) - | - | failed with: - | - | Ambiguous overload. The overloaded alternatives of method º in object dsl with types - | [T1, T2] - | (x: BugExp4Point2D.ColumnType[T1]) - | (y: BugExp4Point2D.ColumnType[T2]) - | (implicit evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2] - | [T1, T2] - | (x: T1) - | (y: BugExp4Point2D.ColumnType[T2]) - | (implicit evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2] - | both match arguments ((x : BugExp4Point2D.IntT.type))((y : BugExp4Point2D.DoubleT.type)) + | value º is not a member of object BugExp4Point2D.IntT. + | An extension method was tried, but could not be fully constructed: + | + | º(x) + | + | failed with: + | + | Ambiguous overload. The overloaded alternatives of method º in object dsl with types + | [T1, T2] + | (x: BugExp4Point2D.ColumnType[T1]) + | (y: BugExp4Point2D.ColumnType[T2]) + | (using evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2] + | [T1, T2] + | (x: T1) + | (y: BugExp4Point2D.ColumnType[T2]) + | (using evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2] + | both match arguments ((x : BugExp4Point2D.IntT.type))((y : BugExp4Point2D.DoubleT.type)) -- [E008] Not Found Error: tests/neg/i10901.scala:48:38 ---------------------------------------------------------------- 48 | val pos4: Point2D[Int,Double] = x º 201.1 // error | ^^^ @@ -31,8 +31,8 @@ | Ambiguous overload. The overloaded alternatives of method º in object dsl with types | [T1, T2] | (x: BugExp4Point2D.ColumnType[T1]) - | (y: T2)(implicit evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2] - | [T1, T2](x: T1)(y: T2)(implicit evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2] + | (y: T2)(using evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2] + | [T1, T2](x: T1)(y: T2)(using evidence$1: Numeric[T1], evidence$2: Numeric[T2]): BugExp4Point2D.Point2D[T1, T2] | both match arguments ((x : BugExp4Point2D.IntT.type))((201.1d : Double)) -- [E008] Not Found Error: tests/neg/i10901.scala:62:16 ---------------------------------------------------------------- 62 | val y = "abc".foo // error diff --git a/tests/pos/i20901/Foo.tastycheck b/tests/pos/i20901/Foo.tastycheck index 565c5c793bad..583595a7eb0a 100644 --- a/tests/pos/i20901/Foo.tastycheck +++ b/tests/pos/i20901/Foo.tastycheck @@ -74,7 +74,7 @@ Trees (98 bytes, starting from ): 61: SHAREDtype 6 63: IDENTtpt 16 [T] 65: TYPEREFdirect 39 - 67: IMPLICIT + 67: GIVEN 68: IDENTtpt 17 [Nothing] 70: TYPEREF 17 [Nothing] 72: TERMREFpkg 2 [scala] diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 16f1b7c13d1f..dffed5c0d477 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -2621,9 +2621,9 @@ example/Methods#m6(+1). => method m6 (param x: List[T]): Nothing example/Methods#m6(+1).(x) => param x: List[T] example/Methods#m6(+2). => method m6 (param x: List[T]): Nothing example/Methods#m6(+2).(x) => param x: List[T] -example/Methods#m7(). => method m7 [typeparam U ](param c: Methods[T], param l: List[U])(implicit param evidence$1: Ordering[U]): Nothing +example/Methods#m7(). => method m7 [typeparam U ](param c: Methods[T], param l: List[U])(implicit given param evidence$1: Ordering[U]): Nothing example/Methods#m7().(c) => param c: Methods[T] -example/Methods#m7().(evidence$1) => implicit param evidence$1: Ordering[U] +example/Methods#m7().(evidence$1) => implicit given param evidence$1: Ordering[U] example/Methods#m7().(l) => param l: List[U] example/Methods#m7().[U] => typeparam U example/Methods#m9(). => method m9 (param x: m9().): Nothing @@ -3553,10 +3553,10 @@ example/Synthetic#F# => class F extends Object { self: F => +1 decls } example/Synthetic#F#``(). => primary ctor (): F example/Synthetic#J# => class J [typeparam T ] extends Object { self: J[T] => +4 decls } example/Synthetic#J#[T] => typeparam T -example/Synthetic#J#``(). => primary ctor [typeparam T ]()(implicit param evidence$1: Manifest[T]): J[T] -example/Synthetic#J#``().(evidence$1) => implicit param evidence$1: Manifest[T] +example/Synthetic#J#``(). => primary ctor [typeparam T ](implicit given param evidence$1: Manifest[T])(): J[T] +example/Synthetic#J#``().(evidence$1) => implicit given param evidence$1: Manifest[T] example/Synthetic#J#arr. => val method arr Array[T] -example/Synthetic#J#evidence$1. => private[this] implicit val method evidence$1 Manifest[T] +example/Synthetic#J#evidence$1. => private[this] implicit val given method evidence$1 Manifest[T] example/Synthetic#Name. => val method Name Regex example/Synthetic#``(). => primary ctor (): Synthetic example/Synthetic#a1. => val method a1 Int