From 7c5d18e21d438ff0374b86e43b142cd9328eac8c Mon Sep 17 00:00:00 2001 From: Evan Ovadia <> Date: Thu, 13 Jul 2023 21:37:33 -0400 Subject: [PATCH 1/2] Regions merge: tuples, function returns, incremental solves --- Frontend/Builtins/src/dev/vale/Builtins.scala | 5 +- .../Builtins/src/dev/vale/resources/tup.vale | 16 ---- .../Builtins/src/dev/vale/resources/tup0.vale | 2 + .../Builtins/src/dev/vale/resources/tup1.vale | 10 +++ .../Builtins/src/dev/vale/resources/tup2.vale | 12 +++ .../Builtins/src/dev/vale/resources/tupN.vale | 83 +++++++++++++++++++ .../vale/AfterRegionsIntegrationTests.scala | 26 +----- .../test/dev/vale/IntegrationTestsA.scala | 18 +++- .../test/dev/vale/PatternTests.scala | 3 +- .../test/dev/vale/TupleTests.scala | 34 ++++++-- .../test/dev/vale/VirtualTests.scala | 2 +- .../PostParserErrorHumanizer.scala | 3 +- .../vale/postparsing/rules/TemplexScout.scala | 4 +- .../Solver/src/dev/vale/solver/Solver.scala | 28 ++++--- .../src/dev/vale/typing/ArrayCompiler.scala | 4 +- .../vale/typing/CompilerErrorHumanizer.scala | 1 + .../src/dev/vale/typing/HinputsT.scala | 6 +- .../dev/vale/typing/SequenceCompiler.scala | 2 +- .../src/dev/vale/typing/ast/ast.scala | 17 ++-- .../src/dev/vale/typing/ast/citizens.scala | 5 +- .../src/dev/vale/typing/ast/expressions.scala | 9 +- .../vale/typing/expression/CallCompiler.scala | 9 +- .../typing/function/DestructorCompiler.scala | 10 ++- .../function/FunctionBodyCompiler.scala | 42 +++++++--- .../typing/function/FunctionCompiler.scala | 2 - .../function/FunctionCompilerCore.scala | 18 +--- .../FunctionCompilerMiddleLayer.scala | 17 +--- .../FunctionCompilerSolvingLayer.scala | 81 ++++++++++++++---- .../dev/vale/typing/AfterRegionsTests.scala | 45 +--------- .../test/dev/vale/typing/CompilerTests.scala | 40 +++++++++ Frontend/Utils/src/dev/vale/Keywords.scala | 15 +++- 31 files changed, 377 insertions(+), 192 deletions(-) delete mode 100644 Frontend/Builtins/src/dev/vale/resources/tup.vale create mode 100644 Frontend/Builtins/src/dev/vale/resources/tup0.vale create mode 100644 Frontend/Builtins/src/dev/vale/resources/tup1.vale create mode 100644 Frontend/Builtins/src/dev/vale/resources/tup2.vale create mode 100644 Frontend/Builtins/src/dev/vale/resources/tupN.vale diff --git a/Frontend/Builtins/src/dev/vale/Builtins.scala b/Frontend/Builtins/src/dev/vale/Builtins.scala index 2b9d35dd7..79742a503 100644 --- a/Frontend/Builtins/src/dev/vale/Builtins.scala +++ b/Frontend/Builtins/src/dev/vale/Builtins.scala @@ -23,7 +23,10 @@ object Builtins { "mainargs" -> "mainargs.vale", "as" -> "as.vale", "print" -> "print.vale", - "tup" -> "tup.vale", + "tup0" -> "tup0.vale", + "tup1" -> "tup1.vale", + "tup2" -> "tup2.vale", + "tupN" -> "tupN.vale", "streq" -> "streq.vale", "panic" -> "panic.vale", "panicutils" -> "panicutils.vale", diff --git a/Frontend/Builtins/src/dev/vale/resources/tup.vale b/Frontend/Builtins/src/dev/vale/resources/tup.vale deleted file mode 100644 index cee89aafc..000000000 --- a/Frontend/Builtins/src/dev/vale/resources/tup.vale +++ /dev/null @@ -1,16 +0,0 @@ - -// See TAVWG for what it would take to re-enable variadic tuples. -// struct Tup { -// _ ..T; -// } - -#!DeriveStructDrop -struct Tup { - 0 T1; - 1 T2; -} - -func drop(tup Tup) -where func drop(T1)void, func drop(T2)void { - [a, b] = tup; -} \ No newline at end of file diff --git a/Frontend/Builtins/src/dev/vale/resources/tup0.vale b/Frontend/Builtins/src/dev/vale/resources/tup0.vale new file mode 100644 index 000000000..33c40c79a --- /dev/null +++ b/Frontend/Builtins/src/dev/vale/resources/tup0.vale @@ -0,0 +1,2 @@ + +struct Tup0 { } diff --git a/Frontend/Builtins/src/dev/vale/resources/tup1.vale b/Frontend/Builtins/src/dev/vale/resources/tup1.vale new file mode 100644 index 000000000..9657337bc --- /dev/null +++ b/Frontend/Builtins/src/dev/vale/resources/tup1.vale @@ -0,0 +1,10 @@ + +// See TAVWG for what it would take to re-enable variadic tuples. +// struct Tup { +// _ ..T; +// } + +#!DeriveStructDrop +struct Tup1 { 0 T0; } +func drop(tup Tup1) +where func drop(T0)void { [a] = tup; } diff --git a/Frontend/Builtins/src/dev/vale/resources/tup2.vale b/Frontend/Builtins/src/dev/vale/resources/tup2.vale new file mode 100644 index 000000000..4cc7e0e77 --- /dev/null +++ b/Frontend/Builtins/src/dev/vale/resources/tup2.vale @@ -0,0 +1,12 @@ + +// See TAVWG for what it would take to re-enable variadic tuples. +// struct Tup { +// _ ..T; +// } + +#!DeriveStructDrop +struct Tup2 { 0 T0; 1 T1; } +func drop(tup Tup2) +where func drop(T0)void, + func drop(T1)void +{ [a, b] = tup; } diff --git a/Frontend/Builtins/src/dev/vale/resources/tupN.vale b/Frontend/Builtins/src/dev/vale/resources/tupN.vale new file mode 100644 index 000000000..7273976ce --- /dev/null +++ b/Frontend/Builtins/src/dev/vale/resources/tupN.vale @@ -0,0 +1,83 @@ + +// See TAVWG for what it would take to re-enable variadic tuples. +// struct Tup { +// _ ..T; +// } + +#!DeriveStructDrop +struct Tup3 { 0 T0; 1 T1; 2 T2; } +func drop(tup Tup3) +where func drop(T0)void, + func drop(T1)void, + func drop(T2)void +{ [a, b, c] = tup; } + +// #!DeriveStructDrop +// struct Tup4 { 0 T0; 1 T1; 2 T2; 3 T3; } +// func drop(tup Tup4) +// where func drop(T0)void, +// func drop(T1)void, +// func drop(T2)void, +// func drop(T3)void +// { [a, b, c, d] = tup; } +// +// #!DeriveStructDrop +// struct Tup5 { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; } +// func drop(tup Tup5) +// where func drop(T0)void, +// func drop(T1)void, +// func drop(T2)void, +// func drop(T3)void, +// func drop(T4)void +// { [a, b, c, d, e] = tup; } +// +// #!DeriveStructDrop +// struct Tup6 { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; 5 T5; } +// func drop(tup Tup6) +// where func drop(T0)void, +// func drop(T1)void, +// func drop(T2)void, +// func drop(T3)void, +// func drop(T4)void, +// func drop(T5)void +// { [a, b, c, d, e, f] = tup; } +// +// #!DeriveStructDrop +// struct Tup7 { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; 5 T5; 6 T6; } +// func drop(tup Tup7) +// where func drop(T0)void, +// func drop(T1)void, +// func drop(T2)void, +// func drop(T3)void, +// func drop(T4)void, +// func drop(T5)void, +// func drop(T6)void +// { [a, b, c, d, e, f, g] = tup; } +// +// #!DeriveStructDrop +// struct Tup8 { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; 5 T5; 6 T6; 7 T7; } +// func drop(tup Tup8) +// where func drop(T0)void, +// func drop(T1)void, +// func drop(T2)void, +// func drop(T3)void, +// func drop(T4)void, +// func drop(T5)void, +// func drop(T6)void, +// func drop(T7)void +// { [a, b, c, d, e, f, g, h] = tup; } +// +// #!DeriveStructDrop +// struct Tup9 { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; 5 T5; 6 T6; 7 T7; 8 T8; } +// func drop(tup Tup9) +// where func drop(T0)void, +// func drop(T1)void, +// func drop(T2)void, +// func drop(T3)void, +// func drop(T4)void, +// func drop(T5)void, +// func drop(T6)void, +// func drop(T7)void, +// func drop(T8)void +// { [a, b, c, d, e, f, g, h, i] = tup; } +// \ No newline at end of file diff --git a/Frontend/IntegrationTests/test/dev/vale/AfterRegionsIntegrationTests.scala b/Frontend/IntegrationTests/test/dev/vale/AfterRegionsIntegrationTests.scala index 839d30bf6..db2535739 100644 --- a/Frontend/IntegrationTests/test/dev/vale/AfterRegionsIntegrationTests.scala +++ b/Frontend/IntegrationTests/test/dev/vale/AfterRegionsIntegrationTests.scala @@ -85,7 +85,7 @@ class AfterRegionsIntegrationTests extends FunSuite with Matchers { |import array.each.*; |func myfunc(i int) { } |exported func main() int { - | mylist = [#][1, 3, 3, 7]; + | mylist = [#](1, 3, 3, 7); | mylist.each(myfunc); | 42 |} @@ -93,17 +93,6 @@ class AfterRegionsIntegrationTests extends FunSuite with Matchers { compile.evalForKind(Vector()) match { case VonInt(42) => } } - test("Simple tuple with one int") { - val compile = RunCompilation.test( "exported func main() int { return (9,).0; }") - - val coutputs = compile.expectCompilerOutputs() - coutputs.lookupFunction("main").header.returnType.kind shouldEqual IntT.i32 - // Funny story, theres no such thing as a one element tuple! It becomes a one element array. - Collector.only(coutputs.lookupFunction("main"), { case TupleTE(_, _) => }) - - compile.evalForKind(Vector()) match { case VonInt(9) => } - } - test("Upcasting in a generic function") { // This is testing two things: // - Upcasting inside a generic function @@ -321,17 +310,4 @@ class AfterRegionsIntegrationTests extends FunSuite with Matchers { compile.evalForKind(Vector()) match { case VonInt(8) => } } - - test("Ignoring receiver") { - val compile = RunCompilation.test( - """ - |struct Marine { hp int; } - |exported func main() int { [_, y] = (Marine(6), Marine(8)); return y.hp; } - | - """.stripMargin) - val coutputs = compile.expectCompilerOutputs() - val main = coutputs.lookupFunction("main"); - main.header.returnType shouldEqual CoordT(ShareT, RegionT(), IntT.i32) - compile.evalForKind(Vector()) match { case VonInt(8) => } - } } diff --git a/Frontend/IntegrationTests/test/dev/vale/IntegrationTestsA.scala b/Frontend/IntegrationTests/test/dev/vale/IntegrationTestsA.scala index 47698c91d..aa8ed299d 100644 --- a/Frontend/IntegrationTests/test/dev/vale/IntegrationTestsA.scala +++ b/Frontend/IntegrationTests/test/dev/vale/IntegrationTestsA.scala @@ -160,7 +160,7 @@ class IntegrationTestsA extends FunSuite with Matchers { compile.evalForKind(Vector()) match { case VonInt(3) => } } test("Simple program with tup") { - val compile = RunCompilation.test("import v.builtins.tup.*; exported func main() int { return 3; }", false) + val compile = RunCompilation.test("import v.builtins.tup2.*; exported func main() int { return 3; }", false) compile.evalForKind(Vector()) match { case VonInt(3) => } } test("Simple program with panic") { @@ -1004,4 +1004,20 @@ class IntegrationTestsA extends FunSuite with Matchers { case VonInt(42) => } } + + test("Ignoring receiver") { + val compile = RunCompilation.test( + """ + |struct Marine { hp int; } + |exported func main() int { [_, y] = (Marine(6), Marine(8)); return y.hp; } + | + """.stripMargin) + val coutputs = compile.expectCompilerOutputs() + val main = coutputs.lookupFunction("main"); + main.header.returnType shouldEqual CoordT(ShareT, RegionT(), IntT.i32) + compile.evalForKind(Vector()) match { + case VonInt(8) => + } + } + } diff --git a/Frontend/IntegrationTests/test/dev/vale/PatternTests.scala b/Frontend/IntegrationTests/test/dev/vale/PatternTests.scala index 5317ad9c9..6b892e5b8 100644 --- a/Frontend/IntegrationTests/test/dev/vale/PatternTests.scala +++ b/Frontend/IntegrationTests/test/dev/vale/PatternTests.scala @@ -71,7 +71,7 @@ class PatternTests extends FunSuite with Matchers { coutputs.functions.head.header.returnType == CoordT(ShareT, RegionT(), IntT.i32) val monouts = compile.getMonouts() - val tupDef = monouts.lookupStruct("Tup") + val tupDef = monouts.lookupStruct("Tup2") val tupDefMemberTypes = tupDef.members.collect({ case StructMemberI(_, _, tyype) => tyype.reference }) tupDefMemberTypes match { @@ -159,4 +159,5 @@ class PatternTests extends FunSuite with Matchers { // coutputs.functions.head.header.returnType == CoordT(ShareT, IntT.i32) // compile.evalForKind(Vector()) match { case VonInt(8) => } // } + } diff --git a/Frontend/IntegrationTests/test/dev/vale/TupleTests.scala b/Frontend/IntegrationTests/test/dev/vale/TupleTests.scala index 705440fea..39a4cf058 100644 --- a/Frontend/IntegrationTests/test/dev/vale/TupleTests.scala +++ b/Frontend/IntegrationTests/test/dev/vale/TupleTests.scala @@ -10,32 +10,56 @@ class TupleTests extends FunSuite with Matchers { test("Returning tuple from function and dotting it") { val compile = RunCompilation.test( """ + |import v.builtins.tup2.*; + |import v.builtins.drop.*; + | |func makeTup() (int, int) { return (2, 3); } |exported func main() int { | return makeTup().1; |} - """.stripMargin) + """.stripMargin, false) compile.evalForKind(Vector()) match { case VonInt(3) => } } test("Tuple with two things") { - val compile = RunCompilation.test( "exported func main() bool { return (9, true).1; }") + val compile = RunCompilation.test( + """ + |import v.builtins.tup2.*; + |import v.builtins.drop.*; + | + |exported func main() bool { + | return (9, true).1; + |} + |""".stripMargin, false) compile.evalForKind(Vector()) match { case VonBool(true) => } } - test("Tuple type") { val compile = RunCompilation.test( """ + |import v.builtins.tup2.*; + |import v.builtins.drop.*; + | |func moo(a (int, int)) int { return a.1; } | |exported func main() int { | return moo((3, 4)); |} - |""".stripMargin) + |""".stripMargin, false) compile.evalForKind(Vector()) match { case VonInt(4) => } } - // todo: indexing into it with a variable, to get a union type + test("Simple tuple with one int") { + val compile = RunCompilation.test("exported func main() int { return (9,).0; }") + + val coutputs = compile.expectCompilerOutputs() + coutputs.lookupFunction("main").header.returnType.kind shouldEqual IntT.i32 + // Funny story, theres no such thing as a one element tuple! It becomes a one element array. + Collector.only(coutputs.lookupFunction("main"), { case TupleTE(_, _) => }) + + compile.evalForKind(Vector()) match { + case VonInt(9) => + } + } } diff --git a/Frontend/IntegrationTests/test/dev/vale/VirtualTests.scala b/Frontend/IntegrationTests/test/dev/vale/VirtualTests.scala index db5f3ee54..ec1582b9f 100644 --- a/Frontend/IntegrationTests/test/dev/vale/VirtualTests.scala +++ b/Frontend/IntegrationTests/test/dev/vale/VirtualTests.scala @@ -342,7 +342,7 @@ class VirtualTests extends FunSuite with Matchers { val moo = compile.expectCompilerOutputs().lookupFunction("moo") val (destVar, returnType) = Collector.only(moo, { - case LetNormalTE(destVar, FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("as"), _), _, _)), returnType), _)) => { + case LetNormalTE(destVar, FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("as"), _), _, _)), returnType), _, _)) => { (destVar, returnType) } }) diff --git a/Frontend/PostParsingPass/src/dev/vale/postparsing/PostParserErrorHumanizer.scala b/Frontend/PostParsingPass/src/dev/vale/postparsing/PostParserErrorHumanizer.scala index d08cc1509..332e70893 100644 --- a/Frontend/PostParsingPass/src/dev/vale/postparsing/PostParserErrorHumanizer.scala +++ b/Frontend/PostParsingPass/src/dev/vale/postparsing/PostParserErrorHumanizer.scala @@ -173,11 +173,12 @@ object PostParserErrorHumanizer { case MacroSelfCoordRuneS() => "_MSelf" case MacroVoidKindRuneS() => "_MVoidK" case MacroVoidCoordRuneS() => "_MVoid" + case MacroSelfKindTemplateRuneS() => "_MSelfKT" case AnonymousSubstructMemberRuneS(interface, method) => "$" + humanizeName(interface) + ".anon." + humanizeName(method) + ".functor" case AnonymousSubstructFunctionBoundParamsListRuneS(interface, method) => "$" + humanizeName(interface) + ".anon." + humanizeName(method) + ".params" case AnonymousSubstructFunctionBoundPrototypeRuneS(interface, method) => "$" + humanizeName(interface) + ".anon." + humanizeName(method) + ".proto" case AnonymousSubstructFunctionInterfaceTemplateRune(interface, method) => "$" + humanizeName(interface) + ".anon." + humanizeName(method) + ".itemplate" -// case AnonymousSubstructFunctionInterfaceKindRune(interface, method) => "$" + humanizeName(interface) + ".anon." + humanizeName(method) + ".ikind" + case AnonymousSubstructFunctionInterfaceKindRune(interface, method) => "$" + humanizeName(interface) + ".anon." + humanizeName(method) + ".ikind" // case AnonymousSubstructFunctionInterfaceOwnershipRune(interface, method) => "$" + humanizeName(interface) + ".anon." + humanizeName(method) + ".iown" case AnonymousSubstructDropBoundParamsListRuneS(interface, method) => "$" + humanizeName(interface) + ".anon.drop.params" case AnonymousSubstructDropBoundPrototypeRuneS(interface, method) => "$" + humanizeName(interface) + ".anon.drop.proto" diff --git a/Frontend/PostParsingPass/src/dev/vale/postparsing/rules/TemplexScout.scala b/Frontend/PostParsingPass/src/dev/vale/postparsing/rules/TemplexScout.scala index 8943cfc50..9160f54c9 100644 --- a/Frontend/PostParsingPass/src/dev/vale/postparsing/rules/TemplexScout.scala +++ b/Frontend/PostParsingPass/src/dev/vale/postparsing/rules/TemplexScout.scala @@ -210,7 +210,7 @@ class TemplexScout( MaybeCoercingLookupSR( rangeS, templateRuneS, - CodeNameS(keywords.tupleHumanName)) + CodeNameS(keywords.tupleHumanName(members.length))) val resultRuneS = rules.RuneUsage(rangeS, ImplicitRuneS(lidb.child().consume())) ruleBuilder += MaybeCoercingCallSR( @@ -277,7 +277,7 @@ class TemplexScout( rules.MaybeCoercingLookupSR( rangeS, templateRuneS, - interner.intern(CodeNameS(keywords.TUP))) + interner.intern(CodeNameS(keywords.tupleHumanName(elements.length)))) ruleBuilder += rules.MaybeCoercingCallSR( rangeS, diff --git a/Frontend/Solver/src/dev/vale/solver/Solver.scala b/Frontend/Solver/src/dev/vale/solver/Solver.scala index 34e98b19c..bf3a2636c 100644 --- a/Frontend/Solver/src/dev/vale/solver/Solver.scala +++ b/Frontend/Solver/src/dev/vale/solver/Solver.scala @@ -128,7 +128,23 @@ class Solver[Rule, Rune, Env, State, Conclusion, ErrType]( solverState.sanityCheck() } - initialRules.foreach(rule => { + addRules(initialRules.toVector) + + if (sanityCheck) { + solverState.sanityCheck() + } + solverState + }) + + def getAllRules(): Vector[Rule] = { + solverState.getAllRules() + } + + def addRules(rules: Vector[Rule]): Unit = { + rules.foreach(rule => addRule(rule)) + } + + def addRule(rule: Rule): Unit = { val ruleIndex = solverState.addRule(rule) if (sanityCheck) { solverState.sanityCheck() @@ -139,16 +155,6 @@ class Solver[Rule, Rune, Env, State, Conclusion, ErrType]( if (sanityCheck) { solverState.sanityCheck() } - }) - - if (sanityCheck) { - solverState.sanityCheck() - } - solverState - }) - - def getAllRules(): Vector[Rule] = { - solverState.getAllRules() } def manualStep(newConclusions: Map[Rune, Conclusion]): diff --git a/Frontend/TypingPass/src/dev/vale/typing/ArrayCompiler.scala b/Frontend/TypingPass/src/dev/vale/typing/ArrayCompiler.scala index cb4d0fdb5..9dee4f9e5 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/ArrayCompiler.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/ArrayCompiler.scala @@ -261,8 +261,10 @@ class ArrayCompiler( } }) vassert(coutputs.getInstantiationBounds(prototype.prototype.id).nonEmpty) + val resultTE = + prototype.prototype.returnType val callTE = - FunctionCallTE(prototype.prototype, Vector(sizeTE) ++ maybeCallableTE) + FunctionCallTE(prototype.prototype, Vector(sizeTE) ++ maybeCallableTE, resultTE) callTE // throw CompileErrorExceptionT(RangedInternalErrorT(range, "Can't construct a mutable runtime array from a callable!")) } diff --git a/Frontend/TypingPass/src/dev/vale/typing/CompilerErrorHumanizer.scala b/Frontend/TypingPass/src/dev/vale/typing/CompilerErrorHumanizer.scala index 95e68f3e4..6a046413d 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/CompilerErrorHumanizer.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/CompilerErrorHumanizer.scala @@ -650,6 +650,7 @@ object CompilerErrorHumanizer { "asc:" + humanizeName(codeMap, substruct) } case SelfNameT() => "self" + case OverrideDispatcherTemplateNameT(implId) => "ovdt:" + humanizeId(codeMap, implId) case IteratorNameT(range) => "it:" + codeMap(range.begin) case IterableNameT(range) => "ib:" + codeMap(range.begin) case IterationOptionNameT(range) => "io:" + codeMap(range.begin) diff --git a/Frontend/TypingPass/src/dev/vale/typing/HinputsT.scala b/Frontend/TypingPass/src/dev/vale/typing/HinputsT.scala index 3ed888122..a612f9e65 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/HinputsT.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/HinputsT.scala @@ -201,9 +201,9 @@ case class HinputsT( vassertOne(lookupLambdasIn(needleFunctionHumanName)) } - def getAllNonExternFunctions: Iterable[FunctionDefinitionT] = { - functions.filter(!_.header.isExtern) - } + // def getAllNonExternFunctions: Iterable[FunctionDefinitionT] = { + // functions.filter(!_.header.isExtern) + // } def getAllUserFunctions: Iterable[FunctionDefinitionT] = { functions.filter(_.header.isUserFunction) diff --git a/Frontend/TypingPass/src/dev/vale/typing/SequenceCompiler.scala b/Frontend/TypingPass/src/dev/vale/typing/SequenceCompiler.scala index dc52ec7c0..7a6394cd7 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/SequenceCompiler.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/SequenceCompiler.scala @@ -44,7 +44,7 @@ class SequenceCompiler( val tupleTemplate @ StructDefinitionTemplataT(_, _) = vassertSome( env.lookupNearestWithName( - interner.intern(StructTemplateNameT(keywords.tupleHumanName)), Set(TemplataLookupContext))) + interner.intern(StructTemplateNameT(keywords.tupleHumanName(types2.length))), Set(TemplataLookupContext))) structCompiler.resolveStruct( coutputs, env, diff --git a/Frontend/TypingPass/src/dev/vale/typing/ast/ast.scala b/Frontend/TypingPass/src/dev/vale/typing/ast/ast.scala index 12f7e7479..1cfed18e4 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/ast/ast.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/ast/ast.scala @@ -78,7 +78,7 @@ case class FunctionExportT( exportedName: StrI ) { override def equals(obj: Any): Boolean = vcurious(); override def hashCode(): Int = vcurious() - + vpass() } case class KindExternT( @@ -340,14 +340,14 @@ case class FunctionHeaderT( case None => case Some(originFunctionTemplata) => { val templateName = TemplataCompiler.getFunctionTemplate(id) - val placeholders = + val placeholderInThisFunctionNames = Collector.all(id, { case KindPlaceholderT(name) => name case PlaceholderTemplataT(name, _) => name }) // Filter out any placeholders that came from the parent, in case this is a lambda function. - val placeholdersOfThisFunction = - placeholders.filter({ case IdT(packageCoord, initSteps, last) => + val selfPlaceholdersInThisFunctionName = + placeholderInThisFunctionNames.filter({ case IdT(packageCoord, initSteps, last) => val parentName = IdT(packageCoord, initSteps.init, initSteps.last) // Not sure which one it is, this should catch both. parentName == id || parentName == templateName @@ -355,14 +355,15 @@ case class FunctionHeaderT( if (originFunctionTemplata.function.isLambda()) { // make sure there are no placeholders - vassert(placeholdersOfThisFunction.isEmpty) + vassert(selfPlaceholdersInThisFunctionName.isEmpty) } else { if (originFunctionTemplata.function.genericParameters.isEmpty) { // make sure there are no placeholders - vassert(placeholdersOfThisFunction.isEmpty) + vassert(selfPlaceholdersInThisFunctionName.isEmpty) } else { - // make sure all the placeholders in the parameters exist as template args - placeholdersOfThisFunction.foreach({ + // Make sure all the placeholders in the generic parameters exist as template args in + // the original function definition. + selfPlaceholdersInThisFunctionName.foreach({ case placeholderName @ IdT(_, _, KindPlaceholderNameT(KindPlaceholderTemplateNameT(index, rune))) => { id.localName.templateArgs(index) match { case KindTemplataT(KindPlaceholderT(placeholderNameAtIndex)) => { diff --git a/Frontend/TypingPass/src/dev/vale/typing/ast/citizens.scala b/Frontend/TypingPass/src/dev/vale/typing/ast/citizens.scala index 956b764c9..9303741c0 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/ast/citizens.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/ast/citizens.scala @@ -14,6 +14,7 @@ trait CitizenDefinitionT { def templateName: IdT[ICitizenTemplateNameT] def genericParamTypes: Vector[ITemplataType] def instantiatedCitizen: ICitizenTT + def defaultRegion: RegionT } case class StructDefinitionT( @@ -28,7 +29,7 @@ case class StructDefinitionT( runeToFunctionBound: Map[IRuneS, IdT[FunctionBoundNameT]], runeToImplBound: Map[IRuneS, IdT[ImplBoundNameT]], ) extends CitizenDefinitionT { - vpass() + def defaultRegion: RegionT = RegionT() override def genericParamTypes: Vector[ITemplataType] = { instantiatedCitizen.id.localName.templateArgs.map(_.tyype) @@ -118,6 +119,8 @@ case class InterfaceDefinitionT( // See IMRFDI for why we need to remember only the internal methods here. internalMethods: Vector[(PrototypeT, Int)] ) extends CitizenDefinitionT { + def defaultRegion: RegionT = RegionT() + override def genericParamTypes: Vector[ITemplataType] = { instantiatedCitizen.id.localName.templateArgs.map(_.tyype) } diff --git a/Frontend/TypingPass/src/dev/vale/typing/ast/expressions.scala b/Frontend/TypingPass/src/dev/vale/typing/ast/expressions.scala index d1ba162cc..f0597a29d 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/ast/expressions.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/ast/expressions.scala @@ -595,7 +595,10 @@ case class ExternFunctionCallTE( case class FunctionCallTE( callable: PrototypeT, - args: Vector[ReferenceExpressionTE] + args: Vector[ReferenceExpressionTE], + // We have this not only for convenience, but also because sometimes a call's result is in a different region than + // what the prototype thinks. + returnType: CoordT ) extends ReferenceExpressionTE { override def equals(obj: Any): Boolean = vcurious(); override def hashCode(): Int = vcurious() @@ -605,9 +608,7 @@ case class FunctionCallTE( case (a, b) => vassert(a == b) }) - override def result: ReferenceResultT = { - ReferenceResultT(callable.returnType) - } + override def result: ReferenceResultT = ReferenceResultT(returnType) } // A typingpass reinterpret is interpreting a type as a different one which is hammer-equivalent. diff --git a/Frontend/TypingPass/src/dev/vale/typing/expression/CallCompiler.scala b/Frontend/TypingPass/src/dev/vale/typing/expression/CallCompiler.scala index 4ebc5b8c7..1d5d78b0c 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/expression/CallCompiler.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/expression/CallCompiler.scala @@ -85,7 +85,9 @@ class CallCompiler( exact = true) vassert(coutputs.getInstantiationBounds(prototype.prototype.prototype.id).nonEmpty) - (ast.FunctionCallTE(prototype.prototype.prototype, argsExprs2)) + val resultTE = + prototype.prototype.prototype.returnType + ast.FunctionCallTE(prototype.prototype.prototype, argsExprs2, resultTE) } case other => { evaluateCustomCall( @@ -188,6 +190,7 @@ class CallCompiler( val actualArgsExprs2 = Vector(actualCallableExpr2) ++ givenArgsExprs2 + val StampFunctionSuccess(prototype, inferences) = resolved val argTypes = actualArgsExprs2.map(_.result.coord) if (argTypes != resolved.prototype.prototype.paramTypes) { throw CompileErrorExceptionT(RangedInternalErrorT(range, "arg param type mismatch. params: " + resolved.prototype.prototype.paramTypes + " args: " + argTypes)) @@ -196,7 +199,9 @@ class CallCompiler( checkTypes(coutputs, env, range, callLocation, resolved.prototype.prototype.paramTypes, argTypes, exact = true) vassert(coutputs.getInstantiationBounds(resolved.prototype.prototype.id).nonEmpty) - val resultingExpr2 = FunctionCallTE(resolved.prototype.prototype, actualArgsExprs2); + val resultTE = + prototype.prototype.returnType + val resultingExpr2 = FunctionCallTE(resolved.prototype.prototype, actualArgsExprs2, resultTE); (resultingExpr2) } diff --git a/Frontend/TypingPass/src/dev/vale/typing/function/DestructorCompiler.scala b/Frontend/TypingPass/src/dev/vale/typing/function/DestructorCompiler.scala index 3de56883c..e119c26a2 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/function/DestructorCompiler.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/function/DestructorCompiler.scala @@ -61,10 +61,12 @@ class DestructorCompiler( case CoordT(ShareT, _, NeverT(_)) => undestructedExpr2 case CoordT(ShareT, _, _) => DiscardTE(undestructedExpr2) case r@CoordT(OwnT, _, _) => { - val destructorPrototype = getDropFunction(env, coutputs, callRange, callLocation, RegionT(), r) - vassert(coutputs.getInstantiationBounds(destructorPrototype.prototype.prototype.id).nonEmpty) - - FunctionCallTE(destructorPrototype.prototype.prototype, Vector(undestructedExpr2)) + val StampFunctionSuccess(destructorPrototype, _) = + getDropFunction(env, coutputs, callRange, callLocation, RegionT(), r) + vassert(coutputs.getInstantiationBounds(destructorPrototype.prototype.id).nonEmpty) + val resultTT = + destructorPrototype.prototype.returnType + FunctionCallTE(destructorPrototype.prototype, Vector(undestructedExpr2), resultTT) } case CoordT(BorrowT, _, _) => (DiscardTE(undestructedExpr2)) case CoordT(WeakT, _, _) => (DiscardTE(undestructedExpr2)) diff --git a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionBodyCompiler.scala b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionBodyCompiler.scala index 4c011a6ee..f85d8f332 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionBodyCompiler.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionBodyCompiler.scala @@ -132,15 +132,24 @@ class BodyCompiler( case Ok((body, returns)) => (body, returns) } - if (returns == Set(explicitRetCoord)) { - // Let it through, it returns the expected type. - } else if (returns == Set(CoordT(ShareT, RegionT(), NeverT(false)))) { - // Let it through, it returns a never but we expect something else, that's fine - } else if (returns == Set() && body2.result.kind == NeverT(false)) { - // Let it through, it doesn't return anything yet it results in a never, which means - // we called panic or something from inside. - } else { - throw CompileErrorExceptionT(CouldntConvertForReturnT(bodyS.range :: parentRanges, explicitRetCoord, returns.head)) + + vcurious(returns.size <= 1) + (returns.headOption, body2.result.kind) match { + case (Some(x), _) if x == explicitRetCoord => { + // Let it through, it returns the expected type. + } + case (Some(CoordT(ShareT, _, NeverT(false))), _) => { + // Let it through, it returns a never but we expect something else, that's fine + } + case (None, NeverT(false)) => { + // Let it through, it doesn't return anything yet it results in a never, which means + // we called panic or something from inside. + } + case _ => { + throw CompileErrorExceptionT( + CouldntConvertForReturnT( + bodyS.range :: parentRanges, explicitRetCoord, returns.head)) + } } (None, body2) @@ -206,9 +215,20 @@ class BodyCompiler( // If we already had a ret, then the above will add a Never to the returns, but that's fine, it will be filtered // out below. + + // val returns = + // if (returnsMaybeWithNever.size > 1 && returnsMaybeWithNever.contains(CoordT(ShareT, NeverT(false)))) { + // returnsMaybeWithNever - CoordT(ShareT, NeverT(false)) + // } else { + // returnsMaybeWithNever + // } + val returns = - if (returnsMaybeWithNever.size > 1 && returnsMaybeWithNever.contains(CoordT(ShareT, RegionT(), NeverT(false)))) { - returnsMaybeWithNever - CoordT(ShareT, RegionT(), NeverT(false)) + if (returnsMaybeWithNever.size > 1) { + returnsMaybeWithNever.filter({ + case CoordT(ShareT, _, NeverT(false)) => false + case _ => true + }) } else { returnsMaybeWithNever } diff --git a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompiler.scala b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompiler.scala index d2fca0c78..e09f18dac 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompiler.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompiler.scala @@ -69,8 +69,6 @@ trait IFunctionCompilerDelegate { FunctionHeaderT } -object FunctionCompiler - trait IEvaluateFunctionResult case class EvaluateFunctionSuccess( diff --git a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerCore.scala b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerCore.scala index 12040aeeb..990082605 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerCore.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerCore.scala @@ -216,23 +216,6 @@ class FunctionCompilerCore( } } - // maybeExport match { - // case None => - // case Some(exportPackageCoord) => { - // val exportedName = - // fullEnv.id.localName match { - // case FunctionNameT(FunctionTemplateNameT(humanName, _), _, _) => humanName - // case _ => vfail("Can't export something that doesn't have a human readable name!") - // } - // coutputs.addInstantiationBounds(header.toPrototype.id, InstantiationBoundArgumentsT(Map(), Map())) - // coutputs.addFunctionExport( - // fullEnv.function.range, - // header.toPrototype, - // exportPackageCoord.packageCoordinate, - // exportedName) - // } - // } - if (header.attributes.contains(PureT)) { // header.params.foreach(param => { // if (param.tyype.permission != ReadonlyT) { @@ -345,6 +328,7 @@ class FunctionCompilerCore( // case ExportA(packageCoord) => Export2(packageCoord) case UserFunctionS => UserFunctionT case PureS => PureT + case AdditiveS => AdditiveT }) } diff --git a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerMiddleLayer.scala b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerMiddleLayer.scala index dd28c0425..a38de73e1 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerMiddleLayer.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerMiddleLayer.scala @@ -226,8 +226,8 @@ class FunctionCompilerMiddleLayer( // }) // // val paramTypes2 = evaluateFunctionParamTypes(runedEnv, function1.params); -// val functionFullName = assembleName(runedEnv.fullName, runedEnv.templateArgs, paramTypes2) -// val needleSignature = SignatureT(functionFullName) +// val functionId = assembleName(runedEnv.fullName, runedEnv.templateArgs, paramTypes2) +// val needleSignature = SignatureT(functionId) // val p = vassertSome(coutputs.lookupFunction(needleSignature)).header.toPrototype // PrototypeTemplata(function1.range, p) // } @@ -310,15 +310,6 @@ class FunctionCompilerMiddleLayer( ParameterT(nameT, maybeVirtuality, param1.preChecked, coord) }) } -// -// private def assembleName( -// name: FullNameT[IFunctionTemplateNameT], -// templateArgs: Vector[ITemplata[ITemplataType]], -// params: Vector[CoordT]): -// FullNameT[IFunctionNameT] = { -// val newLastStep = name.last.makeFunctionName(interner, keywords, templateArgs, params) -// FullNameT(name.packageCoord, name.initSteps, newLastStep) -// } private def getMaybeReturnType( nearEnv: BuildingFunctionEnvironmentWithClosuredsAndTemplateArgsT, @@ -428,8 +419,8 @@ class FunctionCompilerMiddleLayer( // }) // // val paramTypes2 = evaluateFunctionParamTypes(runedEnv, function1.params); -// val functionFullName = assembleName(runedEnv.fullName, runedEnv.templateArgs, paramTypes2) -// val needleSignature = SignatureT(functionFullName) +// val functionId = assembleName(runedEnv.fullName, runedEnv.templateArgs, paramTypes2) +// val needleSignature = SignatureT(functionId) // coutputs.lookupFunction(needleSignature) match { // case Some(FunctionT(header, _)) => { // (header) diff --git a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerSolvingLayer.scala b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerSolvingLayer.scala index a98d6d4a3..32e16fe60 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerSolvingLayer.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/function/FunctionCompilerSolvingLayer.scala @@ -142,7 +142,7 @@ class FunctionCompilerSolvingLayer( false, Vector() ) match { - case Err(e) => return (EvaluateFunctionFailure(InferFailure(e))) + case Err(e) => return EvaluateFunctionFailure(InferFailure(e)) case Ok(i) => (i) } @@ -308,20 +308,65 @@ class FunctionCompilerSolvingLayer( function.rules, function.genericParameters, explicitTemplateArgs.size) val initialSends = assembleInitialSendsFromArgs(callRange.head, function, args) + + + val envs = InferEnv(callingEnv, callRange, callLocation, outerEnv, contextRegion) + val rules = callSiteRules + val runeToType = function.runeToType + val invocationRange = callRange + val initialKnowns = assembleKnownTemplatas(function, explicitTemplateArgs) + val verifyConclusions = true + val isRootSolve = false + val includeReachableBoundsForRunes = Vector() + + val solver = + inferCompiler.makeSolver(envs, coutputs, rules, runeToType, invocationRange, initialKnowns, initialSends) + + var loopCheck = function.genericParameters.size + 1 + + // Incrementally solve and add default generic parameters (and context region). + inferCompiler.incrementallySolve( + envs, coutputs, solver, + (solver) => { + if (loopCheck == 0) { + throw CompileErrorExceptionT(RangedInternalErrorT(callRange, "Infinite loop detected in incremental call solve!")) + } + loopCheck = loopCheck - 1 + + TemplataCompiler.getFirstUnsolvedIdentifyingRune( + function.genericParameters, + (rune) => solver.getConclusion(rune).nonEmpty) match { + case None => false + case Some((genericParam, index)) => { + // This unsolved rune better be one we didn't explicitly hand in already. + vassert(index >= explicitTemplateArgs.size) + + genericParam.default match { + case Some(defaultRules) => { + solver.addRules(defaultRules.rules) + true + } + case None => { + // There are no defaults for this. + false + } + } + } + } + }) match { + case Err(f@FailedCompilerSolve(_, _, err)) => { + return (EvaluateFunctionFailure(InferFailure(f))) + } + case Ok(true) => + case Ok(false) => // Incomplete, will be detected as IncompleteCompilerSolve below. + } + val CompleteCompilerSolve(_, inferredTemplatas, runeToFunctionBound, reachableBounds) = - inferCompiler.solveComplete( - InferEnv(callingEnv, callRange, callLocation, outerEnv, RegionT()), - coutputs, - callSiteRules, - function.runeToType, - callRange, - callLocation, - assembleKnownTemplatas(function, explicitTemplateArgs), - initialSends, - true, - false, - Vector() - ) match { + (inferCompiler.interpretResults(envs, coutputs, invocationRange, callLocation, runeToType, rules, verifyConclusions, isRootSolve, includeReachableBoundsForRunes, solver) match { + case f@FailedCompilerSolve(_, _, _) => Err(f) + case i@IncompleteCompilerSolve(_, _, _, _) => Err(i) + case c@CompleteCompilerSolve(_, _, _, _) => Ok(c) + }) match { case Err(e) => return (EvaluateFunctionFailure(InferFailure(e))) case Ok(i) => (i) } @@ -421,7 +466,8 @@ class FunctionCompilerSolvingLayer( } }) - // Now that we have placeholders, let's do the rest of the solve, so we can get a full prototype out of it. + // Now that we have placeholders, let's do the rest of the solve, so we can get a full + // prototype out of it. val CompleteCompilerSolve(_, inferences, runeToFunctionBound, reachableBounds) = inferCompiler.solveExpectComplete( @@ -516,9 +562,10 @@ class FunctionCompilerSolvingLayer( middleLayer.getOrEvaluateFunctionForHeader( nearEnv, runedEnv, coutputs, parentRanges, callLocation, function) - // We don't add these here because we aren't instantiating anything here, we're compiling a function + // We don't add these here because we aren't instantiating anything here, we're compiling a + // function // not calling it. - // coutputs.addInstantiationBounds(header.toPrototype.fullName, runeToFunctionBound) + // coutputs.addInstantiationBounds(header.toPrototype.id, runeToFunctionBound) header } diff --git a/Frontend/TypingPass/test/dev/vale/typing/AfterRegionsTests.scala b/Frontend/TypingPass/test/dev/vale/typing/AfterRegionsTests.scala index 280db665b..25f4cb24a 100644 --- a/Frontend/TypingPass/test/dev/vale/typing/AfterRegionsTests.scala +++ b/Frontend/TypingPass/test/dev/vale/typing/AfterRegionsTests.scala @@ -35,7 +35,7 @@ class AfterRegionsTests extends FunSuite with Matchers { |} | |exported func main() { - | launchGeneric(Raza(42)); + | launchGeneric(&Raza(42)); |} |""".stripMargin) val coutputs = compile.expectCompilerOutputs() @@ -83,20 +83,6 @@ class AfterRegionsTests extends FunSuite with Matchers { val coutputs = compile.expectCompilerOutputs() } - // Depends on IFunction1, and maybe Generic interface anonymous subclass - test("Basic IFunction1 anonymous subclass") { - val compile = CompilerTestCompilation.test( - """ - |import ifunction.ifunction1.*; - | - |exported func main() int { - | f = IFunction1({_}); - | return (f)(7); - |} - """.stripMargin) - val coutputs = compile.expectCompilerOutputs() - } - test("Prototype rule to get return type") { // i dont think we support this anymore, now that we have generics? @@ -123,7 +109,7 @@ class AfterRegionsTests extends FunSuite with Matchers { test("Can destructure and assemble tuple") { val compile = CompilerTestCompilation.test( """ - |import v.builtins.tup.*; + |import v.builtins.tup2.*; |import v.builtins.drop.*; | |func swap(x (T, Y)) (Y, T) { @@ -132,7 +118,7 @@ class AfterRegionsTests extends FunSuite with Matchers { |} | |exported func main() bool { - | return swap((5, true)).a; + | return swap((5, true)).0; |} |""".stripMargin ) @@ -245,31 +231,6 @@ class AfterRegionsTests extends FunSuite with Matchers { // Collector.only(main, { case call @ FunctionCallTE(PrototypeT(FullNameT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("__call"), _), _, _)), _), _) => call }) } - test("Test struct default generic argument in call") { - val compile = CompilerTestCompilation.test( - """ - |struct MyHashSet { } - |func moo() { - | x = MyHashSet(); - |} - """.stripMargin) - val coutputs = compile.expectCompilerOutputs() - val moo = coutputs.lookupFunction("moo") - val variable = Collector.only(moo, { case LetNormalTE(v, _) => v }) - variable.coord match { - case CoordT( - OwnT, - _, - StructTT( - IdT(_,_, - StructNameT( - StructTemplateNameT(StrI("MyHashSet")), - Vector( - CoordTemplataT(CoordT(ShareT,_,BoolT())), - IntegerTemplataT(5)))))) => - } - } - test("Test interface default generic argument in type") { val compile = CompilerTestCompilation.test( """ diff --git a/Frontend/TypingPass/test/dev/vale/typing/CompilerTests.scala b/Frontend/TypingPass/test/dev/vale/typing/CompilerTests.scala index 9d3778ad4..4c03c1317 100644 --- a/Frontend/TypingPass/test/dev/vale/typing/CompilerTests.scala +++ b/Frontend/TypingPass/test/dev/vale/typing/CompilerTests.scala @@ -1970,4 +1970,44 @@ class CompilerTests extends FunSuite with Matchers { |""".stripMargin) val coutputs = compile.expectCompilerOutputs() } + + // Depends on IFunction1, and maybe Generic interface anonymous subclass + test("Basic IFunction1 anonymous subclass") { + val compile = CompilerTestCompilation.test( + """ + |import ifunction.ifunction1.*; + | + |exported func main() int { + | f = IFunction1({_}); + | return (f)(7); + |} + """.stripMargin) + val coutputs = compile.expectCompilerOutputs() + } + + test("Test struct default generic argument in call") { + val compile = CompilerTestCompilation.test( + """ + |struct MyHashSet { } + |func moo() { + | x = MyHashSet(); + |} + """.stripMargin) + val coutputs = compile.expectCompilerOutputs() + val moo = coutputs.lookupFunction("moo") + val variable = Collector.only(moo, { case LetNormalTE(v, _) => v }) + variable.coord match { + case CoordT( + OwnT, + _, + StructTT( + IdT(_,_, + StructNameT( + StructTemplateNameT(StrI("MyHashSet")), + Vector( + CoordTemplataT(CoordT(ShareT,_,BoolT())), + IntegerTemplataT(5)))))) => + } + } + } diff --git a/Frontend/Utils/src/dev/vale/Keywords.scala b/Frontend/Utils/src/dev/vale/Keywords.scala index 07759c856..6b31d70f4 100644 --- a/Frontend/Utils/src/dev/vale/Keywords.scala +++ b/Frontend/Utils/src/dev/vale/Keywords.scala @@ -99,7 +99,18 @@ class Keywords(interner: Interner) { val isEmpty: StrI = interner.intern(StrI("isEmpty")) val get: StrI = interner.intern(StrI("get")) val underscoresCall: StrI = interner.intern(StrI("__call")) - val tupleHumanName: StrI = interner.intern(StrI("Tup")) + val tupleHumanName: Vector[StrI] = + Vector( + interner.intern(StrI("Tup0")), + interner.intern(StrI("Tup1")), + interner.intern(StrI("Tup2")), + interner.intern(StrI("Tup3")), + interner.intern(StrI("Tup4")), + interner.intern(StrI("Tup5")), + interner.intern(StrI("Tup6")), + interner.intern(StrI("Tup7")), + interner.intern(StrI("Tup8")), + interner.intern(StrI("Tup9"))) // Macros exposed to the user val DeriveStructDrop: StrI = interner.intern(StrI("DeriveStructDrop")) @@ -162,7 +173,7 @@ class Keywords(interner: Interner) { val REF_LIST_COMPOUND_MUTABILITY = interner.intern(StrI("refListCompoundMutability")) val ANY = interner.intern(StrI("any")) val IFUNCTION = interner.intern(StrI("IFunction")) - val TUP = interner.intern(StrI("Tup")) + // val TUP = interner.intern(StrI("Tup")) val M = interner.intern(StrI("M")) val E = interner.intern(StrI("E")) val F = interner.intern(StrI("F")) From 7ec8adb9c61ac308857e3c6975809cbd2caddb8c Mon Sep 17 00:00:00 2001 From: Evan Ovadia <> Date: Thu, 13 Jul 2023 22:27:43 -0400 Subject: [PATCH 2/2] Merges from master --- .../dev/vale/instantiating/Instantiator.scala | 2 +- .../test/dev/vale/ClosureTests.scala | 2 +- .../test/dev/vale/InferTemplateTests.scala | 2 +- .../test/dev/vale/OwnershipTests.scala | 28 +++++++++---------- .../src/dev/vale/typing/Compiler.scala | 1 - .../dev/vale/typing/CompilerLambdaTests.scala | 2 +- .../dev/vale/typing/CompilerSolverTests.scala | 19 +++++++------ .../test/dev/vale/typing/CompilerTests.scala | 28 +++++++++++-------- 8 files changed, 45 insertions(+), 39 deletions(-) diff --git a/Frontend/InstantiatingPass/src/dev/vale/instantiating/Instantiator.scala b/Frontend/InstantiatingPass/src/dev/vale/instantiating/Instantiator.scala index b06b14f6e..0cf6b9932 100644 --- a/Frontend/InstantiatingPass/src/dev/vale/instantiating/Instantiator.scala +++ b/Frontend/InstantiatingPass/src/dev/vale/instantiating/Instantiator.scala @@ -2072,7 +2072,7 @@ class Instantiator( case VoidLiteralTE(_) => { (CoordI[sI](MutableShareI, VoidIT()), VoidLiteralIE()) } - case FunctionCallTE(prototypeT, args) => { + case FunctionCallTE(prototypeT, args, returnType) => { val innersCE = args.map(argTE => { val (argIT, argCE) = diff --git a/Frontend/IntegrationTests/test/dev/vale/ClosureTests.scala b/Frontend/IntegrationTests/test/dev/vale/ClosureTests.scala index eb443aa63..c2770f186 100644 --- a/Frontend/IntegrationTests/test/dev/vale/ClosureTests.scala +++ b/Frontend/IntegrationTests/test/dev/vale/ClosureTests.scala @@ -159,7 +159,7 @@ class ClosureTests extends FunSuite with Matchers { Collector.all( coutputs.lookupFunction("main"), { - case FunctionCallTE(p @ PrototypeT(IdT(_, _, LambdaCallFunctionNameT(_, _, _)), _), _) => p + case FunctionCallTE(p @ PrototypeT(IdT(_, _, LambdaCallFunctionNameT(_, _, _)), _), _, _) => p })) params.head match { case CoordT(ShareT, _, StructTT(IdT(_, Vector(FunctionNameT(FunctionTemplateNameT(StrI("main"), _),Vector(),Vector())),LambdaCitizenNameT(_)))) => diff --git a/Frontend/IntegrationTests/test/dev/vale/InferTemplateTests.scala b/Frontend/IntegrationTests/test/dev/vale/InferTemplateTests.scala index 740346f6b..682561216 100644 --- a/Frontend/IntegrationTests/test/dev/vale/InferTemplateTests.scala +++ b/Frontend/IntegrationTests/test/dev/vale/InferTemplateTests.scala @@ -27,7 +27,7 @@ class InferTemplateTests extends FunSuite with Matchers { } val main = compile.expectCompilerOutputs().lookupFunction("main") Collector.only(main, { - case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("moo"), _), templateArgs, _)), _), _) => { + case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("moo"), _), templateArgs, _)), _), _, _) => { templateArgs match { case Vector(CoordTemplataT(CoordT(OwnT, _, StructTT(IdT(x, Vector(), StructNameT(StructTemplateNameT(StrI("Muta")), Vector())))))) => { vassert(x.isTest) diff --git a/Frontend/IntegrationTests/test/dev/vale/OwnershipTests.scala b/Frontend/IntegrationTests/test/dev/vale/OwnershipTests.scala index 38b8dabfa..70f9d9ff9 100644 --- a/Frontend/IntegrationTests/test/dev/vale/OwnershipTests.scala +++ b/Frontend/IntegrationTests/test/dev/vale/OwnershipTests.scala @@ -69,8 +69,8 @@ class OwnershipTests extends FunSuite with Matchers { """.stripMargin) val main = compile.expectCompilerOutputs().lookupFunction("main") - Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => }) - Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2 + Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => }) + Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2 compile.evalForKind(Vector()) } @@ -94,8 +94,8 @@ class OwnershipTests extends FunSuite with Matchers { """.stripMargin) val main = compile.expectCompilerOutputs().lookupFunction("main") - Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => }) - Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2 + Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => }) + Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2 compile.evalForStdout(Vector()) shouldEqual "Destroying!\n" } @@ -119,7 +119,7 @@ class OwnershipTests extends FunSuite with Matchers { """.stripMargin) val main = compile.expectCompilerOutputs().lookupFunction("main") - Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => }) + Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => }) compile.evalForKindAndStdout(Vector()) match { case (VonInt(10), "Destroying!\n") => } } @@ -143,8 +143,8 @@ class OwnershipTests extends FunSuite with Matchers { """.stripMargin) val main = compile.expectCompilerOutputs().lookupFunction("main") - Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => }) - Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2 + Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => }) + Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2 compile.evalForStdout(Vector()) shouldEqual "Destroying!\n" } @@ -184,18 +184,18 @@ class OwnershipTests extends FunSuite with Matchers { } })) // The only function lookup should be println - Collector.only(destructor, { case FunctionCallTE(functionNameT("println"), _) => }) + Collector.only(destructor, { case FunctionCallTE(functionNameT("println"), _, _) => }) // Only one call (the above println) - Collector.all(destructor, { case FunctionCallTE(_, _) => }).size shouldEqual 1 + Collector.all(destructor, { case FunctionCallTE(_, _, _) => }).size shouldEqual 1 // moo should be calling the destructor val moo = coutputs.lookupFunction("moo") - Collector.only(moo, { case FunctionCallTE(functionNameT("drop"), _) => }) - Collector.only(moo, { case FunctionCallTE(_, _) => }) + Collector.only(moo, { case FunctionCallTE(functionNameT("drop"), _, _) => }) + Collector.only(moo, { case FunctionCallTE(_, _, _) => }) // main should not be calling the destructor val main = coutputs.lookupFunction("main") - Collector.all(main, { case FunctionCallTE(functionNameT("drop"), _) => true }).size shouldEqual 0 + Collector.all(main, { case FunctionCallTE(functionNameT("drop"), _, _) => true }).size shouldEqual 0 compile.evalForStdout(Vector()) shouldEqual "Destroying!\n" } @@ -220,8 +220,8 @@ class OwnershipTests extends FunSuite with Matchers { """.stripMargin) val main = compile.expectCompilerOutputs().lookupFunction("main") - Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => }) - Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2 + Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => }) + Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2 compile.evalForKindAndStdout(Vector()) match { case (VonInt(10), "Destroying!\n") => } } diff --git a/Frontend/TypingPass/src/dev/vale/typing/Compiler.scala b/Frontend/TypingPass/src/dev/vale/typing/Compiler.scala index a7a3e1d00..25999b7bc 100644 --- a/Frontend/TypingPass/src/dev/vale/typing/Compiler.scala +++ b/Frontend/TypingPass/src/dev/vale/typing/Compiler.scala @@ -33,7 +33,6 @@ import dev.vale.typing.expression.LocalHelper import dev.vale.typing.types._ import dev.vale.typing.templata._ import dev.vale.typing.function.FunctionCompiler -import dev.vale.typing.function.FunctionCompiler._ import dev.vale.typing.macros.citizen.StructDropMacro import dev.vale.typing.macros.ssa.SSALenMacro diff --git a/Frontend/TypingPass/test/dev/vale/typing/CompilerLambdaTests.scala b/Frontend/TypingPass/test/dev/vale/typing/CompilerLambdaTests.scala index 12edb4da5..373029390 100644 --- a/Frontend/TypingPass/test/dev/vale/typing/CompilerLambdaTests.scala +++ b/Frontend/TypingPass/test/dev/vale/typing/CompilerLambdaTests.scala @@ -133,7 +133,7 @@ class CompilerLambdaTests extends FunSuite with Matchers { vassert(coutputs.nameIsLambdaIn(lambda.header.id, "main")) val main = coutputs.lookupFunction("main"); - Collector.only(main, { case FunctionCallTE(callee, _) if coutputs.nameIsLambdaIn(callee.id, "main") => }) + Collector.only(main, { case FunctionCallTE(callee, _, _) if coutputs.nameIsLambdaIn(callee.id, "main") => }) } test("Tests lambda and concept function") { diff --git a/Frontend/TypingPass/test/dev/vale/typing/CompilerSolverTests.scala b/Frontend/TypingPass/test/dev/vale/typing/CompilerSolverTests.scala index 1e65f474d..8f9c92203 100644 --- a/Frontend/TypingPass/test/dev/vale/typing/CompilerSolverTests.scala +++ b/Frontend/TypingPass/test/dev/vale/typing/CompilerSolverTests.scala @@ -88,6 +88,7 @@ class CompilerSolverTests extends FunSuite with Matchers { Vector(FunctionTemplateNameT(StrI("bork"),_)), KindPlaceholderNameT(KindPlaceholderTemplateNameT(0, _)))))))), CoordT(ShareT,_, VoidT())), + _, _) => } } @@ -115,7 +116,8 @@ class CompilerSolverTests extends FunSuite with Matchers { Vector(CoordTemplataT(CoordT(ShareT,RegionT(), IntT(32)))), Vector(CoordT(ShareT,RegionT(), IntT(32))))), CoordT(ShareT,RegionT(), IntT(32))), - Vector(ConstantIntTE(IntegerTemplataT(3),32, _))) => + Vector(ConstantIntTE(IntegerTemplataT(3),32, _)), + _) => } } @@ -168,7 +170,7 @@ class CompilerSolverTests extends FunSuite with Matchers { case BlockTE( ReturnTE( ConsecutorTE( - Vector(FunctionCallTE(prototype, _), + Vector(FunctionCallTE(prototype, _, _), VoidLiteralTE(_))))) => prototype } prototype match { @@ -357,7 +359,7 @@ class CompilerSolverTests extends FunSuite with Matchers { ) val coutputs = compile.expectCompilerOutputs() Collector.only(coutputs.lookupFunction("main"), { - case FunctionCallTE(PrototypeT(simpleNameT("moo"), _), _) => + case FunctionCallTE(PrototypeT(simpleNameT("moo"), _), _, _) => }) } @@ -375,7 +377,7 @@ class CompilerSolverTests extends FunSuite with Matchers { ) val coutputs = compile.expectCompilerOutputs() Collector.only(coutputs.lookupFunction("main"), { - case FunctionCallTE(PrototypeT(simpleNameT("moo"), _), _) => + case FunctionCallTE(PrototypeT(simpleNameT("moo"), _), _, _) => }) } @@ -426,7 +428,7 @@ class CompilerSolverTests extends FunSuite with Matchers { val coutputs = compile.expectCompilerOutputs() val arg = coutputs.lookupFunction("main").body shouldHave { - case FunctionCallTE(_, Vector(arg)) => arg + case FunctionCallTE(_, Vector(arg), _) => arg } arg.result.coord match { case CoordT(_, _, StructTT(_)) => @@ -452,7 +454,7 @@ class CompilerSolverTests extends FunSuite with Matchers { val moo = coutputs.lookupFunction("moo") val main = coutputs.lookupFunction("main") main.body shouldHave { - case FunctionCallTE(prototype, Vector(_, _)) => { + case FunctionCallTE(prototype, Vector(_, _), _) => { prototype.id.localName.templateArgs.head match { case CoordTemplataT(CoordT(_, _, InterfaceTT(_))) => } @@ -489,7 +491,8 @@ class CompilerSolverTests extends FunSuite with Matchers { UpcastTE( _, InterfaceTT(IdT(_,_,InterfaceNameT(InterfaceTemplateNameT(StrI("IShip")),Vector(CoordTemplataT(CoordT(ShareT,_,IntT(32))))))), - _))) => + _)), + _) => } } @@ -622,7 +625,7 @@ class CompilerSolverTests extends FunSuite with Matchers { val main = coutputs.lookupFunction("main") val call = Collector.only(main, { - case call @ FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("swap"), _), _, _)), _), _) => call + case call @ FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("swap"), _), _, _)), _), _, _) => call }) call.callable.id.localName.templateArgs.last match { case CoordTemplataT(CoordT(ShareT, _, IntT(32))) => diff --git a/Frontend/TypingPass/test/dev/vale/typing/CompilerTests.scala b/Frontend/TypingPass/test/dev/vale/typing/CompilerTests.scala index 4c03c1317..86818925c 100644 --- a/Frontend/TypingPass/test/dev/vale/typing/CompilerTests.scala +++ b/Frontend/TypingPass/test/dev/vale/typing/CompilerTests.scala @@ -113,7 +113,8 @@ class CompilerTests extends FunSuite with Matchers { functionNameT("+"), Vector( ConstantIntTE(IntegerTemplataT(2), _, _), - ConstantIntTE(IntegerTemplataT(3), _, _))) => + ConstantIntTE(IntegerTemplataT(3), _, _)), + _) => }) } @@ -163,7 +164,7 @@ class CompilerTests extends FunSuite with Matchers { val coutputs = compile.expectCompilerOutputs() val main = coutputs.lookupFunction("main") Collector.only(main, { - case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("drop"), _), _, _)), _), _) => + case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("drop"), _), _, _)), _), _, _) => }) } @@ -182,7 +183,7 @@ class CompilerTests extends FunSuite with Matchers { val coutputs = compile.expectCompilerOutputs() val main = coutputs.lookupFunction("main") Collector.only(main, { - case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("drop"), _), _, _)), _), _) => + case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("drop"), _), _, _)), _), _, _) => }) } @@ -301,7 +302,8 @@ class CompilerTests extends FunSuite with Matchers { Collector.only(main, { case FunctionCallTE( PrototypeT(simpleNameT("MyStruct"), _), - Vector(ConstantIntTE(IntegerTemplataT(7), _, _))) => + Vector(ConstantIntTE(IntegerTemplataT(7), _, _)), + _) => }) } @@ -320,8 +322,8 @@ class CompilerTests extends FunSuite with Matchers { """.stripMargin) val main = compile.expectCompilerOutputs().lookupFunction("main") - Collector.only(main, { case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("drop"), _), _, _)), _), _) => }) - Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2 + Collector.only(main, { case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("drop"), _), _, _)), _), _, _) => }) + Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2 } test("Tests defining an empty interface and an implementing struct") { @@ -462,7 +464,7 @@ class CompilerTests extends FunSuite with Matchers { FunctionTemplateNameT(StrI("drop"),_), Vector(), Vector(CoordT(OwnT,_,StructTT(IdT(_,_,StructNameT(StructTemplateNameT(StrI("MyStruct")),Vector()))))))), - CoordT(ShareT,_,VoidT())), _) => + CoordT(ShareT,_,VoidT())), _, _) => } } @@ -602,7 +604,7 @@ class CompilerTests extends FunSuite with Matchers { } Collector.all(coutputs.lookupFunction("main"), { - case FunctionCallTE(functionNameT("MySome"), _) => + case FunctionCallTE(functionNameT("MySome"), _, _) => }) } @@ -660,7 +662,7 @@ class CompilerTests extends FunSuite with Matchers { val main = coutputs.lookupFunction("main") Collector.only(main, { - case f @ FunctionCallTE(PrototypeT(simpleNameT("doCivicDance"),CoordT(ShareT,_, IntT.i32)), _) => { + case f @ FunctionCallTE(PrototypeT(simpleNameT("doCivicDance"),CoordT(ShareT,_, IntT.i32)), _, _) => { // vassert(f.callable.paramTypes == Vector(Coord(Borrow,InterfaceRef2(simpleName("Car"))))) } }) @@ -822,7 +824,7 @@ class CompilerTests extends FunSuite with Matchers { val main = coutputs.lookupFunction("main") Collector.only(main, { - case f @ FunctionCallTE(functionNameT("forEach"), _) => f + case f @ FunctionCallTE(functionNameT("forEach"), _, _) => f }) } @@ -847,7 +849,8 @@ class CompilerTests extends FunSuite with Matchers { val main = coutputs.lookupFunction("main") val destructorCalls = Collector.all(main, { - case fpc @ FunctionCallTE(PrototypeT(IdT(_,Vector(StructTemplateNameT(StrI("Marine"))),FunctionNameT(FunctionTemplateNameT(StrI("drop"),_),Vector(),Vector(CoordT(OwnT,_, StructTT(IdT(_,Vector(),StructNameT(StructTemplateNameT(StrI("Marine")),Vector()))))))),_),_) => fpc + case fpc @ FunctionCallTE( + PrototypeT(IdT(_,Vector(StructTemplateNameT(StrI("Marine"))),FunctionNameT(FunctionTemplateNameT(StrI("drop"),_),Vector(),Vector(CoordT(OwnT,_, StructTT(IdT(_,Vector(),StructNameT(StructTemplateNameT(StrI("Marine")),Vector()))))))),_),_,_) => fpc }) destructorCalls.size shouldEqual 2 } @@ -1866,7 +1869,8 @@ class CompilerTests extends FunSuite with Matchers { Collector.only(mainFunc, { case FunctionCallTE( prototype @ PrototypeT(IdT(_,Vector(),FunctionNameT(FunctionTemplateNameT(StrI("as"),_),_,_)), _), - Vector(arg)) => { + Vector(arg), + _) => { (prototype, arg) } })