Skip to content

Change to new given syntax #7210

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 25 commits into from
Sep 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
73d1c0a
Change to new extension method syntax
odersky Sep 12, 2019
77fbcdb
Change named extension syntax
odersky Sep 12, 2019
35da844
Drop extension keyword
odersky Sep 13, 2019
9023963
Implement new `given` syntax
odersky Sep 14, 2019
b5bec30
Temporarily disable shapeless in the community build
odersky Sep 14, 2019
4d2f216
Adapt xml-interpolator to new extension method syntax
odersky Sep 14, 2019
a6ecc14
Drop implicit match and given match
odersky Sep 12, 2019
b0bf4df
Temporarily allow `delegate` for implicit function types and closures
odersky Sep 14, 2019
2852095
fix test
odersky Sep 14, 2019
5ce4475
Drop "delegate for" in tests
odersky Sep 14, 2019
23ca102
Drop given A => B syntax
odersky Sep 14, 2019
3933284
Implement new syntax for implicit closures
odersky Sep 14, 2019
aa3f364
Switch to new syntax for implicit function types and closures
odersky Sep 14, 2019
c5dac5b
Drop trailing given parameters
odersky Sep 14, 2019
ce973a2
Drop `given as` in instance definitions
odersky Sep 15, 2019
78047d0
Drop infix given for parameters and arguments
odersky Sep 15, 2019
b7a80dc
Adapt CB projects to new given syntax
odersky Sep 15, 2019
4b2f9cd
Disable failing rename tests in language server
odersky Sep 16, 2019
bc00dc6
Refactor imports and implement new given import syntax
odersky Sep 16, 2019
d2cbcc0
Adapt semanticDB to new given imports
odersky Sep 16, 2019
afe3d2f
Fix newline insertion with imports ending with given
odersky Sep 16, 2019
9fe3f70
Change more tests to new given syntax
odersky Sep 16, 2019
d79c66e
Fix tests
odersky Sep 16, 2019
d724f2b
Fixes to syntax and docs
odersky Sep 17, 2019
32b5382
Re-bootstrap the compiler on the previous commit
smarter Sep 17, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class CommunityBuildTest {
extraSbtArgs = Seq("-Dscala.build.compileWithDotty=true")
)

