diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 67e1885b511f..971c2d11a4ec 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -272,18 +272,20 @@ object desugar { case ContextBounds(tbounds, ctxbounds) => val isMember = evidenceFlags.isAllOf(DeferredGivenFlags) for bound <- ctxbounds do - val evidenceName = bound match + val (evidenceName, spanPoint) = bound match case ContextBoundTypeTree(_, _, ownName) if !ownName.isEmpty => - ownName // if there is an explicitly given name, use it. + val realName = ownName.stripModuleClassSuffix.lastPart + (ownName, bound.span.end - realName.length) // if there is an explicitly given name, use it. case _ => if Config.nameSingleContextBounds && !isMember && ctxbounds.tail.isEmpty && Feature.enabled(Feature.modularity) - then tdef.name.toTermName - else freshName(bound) + then (tdef.name.toTermName, bound.span.point) + else (freshName(bound), bound.span.point) evidenceNames += evidenceName - val evidenceParam = ValDef(evidenceName, bound, EmptyTree).withFlags(evidenceFlags) + val evidenceParam = + ValDef(evidenceName, bound, EmptyTree).withFlags(evidenceFlags).withSpan(bound.span.withPoint(spanPoint)) evidenceParam.pushAttachment(ContextBoundParam, ()) evidenceBuf += evidenceParam tbounds diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 7933cbbea12f..0d6df11713b6 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -2265,7 +2265,8 @@ object Parsers { in.nextToken() ident() else EmptyTermName - ContextBoundTypeTree(t, pname, ownName) + val newSpan = t.span.withPoint(t.span.end).withEnd(in.lastOffset) + ContextBoundTypeTree(t, pname, ownName).withSpan(newSpan) /** ContextBounds ::= ContextBound [`:` ContextBounds] * | `{` ContextBound {`,` ContextBound} `}` diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 76b853c4aabd..39397d7f5d16 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2466,7 +2466,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer def typedContextBoundTypeTree(tree: untpd.ContextBoundTypeTree)(using Context): Tree = val tycon = typedType(tree.tycon) def spliced(tree: Tree) = untpd.TypedSplice(tree) - val tparam = untpd.Ident(tree.paramName).withSpan(tree.span) + val tparam = untpd.Ident(tree.paramName).withSpan(tree.span.withEnd(tree.span.point)) if tycon.tpe.typeParams.nonEmpty then val tycon0 = tycon.withType(tycon.tpe.etaCollapse) typed(untpd.AppliedTypeTree(spliced(tycon0), tparam :: Nil)) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala index f4ce4473e60a..34aca39dcf50 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala @@ -238,3 +238,27 @@ class HoverDefnSuite extends BaseHoverSuite: |""".stripMargin, "val foo: Int".hover ) + + @Test def `i22335` = + check( + """|def fromInt[T: Numeric as n@@um](t: Int): T = num.fromInt(t) + |""".stripMargin, + """|num: Numeric[T] + |""".stripMargin.hover + ) + + @Test def `i22335-2` = + check( + """|def showMax[X : {Numeric as nu@@m, Ordered as ord}](x: X, y: X): String = ??? + |""".stripMargin, + """|num: Numeric[X] + |""".stripMargin.hover + ) + + @Test def `i22335-3` = + check( + """|def showMax[X : {Nu@@meric as num, Ordered as ord}](x: X, y: X): String = ??? + |""".stripMargin, + """|type Numeric: Numeric + |""".stripMargin.hover + ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala index fac30bc757b7..b2735d6354b8 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/inlayHints/InlayHintsSuite.scala @@ -898,7 +898,7 @@ class InlayHintsSuite extends BaseInlayHintsSuite { | import quotes.reflect.* | Type.of[T] match | case '[f] => - | val fr/*: TypeRepr<>*/ = TypeRepr.of[T]/*(using evidence$1<<(3:23)>>)*/ + | val fr/*: TypeRepr<>*/ = TypeRepr.of[T]/*(using evidence$1<<(3:27)>>)*/ |""".stripMargin ) diff --git a/tests/pos/i20901/Foo.tastycheck b/tests/pos/i20901/Foo.tastycheck index 583595a7eb0a..82e95946f96c 100644 --- a/tests/pos/i20901/Foo.tastycheck +++ b/tests/pos/i20901/Foo.tastycheck @@ -92,7 +92,7 @@ Trees (98 bytes, starting from ): 96: STRINGconst 32 [] 98: -Positions (73 bytes, starting from ): +Positions (75 bytes, starting from ): lines: 7 line sizes: 38, 0, 23, 0, 10, 41, 0 diff --git a/tests/semanticdb/expect/Synthetic.expect.scala b/tests/semanticdb/expect/Synthetic.expect.scala index c8ccb2281cbb..5286745100a7 100644 --- a/tests/semanticdb/expect/Synthetic.expect.scala +++ b/tests/semanticdb/expect/Synthetic.expect.scala @@ -30,7 +30,7 @@ class Synthetic/*<-example::Synthetic#*/ { null.asInstanceOf/*->scala::Any#asInstanceOf().*/[Int/*->scala::Int#*/ => Int/*->scala::Int#*/](2) } - class J/*<-example::Synthetic#J#*/[T/*<-example::Synthetic#J#[T]*/: /*<-example::Synthetic#J#evidence$1.*/Manifest/*->scala::Predef.Manifest#*//*->example::Synthetic#J#[T]*/] { val arr/*<-example::Synthetic#J#arr.*/ = Array/*->scala::Array.*/.empty/*->scala::Array.empty().*/[T/*->example::Synthetic#J#[T]*/] } + class J/*<-example::Synthetic#J#*/[T/*<-example::Synthetic#J#[T]*/: Manifest/*->scala::Predef.Manifest#*//*->example::Synthetic#J#[T]*//*<-example::Synthetic#J#evidence$1.*/] { val arr/*<-example::Synthetic#J#arr.*/ = Array/*->scala::Array.*/.empty/*->scala::Array.empty().*/[T/*->example::Synthetic#J#[T]*/] } class F/*<-example::Synthetic#F#*/ implicit val ordering/*<-example::Synthetic#ordering.*/: Ordering/*->scala::package.Ordering#*/[F/*->example::Synthetic#F#*/] = ???/*->scala::Predef.`???`().*/ diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 26221899035b..b038d4a4d388 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -2734,7 +2734,7 @@ Occurrences: [17:9..17:10): U <- example/Methods#m7().[U] [17:12..17:20): Ordering -> scala/math/Ordering# [17:12..17:20): Ordering -> example/Methods#m7().[U] -[17:12..17:12): <- example/Methods#m7().(evidence$1) +[17:20..17:20): <- example/Methods#m7().(evidence$1) [17:22..17:23): c <- example/Methods#m7().(c) [17:25..17:32): Methods -> example/Methods# [17:33..17:34): T -> example/Methods#[T] @@ -3668,9 +3668,9 @@ Occurrences: [32:8..32:9): J <- example/Synthetic#J# [32:9..32:9): <- example/Synthetic#J#``(). [32:10..32:11): T <- example/Synthetic#J#[T] -[32:13..32:13): <- example/Synthetic#J#evidence$1. [32:13..32:21): Manifest -> scala/Predef.Manifest# [32:13..32:21): Manifest -> example/Synthetic#J#[T] +[32:21..32:21): <- example/Synthetic#J#evidence$1. [32:29..32:32): arr <- example/Synthetic#J#arr. [32:35..32:40): Array -> scala/Array. [32:41..32:46): empty -> scala/Array.empty().