Skip to content

Commit e7221c6

Browse files
committed
fix: Allow as as an infix type in non context bound types
1 parent dd37f07 commit e7221c6

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

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

Lines changed: 13 additions & 9 deletions
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
@@ -1550,7 +1553,8 @@ object Parsers {
15501553
/** Same as [[typ]], but if this results in a wildcard it emits a syntax error and
15511554
* returns a tree for type `Any` instead.
15521555
*/
1553-
def toplevelTyp(intoOK: IntoOK = IntoOK.No): Tree = rejectWildcardType(typ(intoOK))
1556+
def toplevelTyp(intoOK: IntoOK = IntoOK.No, inContextBound: InContextBound = InContextBound.No): Tree =
1557+
rejectWildcardType(typ(intoOK, inContextBound))
15541558

15551559
private def getFunction(tree: Tree): Option[Function] = tree match {
15561560
case Parens(tree1) => getFunction(tree1)
@@ -1605,7 +1609,7 @@ object Parsers {
16051609
* IntoTargetType ::= Type
16061610
* | FunTypeArgs (‘=>’ | ‘?=>’) IntoType
16071611
*/
1608-
def typ(intoOK: IntoOK = IntoOK.No): Tree =
1612+
def typ(intoOK: IntoOK = IntoOK.No, inContextBound: InContextBound = InContextBound.No): Tree =
16091613
val start = in.offset
16101614
var imods = Modifiers()
16111615
val erasedArgs: ListBuffer[Boolean] = ListBuffer()
@@ -1754,7 +1758,7 @@ object Parsers {
17541758
val tuple = atSpan(start):
17551759
makeTupleOrParens(args.mapConserve(convertToElem))
17561760
typeRest:
1757-
infixTypeRest:
1761+
infixTypeRest(inContextBound):
17581762
refinedTypeRest:
17591763
withTypeRest:
17601764
annotTypeRest:
@@ -1777,7 +1781,7 @@ object Parsers {
17771781
else if isIntoPrefix then
17781782
PrefixOp(typeIdent(), typ(IntoOK.Nested))
17791783
else
1780-
typeRest(infixType())
1784+
typeRest(infixType(inContextBound))
17811785
end typ
17821786

17831787
private def makeKindProjectorTypeDef(name: TypeName): TypeDef = {
@@ -1832,13 +1836,13 @@ object Parsers {
18321836
/** InfixType ::= RefinedType {id [nl] RefinedType}
18331837
* | RefinedType `^` // under capture checking
18341838
*/
1835-
def infixType(): Tree = infixTypeRest(refinedType())
1839+
def infixType(inContextBound: InContextBound = InContextBound.No): Tree = infixTypeRest(inContextBound)(refinedType())
18361840

1837-
def infixTypeRest(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
1841+
def infixTypeRest(inContextBound: InContextBound = InContextBound.No)(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
18381842
infixOps(t, canStartInfixTypeTokens, operand, Location.ElseWhere, ParseKind.Type,
18391843
isOperator = !followingIsVararg()
18401844
&& !isPureArrow
1841-
&& !(isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`))
1845+
&& !(isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`) && inContextBound == InContextBound.Yes)
18421846
&& nextCanFollowOperator(canStartInfixTypeTokens))
18431847

18441848
/** RefinedType ::= WithType {[nl] Refinement} [`^` CaptureSet]
@@ -2229,7 +2233,7 @@ object Parsers {
22292233

22302234
/** ContextBound ::= Type [`as` id] */
22312235
def contextBound(pname: TypeName): Tree =
2232-
val t = toplevelTyp()
2236+
val t = toplevelTyp(inContextBound = InContextBound.Yes)
22332237
val ownName =
22342238
if isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`) then
22352239
in.nextToken()
@@ -4207,7 +4211,7 @@ object Parsers {
42074211
else constrApp() match
42084212
case parent: Apply => parent :: moreConstrApps()
42094213
case parent if in.isIdent && newSyntaxAllowed =>
4210-
infixTypeRest(parent, _ => annotType1()) :: Nil
4214+
infixTypeRest()(parent, _ => annotType1()) :: Nil
42114215
case parent => parent :: moreConstrApps()
42124216

42134217
// The term parameters and parent references */

tests/pos/i21769.scala

Lines changed: 19 additions & 0 deletions
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)