@Test def shapeless = test(
/*@Test*/ def shapeless = test(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Open an issue for this

project = "shapeless",
testCommand = "test",
updateCommand = "update"
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
.setTyperState(new TyperState(ctx.typerState))
.setFreshNames(new FreshNameCreator.Default)
ctx.initialize()(start) // re-initialize the base context with start
def addImport(ctx: Context, refFn: () => TermRef) =
ctx.fresh.setImportInfo(ImportInfo.rootImport(refFn)(ctx))
def addImport(ctx: Context, rootRef: ImportInfo.RootRef) =
ctx.fresh.setImportInfo(ImportInfo.rootImport(rootRef)(ctx))
defn.RootImportFns.foldLeft(start.setRun(this))(addImport)
}

Expand Down
7 changes: 4 additions & 3 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -476,17 +476,18 @@ object desugar {
stat
}
// The Identifiers defined by a case
def caseIds(tree: Tree) = tree match {
def caseIds(tree: Tree): List[Ident] = tree match {
case tree: MemberDef => Ident(tree.name.toTermName) :: Nil
case PatDef(_, ids, _, _) => ids
case PatDef(_, ids: List[Ident] @ unchecked, _, _) => ids
}
val stats = impl.body.map(expandConstructor)
if (isEnum) {
val (enumCases, enumStats) = stats.partition(DesugarEnums.isEnumCase)
if (enumCases.isEmpty)
ctx.error("Enumerations must constain at least one case", namePos)
val enumCompanionRef = TermRefTree()
val enumImport = Import(importGiven = false, enumCompanionRef, enumCases.flatMap(caseIds))
val enumImport =
Import(enumCompanionRef, enumCases.flatMap(caseIds).map(ImportSelector(_)))
(enumImport :: enumStats, enumCases, enumCompanionRef)
}
else (stats, Nil, EmptyTree)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
def statPurity(tree: Tree)(implicit ctx: Context): PurityLevel = unsplice(tree) match {
case EmptyTree
| TypeDef(_, _)
| Import(_, _, _)
| Import(_, _)
| DefDef(_, _, _, _, _) =>
Pure
case vdef @ ValDef(_, _, _) =>
Expand Down
14 changes: 7 additions & 7 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ object Trees {
* where a selector is either an untyped `Ident`, `name` or
* an untyped thicket consisting of `name` and `rename`.
*/
case class Import[-T >: Untyped] private[ast] (importGiven: Boolean, expr: Tree[T], selectors: List[Tree[Untyped]])(implicit @constructorOnly src: SourceFile)
case class Import[-T >: Untyped] private[ast] (expr: Tree[T], selectors: List[untpd.ImportSelector])(implicit @constructorOnly src: SourceFile)
extends DenotingTree[T] {
type ThisTree[-T >: Untyped] = Import[T]
}
Expand Down Expand Up @@ -1191,9 +1191,9 @@ object Trees {
case tree: Template if (constr eq tree.constr) && (parents eq tree.parents) && (derived eq tree.derived) && (self eq tree.self) && (body eq tree.unforcedBody) => tree
case tree => finalize(tree, untpd.Template(constr, parents, derived, self, body)(sourceFile(tree)))
}
def Import(tree: Tree)(importGiven: Boolean, expr: Tree, selectors: List[untpd.Tree])(implicit ctx: Context): Import = tree match {
case tree: Import if (importGiven == tree.importGiven) && (expr eq tree.expr) && (selectors eq tree.selectors) => tree
case _ => finalize(tree, untpd.Import(importGiven, expr, selectors)(sourceFile(tree)))
def Import(tree: Tree)(expr: Tree, selectors: List[untpd.ImportSelector])(implicit ctx: Context): Import = tree match {
case tree: Import if (expr eq tree.expr) && (selectors eq tree.selectors) => tree
case _ => finalize(tree, untpd.Import(expr, selectors)(sourceFile(tree)))
}
def PackageDef(tree: Tree)(pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef = tree match {
case tree: PackageDef if (pid eq tree.pid) && (stats eq tree.stats) => tree
Expand Down Expand Up @@ -1335,8 +1335,8 @@ object Trees {
cpy.TypeDef(tree)(name, transform(rhs))
case tree @ Template(constr, parents, self, _) if tree.derived.isEmpty =>
cpy.Template(tree)(transformSub(constr), transform(tree.parents), Nil, transformSub(self), transformStats(tree.body))
case Import(importGiven, expr, selectors) =>
cpy.Import(tree)(importGiven, transform(expr), selectors)
case Import(expr, selectors) =>
cpy.Import(tree)(transform(expr), selectors)
case PackageDef(pid, stats) =>
cpy.PackageDef(tree)(transformSub(pid), transformStats(stats)(localCtx))
case Annotated(arg, annot) =>
Expand Down Expand Up @@ -1455,7 +1455,7 @@ object Trees {
this(x, rhs)
case tree @ Template(constr, parents, self, _) if tree.derived.isEmpty =>
this(this(this(this(x, constr), parents), self), tree.body)
case Import(_, expr, _) =>
case Import(expr, _) =>
this(x, expr)
case PackageDef(pid, stats) =>
this(this(x, pid), stats)(localCtx)
Expand Down
35 changes: 14 additions & 21 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
Block(cdef :: Nil, New(cls.typeRef, Nil))
}

def Import(importGiven: Boolean, expr: Tree, selectors: List[untpd.Tree])(implicit ctx: Context): Import =
ta.assignType(untpd.Import(importGiven, expr, selectors), ctx.newImportSymbol(ctx.owner, expr))
def Import(expr: Tree, selectors: List[untpd.ImportSelector])(implicit ctx: Context): Import =
ta.assignType(untpd.Import(expr, selectors), ctx.newImportSymbol(ctx.owner, expr))

def PackageDef(pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef =
ta.assignType(untpd.PackageDef(pid, stats), pid)
Expand Down Expand Up @@ -1292,16 +1292,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
* @return The symbols imported.
*/
def importedSymbols(imp: Import,
selectorPredicate: untpd.Tree => Boolean = util.common.alwaysTrue)
selectorPredicate: untpd.ImportSelector => Boolean = util.common.alwaysTrue)
(implicit ctx: Context): List[Symbol] =
imp.selectors.find(selectorPredicate) match {
case Some(id: untpd.Ident) =>
importedSymbols(imp.expr, id.name)
case Some(Thicket((id: untpd.Ident) :: (_: untpd.Ident) :: Nil)) =>
importedSymbols(imp.expr, id.name)
case _ =>
Nil
}
imp.selectors.find(selectorPredicate) match
case Some(sel) => importedSymbols(imp.expr, sel.name)
case _ => Nil

/**
* The list of select trees that resolve to the same symbols as the ones that are imported
Expand All @@ -1326,16 +1321,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}
}

imp.selectors.flatMap {
case Ident(nme.WILDCARD) =>
Nil
case id: untpd.Ident =>
importedSymbols(imp.expr, id.name).flatMap { sym =>
imported(sym, id, None)
}
case Thicket((id: untpd.Ident) :: (newName: untpd.Ident) :: Nil) =>
importedSymbols(imp.expr, id.name).flatMap { sym =>
imported(sym, id, Some(newName))
imp.selectors.flatMap { sel =>
if sel.isWildcard then Nil
else
val renamedOpt = sel.renamed match
case renamed: untpd.Ident => Some(renamed)
case untpd.EmptyTree => None
importedSymbols(imp.expr, sel.name).flatMap { sym =>
imported(sym, sel.imported, renamedOpt)
}
}
}
Expand Down
42 changes: 34 additions & 8 deletions compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,25 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case class GenAlias(pat: Tree, expr: Tree)(implicit @constructorOnly src: SourceFile) extends Tree
case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree])(implicit @constructorOnly src: SourceFile) extends TypTree
case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree)(implicit @constructorOnly src: SourceFile) extends DefTree
case class Export(impliedOnly: Boolean, expr: Tree, selectors: List[Tree])(implicit @constructorOnly src: SourceFile) extends Tree
case class Export(expr: Tree, selectors: List[ImportSelector])(implicit @constructorOnly src: SourceFile) extends Tree

case class ImportSelector(imported: Ident, renamed: Tree = EmptyTree, bound: Tree = EmptyTree)(implicit @constructorOnly src: SourceFile) extends Tree {

/** It's a `given` selector */
val isGiven: Boolean = imported.name.isEmpty

/** It's a `given` or `_` selector */
val isWildcard: Boolean = isGiven || imported.name == nme.WILDCARD

/** The imported name, EmptyTermName if it's a given selector */
val name: TermName = imported.name.asInstanceOf[TermName]

/** The renamed part (which might be `_`), if present, or `name`, if missing */
val rename: TermName = renamed match
case Ident(rename: TermName) => rename
case _ => name
}

case class Number(digits: String, kind: NumberKind)(implicit @constructorOnly src: SourceFile) extends TermTree

enum NumberKind {
Expand Down Expand Up @@ -344,7 +362,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def Template(constr: DefDef, parents: List[Tree], derived: List[Tree], self: ValDef, body: LazyTreeList)(implicit src: SourceFile): Template =
if (derived.isEmpty) new Template(constr, parents, self, body)
else new DerivingTemplate(constr, parents ++ derived, self, body, derived.length)
def Import(importGiven: Boolean, expr: Tree, selectors: List[Tree])(implicit src: SourceFile): Import = new Import(importGiven, expr, selectors)
def Import(expr: Tree, selectors: List[ImportSelector])(implicit src: SourceFile): Import = new Import(expr, selectors)
def PackageDef(pid: RefTree, stats: List[Tree])(implicit src: SourceFile): PackageDef = new PackageDef(pid, stats)
def Annotated(arg: Tree, annot: Tree)(implicit src: SourceFile): Annotated = new Annotated(arg, annot)

Expand Down Expand Up @@ -561,9 +579,13 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case tree: PatDef if (mods eq tree.mods) && (pats eq tree.pats) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
case _ => finalize(tree, untpd.PatDef(mods, pats, tpt, rhs)(tree.source))
}
def Export(tree: Tree)(impliedOnly: Boolean, expr: Tree, selectors: List[Tree])(implicit ctx: Context): Tree = tree match {
case tree: Export if (impliedOnly == tree.impliedOnly) && (expr eq tree.expr) && (selectors eq tree.selectors) => tree
case _ => finalize(tree, untpd.Export(impliedOnly, expr, selectors)(tree.source))
def Export(tree: Tree)(expr: Tree, selectors: List[ImportSelector])(implicit ctx: Context): Tree = tree match {
case tree: Export if (expr eq tree.expr) && (selectors eq tree.selectors) => tree
case _ => finalize(tree, untpd.Export(expr, selectors)(tree.source))
}
def ImportSelector(tree: Tree)(imported: Ident, renamed: Tree, bound: Tree)(implicit ctx: Context): Tree = tree match {
case tree: ImportSelector if (imported eq tree.imported) && (renamed eq tree.renamed) && (bound eq tree.bound) => tree
case _ => finalize(tree, untpd.ImportSelector(imported, renamed, bound)(tree.source))
}
def Number(tree: Tree)(digits: String, kind: NumberKind)(implicit ctx: Context): Tree = tree match {
case tree: Number if (digits == tree.digits) && (kind == tree.kind) => tree
Expand Down Expand Up @@ -621,8 +643,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
cpy.ContextBounds(tree)(transformSub(bounds), transform(cxBounds))
case PatDef(mods, pats, tpt, rhs) =>
cpy.PatDef(tree)(mods, transform(pats), transform(tpt), transform(rhs))
case Export(impliedOnly, expr, selectors) =>
cpy.Export(tree)(impliedOnly, transform(expr), selectors)
case Export(expr, selectors) =>
cpy.Export(tree)(transform(expr), selectors)
case ImportSelector(imported, renamed, bound) =>
cpy.ImportSelector(tree)(transformSub(imported), transform(renamed), transform(bound))
case Number(_, _) | TypedSplice(_) =>
tree
case _ =>
Expand Down Expand Up @@ -676,8 +700,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
this(this(x, bounds), cxBounds)
case PatDef(mods, pats, tpt, rhs) =>
this(this(this(x, pats), tpt), rhs)
case Export(_, expr, _) =>
case Export(expr, _) =>
this(x, expr)
case ImportSelector(imported, renamed, bound) =>
this(this(this(x, imported), renamed), bound)
case Number(_, _) =>
x
case TypedSplice(splice) =>
Expand Down
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 @@ -118,14 +118,14 @@ object Annotations {
apply(New(atp, args))

/** Create an annotation where the tree is computed lazily. */
def deferred(sym: Symbol)(treeFn: given Context => Tree)(implicit ctx: Context): Annotation =
def deferred(sym: Symbol)(treeFn: ImplicitFunction1[Context, Tree])(implicit ctx: Context): Annotation =
new LazyAnnotation {
override def symbol(implicit ctx: Context): Symbol = sym
def complete(implicit ctx: Context) = treeFn given ctx
}

/** Create an annotation where the symbol and the tree are computed lazily. */
def deferredSymAndTree(symf: given Context => Symbol)(treeFn: given Context => Tree)(implicit ctx: Context): Annotation =
def deferredSymAndTree(symf: ImplicitFunction1[Context, Symbol])(treeFn: ImplicitFunction1[Context, Tree])(implicit ctx: Context): Annotation =
new LazyAnnotation {
private[this] var mySym: Symbol = _

Expand Down Expand Up @@ -153,7 +153,7 @@ object Annotations {
object Child {

/** A deferred annotation to the result of a given child computation */
def later(delayedSym: given Context => Symbol, span: Span)(implicit ctx: Context): Annotation = {
def later(delayedSym: ImplicitFunction1[Context, Symbol], span: Span)(implicit ctx: Context): Annotation = {
def makeChildLater(implicit ctx: Context) = {
val sym = delayedSym
New(defn.ChildAnnot.typeRef.appliedTo(sym.owner.thisType.select(sym.name, sym)), Nil)
Expand All @@ -163,7 +163,7 @@ object Annotations {
}

/** A regular, non-deferred Child annotation */
def apply(sym: Symbol, span: Span)(implicit ctx: Context): Annotation = later(given _ => sym, span)
def apply(sym: Symbol, span: Span)(implicit ctx: Context): Annotation = later(sym, span)

def unapply(ann: Annotation)(implicit ctx: Context): Option[Symbol] =
if (ann.symbol == defn.ChildAnnot) {
Expand Down
7 changes: 3 additions & 4 deletions compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ object Contexts {
implicitsCache = {
val implicitRefs: List[ImplicitRef] =
if (isClassDefContext)
try owner.thisType.implicitMembers(GivenOrImplicit)
try owner.thisType.implicitMembers
catch {
case ex: CyclicReference => Nil
}
Expand Down Expand Up @@ -315,7 +315,7 @@ object Contexts {
/** Run `op` as if it was run in a fresh explore typer state, but possibly
* optimized to re-use the current typer state.
*/
final def test[T](op: given Context => T): T = typerState.test(op)(this)
final def test[T](op: ImplicitFunction1[Context, T]): T = typerState.test(op)(this)

/** Is this a context for the members of a class definition? */
def isClassDefContext: Boolean =
Expand Down Expand Up @@ -405,8 +405,7 @@ object Contexts {
case ref: RefTree[?] => Some(ref.name.asTermName)
case _ => None
}
ctx.fresh.setImportInfo(
ImportInfo(sym, imp.selectors, impNameOpt, imp.importGiven))
ctx.fresh.setImportInfo(ImportInfo(sym, imp.selectors, impNameOpt))
}

/** Does current phase use an erased types interpretation? */
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Decorators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ object Decorators {

implicit object reportDeco {
def (x: T) reporting[T](
op: given WrappedResult[T] => String,
op: ImplicitFunction1[WrappedResult[T], String],
printer: config.Printers.Printer = config.Printers.default): T = {
printer.println(op given WrappedResult(x))
x
Expand Down
19 changes: 10 additions & 9 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import scala.collection.mutable
import collection.mutable
import Denotations.SingleDenotation
import util.SimpleIdentityMap
import typer.ImportInfo.RootRef

import scala.annotation.tailrec

Expand Down Expand Up @@ -1028,23 +1029,23 @@ class Definitions {
def isPredefClass(cls: Symbol): Boolean =
(cls.owner eq ScalaPackageClass) && predefClassNames.contains(cls.name)

val StaticRootImportFns: List[() => TermRef] = List[() => TermRef](
() => JavaLangPackageVal.termRef,
() => ScalaPackageVal.termRef
val StaticRootImportFns: List[RootRef] = List[RootRef](
(() => JavaLangPackageVal.termRef, false),
(() => ScalaPackageVal.termRef, false)
)

val PredefImportFns: List[() => TermRef] = List[() => TermRef](
() => ScalaPredefModule.termRef,
() => DottyPredefModule.termRef
val PredefImportFns: List[RootRef] = List[RootRef](
(() => ScalaPredefModule.termRef, true),
(() => DottyPredefModule.termRef, false)
)

@tu lazy val RootImportFns: List[() => TermRef] =
if (ctx.settings.YnoImports.value) List.empty[() => TermRef]
@tu lazy val RootImportFns: List[RootRef] =
if (ctx.settings.YnoImports.value) Nil
else if (ctx.settings.YnoPredef.value) StaticRootImportFns
else StaticRootImportFns ++ PredefImportFns

@tu lazy val ShadowableImportNames: Set[TermName] = Set("Predef", "DottyPredef").map(_.toTermName)
@tu lazy val RootImportTypes: List[TermRef] = RootImportFns.map(_())
@tu lazy val RootImportTypes: List[TermRef] = RootImportFns.map(_._1())

/** Modules whose members are in the default namespace and their module classes */
@tu lazy val UnqualifiedOwnerTypes: Set[NamedType] =
Expand Down
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import printing.Printer
import io.AbstractFile
import config.Config
import util.common._
import typer.ProtoTypes.NoViewsAllowed
import collection.mutable.ListBuffer

/** Denotations represent the meaning of symbols and named types.
Expand Down Expand Up @@ -766,6 +767,11 @@ object Denotations {
if (matches) this else NoDenotation
}

def matchesImportBound(bound: Type)(implicit ctx: Context): Boolean =
if bound.isRef(defn.NothingClass) then false
else if bound.isRef(defn.AnyClass) then true
else NoViewsAllowed.normalizedCompatible(info, bound, keepConstraint = false)

// ------ Transformations -----------------------------------------

private[this] var myValidFor: Period = Nowhere
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ object Flags {

type Flag = opaques.Flag

given FlagOps {
given /*FlagOps*/ {

def (x: FlagSet) bits: Long = opaques.toBits(x)

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Periods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ abstract class Periods { self: Context =>
op(ctx.fresh.setPeriod(pd))

/** Execute `op` at given phase id */
def atPhase[T](pid: PhaseId)(op: given Context => T): T =
def atPhase[T](pid: PhaseId)(op: ImplicitFunction1[Context, T]): T =
op given ctx.withPhase(pid)

/** The period containing the current period where denotations do not change.
Expand Down
Loading