diff --git a/effekt/jvm/src/main/scala/effekt/Repl.scala b/effekt/jvm/src/main/scala/effekt/Repl.scala index 8f9ec9a1bd..2ca4466ae3 100644 --- a/effekt/jvm/src/main/scala/effekt/Repl.scala +++ b/effekt/jvm/src/main/scala/effekt/Repl.scala @@ -108,7 +108,7 @@ class Repl(driver: Driver) extends REPL[Tree, EffektConfig, EffektError] { runFrontend(StringSource(""), module.make(UnitLit()), config) { cu => module.definitions.foreach { case u: Def => - outputCode(DeclPrinter(context.symbolsOf(u)), config) + outputCode(DeclPrinter(List(context.symbolOf(u.id))), config) } } } @@ -221,16 +221,16 @@ class Repl(driver: Driver) extends REPL[Tree, EffektConfig, EffektError] { module = extendedDefs // try to find the symbol for the def to print the type - d.ids.foreach(id => (context.symbolOption(id) match { + context.symbolOption(d.id) match { case Some(v: ValueSymbol) => - Some(context.valueTypeOf(v)) + Some(v, context.valueTypeOf(v)) case Some(b: BlockSymbol) => - Some(context.blockTypeOf(b)) + Some(b, context.blockTypeOf(b)) case t => None - }) map { tpe => + } map { case (id, tpe) => outputCode(pp"${id}: ${tpe}", config) - }) + } } case _ => () @@ -297,7 +297,7 @@ class Repl(driver: Driver) extends REPL[Tree, EffektConfig, EffektError] { ) { def +(d: Def) = { // drop all equally named definitions for now. - val otherDefs = definitions.filterNot { other => d.ids.map{_.name}.forall(other.ids.map{_.name}.contains) } + val otherDefs = definitions.filterNot { other => d.id == other.id } copy(definitions = otherDefs :+ d) } def +(i: Import) = copy(imports = imports.filterNot { _.path == i.path } :+ i) diff --git a/effekt/jvm/src/main/scala/effekt/Server.scala b/effekt/jvm/src/main/scala/effekt/Server.scala index 4ae7bb76d8..85f0a52829 100644 --- a/effekt/jvm/src/main/scala/effekt/Server.scala +++ b/effekt/jvm/src/main/scala/effekt/Server.scala @@ -201,7 +201,7 @@ trait LSPServer extends kiama.util.Server[Tree, EffektConfig, EffektError] with * This way, we can use custom kinds like `refactor.closehole` that can be mapped to keys. */ def inferEffectsAction(fun: FunDef)(using C: Context): Option[TreeAction] = - val symbol = fun.symbol.head + val symbol = fun.symbol for { // the inferred type (tpe, eff) <- C.inferredTypeAndEffectOption(fun) diff --git a/effekt/shared/src/main/scala/effekt/Intelligence.scala b/effekt/shared/src/main/scala/effekt/Intelligence.scala index 5ff0fe405d..2dc30b92a1 100644 --- a/effekt/shared/src/main/scala/effekt/Intelligence.scala +++ b/effekt/shared/src/main/scala/effekt/Intelligence.scala @@ -77,7 +77,7 @@ trait Intelligence { case d: Operation => C.definitionTreeOption(d.interface) case a: Anon => Some(a.decl) case s: SelfParam => s.tree match { - case d: source.Def => Some(d.ids.head) // TODO MRV 14 + case d: source.Def => Some(d.id) case _ => Some(s.tree) } case u => C.definitionTreeOption(u) diff --git a/effekt/shared/src/main/scala/effekt/Namer.scala b/effekt/shared/src/main/scala/effekt/Namer.scala index 0f488f479e..016099fca4 100644 --- a/effekt/shared/src/main/scala/effekt/Namer.scala +++ b/effekt/shared/src/main/scala/effekt/Namer.scala @@ -80,7 +80,7 @@ object Namer extends Phase[Parsed, NameResolved] { */ def preresolve(d: Def)(using Context): Unit = Context.focusing(d) { - case d @ source.ValDef(id, annot, binding) => + case d @ source.ValDef(binders, binding) => () case d @ source.VarDef(id, annot, region, binding) => @@ -225,11 +225,11 @@ object Namer extends Phase[Parsed, NameResolved] { Context.define(id, p) Context.bind(p.capture) - case d @ source.ValDef(ids, annots, binding) => - val tpes = annots.map(a => a.map(resolve)) // TODO MRV: remove Option[] + case d @ source.ValDef(binders, binding) => + val tpes = binders.map(a => a.tpe.map(resolve)) // TODO MRV: remove Option[] resolveGeneric(binding) - (ids zip tpes) foreach { (id, tpe) => - Context.define(id, ValBinder(Context.nameFor(id), tpe, d)) + (binders zip tpes) foreach { case (source.ValueParam(id, _), tpe) => + Context.define(id, ValBinder(Name.local(id), tpe, d)) } case d @ source.VarDef(id, annot, region, binding) => @@ -253,7 +253,7 @@ object Namer extends Phase[Parsed, NameResolved] { // FunDef and EffDef have already been resolved as part of the module declaration case f @ source.FunDef(id, tparams, vparams, bparams, ret, body) => - val sym = f.symbol.head + val sym = f.symbol Context scoped { sym.tparams.foreach { p => Context.bind(p) } Context.bindValues(sym.vparams) @@ -292,7 +292,7 @@ object Namer extends Phase[Parsed, NameResolved] { // The type itself has already been resolved, now resolve constructors case d @ source.DataDef(id, tparams, ctors) => - val data = d.symbol.head + val data = d.symbol data.constructors = ctors map { case source.Constructor(id, ps) => val name = Context.freshNameFor(id) @@ -304,7 +304,7 @@ object Namer extends Phase[Parsed, NameResolved] { // The record has been resolved as part of the preresolution step case d @ source.RecordDef(id, tparams, fs) => - val record = d.symbol.head + val record = d.symbol val name = Context.freshNameFor(id) val constructor = Constructor(name, record.tparams, null, record) // we define the constructor on a copy to avoid confusion with symbols diff --git a/effekt/shared/src/main/scala/effekt/Parser.scala b/effekt/shared/src/main/scala/effekt/Parser.scala index 17822b330c..ccbbf84224 100644 --- a/effekt/shared/src/main/scala/effekt/Parser.scala +++ b/effekt/shared/src/main/scala/effekt/Parser.scala @@ -298,14 +298,11 @@ class EffektParsers(positions: Positions) extends EffektLexers(positions) { lazy val valDefs: P[Def] = `val` ~> someSep(valDef, `,`) ~ (`=` ~/> stmt) ^^ { - case defs ~ binding => - val ids = defs.map(_._1) - val tpes = defs.map(_._2) - ValDef(ids, tpes, binding) + case defs ~ binding => ValDef(defs.asInstanceOf, binding) } - lazy val valDef: P[(IdDef, Option[ValueType])] = - idDef ~ (`:` ~/> valueType).? ^^ { case id ~ tpe => (id, tpe)} + lazy val valDef: P[Param] = + idDef ~ (`:` ~/> valueType).? ^^ { case id ~ tpe => ValueParam(id, tpe)} lazy val varDef: P[Def] = `var` ~/> idDef ~ (`:` ~/> valueType).? ~ (`in` ~/> idRef).? ~ (`=` ~/> stmt) ^^ { diff --git a/effekt/shared/src/main/scala/effekt/Typer.scala b/effekt/shared/src/main/scala/effekt/Typer.scala index c5507385ea..f5e91cb1d3 100644 --- a/effekt/shared/src/main/scala/effekt/Typer.scala +++ b/effekt/shared/src/main/scala/effekt/Typer.scala @@ -192,7 +192,7 @@ object Typer extends Phase[NameResolved, Typechecked] { checkOverloadedMethodCall(c, receiver, id, targs map { _.resolve }, vargs, bargs, expected) case tree @ source.Region(name, body) => - val selfRegion = tree.symbol.head + val selfRegion = tree.symbol Context.bind(selfRegion) val inferredCapture = Context.freshCaptVar(CaptUnificationVar.RegionRegion(tree)) @@ -207,7 +207,7 @@ object Typer extends Phase[NameResolved, Typechecked] { // (1) extract all handled effects and capabilities val providedCapabilities: List[symbols.BlockParam] = handlers map Context.withFocus { h => val effect: InterfaceType = h.effect.resolve - val capability = h.capability.map { _.symbol.head }.getOrElse { Context.freshCapabilityFor(effect) } + val capability = h.capability.map { _.symbol }.getOrElse { Context.freshCapabilityFor(effect) } Context.bind(capability, capability.tpe, CaptureSet(capability.capture)) capability } @@ -248,7 +248,7 @@ object Typer extends Phase[NameResolved, Typechecked] { // Helper definitions: // - capabilities that are bound explicitly by the user - val explicitCapabilities = handlers.flatMap { _.capability.map(_.symbol.head) }.toSet + val explicitCapabilities = handlers.flatMap { _.capability.map(_.symbol) }.toSet // - all effects that are handled val handled = ConcreteEffects(handlerFor.map(_._1)) // - capabilities grouped by effect @@ -375,7 +375,7 @@ object Typer extends Phase[NameResolved, Typechecked] { (params zip vps).foreach { case (param, decl) => - val sym = param.symbol.head + val sym = param.symbol val annotType = sym.tpe annotType.foreach { t => matchDeclared(t, decl, param) } Context.bind(sym, annotType.getOrElse(decl)) @@ -490,7 +490,7 @@ object Typer extends Phase[NameResolved, Typechecked] { def checkPattern(sc: ValueType, pattern: MatchPattern)(using Context, Captures): Map[Symbol, ValueType] = Context.focusing(pattern) { case source.IgnorePattern() => Map.empty - case p @ source.AnyPattern(id) => Map(p.symbol.head -> sc) + case p @ source.AnyPattern(id) => Map(p.symbol -> sc) case p @ source.LiteralPattern(lit) => Context.abort("Matching literals is not supported at the moment.") // lit.checkAgainst(sc) // Map.empty @@ -564,17 +564,17 @@ object Typer extends Phase[NameResolved, Typechecked] { // this is necessary for mutually recursive definitions def precheckDef(d: Def)(using Context): Unit = Context.focusing(d) { case d @ source.FunDef(id, tps, vps, bps, ret, body) => - val fun = d.symbol.head + val fun = d.symbol // (1) make up a fresh capture unification variable and annotate on function symbol val cap = Context.freshCaptVar(CaptUnificationVar.FunctionRegion(d)) Context.bind(fun, cap) // (2) Store the annotated type (important for (mutually) recursive and out-of-order definitions) - fun.annotatedType.foreach { tpe => Context.bind(d.symbol.head, tpe) } + fun.annotatedType.foreach { tpe => Context.bind(d.symbol, tpe) } case d @ source.ExternDef(cap, id, tps, vps, bps, tpe, body) => - val fun = d.symbol.head + val fun = d.symbol Context.bind(fun, fun.toType, fun.capture) if (fun.effects.canonical.nonEmpty) { @@ -582,10 +582,10 @@ object Typer extends Phase[NameResolved, Typechecked] { } case d @ source.ExternResource(id, tpe) => - Context.bind(d.symbol.head) + Context.bind(d.symbol) case d @ source.InterfaceDef(id, tparams, ops, isEffect) => - d.symbol.head.operations.foreach { op => + d.symbol.operations.foreach { op => if (op.effects.toList contains op.appliedInterface) { Context.error("Bidirectional effects that mention the same effect recursively are not (yet) supported.") } @@ -597,7 +597,7 @@ object Typer extends Phase[NameResolved, Typechecked] { case source.DataDef(id, tparams, ctors) => ctors.foreach { c => - val constructor = c.symbol.head + val constructor = c.symbol Context.bind(constructor, constructor.toType, CaptureSet()) constructor.fields.foreach { field => val tpe = field.toType @@ -606,7 +606,7 @@ object Typer extends Phase[NameResolved, Typechecked] { } case d @ source.RecordDef(id, tparams, fields) => - val constructor = d.symbol.head.constructor + val constructor = d.symbol.constructor Context.bind(constructor, constructor.toType, CaptureSet()) constructor.fields.foreach { field => val tpe = field.toType @@ -614,15 +614,15 @@ object Typer extends Phase[NameResolved, Typechecked] { Context.bind(field, tpe, CaptureSet()) } - case d: source.TypeDef => wellformed(d.symbol.head.tpe) - case d: source.EffectDef => wellformed(d.symbol.head.effs) + case d: source.TypeDef => wellformed(d.symbol.tpe) + case d: source.EffectDef => wellformed(d.symbol.effs) case _ => () } def synthDef(d: Def)(using Context, Captures): Result[Unit] = Context.at(d) { d match { case d @ source.FunDef(id, tps, vps, bps, ret, body) => - val sym = d.symbol.head + val sym = d.symbol // was assigned by precheck val functionCapture = Context.lookupCapture(sym) val selfRegion = Context.getSelfRegion(d) @@ -701,7 +701,7 @@ object Typer extends Phase[NameResolved, Typechecked] { Result((), unhandledEffects) - case d @ source.ValDef(id, annot, binding) => + case d @ source.ValDef(binders, binding) => val tpeList = d.symbol.map(_.tpe) val Result(t, effBinding) = if (tpeList.forall(_.isDefined)) { val Result(_, effBinding) = binding checkAgainst tpeList.flatten @@ -716,7 +716,7 @@ object Typer extends Phase[NameResolved, Typechecked] { Result((), effBinding) case d @ source.VarDef(id, annot, reg, binding) => - val sym = d.symbol.head // TODO MRV: List? + val sym = d.symbol // TODO MRV: List? // we use the current region as an approximation for the state val stCapt = reg map Context.symbolOf map { @@ -745,13 +745,13 @@ object Typer extends Phase[NameResolved, Typechecked] { given inferredCapture: Captures = Context.freshCaptVar(CaptUnificationVar.BlockRegion(d)) - val Result(t, effBinding) = checkExprAsBlock(binding, d.symbol.head.tpe) - Context.bind(d.symbol.head, t, inferredCapture) + val Result(t, effBinding) = checkExprAsBlock(binding, d.symbol.tpe) + Context.bind(d.symbol, t, inferredCapture) Result((), effBinding) case d @ source.ExternDef(pure, id, tps, vps, bps, tpe, body) => - d.symbol.head.vparams foreach Context.bind - d.symbol.head.bparams foreach Context.bind + d.symbol.vparams foreach Context.bind + d.symbol.bparams foreach Context.bind Result((), Pure) // all other definitions have already been prechecked @@ -796,23 +796,23 @@ object Typer extends Phase[NameResolved, Typechecked] { val valueTypes = (vparams zip vps) map { case (param, expected) => val adjusted = typeSubst substitute expected - val tpe = param.symbol.head.tpe.map { got => + val tpe = param.symbol.tpe.map { got => matchDeclared(got, adjusted, param); got } getOrElse { adjusted } // bind types to check body - Context.bind(param.symbol.head, tpe) + Context.bind(param.symbol, tpe) tpe } val blockTypes = (bparams zip bps) map { case (param, expTpe) => val adjusted = typeSubst substitute expTpe - val sym = param.symbol.head + val sym = param.symbol val got = sym.tpe matchDeclared(got, adjusted, param) // bind types to check body - Context.bind(param.symbol.head, got, CaptureSet(sym.capture)) + Context.bind(param.symbol, got, CaptureSet(sym.capture)) got } @@ -821,7 +821,7 @@ object Typer extends Phase[NameResolved, Typechecked] { val capabilities = effects.canonical.map { tpe => Context.freshCapabilityFor(tpe) } // (5) Substitute capture params - val captParams = (bparams.map(_.symbol.head) ++ capabilities).map { p => p.capture } + val captParams = (bparams.map(_.symbol) ++ capabilities).map { p => p.capture } val captSubst = Substitutions.captures(cps, captParams.map { p => CaptureSet(p) }) // (6) Substitute both types and captures into expected return type @@ -849,15 +849,15 @@ object Typer extends Phase[NameResolved, Typechecked] { case arg @ source.BlockLiteral(tparams, vparams, bparams, body) => Context in { val tps = tparams.map { p => p.symbol.asTypeParam } val vps = vparams.map { p => - val param = p.symbol.head - val tpe = p.symbol.head.tpe.getOrElse { + val param = p.symbol + val tpe = p.symbol.tpe.getOrElse { Context.abort("Expected type needs to be known for function arguments at the moment.") } Context.bind(param, tpe) tpe } val bps = bparams.map { p => - val param = p.symbol.head + val param = p.symbol val tpe = param.tpe Context.bind(param, tpe) tpe @@ -877,14 +877,14 @@ object Typer extends Phase[NameResolved, Typechecked] { val capabilities = effs.canonical.map { caps.apply } Context.bindCapabilities(arg, capabilities) - val cps = (bparams.map(_.symbol.head) ++ capabilities).map(_.capture) + val cps = (bparams.map(_.symbol) ++ capabilities).map(_.capture) val funType = FunctionType(tps, cps, vps, bps, tpe, effs.toEffects) // Like with functions, bound parameters and capabilities are not closed over usingCaptureWithout(inferredCapture) { - (bparams.map(_.symbol.head) ++ capabilities).map(_.capture) ++ List(selfRegion) + (bparams.map(_.symbol) ++ capabilities).map(_.capture) ++ List(selfRegion) } Result(funType, Pure) diff --git a/effekt/shared/src/main/scala/effekt/context/Annotations.scala b/effekt/shared/src/main/scala/effekt/context/Annotations.scala index 3990ebc34d..57c9d2750c 100644 --- a/effekt/shared/src/main/scala/effekt/context/Annotations.scala +++ b/effekt/shared/src/main/scala/effekt/context/Annotations.scala @@ -504,15 +504,6 @@ trait AnnotationsDB { self: Context => sym } - /** - * Searching the symbol for a definition - * - * These lookups should not fail (except there is a bug in the compiler) - */ - - def symbolsOf(tree: source.Definition): List[Symbol] = - tree.ids.map(symbolOf) - /** * Searching the definition for a symbol */ diff --git a/effekt/shared/src/main/scala/effekt/core/Transformer.scala b/effekt/shared/src/main/scala/effekt/core/Transformer.scala index ff12851cf1..079df9549a 100644 --- a/effekt/shared/src/main/scala/effekt/core/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/core/Transformer.scala @@ -41,27 +41,27 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { def transformToplevel(d: source.Def)(using Context): List[Definition | Declaration | Extern] = d match { case f @ source.FunDef(id, tps, vps, bps, ret, body) => val tparams = tps.map { p => p.symbol } - val cparams = bps.map { b => b.symbol.head.capture } + val cparams = bps.map { b => b.symbol.capture } val vparams = vps map transform val bparams = bps map transform - List(Definition.Def(f.symbol.head, BlockLit(tparams, cparams, vparams, bparams, transform(body)))) + List(Definition.Def(f.symbol, BlockLit(tparams, cparams, vparams, bparams, transform(body)))) case d @ source.DataDef(id, _, ctors) => - val datatype = d.symbol.head + val datatype = d.symbol List(Data(datatype, datatype.tparams, datatype.constructors.map(transform))) case d @ source.RecordDef(id, _, _) => - val rec = d.symbol.head + val rec = d.symbol List(Data(rec, rec.tparams, List(transform(rec.constructor)))) - case v @ source.ValDef(ids, _, binding) if pureOrIO(binding) => + case v @ source.ValDef(_, binding) if pureOrIO(binding) => List(Definition.Let(v.symbol, Run(transform(binding)))) // TODO MRV: symbol must return list - case v @ source.ValDef(ids, _, binding) => + case v @ source.ValDef(_, binding) => Context.at(d) { Context.abort("Effectful bindings not allowed on the toplevel") } case v @ source.DefDef(id, annot, binding) => - val sym = v.symbol.head + val sym = v.symbol val (definition, bindings) = Context.withBindings { Definition.Def(sym, transformAsBlock(binding)) } @@ -78,7 +78,7 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { Context.at(d) { Context.abort("Mutable variable bindings currently not allowed on the toplevel") } case d @ source.InterfaceDef(id, tparamsInterface, ops, isEffect) => - val interface = d.symbol.head + val interface = d.symbol List(core.Interface(interface, interface.tparams, interface.operations.map { case op @ symbols.Operation(name, tps, vps, resultType, effects, interface) => // like in asSeenFrom we need to make up cparams, they cannot occur free in the result type @@ -95,9 +95,9 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { })) case f @ source.ExternDef(pure, id, _, vps, bps, _, body) => - val sym@ExternFunction(name, tps, _, _, ret, effects, capt, _) = f.symbol.head + val sym@ExternFunction(name, tps, _, _, ret, effects, capt, _) = f.symbol assert(effects.isEmpty) - val cps = bps.map(b => b.symbol.head.capture) + val cps = bps.map(b => b.symbol.capture) List(Extern.Def(sym, tps, cps, vps map transform, bps map transform, ret.map(transform), transform(capt), body)) @@ -138,25 +138,25 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { case source.DefStmt(d, rest) => d match { case f @ source.FunDef(id, tps, vps, bps, ret, body) => val tparams = tps.map { p => p.symbol } - val cparams = bps.map { b => b.symbol.head.capture } + val cparams = bps.map { b => b.symbol.capture } val vparams = vps map transform val bparams = bps map transform - Def(f.symbol.head, BlockLit(tparams, cparams, vparams, bparams, transform(body)), transform(rest)) + Def(f.symbol, BlockLit(tparams, cparams, vparams, bparams, transform(body)), transform(rest)) - case v @ source.ValDef(id, _, binding) if pureOrIO(binding) => + case v @ source.ValDef(_, binding) if pureOrIO(binding) => Let(v.symbol, Run(transform(binding)), transform(rest)) - case v @ source.ValDef(id, _, binding) => + case v @ source.ValDef(_, binding) => Val(v.symbol, transform(binding), transform(rest)) case v @ source.DefDef(id, annot, binding) => - val sym = v.symbol.head + val sym = v.symbol insertBindings { Def(sym, transformAsBlock(binding), transform(rest)) } case v @ source.VarDef(id, _, reg, binding) => - val sym = v.symbol.head + val sym = v.symbol insertBindings { Context.bind(transform(binding)) match { case List(v) => State(sym, v, sym.region, transform(rest)) @@ -276,7 +276,7 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { case source.BlockLiteral(tps, vps, bps, body) => val tparams = tps.map(t => t.symbol) - val cparams = bps.map { b => b.symbol.head.capture } + val cparams = bps.map { b => b.symbol.capture } BlockLit(tparams, cparams, vps map transform, bps map transform, transform(body)) case s @ source.New(impl) => @@ -384,7 +384,7 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { case source.TryHandle(prog, handlers) => val (bps, cps) = handlers.map { h => - val cap = h.capability.get.symbol.head + val cap = h.capability.get.symbol (BlockParam(cap), cap.capture) }.unzip @@ -399,7 +399,7 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { } case r @ source.Region(name, body) => - val region = r.symbol.head + val region = r.symbol val tpe = Context.blockTypeOf(region) val cap: core.BlockParam = core.BlockParam(region, transform(tpe)) Context.bind(Region(BlockLit(Nil, List(region.capture), Nil, List(cap), transform(body)))) match { @@ -575,9 +575,9 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { } } - def transform(p: source.BlockParam)(using Context): core.BlockParam = BlockParam(p.symbol.head) + def transform(p: source.BlockParam)(using Context): core.BlockParam = BlockParam(p.symbol) - def transform(p: source.ValueParam)(using Context): core.ValueParam = ValueParam(p.symbol.head) + def transform(p: source.ValueParam)(using Context): core.ValueParam = ValueParam(p.symbol) def insertBindings(stmt: => Stmt)(using Context): Stmt = { val (body, bindings) = Context.withBindings { stmt } @@ -633,7 +633,7 @@ object Transformer extends Phase[Typechecked, CoreTransformed] { // Uses the bind effect to bind the right hand sides of clauses! private def preprocess(sc: List[ValueVar], clause: source.MatchClause)(using Context): Clause = { // TODO MRV: scrutinee is list of ValueVar def boundVars(p: source.MatchPattern): List[ValueParam] = p match { - case p @ source.AnyPattern(id) => p.symbol + case p @ source.AnyPattern(id) => List(p.symbol) case source.TagPattern(id, patterns) => patterns.flatMap(boundVars) case _ => Nil } diff --git a/effekt/shared/src/main/scala/effekt/source/AnnotateCaptures.scala b/effekt/shared/src/main/scala/effekt/source/AnnotateCaptures.scala index 2ae6836d12..d4624ec73d 100644 --- a/effekt/shared/src/main/scala/effekt/source/AnnotateCaptures.scala +++ b/effekt/shared/src/main/scala/effekt/source/AnnotateCaptures.scala @@ -73,7 +73,7 @@ object AnnotateCaptures extends Phase[Typechecked, Typechecked], Query[Unit, Cap case b @ source.BlockLiteral(tps, vps, bps, body) => val selfRegion = Context.annotation(Annotations.SelfRegion, b) - query(body) -- boundCapabilities(b) -- CaptureSet(selfRegion.capture :: bps.map(_.symbol.head.capture)) + query(body) -- boundCapabilities(b) -- CaptureSet(selfRegion.capture :: bps.map(_.symbol.capture)) } override def defn(using Context, Unit) = { @@ -82,10 +82,10 @@ object AnnotateCaptures extends Phase[Typechecked, Typechecked], Query[Unit, Cap */ case tree @ source.FunDef(id, tps, vps, bps, ret, body) => val selfRegion = Context.annotation(Annotations.SelfRegion, tree) - query(body) -- boundCapabilities(tree) -- CaptureSet(selfRegion.capture :: bps.map(_.symbol.head.capture)) + query(body) -- boundCapabilities(tree) -- CaptureSet(selfRegion.capture :: bps.map(_.symbol.capture)) case tree @ VarDef(id, annot, region, binding) => - val symbol = tree.symbol.head + val symbol = tree.symbol query(binding) ++ captureOf(symbol.region) } diff --git a/effekt/shared/src/main/scala/effekt/source/Tree.scala b/effekt/shared/src/main/scala/effekt/source/Tree.scala index 77c3b368f3..212de84121 100644 --- a/effekt/shared/src/main/scala/effekt/source/Tree.scala +++ b/effekt/shared/src/main/scala/effekt/source/Tree.scala @@ -115,28 +115,7 @@ sealed trait Named extends Tree // Something that later will be stored in the symbol table sealed trait Definition extends Named { - def ids: List[IdDef] = this match { - case FunDef(id, _, _, _, _, _) => List(id) - case ValDef(ids, _, _) => ids - case VarDef(id, _, _, _) => List(id) - case DefDef(id, _, _) => List(id) - case InterfaceDef(id, _, _, _) => List(id) - case DataDef(id, _, _) => List(id) - case RecordDef(id, _, _) => List(id) - case TypeDef(id, _, _) => List(id) - case EffectDef(id, _, _) => List(id) - case ExternType(id, _) => List(id) - case ExternDef(_, id, _, _, _, _, _) => List(id) - case ExternResource(id, _) => List(id) - case ExternInterface(id, _) => List(id) - case ExternInclude(_, _, id) => List(id) - case ValueParam(id, _) => List(id) - case BlockParam(id, _) => List(id) - case Constructor(id, _) => List(id) - case Operation(id, _, _, _) => List(id) - case AnyPattern(id) => List(id) - case Region(id, body) => List(id) - } + def id: IdDef } // Something that later can be looked up in the symbol table @@ -191,7 +170,7 @@ export Param.* enum Def extends Definition { case FunDef(id: IdDef, tparams: List[Id], vparams: List[ValueParam], bparams: List[BlockParam], ret: Option[Effectful], body: Stmt) - case ValDef(id: List[IdDef], annot: List[Option[ValueType]], binding: Stmt) + case ValDef(binders: List[ValueParam], binding: Stmt) case VarDef(id: IdDef, annot: Option[ValueType], region: Option[IdRef], binding: Stmt) // TODO MRV 26: List? case DefDef(id: IdDef, annot: Option[BlockType], block: Term) case InterfaceDef(id: IdDef, tparams: List[Id], ops: List[Operation], isEffect: Boolean = true) @@ -539,7 +518,7 @@ object Named { type ResolvedDefinitions[T <: Definitions] = T match { // Defs case FunDef => symbols.UserFunction - case ValDef => symbols.Binder.ValBinder // export Binder.* doesn't seem to work here (maybe because the packages are cyclic?) + case ValDef => List[symbols.Binder.ValBinder] // export Binder.* doesn't seem to work here (maybe because the packages are cyclic?) case VarDef => symbols.Binder.VarBinder case DefDef => symbols.Binder.DefBinder case InterfaceDef => symbols.BlockTypeConstructor.Interface @@ -588,7 +567,10 @@ object Named { } extension [T <: Definitions](t: T & Definition) { - def symbol(using C: Context): List[ResolvedDefinitions[T]] = C.symbolsOf(t).asInstanceOf + def symbol(using C: Context): ResolvedDefinitions[T] = t match { + case t: ValDef => t.binders.map { (b: ValueParam) => C.symbolOf(b.id) }.asInstanceOf + case _ => C.symbolOf(t.id).asInstanceOf + } } extension [T <: References](t: T & Reference) { def definition(using C: Context): ResolvedReferences[T] = C.symbolOf(t).asInstanceOf diff --git a/effekt/shared/src/main/scala/effekt/typer/BoxUnboxInference.scala b/effekt/shared/src/main/scala/effekt/typer/BoxUnboxInference.scala index c9343901af..c0320cdec4 100644 --- a/effekt/shared/src/main/scala/effekt/typer/BoxUnboxInference.scala +++ b/effekt/shared/src/main/scala/effekt/typer/BoxUnboxInference.scala @@ -134,8 +134,8 @@ object BoxUnboxInference extends Phase[NameResolved, NameResolved] { case FunDef(id, tparams, vparams, bparams, ret, body) => FunDef(id, tparams, vparams, bparams, ret, rewrite(body)) - case ValDef(id, annot, binding) => - ValDef(id, annot, rewrite(binding)) + case ValDef(binders, binding) => + ValDef(binders, rewrite(binding)) case VarDef(id, annot, region, binding) => VarDef(id, annot, region, rewrite(binding)) diff --git a/effekt/shared/src/main/scala/effekt/typer/Wellformedness.scala b/effekt/shared/src/main/scala/effekt/typer/Wellformedness.scala index 7404f3adb6..52fac6d856 100644 --- a/effekt/shared/src/main/scala/effekt/typer/Wellformedness.scala +++ b/effekt/shared/src/main/scala/effekt/typer/Wellformedness.scala @@ -89,7 +89,7 @@ object Wellformedness extends Phase[Typechecked, Typechecked], Visit[WFContext] } case tree @ source.Region(id, body) => - val reg = tree.symbol.head + val reg = tree.symbol val tpe = Context.inferredTypeOf(body) val free = freeCapture(tpe) @@ -145,7 +145,7 @@ object Wellformedness extends Phase[Typechecked, Typechecked], Visit[WFContext] * Interface definitions bring an effect in scope that can be handled */ case d @ source.InterfaceDef(id, tparams, ops, isEffect) => - WF.addEffect(d.symbol.head) + WF.addEffect(d.symbol) } /**