Skip to content

Commit b9696fe

Browse files
Backport "fix: Allow as as an infix type in non context bound types" to 3.6.2 (#21901)
Backports #21849 to the 3.6.2 branch. PR submitted by the release tooling. [skip ci]
2 parents 087fd92 + 07583a1 commit b9696fe

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
@@ -1534,7 +1534,8 @@ object Parsers {
15341534
/** Same as [[typ]], but if this results in a wildcard it emits a syntax error and
15351535
* returns a tree for type `Any` instead.
15361536
*/
1537-
def toplevelTyp(intoOK: IntoOK = IntoOK.No): Tree = rejectWildcardType(typ(intoOK))
1537+
def toplevelTyp(intoOK: IntoOK = IntoOK.No, inContextBound: Boolean = false): Tree =
1538+
rejectWildcardType(typ(intoOK, inContextBound))
15381539

15391540
private def getFunction(tree: Tree): Option[Function] = tree match {
15401541
case Parens(tree1) => getFunction(tree1)
@@ -1594,7 +1595,7 @@ object Parsers {
15941595
* IntoTargetType ::= Type
15951596
* | FunTypeArgs (‘=>’ | ‘?=>’) IntoType
15961597
*/
1597-
def typ(intoOK: IntoOK = IntoOK.No): Tree =
1598+
def typ(intoOK: IntoOK = IntoOK.No, inContextBound: Boolean = false): Tree =
15981599
val start = in.offset
15991600
var imods = Modifiers()
16001601
val erasedArgs: ListBuffer[Boolean] = ListBuffer()
@@ -1743,7 +1744,7 @@ object Parsers {
17431744
val tuple = atSpan(start):
17441745
makeTupleOrParens(args.mapConserve(convertToElem))
17451746
typeRest:
1746-
infixTypeRest:
1747+
infixTypeRest(inContextBound):
17471748
refinedTypeRest:
17481749
withTypeRest:
17491750
annotTypeRest:
@@ -1772,7 +1773,7 @@ object Parsers {
17721773
else if isIntoPrefix then
17731774
PrefixOp(typeIdent(), typ(IntoOK.Nested))
17741775
else
1775-
typeRest(infixType())
1776+
typeRest(infixType(inContextBound))
17761777
end typ
17771778

17781779
private def makeKindProjectorTypeDef(name: TypeName): TypeDef = {
@@ -1827,13 +1828,13 @@ object Parsers {
18271828
/** InfixType ::= RefinedType {id [nl] RefinedType}
18281829
* | RefinedType `^` // under capture checking
18291830
*/
1830-
def infixType(): Tree = infixTypeRest(refinedType())
1831+
def infixType(inContextBound: Boolean = false): Tree = infixTypeRest(inContextBound)(refinedType())
18311832

1832-
def infixTypeRest(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
1833+
def infixTypeRest(inContextBound: Boolean = false)(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
18331834
infixOps(t, canStartInfixTypeTokens, operand, Location.ElseWhere, ParseKind.Type,
18341835
isOperator = !followingIsVararg()
18351836
&& !isPureArrow
1836-
&& !(isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`))
1837+
&& !(isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`) && inContextBound)
18371838
&& nextCanFollowOperator(canStartInfixTypeTokens))
18381839

18391840
/** RefinedType ::= WithType {[nl] Refinement} [`^` CaptureSet]
@@ -2224,7 +2225,7 @@ object Parsers {
22242225

22252226
/** ContextBound ::= Type [`as` id] */
22262227
def contextBound(pname: TypeName): Tree =
2227-
val t = toplevelTyp()
2228+
val t = toplevelTyp(inContextBound = true)
22282229
val ownName =
22292230
if isIdent(nme.as) && sourceVersion.isAtLeast(`3.6`) then
22302231
in.nextToken()
@@ -4209,7 +4210,7 @@ object Parsers {
42094210
else constrApp() match
42104211
case parent: Apply => parent :: moreConstrApps()
42114212
case parent if in.isIdent && newSyntaxAllowed =>
4212-
infixTypeRest(parent, _ => annotType1()) :: Nil
4213+
infixTypeRest()(parent, _ => annotType1()) :: Nil
42134214
case parent => parent :: moreConstrApps()
42144215

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