diff --git a/CHANGELOG.md b/CHANGELOG.md index a867f1d0d038..6544fcaa5885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -917,6 +917,7 @@ - [Using official BigInteger support][7420] - [Allow users to give a project other than Upper_Snake_Case name][7397] - [Support renaming variable or function][7515] +- [Only use types as State keys][7585] [3227]: https://github.com/enso-org/enso/pull/3227 [3248]: https://github.com/enso-org/enso/pull/3248 @@ -1048,6 +1049,7 @@ [7420]: https://github.com/enso-org/enso/pull/7420 [7397]: https://github.com/enso-org/enso/pull/7397 [7515]: https://github.com/enso-org/enso/pull/7515 +[7585]: https://github.com/enso-org/enso/pull/7585 # Enso 2.0.0-alpha.18 (2021-10-12) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/State.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/State.enso index 1082acf2926f..1af987f44781 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/State.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime/State.enso @@ -12,7 +12,7 @@ from project.Errors.Common import Uninitialized_State Arguments: - key: The key to associate your local_state with in the environment. - It is recommended that types be used as keys. + Use types as keys. - local_state: The value to associate with key. - computation: The computation to execute in the local state environment. diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/SQL.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/SQL.enso index e3600fb454e0..6d201e19160a 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/SQL.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/SQL.enso @@ -158,23 +158,23 @@ optimize_fragments : Vector SQL_Fragment -> Vector SQL_Fragment optimize_fragments fragments = builder = Vector.new_builder go elem = - last_part = State.get SQL_Fragment.Code_Part + last_part = State.get SQL_Fragment case elem of SQL_Fragment.Code_Part code -> new_part = case last_part of Nothing -> SQL_Fragment.Code_Part code SQL_Fragment.Code_Part other -> SQL_Fragment.Code_Part other+code - State.put SQL_Fragment.Code_Part new_part + State.put SQL_Fragment new_part SQL_Fragment.Interpolation _ -> case last_part of Nothing -> Nothing SQL_Fragment.Code_Part _ -> builder.append last_part - State.put SQL_Fragment.Code_Part Nothing + State.put SQL_Fragment Nothing builder.append elem - State.run SQL_Fragment.Code_Part Nothing <| + State.run SQL_Fragment Nothing <| fragments.each go - last_part = State.get SQL_Fragment.Code_Part + last_part = State.get SQL_Fragment case last_part of Nothing -> Nothing SQL_Fragment.Code_Part _ -> builder.append last_part diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/state/RunStateNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/state/RunStateNode.java index 451982d06de3..323ce676d099 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/state/RunStateNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/state/RunStateNode.java @@ -2,6 +2,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached.Shared; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.ReportPolymorphism; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; @@ -12,6 +13,9 @@ import org.enso.interpreter.dsl.Suspend; import org.enso.interpreter.node.BaseNode; import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode; +import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.data.Type; +import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.state.State; @BuiltinMethod( @@ -35,7 +39,7 @@ abstract Object execute( Object doExisting( VirtualFrame frame, State state, - Object key, + Type key, Object local, Object computation, @Bind("state.getContainer()") State.Container data, @@ -54,7 +58,7 @@ Object doExisting( Object doFresh( VirtualFrame frame, State state, - Object key, + Type key, Object local, Object computation, @Bind("state.getContainer()") State.Container data, @@ -67,4 +71,11 @@ Object doFresh( objects.removeKey(data, key); } } + + @Fallback + Object doNonType(State state, Object key, Object local, Object computation) { + var b = EnsoContext.get(this).getBuiltins(); + var payload = b.error().makeUnsupportedArgumentsError(new Object[] {key}, "Use type as a key."); + throw new PanicException(payload, this); + } } diff --git a/test/Tests/src/Main.enso b/test/Tests/src/Main.enso index 7a815aec667d..f14a8ac24f3e 100644 --- a/test/Tests/src/Main.enso +++ b/test/Tests/src/Main.enso @@ -69,6 +69,7 @@ import project.Runtime.Lazy_Spec import project.Runtime.Lazy_Generator_Spec import project.Runtime.Managed_Resource_Spec import project.Runtime.Ref_Spec +import project.Runtime.State_Spec import project.Runtime.Stack_Traces_Spec import project.System.Environment_Spec @@ -135,6 +136,7 @@ main = Test_Suite.run_main <| Runtime_Spec.spec Self_Type_Spec.spec Span_Spec.spec + State_Spec.spec Encoding_Spec.spec Text_Sub_Range_Spec.spec Managed_Resource_Spec.spec diff --git a/test/Tests/src/Runtime/State_Spec.enso b/test/Tests/src/Runtime/State_Spec.enso new file mode 100644 index 000000000000..3e63ebe3f057 --- /dev/null +++ b/test/Tests/src/Runtime/State_Spec.enso @@ -0,0 +1,25 @@ +from Standard.Base import all + +import Standard.Base.Runtime.State +import Standard.Base.Errors.Common.Unsupported_Argument_Types + +from Standard.Test import Test, Test_Suite +import Standard.Test.Extensions + +spec = Test.group "State" <| + Test.specify "Type as a key" <| + s = State.run Test 42 <| + State.get Test + s . should_equal 42 + + Test.specify "string as a key" <| + s n = State.run "my_state" n <| + State.get "my_state" + + p = Panic.catch Unsupported_Argument_Types (s 42) err-> + err.payload + + Meta.type_of p . should_equal Unsupported_Argument_Types + + +main = Test_Suite.run_main spec