Skip to content

Commit aa60a39

Browse files
authored
fix: Allow as as an infix type in non context bound types (#21849)
potential fix for #21769
2 parents 6ab3e44 + ae9cffa commit aa60a39

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

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

+10-9
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,8 @@ object Parsers {
15501550
/** Same as [[typ]], but if this results in a wildcard it emits a syntax error and
15511551
* returns a tree for type `Any` instead.
15521552
*/
1553-
def toplevelTyp(intoOK: IntoOK = IntoOK.No): Tree = rejectWildcardType(typ(intoOK))
1553+
def toplevelTyp(intoOK: IntoOK = IntoOK.No, inContextBound: Boolean = false): Tree =
1554+
rejectWildcardType(typ(intoOK, inContextBound))
15541555

15551556
private def getFunction(tree: Tree): Option[Function] = tree match {
15561557
case Parens(tree1) => getFunction(tree1)
@@ -1606,7 +1607,7 @@ object Parsers {
16061607
* IntoTargetType ::= Type
16071608
* | FunTypeArgs (‘=>’ | ‘?=>’) IntoType
16081609
*/
1609-
def typ(intoOK: IntoOK = IntoOK.No): Tree =
1610+
def typ(intoOK: IntoOK = IntoOK.No, inContextBound: Boolean = false): Tree =
16101611
val start = in.offset
16111612
var imods = Modifiers()
16121613
val erasedArgs: ListBuffer[Boolean] = ListBuffer()
@@ -1755,7 +1756,7 @@ object Parsers {
17551756
val tuple = atSpan(start):
17561757
makeTupleOrParens(args.mapConserve(convertToElem))
17571758
typeRest:
1758-
infixTypeRest:
1759+
infixTypeRest(inContextBound):
17591760
refinedTypeRest:
17601761
withTypeRest:
17611762
annotTypeRest:
@@ -1778,7 +1779,7 @@ object Parsers {
17781779
else if isIntoPrefix then
17791780
PrefixOp(typeIdent(), typ(IntoOK.Nested))
17801781
else
1781-
typeRest(infixType())
1782+
typeRest(infixType(inContextBound))
17821783
end typ
17831784

17841785
private def makeKindProjectorTypeDef(name: TypeName): TypeDef = {
@@ -1833,13 +1834,13 @@ object Parsers {
18331834
/** InfixType ::= RefinedType {id [nl] RefinedType}
18341835
* | RefinedType `^` // under capture checking
18351836
*/
1836-
def infixType(): Tree = infixTypeRest(refinedType())
1837+
def infixType(inContextBound: Boolean = false): Tree = infixTypeRest(inContextBound)(refinedType())
18371838

1838-
def infixTypeRest(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
1839+
def infixTypeRest(inContextBound: Boolean = false)(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
18391840
infixOps(t, canStartInfixTypeTokens, operand, Location.ElseWhere, ParseKind.Type,
18401841
isOperator = !followingIsVararg()
18411842
&& !isPureArrow
1842-
&& !(isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`))
1843+
&& !(isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`) && inContextBound)
18431844
&& nextCanFollowOperator(canStartInfixTypeTokens))
18441845

18451846
/** RefinedType ::= WithType {[nl] Refinement} [`^` CaptureSet]
@@ -2230,7 +2231,7 @@ object Parsers {
22302231

22312232
/** ContextBound ::= Type [`as` id] */
22322233
def contextBound(pname: TypeName): Tree =
2233-
val t = toplevelTyp()
2234+
val t = toplevelTyp(inContextBound = true)
22342235
val ownName =
22352236
if isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`) then
22362237
in.nextToken()
@@ -4208,7 +4209,7 @@ object Parsers {
42084209
else constrApp() match
42094210
case parent: Apply => parent :: moreConstrApps()
42104211
case parent if in.isIdent && newSyntaxAllowed =>
4211-
infixTypeRest(parent, _ => annotType1()) :: Nil
4212+
infixTypeRest()(parent, _ => annotType1()) :: Nil
42124213
case parent => parent :: moreConstrApps()
42134214

42144215
// 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)