Skip to content

Disable old context function syntax #10786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/core/Annotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ object Annotations {
object LazyBodyAnnotation {
def apply(bodyFn: Context ?=> Tree): LazyBodyAnnotation =
new LazyBodyAnnotation:
protected var myTree: Tree | (Context ?=> Tree) = (using ctx) => bodyFn(using ctx)
protected var myTree: Tree | (Context ?=> Tree) = ctx ?=> bodyFn(using ctx)
}

object Annotation {
Expand Down Expand Up @@ -155,15 +155,15 @@ object Annotations {
/** Create an annotation where the tree is computed lazily. */
def deferred(sym: Symbol)(treeFn: Context ?=> Tree)(using Context): Annotation =
new LazyAnnotation {
protected var myTree: Tree | (Context ?=> Tree) = (using ctx) => treeFn(using ctx)
protected var myTree: Tree | (Context ?=> Tree) = ctx ?=> treeFn(using ctx)
protected var mySym: Symbol | (Context ?=> Symbol) = sym
}

/** Create an annotation where the symbol and the tree are computed lazily. */
def deferredSymAndTree(symFn: Context ?=> Symbol)(treeFn: Context ?=> Tree)(using Context): Annotation =
new LazyAnnotation {
protected var mySym: Symbol | (Context ?=> Symbol) = (using ctx) => symFn(using ctx)
protected var myTree: Tree | (Context ?=> Tree) = (using ctx) => treeFn(using ctx)
protected var mySym: Symbol | (Context ?=> Symbol) = ctx ?=> symFn(using ctx)
protected var myTree: Tree | (Context ?=> Tree) = ctx ?=> treeFn(using ctx)
}

/** Extractor for child annotations */
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2506,7 +2506,7 @@ object SymDenotations {
}

object LazyType:
private val NoSymbolFn = (using _: Context) => NoSymbol
private val NoSymbolFn = (_: Context) ?=> NoSymbol

/** A subtrait of LazyTypes where completerTypeParams yields a List[TypeSymbol], which
* should be completed independently of the info.
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5148,7 +5148,7 @@ object Types {
derivedSuperType(tp, this(thistp), this(supertp))

case tp: LazyRef =>
LazyRef { (using refCtx) =>
LazyRef { refCtx ?=>
val ref1 = tp.ref
if refCtx.runId == mapCtx.runId then this(ref1)
else // splice in new run into map context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,10 @@ class ClassfileParser(
}

protected var mySym: Symbol | (Context ?=> Symbol) =
(using ctx: Context) => annotType.classSymbol
(ctx: Context) ?=> annotType.classSymbol

protected var myTree: Tree | (Context ?=> Tree) =
(using ctx: Context) => untpd.resolveConstructor(annotType, args)
(ctx: Context) ?=> untpd.resolveConstructor(annotType, args)

def untpdTree(using Context): untpd.Tree =
untpd.New(untpd.TypeTree(annotType), List(args))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ class TreeUnpickler(reader: TastyReader,
forkAt(templateStart).indexTemplateParams()(using localContext(sym))
}
else if (sym.isInlineMethod)
sym.addAnnotation(LazyBodyAnnotation { (using ctx0: Context) =>
sym.addAnnotation(LazyBodyAnnotation { (ctx0: Context) ?=>
val ctx1 = localContext(sym)(using ctx0).addMode(Mode.ReadPositions)
inContext(sourceChangeContext(Addr(0))(using ctx1)) {
// avoids space leaks by not capturing the current context
Expand Down
27 changes: 15 additions & 12 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,7 @@ object Parsers {
val start = in.offset
var imods = Modifiers()
def functionRest(params: List[Tree]): Tree =
val paramSpan = Span(start, in.lastOffset)
atSpan(start, in.offset) {
if in.token == TLARROW then
if !imods.flags.isEmpty || params.isEmpty then
Expand All @@ -1382,14 +1383,16 @@ object Parsers {
accept(ARROW)
val t = typ()

if (imods.isOneOf(Given | Erased)) new FunctionWithMods(params, t, imods)
else if (ctx.settings.YkindProjector.value) {
if imods.isOneOf(Given | Erased) then
if imods.is(Given) && params.isEmpty then
syntaxError("context function types require at least one parameter", paramSpan)
new FunctionWithMods(params, t, imods)
else if ctx.settings.YkindProjector.value then
val (newParams :+ newT, tparams) = replaceKindProjectorPlaceholders(params :+ t)

lambdaAbstract(tparams, Function(newParams, newT))
} else {
else
Function(params, t)
}
}
def funArgTypesRest(first: Tree, following: () => Tree) = {
val buf = new ListBuffer[Tree] += first
Expand Down Expand Up @@ -1904,10 +1907,7 @@ object Parsers {

def expr(location: Location): Tree = {
val start = in.offset
def isSpecialClosureStart =
val lookahead = in.LookaheadScanner()
lookahead.nextToken()
lookahead.isIdent(nme.using) || lookahead.token == ERASED
def isSpecialClosureStart = in.lookahead.token == ERASED
if in.token == IMPLICIT then
closure(start, location, modifiers(BitSet(IMPLICIT)))
else if in.token == LPAREN && isSpecialClosureStart then
Expand Down Expand Up @@ -2137,9 +2137,7 @@ object Parsers {
else
openParens.change(LPAREN, 1)
var mods1 = mods
if mods.flags.isEmpty then
if isIdent(nme.using) then mods1 = addMod(mods1, atSpan(in.skipToken()) { Mod.Given() })
if in.token == ERASED then mods1 = addModifier(mods1)
if in.token == ERASED then mods1 = addModifier(mods1)
try
commaSeparated(() => binding(mods1))
finally
Expand Down Expand Up @@ -2188,7 +2186,12 @@ object Parsers {

def closureRest(start: Int, location: Location, params: List[Tree]): Tree =
atSpan(start, in.offset) {
if in.token == CTXARROW then in.nextToken() else accept(ARROW)
if in.token == CTXARROW then
if params.isEmpty then
syntaxError("context function literals require at least one formal parameter", Span(start, in.lastOffset))
in.nextToken()
else
accept(ARROW)
Function(params, if (location == Location.InBlock) block() else expr())
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ object PickledQuotes {
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match {
case Hole(isTerm, idx, args) =>
val reifiedArgs = args.map { arg =>
if (arg.isTerm) (using q: Quotes) => new ExprImpl(arg, QuotesImpl.scopeId)
if (arg.isTerm) (q: Quotes) ?=> new ExprImpl(arg, QuotesImpl.scopeId)
else new TypeImpl(arg, QuotesImpl.scopeId)
}
if isTerm then
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ object Implicits:
else
val candidates = new mutable.ListBuffer[Candidate]
def tryCandidate(extensionOnly: Boolean)(ref: ImplicitRef) =
var ckind = exploreInFreshCtx { (using ctx: FreshContext) =>
var ckind = exploreInFreshCtx { (ctx: FreshContext) ?=>
ctx.setMode(ctx.mode | Mode.TypevarsMissContext)
candidateKind(ref.underlyingRef)
}
Expand Down
10 changes: 10 additions & 0 deletions tests/neg/context-function-syntax.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
val test =
(using x: Int) => x // error // error

val f = () ?=> 23 // error
val g: ContextFunction0[Int] = ??? // ok
val h: () ?=> Int = ??? // error

object Example3 extends App {
final case class Foo[A, B](run: () ?=> Int) // error
}
3 changes: 1 addition & 2 deletions tests/pos-macros/i8302.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import scala.quoted._
def foo[T](using Quotes, Type[T]): Expr[Any] =
'{ (using q: Quotes) =>
'{ (q: Quotes) ?=>
type TT = T
val t = Type.of[TT]
???
}

4 changes: 2 additions & 2 deletions tests/pos-macros/splice-with-explicit-context.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import scala.quoted._

def f(a: Expr[Int])(using q: Quotes): Unit =

'{ val x: Int = ${ (using q2) => a } }
'{ val x: Int = ${ (q2) ?=> a } }

'{ val x: Int = ${ (using q2: q.Nested) => a } }
'{ val x: Int = ${ (q2: q.Nested) ?=> a } }
5 changes: 0 additions & 5 deletions tests/pos/i7778.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,3 @@ object Example extends App {
object Example2 extends App {
final case class Foo[A, B](run: (A, B) ?=> Int)
}


object Example3 extends App {
final case class Foo[A, B](run: () ?=> Int)
}
2 changes: 1 addition & 1 deletion tests/run-staging/multi-staging.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object Test {
println(run(s1))
}
def stage1(x: Expr[Int])(using Quotes): Expr[Quotes ?=> Expr[Int]] =
val code = '{ (using q1: Quotes) =>
val code = '{ (q1: Quotes) ?=>
val x1 = $x
'{ 1 + ${Expr(x1)} }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/run-staging/quote-nested-4.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object Test {
given Toolbox = Toolbox.make(getClass.getClassLoader)
def main(args: Array[String]): Unit = withQuotes {

val q = '{ (using q: Quotes) =>
val q = '{ (q: Quotes) ?=>
val t = Type.of[String]
t
}
Expand Down
2 changes: 1 addition & 1 deletion tests/run/i10016.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ def f(init: Int ?=> Int) : Int = 1
def f(s: String)(init: Int ?=> Int) : Int = 2

@main def Test() =
assert(f((using x:Int) => x) == 1)
assert(f((x: Int) ?=> x) == 1)