@@ -357,6 +357,21 @@ object Parsers {
357357 accept(SEMI )
358358 }
359359
360+ def acceptNested (): Unit =
361+ if in.token != LBRACE && in.token != INDENT then
362+ syntaxError(i " indented definitions or `{' expected " )
363+
364+ /** Under -language:Scala2 or -old-syntax, flag
365+ *
366+ * extends p1 with new p1 with t1 with
367+ * p2 p2 t2
368+ *
369+ * as a migration warning or error since that means something else under significant indentation.
370+ */
371+ def checkNotWithAtEOL (): Unit =
372+ if (in.isScala2Mode || in.oldSyntax) && in.isAfterLineEnd then
373+ in.errorOrMigrationWarning(" `with` cannot be followed by new line, place at beginning of next line instead" )
374+
360375 def rewriteNotice (additionalOption : String = " " ) = {
361376 val optionStr = if (additionalOption.isEmpty) " " else " " ++ additionalOption
362377 i " \n This construct can be rewritten automatically under $optionStr -rewrite. "
@@ -1254,8 +1269,7 @@ object Parsers {
12541269 def possibleTemplateStart (): Unit =
12551270 if in.token == WITH then
12561271 in.nextToken()
1257- if in.token != LBRACE && in.token != INDENT then
1258- syntaxError(i " indented definitions or `{' expected " )
1272+ acceptNested()
12591273 else if silentTemplateIdent then
12601274 in.observeIndented()
12611275 newLineOptWhenFollowedBy(LBRACE )
@@ -1402,7 +1416,7 @@ object Parsers {
14021416 makeParameter(name, typ(), mods | Param )
14031417 }
14041418
1405- /** InfixType ::= RefinedType {id [nl] refinedType }
1419+ /** InfixType ::= RefinedType {id [nl] RefinedType }
14061420 */
14071421 def infixType (): Tree = infixTypeRest(refinedType())
14081422
@@ -1413,7 +1427,7 @@ object Parsers {
14131427 def infixTypeRest (t : Tree ): Tree =
14141428 infixOps(t, canStartTypeTokens, refinedType, isType = true , isOperator = ! isPostfixStar)
14151429
1416- /** RefinedType ::= WithType {Annotation | [nl ] Refinement}
1430+ /** RefinedType ::= WithType {[nl | `with' ] Refinement}
14171431 */
14181432 val refinedType : () => Tree = () => refinedTypeRest(withType())
14191433
@@ -1429,12 +1443,16 @@ object Parsers {
14291443 def withType (): Tree = withTypeRest(annotType())
14301444
14311445 def withTypeRest (t : Tree ): Tree =
1432- if (in.token == WITH ) {
1433- if (ctx.settings.strict.value)
1434- deprecationWarning(DeprecatedWithOperator ())
1446+ if in.token == WITH then
1447+ val withOffset = in.offset
14351448 in.nextToken()
1436- makeAndType(t, withType())
1437- }
1449+ if in.token == LBRACE || in.token == INDENT then
1450+ t
1451+ else
1452+ checkNotWithAtEOL()
1453+ if (ctx.settings.strict.value)
1454+ deprecationWarning(DeprecatedWithOperator (), withOffset)
1455+ makeAndType(t, withType())
14381456 else t
14391457
14401458 /** AnnotType ::= SimpleType {Annotation}
@@ -3434,14 +3452,7 @@ object Parsers {
34343452 in.nextToken()
34353453 if templateCanFollow && (in.token == LBRACE || in.token == INDENT ) then Nil
34363454 else
3437- if (in.isScala2Mode || in.oldSyntax) && in.isAfterLineEnd then
3438- // Disallow
3439- //
3440- // extends p1 with
3441- // p2
3442- //
3443- // since that means something else under significant indentation
3444- in.errorOrMigrationWarning(" `with` cannot be followed by new line, place at beginning of next line instead" )
3455+ checkNotWithAtEOL()
34453456 constrApps(commaOK, templateCanFollow)
34463457 else if commaOK && in.token == COMMA then
34473458 in.nextToken()
0 commit comments