Skip to content

Commit dac7f7e

Browse files
KacperFKorbanWojciechMazur
authored andcommitted
fix: Allow as as an infix type in non context bound types
[Cherry-picked e7221c6]
1 parent 7ee2683 commit dac7f7e

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+13-9
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ object Parsers {
8080
enum IntoOK:
8181
case Yes, No, Nested
8282

83+
enum InContextBound:
84+
case Yes, No
85+
8386
type StageKind = Int
8487
object StageKind {
8588
val None = 0
@@ -1534,7 +1537,8 @@ object Parsers {
15341537
/** Same as [[typ]], but if this results in a wildcard it emits a syntax error and
15351538
* returns a tree for type `Any` instead.
15361539
*/
1537-
def toplevelTyp(intoOK: IntoOK = IntoOK.No): Tree = rejectWildcardType(typ(intoOK))
1540+
def toplevelTyp(intoOK: IntoOK = IntoOK.No, inContextBound: InContextBound = InContextBound.No): Tree =
1541+
rejectWildcardType(typ(intoOK, inContextBound))
15381542

15391543
private def getFunction(tree: Tree): Option[Function] = tree match {
15401544
case Parens(tree1) => getFunction(tree1)
@@ -1594,7 +1598,7 @@ object Parsers {
15941598
* IntoTargetType ::= Type
15951599
* | FunTypeArgs (‘=>’ | ‘?=>’) IntoType
15961600
*/
1597-
def typ(intoOK: IntoOK = IntoOK.No): Tree =
1601+
def typ(intoOK: IntoOK = IntoOK.No, inContextBound: InContextBound = InContextBound.No): Tree =
15981602
val start = in.offset
15991603
var imods = Modifiers()
16001604
val erasedArgs: ListBuffer[Boolean] = ListBuffer()
@@ -1743,7 +1747,7 @@ object Parsers {
17431747
val tuple = atSpan(start):
17441748
makeTupleOrParens(args.mapConserve(convertToElem))
17451749
typeRest:
1746-
infixTypeRest:
1750+
infixTypeRest(inContextBound):
17471751
refinedTypeRest:
17481752
withTypeRest:
17491753
annotTypeRest:
@@ -1772,7 +1776,7 @@ object Parsers {
17721776
else if isIntoPrefix then
17731777
PrefixOp(typeIdent(), typ(IntoOK.Nested))
17741778
else
1775-
typeRest(infixType())
1779+
typeRest(infixType(inContextBound))
17761780
end typ
17771781

17781782
private def makeKindProjectorTypeDef(name: TypeName): TypeDef = {
@@ -1827,13 +1831,13 @@ object Parsers {
18271831
/** InfixType ::= RefinedType {id [nl] RefinedType}
18281832
* | RefinedType `^` // under capture checking
18291833
*/
1830-
def infixType(): Tree = infixTypeRest(refinedType())
1834+
def infixType(inContextBound: InContextBound = InContextBound.No): Tree = infixTypeRest(inContextBound)(refinedType())
18311835

1832-
def infixTypeRest(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
1836+
def infixTypeRest(inContextBound: InContextBound = InContextBound.No)(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
18331837
infixOps(t, canStartInfixTypeTokens, operand, Location.ElseWhere, ParseKind.Type,
18341838
isOperator = !followingIsVararg()
18351839
&& !isPureArrow
1836-
&& !(isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`))
1840+
&& !(isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`) && inContextBound == InContextBound.Yes)
18371841
&& nextCanFollowOperator(canStartInfixTypeTokens))
18381842

18391843
/** RefinedType ::= WithType {[nl] Refinement} [`^` CaptureSet]
@@ -2224,7 +2228,7 @@ object Parsers {
22242228

22252229
/** ContextBound ::= Type [`as` id] */
22262230
def contextBound(pname: TypeName): Tree =
2227-
val t = toplevelTyp()
2231+
val t = toplevelTyp(inContextBound = InContextBound.Yes)
22282232
val ownName =
22292233
if isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`) then
22302234
in.nextToken()
@@ -4209,7 +4213,7 @@ object Parsers {
42094213
else constrApp() match
42104214
case parent: Apply => parent :: moreConstrApps()
42114215
case parent if in.isIdent && newSyntaxAllowed =>
4212-
infixTypeRest(parent, _ => annotType1()) :: Nil
4216+
infixTypeRest()(parent, _ => annotType1()) :: Nil
42134217
case parent => parent :: moreConstrApps()
42144218

42154219
// The term parameters and parent references */

tests/pos/i21769.scala

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
infix trait as[From, To]
3+
4+
val conv: (String as Int) = ???
5+
given instance: (String as Int) = ???
6+
def test(ev: (String as Int)) = ???
7+
8+
class F
9+
10+
class K extends (F as K)
11+
12+
class TC1[X]
13+
14+
def doSth[X: TC1 as tc] = ???
15+
16+
class TC2[X]:
17+
type Self = X
18+
19+
def doSth2[X: {TC1 as tc1, TC2 as tc2}](x: tc2.Self) = ???

0 commit comments

Comments
 (0)