Commit Graph

1230 Commits

Author SHA1 Message Date
KtorZ 442010d056
Fix generation of fallback validator
This must only happen in case all other validator succeed; otherwise
  we might generate invalid validators.
2024-08-25 16:20:08 +02:00
rvcas ff1464b462
feat: annotated data for option datum 2024-08-25 16:20:08 +02:00
rvcas 4589c51cd3
feat: enforcement that spend first arg is option 2024-08-25 16:20:07 +02:00
rvcas c57009bf99
chore: fix some tests that now correctly fail due to arity checks 2024-08-25 16:20:07 +02:00
KtorZ f9acbd3bcb
DRY handlers generation from validator 2024-08-25 16:20:07 +02:00
KtorZ 6a6bf6f65f
Handle (though discard) first script purpose argument of publish and propose. 2024-08-25 16:20:07 +02:00
KtorZ fe205e360f
Update remaining script context e2e tests. 2024-08-25 16:20:06 +02:00
KtorZ 7ec3f2e8df
DRY builtins types creation to ensure proper consistency. 2024-08-25 16:20:06 +02:00
rvcas 5b61a75088
feat: handler withdraw purpose 2024-08-25 16:20:06 +02:00
microproofs f86d550ca0
Fix type for mint scriptinfo 2024-08-25 16:20:06 +02:00
microproofs 953ee6b5d1
Fix ordering for ScriptInfo type 2024-08-25 16:20:05 +02:00
rvcas b9456b5946
fix: wrap_validator_condition needs to happen earlier 2024-08-25 16:20:05 +02:00
rvcas 79099675d4
fix: free unique on purpose arg 2024-08-25 16:20:05 +02:00
rvcas c2c4bddfb3
feat: new check for valid purpose names 2024-08-25 16:20:05 +02:00
KtorZ 5cf0a4d294
Fix validator arity check
For now, this panics, but ideally, we should return a "unknown
  purpose" error when we cannot map the name to an arity.
2024-08-25 16:20:04 +02:00
KtorZ 972e9bd763
Define ScriptPurpose & ScriptContext types in prelude, fix codegen new v3 wrapper. 2024-08-25 16:20:04 +02:00
rvcas f94e40daf4
fix: more test and issues with scoping/names 2024-08-25 16:20:03 +02:00
rvcas cf3180996a
fix: map fallback name if present to else 2024-08-25 16:20:03 +02:00
rvcas 00907c2bcc
fix: format snapshot tests 2024-08-25 16:20:03 +02:00
rvcas 7f26db401c
feat: handler implicit some and none 2024-08-25 16:20:03 +02:00
rvcas 6b8be61b6e
test: new snapshots for parsing v3 validators 2024-08-25 16:20:03 +02:00
rvcas 0d8d80e5a7
feat: transform TypedValidator in a function of handlers 2024-08-25 16:20:03 +02:00
rvcas 471bbe2175
feat: append validator name to handlers 2024-08-25 16:20:02 +02:00
rvcas b984f0455a
feat: return a vec instead of Option 2024-08-25 16:20:02 +02:00
rvcas 4287fa3f4a
feat: new formatting for validators v3 2024-08-25 16:20:02 +02:00
rvcas 9e866a5ec1
fix: make sure that fallback gets it's own scope with params 2024-08-25 16:20:02 +02:00
rvcas 1d9034573b
feat: impl infer for new validators 2024-08-25 16:20:02 +02:00
rvcas fff90f7df5
feat: fix inference comp issues 2024-08-25 16:20:02 +02:00
rvcas 0de5cbc74e
feat: implement new validator parsing 2024-08-25 16:20:01 +02:00
KtorZ 9aa9070f56
Revise desugaring following feedback
- We now consistently desugar an expect in the last position as
    `Void`. Regardless of the pattern. Desugaring to a boolean value is
    deemed too confusing.

  - This commit also removes the desugaring for let-binding. It's only
    ever allowed for _expect_ which then behaves like a side effect.

  - We also now allow tests to return either `Bool` or `Void`. A test
    that returns `Void` is treated the same as a test returning `True`.
2024-08-23 16:04:40 +02:00
KtorZ fbe6f02fd1
Allow assignment as last expression
This is debatable, but I would argue that it's been sufficiently
  annoying for people and such a low-hanging fruit that we ought to do
  something about it.

  The strategy here is simple: when we find a sequence of expression
  that ends with an assignment (let or expect), we can simply desugar it
  into two expressions: the assignment followed by either `Void` or a
  boolean.

  The latter is used when the assignment pattern is itself a boolean;
  the next boolean becomes the expected value. The former, `Void`, is
  used for everything else. So said differently, any assignment
  implicitly _returns Void_, except for boolean which return the actual
  patterned bool.

  <table>
  <thead><tr><th>expression</th><th>desugar into</th></tr></thead>
  <tbody>
  <tr>
  <td>

  ```aiken
  fn expect_bool(data: Data) -> Void {
    expect _: Bool = data
  }
  ```
  </td>
  <td>

  ```aiken
  fn expect_bool(data: Data) -> Void {
    expect _: Bool = data
    Void
  }
  ```
  </td>
  </tr>
  <tr>
  <td>

  ```aiken
  fn weird_maths() -> Bool {
    expect 1 == 2
  }
  ```
  </td>
  <td>

  ```aiken
  fn weird_maths() -> Bool {
    expect True = 1 == 2
    True
  }
  ```
  </td>
  </tr>
  </tbody>
  </table>
2024-08-23 16:04:39 +02:00
KtorZ 0f905045e7
Rename mk_nil_data, mk_pair_data & mk_nil_pair_data builtins. 2024-08-23 10:39:37 +02:00
KtorZ 5067aad0d8
Fix 'Pair' formatter inside forced unbroken components. 2024-08-13 17:05:41 +02:00
KtorZ f56b9bbbc7
Rename function variable in parser
Better reflect its actual semantic. The name probably slipped through a wrong copy pasting.
2024-08-13 10:56:28 +02:00
Riley-Kilgore cab58e5aab One other place 2024-08-12 17:57:54 -04:00
Riley-Kilgore 213ad48de7 Fixed span calculation for backpassing (sort of) 2024-08-12 17:57:54 -04:00
Matthias Benkort eb4a43719c
Merge pull request #998 from aiken-lang/riley/misc-hover
Added more granularity to find_node for Fn
2024-08-12 02:16:38 +02:00
Riley-Kilgore 52c8ca6cee Added fix to Fn find_node 2024-08-08 17:15:28 -07:00
microproofs 72059eacee
Fix: Recursion issue where the static param optimization on recursive functions that were passed as arguments to other functions 2024-08-08 19:36:16 -04:00
microproofs 0800901135 Fix clippy 2024-08-08 00:39:44 -04:00
microproofs 51fd503317 warning fix 2024-08-08 00:39:44 -04:00
microproofs 0a1992acd2 Run acceptance tests 2024-08-08 00:39:44 -04:00
microproofs 56ff4ec678 Fixing other tests 2024-08-08 00:39:44 -04:00
microproofs 33370b8637 Fix minor issues found when testing 2024-08-08 00:39:44 -04:00
KtorZ f5c4e185d4 Redact compiledCode & hash in generated blueprint tests
The point of those tests is to ensure that blueprints are generated
  properly, irrespective of the generated code. It is annoying to
  constantly get those test failing every time we introduce an
  optimization or something that would slightly change the generated
  UPLC.
2024-08-08 00:39:44 -04:00
microproofs 8a461d5bd5 Few minor changes, clippy fixes, and test fixes 2024-08-08 00:39:44 -04:00
microproofs 4cf81a19b1 Update most of the tests and builder functions to use the new delay_branch_functions 2024-08-08 00:39:44 -04:00
microproofs d7e9fef4d3 Create new helper functions to take care of force and delaying branch terms 2024-08-08 00:39:44 -04:00
KtorZ 23a3134642 Rework choose_data_xxx API to include force/delay inside functions. 2024-08-08 00:39:44 -04:00
microproofs d23a5b2f11 Fix test for expect_head_cast_data_with_tail 2024-08-08 00:39:44 -04:00
KtorZ 021679b8ac Force unwrap_xxx_or inside function body
Otherwise, it becomes the responsibility of the caller to force the result; which may be easily forgotten.
2024-08-08 00:39:44 -04:00
microproofs a132a2e486 Fix unwrap issues 2024-08-08 00:39:44 -04:00
KtorZ aefbc6e1b9 Define a safer API for unwrap_xxx_or and choose_data_xxx
Cloning a 'Term' is potentially dangerous, so we don't want this to
  happen by mistake. So instead, we pass in var names and turn them into
  terms when necessary.
2024-08-08 00:39:44 -04:00
KtorZ 9610237616 Refactor unknown_data_to_type, break down into smaller functions. 2024-08-08 00:39:44 -04:00
KtorZ c3a61706b5 Factor out common UPLC logic for converting Data to Bool. 2024-08-08 00:39:44 -04:00
microproofs 05504b9762 Fix out of order expect check. Also fix no_inline error in code gen. @acceptance_107 2024-08-08 00:39:44 -04:00
microproofs 663695558c Fix remaining errors and now onto testing 2024-08-08 00:39:44 -04:00
microproofs 0be5229f1c Only 2 errors and todos left to finish 2024-08-08 00:39:44 -04:00
microproofs 6ba9a312f0 Work through all but constr case for expect_type_assign
TODO: constr case for expect_type_assign
TODO: soft_cast opcode uplc codegen
TODO: fix PairAccessor opcode uplc codegen
2024-08-08 00:39:44 -04:00
microproofs dd5badd884 Start work on revamping assignment so we can handle soft casting properly 2024-08-08 00:39:44 -04:00
KtorZ a6c5dbb5ad Thread down if/is pattern assignment type down to code-generation.
This isn't sufficient however, as the 'assignment' helper handling
  code generation doesn't perform any check when patterns are vars. This
  is curious, and need to be investigated further.
2024-08-08 00:39:44 -04:00
KtorZ aa872846bb
Re-generate insta snapshots, remove obsolete snapshots. 2024-08-06 19:25:35 +02:00
KtorZ 9d8fdf787c
Improve formatter on long-lines, in particular bin-ops. 2024-08-06 19:25:35 +02:00
KtorZ 91e0e2493a
Provide better errors on unknown type in cyclic definitions.
Let's consider the following case:

  ```
  type Var =
    Integer

  type Vars =
    List<Var>
  ```

  This incorrectly reports an infinite cycle; due to the inability to
  properly type-check `Var` which is also a dependent var of `Vars`. Yet
  the real issue here being that `Integer` is an unknown type.

  This commit also upgrades miette to 7.2.0, so that we can also display
  a better error output when the problem is actually a cycle.
2024-08-06 19:24:48 +02:00
KtorZ 1ae6640cd0
Make alternative clause parser more flexible.
The spirit here is to make it easier to discover this syntax. People
  have different intuition about it and the single pipe may not be the
  most obvious one.

  It is however the recommended syntax, and the formatter will rewrite
  any of the other to it.
2024-08-06 11:31:11 +02:00
KtorZ 8c121f6d97
Document 'export' and provide better errors on module not found. 2024-08-06 11:09:05 +02:00
KtorZ 6454266b06
Allow simple expressions as configuration in aiken.toml
This is currently extremely limited as it only supports (UTF-8)
  bytearrays and integers. We should seek to at least support hex bytes
  sequences, as well as bools, lists and possibly options.

  For the latter, we the rework on constant outlined in #992 is
  necessary.
2024-08-04 14:48:03 +02:00
KtorZ 6de1d91104
Create dedicated error when environment isn't found.
This is less confusing that getting an 'UnknownModule' error reporting
  even a different module name than the one actually being important
  ('env').

  Also, this commit fixes a few errors found in the type-checker
  when reporting 'UnknownModule' errors. About half the time, we would
  actually attached _imported modules_ instead of _importable modules_
  to the error, making the neighboring suggestion quite worse (nay
  useless).
2024-08-04 14:48:03 +02:00
KtorZ 2dca0c4185
Ensure env modules dependencies are properly handled.
We figure out dependencies by looking at 'use' definition in parsed
  modules. However, in the case of environment modules, we must consider
  all of them when seeing "use env". Without that, the env modules are
  simply compiled in parallel and may not yet have been compiled when
  they are needed as actual dependencies.
2024-08-04 10:33:58 +02:00
KtorZ fbe2f82582
Thread down environment module from cli down to the type-checker
We simply provide a flag with a free-form output which acts as
  the module to lookup in the 'env' folder. The strategy is to replace
  the environment module name on-the-fly when a user tries to import
  'env'.

  If the environment isn't found, an 'UnknownModule' error is raised
  (which I will slightly adjust in a following commits to something more
  related to environment)

  There are few important consequences to this design which may not seem
  immediately obvious:

  1. We parse and type-check every env modules, even if they aren't
     used. This ensures that code doesn't break with a compilation error
     simply because people forgot to type-check a given env.

     Note that compilation could still fail because the env module
     itself could provide an invalid API. So it only prevents each
     modules to be independently wrong when taken in isolation.

  2. Technically, this also means that one can import env modules in
     other env modules by their names. I don't know if it's a good or
     bad idea at this point but it doesn't really do any wrong;
     dependencies and cycles are handlded all-the-same.
2024-08-04 10:27:32 +02:00
KtorZ c9d0da0c22
Parse sources of conditional env modules.
Do nothing about it yet, but trigger an error if env/default.ak is
  missing; but only if there's any module at all under env.
2024-08-03 17:42:55 +02:00
KtorZ 4645257e62
Prune pallas dependencies.
Using 'pallas' as a dependency brings utxo-rpc other annoying dependencies such as _tokyo_. This not only makes the overall build longer, but it also prevents it to even work when targetting wasm.
2024-08-03 14:14:49 +02:00
KtorZ f14dfdf8e1
Allow pattern-matching on bytearrays
- Doesn't allow pattern-matching on G1/G2 elements and strings,
    because the use cases for those is unclear and it adds complexity to
    the feature.

  - We still _parse_ patterns on G1/G2 elements and strings, but emit an
    error in those cases.

  - The syntax is the same as for bytearray literals (i.e. supports hex,
    utf-8 strings or plain arrays of bytes).
2024-08-03 13:51:36 +02:00
KtorZ 86aed1baa5 Enable 'mk_pair_data' builtin. 2024-08-02 00:17:16 -04:00
KtorZ 643e43f8aa Fix zero-arg builtins invokations.
There are currently two zero-arg builtins:

  - mkNilData
  - mkNilPairData

  And while they have strictly speaking no arguments, the VM still
  requires that they are called with an extra unit argument applied.
2024-08-02 00:17:16 -04:00
KtorZ 1c58da4d86 Support mk_cons builtin
While this builtin is readily available through the Aiken syntax
  `[head, ..tail]`, there's no reason to not support its builtin form
  even though we may not encourage its usage. For completeness and to
  avoid bad surprises, it is now supported.

  Fixes #964.
2024-08-02 00:17:16 -04:00
KtorZ bf5a406ffb Remove clause guards.
Closes #886.
2024-08-02 00:16:27 -04:00
rvcas 4645fd3e28
chore: Release 2024-07-25 08:28:15 -04:00
KtorZ 49190b485a
chore: Release 2024-07-25 09:58:06 +02:00
Matthias Benkort 594a304190
Merge pull request #980 from aiken-lang/multivalidator-plus-optimization
Mutlivalidator is now an opcode to help minimize validator size
2024-07-25 09:47:47 +02:00
microproofs dfce9c1d96
feat: Add multivalidator as an AIR tree opcode.
feat: Add uplc eval optimization
2024-07-24 10:00:08 -04:00
KtorZ 67493ad847
Fix casting inferrence on patterns
The original goal for this commit was to allow casting from Data on
  patterns without annotation. For example, given some custom type
  'OrderDatum':

  ```
  expect OrderDatum { requested_handle, destination, .. }: OrderDatum = datum
  ```

  would work fine, but:

  ```
  expect OrderDatum { requested_handle, destination, .. } = datum
  ```

  Yet, the annotation feels unnecessary at this point because type can
  be inferred from the pattern itself. So this commit allows, whenever
  possible (ie when the pattern is neither a discard nor a var), to
  infer the type from a pattern.

  Along the way, I also found a couple of weird behaviours surrounding
  this kind of assignments, in particular in combination with let. I'll
  highlight those in the next PR (#979).
2024-07-24 12:42:24 +02:00
KtorZ 30ddfa23d9
Provide better parse errors in trace when using comma instead of colon. 2024-07-19 12:28:08 +02:00
KtorZ 2922c0aa6f
Display expected patterns/tokens in parse error when applicable.
We've never been using those 'expected' tokens captured during
  parsing, which is lame because they contain useful information!

  This is much better than merely showing our infamous

    "Try removing it!"
2024-07-19 12:28:08 +02:00
KtorZ d6fd37c80e
Rework 'compact' mode for traces
- Trace-if-false are now completely discarded in compact mode.

  - Only the label (i.e. first trace argument) is preserved.

  - When compiling with tracing _compact_, the first label MUST unify to
    a string. This shouldn't be an issue generally speaking and would
    enforce that traces follow the pattern

    ```
    label: arg_0[, arg_1, ..., arg_n]
    ```

  Note that what isn't obvious with these changes is that we now support
  what the "emit" keyword was trying to achieve; as we compile now with
  user-defined traces only, and in compact mode to only keep event
  labels in the final contract; while allowing larger payloads with
  verbose tracing.
2024-07-19 12:28:08 +02:00
KtorZ a9d782e206
re-introduce code-gen patch, but with a test.
Actually, this has been a bug for a long time it seems. Calling any
  prelude functions using a qualified import would result in a codegen
  crash. Whoopsie.

  This is now fixed as shown by the regression test.
2024-07-19 12:28:07 +02:00
KtorZ 5afcc9b0c1
Remove unnecessary code_gen patch.
This is a little weird but, prelude functions are handled slightly
  differently.
2024-07-19 12:28:07 +02:00
KtorZ f8236817fe
Allow serialisable (Data-able) arguments to trace
Somehow, we have to patch some function in gen_uplc because of the
  module name. I have to look further into this because it isn't normal.
2024-07-19 12:28:07 +02:00
KtorZ beb5ac4643
Add 'diagnostic' to the prelude, as well as companion functions.
This is not fully satisfactory as it pollutes a bit the prelude. Ideally, those functions should only be visible
  and usable by the underlying trace code. But for now, we'll just go with it.
2024-07-19 12:28:07 +02:00
KtorZ 754ed07408
Type-check variadic traces & desugarize them. 2024-07-18 10:02:23 +02:00
KtorZ f9719af23e
Allow variadic arguments in trace
Although, doesn't do anything with them yet. The idea is to simplify
  the use of trace to make it a lot more useful than it currently is.
2024-07-18 10:01:34 +02:00
KtorZ 976262c2e6
Allow discard in expect.
Fixes #967.
2024-07-17 18:11:09 +02:00
rvcas 5bdea11cc1 fix: add a new assignment kind instead of using a boolean 2024-06-25 18:50:00 -04:00
microproofs f1cfc84e67 Fix tree traversal node selection for a few of the enum variants 2024-06-25 18:50:00 -04:00
microproofs 4bd9125b86 Fix delay of arguments to be exactly the same as codegen tests 2024-06-25 18:50:00 -04:00
microproofs f695276bf7 Fix codegen tree traversal to be updated for the otherwise field and future proof the traversal function 2024-06-25 18:50:00 -04:00
microproofs b5ac5bc949 Add current fixed tests and start working on codegen fix 2024-06-25 18:50:00 -04:00
microproofs cc9df04093 Fix missing delay in list_access_to_uplc. Also fix one of the unit tests. 2024-06-25 18:50:00 -04:00
microproofs 41b941e0e3 Fix castfromData in record access cases 2024-06-25 18:50:00 -04:00
KtorZ 00d1927dad Add few more test cases for the parser and type-checker. 2024-06-25 18:50:00 -04:00
rvcas aeb079334e chore: this test doesn't make sense anymore 2024-06-25 18:50:00 -04:00
microproofs e09f6bbc87 delay otherwise branch to prevent premature errors 2024-06-25 18:50:00 -04:00
microproofs df939e20ce missed a Air Op Code and updated how we pass in otherwise for assignment 2024-06-25 18:50:00 -04:00
rvcas 579abb7d3d fix: no need to check exhaustiveness during if/is 2024-06-25 18:50:00 -04:00
rvcas 5024bd3f9c feat: code gen support for if/is
Co-authored-by: Kasey White <kwhitemsg@gmail.com>
2024-06-25 18:50:00 -04:00
rvcas 1b8805825b feat: impl if/is
This commit introduces a new feature into
the parser, typechecker, and formatter.
The work for code gen will be in the next commit.

I was able to leverage some existing infrastructure
by making using of `AssignmentPattern`. A new field
`is` was introduced into `IfBranch`. This field holds
a generic `Option<Is>` meaning a new generic has to be
introduced into `IfBranch`. When used in `UntypedExpr`,
`IfBranch` must use `AssignmentPattern`. When used in
`TypedExpr`, `IfBranch` must use `TypedPattern`.

The parser was updated such that we can support this
kind of psuedo grammar:

`if <expr:condition> [is [<pattern>: ]<annotation>]`

This can be read as, when parsing an `if` expression,
always expect an expression after the keyword `if`. And then
optionally there may be this `is` stuff, and within that you
may optionally expect a pattern followed by a colon. We will
always expect an annotation.

This first expression is still saved as the field
`condition` in `IfBranch`. If `pattern` is not there
AND `expr:condition` is `UntypedExpr::Var` we can set
the pattern to be `Pattern::Var` with the same name. From
there shadowing should allow this syntax sugar to feel
kinda magical within the `IfBranch` block that follow.

The typechecker doesn't need to be aware of the sugar
described above. The typechecker looks at `branch.is`
and if it's `Some(is)` then it'll use `infer_assignment`
for some help. Because of the way that `is` can inject
variables into the scope of the branch's block and since
it's basically just like how `expect` works minus the error
we get to re-use that helper method.

It's important to note that in the typechecker, if `is`
is `Some(_)` then we do not enforce that `condition` is
of type `Bool`. This is because the bool itself will be
whether or not the `is` itself holds true given a PlutusData
payload.

When `is` is None, we do exactly what was being done
previously so that plain `if` expressions remain unaffected
with no semantic changes.

The formatter had to be made aware of the new changes with
some simple changes that need no further explanation.
2024-06-25 18:50:00 -04:00
rvcas b2c42febaf chore: move if_branch to helper parser 2024-06-25 18:50:00 -04:00
Dima S d99c014bf7 chore: correct the usage of a legacy numeric constant 2024-06-25 17:49:36 -04:00
KtorZ 0ebffa2b9e
Fix few error messages. 2024-06-13 14:54:47 +02:00
KtorZ 858dfccc82
Authorize complete patterns as function args.
This is mainly a syntactic trick/sugar, but it's been pretty annoying
  to me for a while that we can't simply pattern-match/destructure
  single-variant constructors directly from the args list. A classic
  example is when writing property tests:

  ```ak
  test foo(params via both(bytearray(), int())) {
    let (bytes, ix) = params
    ...
  }
  ```

  Now can be replaced simply with:

  ```
  test foo((bytes, ix) via both(bytearray(), int())) {
    ...
  }
  ```

  If feels natural, especially coming from the JavaScript, Haskell or
  Rust worlds and is mostly convenient. Behind the scene, the compiler
  does nothing more than re-writing the AST as the first form, with
  pre-generated arg names. Then, we fully rely on the existing
  type-checking capabilities and thus, works in a seamless way as if we
  were just pattern matching inline.
2024-06-07 15:42:25 +02:00
KtorZ b6da42baf2
Bump 'is_validator_param' up from 'ArgName' to '...Arg'
There's no reasons for this to be a property of only ArgName::Named to begin with. And now, with the extra indirection introduced for arg_name, it may leads to subtle issues when patterns args are used in validators.
2024-06-07 11:32:05 +02:00
KtorZ 4d42c6cb19
Introduce 'ArgBy' to allow defining function arg not only by name. 2024-06-07 11:17:16 +02:00
KtorZ 216dab99d4
chore: Release 2024-06-06 11:19:34 +02:00
KtorZ d7ec2131ef
Automatically merge import lines from same module.
I slightly altered the way we parse import definitions to ensure we
  merge imports from the same modules (that aren't aliased) together.

  This prevents an annoying warning with duplicated import lines and
  makes it just more convenient overall.

  As a trade-off, we can no longer interleave import definitions with
  other definitions. This should be a minor setback only since the
  formatter was already ensuring that all import definitions would be
  grouped at the top.

  ---

  Note that, I originally attempted to implement this in the formatter
  instead of the parser. As it felt more appropriate there. However, the
  formatter operates on (unmutable) borrowed definitions, which makes it
  annoyingly hard to perform any AST manipulations. The `Document`
  returns by the format carries a lifetime that prevents the creation of
  intermediate local values.

  So instead, slightly tweaking the parser felt like the right thing to
  do.
2024-06-04 10:48:42 +02:00
KtorZ e9e26b969a
Preserve warning display rework, but without breaking the LSP quickfixes. 2024-05-30 19:20:11 +02:00
KtorZ 649e5163fc
Fix parsing of single hex-digits. 2024-05-30 17:19:48 +02:00
KtorZ 5694d9f9cb
Introduce 'fail once' and alter behavior of 'fail' keyword for properties. 2024-05-30 17:18:50 +02:00
rvcas 338fc0eba6
chore: Release 2024-05-23 16:45:10 -04:00
rvcas ff50d4d2cf
chore: Release 2024-05-23 16:23:59 -04:00
microproofs 59cfa209d7 change uplc version number based on plutus version 2024-05-23 15:04:59 -04:00
KtorZ c48f15a957
revert #903 'feat: Emit keyword'
While we agree on the idea of having some ways of emitting events, the
  design hasn't been completely fleshed out and it is unclear whether
  events should have a well-defined format independent of the framework
  / compiler and what this format should be.

  So we need more time discussing and agreeing about what use case we
  are actually trying to solve with that.

  Irrespective of that, some cleanup was also needed on the UPLC side
  anyway since the PR introduced a lot of needless duplications.
2024-05-23 17:22:12 +02:00
KtorZ 5ce30b2632
Rename AList -> Pairs due to popular demand. 2024-05-23 16:45:40 +02:00
rvcas 7f38b55c1c
fix: comments in record patterns closes #946 2024-05-22 12:26:36 -04:00
rvcas 3bc3792aa3
feat: add plutus version to aiken.toml
relates to #907
2024-05-21 17:02:20 -04:00
rvcas 4ca73c4cdf
fix: closes #898
This is the best we can do for this without
rearchitecting when we rewrite backpassing to
plain ol' assignments. In this case, if we see
a var and there is no annotation (thus probably not a cast),
then it's safe to rewrite to a `let` instead of an `expect`.
This way, we don't get a warning that is **unfixable**.
We are not trying to solve every little warning edge
case with this fix. We simply just can't allow there
to be a warning that the user can't make go away through
some means. All other edge cases like pattern matching on
a single contructor type with expect warnings can be fixed
via other means.
2024-05-21 15:21:24 -04:00
KtorZ a3c14d881d
Merge branch 'fix/scope-when-backtracking' 2024-05-16 23:43:00 +02:00
KtorZ 7ff6eba869
Prefer '.clone_from' over mutating a clone.
Clippy says it's more efficient. I trust clippy. Clippy good.
2024-05-16 23:42:53 +02:00
KtorZ ea3e79c132
Renamed 'unseed' -> 'not_yet_inferred' 2024-05-16 23:33:23 +02:00
KtorZ 27b3536f09
Also preserve warnings when resetting scope for backtracking.
This is crucial as some checks regarding variable usages depends on
  warnings; so we may accidentally remove variables from the AST as a
  consequence of backtracking for deep inferrence.
2024-05-16 23:20:52 +02:00
KtorZ e87063824c
Fix pretty-printing of recursive type-alias causing stack overflow.
Fixes #942.
2024-05-16 17:20:26 +02:00
KtorZ eadf709411
Fix scope management issue when deep-inferring callee.
Fixes #941.

  However, this currently breaks the stdlib somehow with some FreeUnique on the shrinker step of the optimizer.
2024-05-15 13:18:51 +02:00
KtorZ 81219cfbdd
Check for data-type serialisability after generic instantiation
Fixes #939.
2024-05-14 10:58:58 +02:00
KtorZ 26ef25ba8d
Make comparison of non-serialisable types illegal.
Fixes #940.
2024-05-14 10:45:15 +02:00
KtorZ 8c67be55ce
Fixes #921: top-level Miller-loop needs not to be serialisable
This is a bit tricky, but in a similar way where we allow functions to
  be returned by functions, this must also work for MillerLoopResult.
2024-05-10 13:52:23 +02:00
microproofs 878298cc8e don't use generic data type lookup when you have a Record Variant as a function 2024-05-06 15:17:01 -04:00
KtorZ a124bdbb05 Infer callee first in function call
The current inferrence system walks expressions from "top to bottom".
  Starting from definitions higher in the source file, and down. When a
  call is encountered, we use the information known for the callee
  definition we have at the moment it is inferred.

  This causes interesting issues in the case where the callee doesn't
  have annotations and in only partially known. For example:

  ```
  pub fn list(fuzzer: Option<a>) -> Option<List<a>> {
    inner(fuzzer, [])
  }

  fn inner(fuzzer, xs) -> Option<List<b>> {
    when fuzzer is {
      None -> Some(xs)
      Some(x) -> Some([x, ..xs])
    }
  }
  ```

  In this small program, we infer `list` first and run into `inner`.
  Yet, the arguments for `inner` are not annotated, so since we haven't
  inferred `inner` yet, we will create two unbound variables.

  And naturally, we will link the type of `[]` to being of the same type
  as `xs` -- which is still unbound at this point. The return type of
  `inner` is given by the annotation, so all-in-all, the unification
  will work without ever having to commit to a type of `[]`.

  It is only later, when `inner` is inferred, that we will generalise
  the unbound type of `xs` to a generic which the same as `b` in the
  annotation. At this point, `[]` is also typed with this same generic,
  which has a different id than `a` in `list` since it comes from
  another type definition.

  This is unfortunate and will cause issues down the line for the code
  generation. The problem doesn't occur when `inner`'s arguments are
  properly annotated or, when `inner` is actually inferred first.

  Hence, I saw two possible avenues for fixing this problem:

  1. Detect the presence of 'uncongruous generics' in definitions after
     they've all been inferred, and raise a user error asking for more
     annotations.

  2. Infer definitions in dependency order, with definitions used in
     other inferred first.

  This commit does (2) (although it may still be a good idea to do (1)
  eventually) since it offers a much better user experience. One way to
  do (2) is to construct a dependency graph between function calls, and
  ensure perform a topological sort.

  Building such graph is, however, quite tricky as it requires walking
  through the AST while maintaining scope etc. which is more-or-less
  already what the inferrence step is doing; so it feels like double
  work.

  Thus instead, this commit tries to do a deep-first inferrence and
  "pause" inferrence of definitions when encountering a call to fully
  infer the callee first. To achieve this properly, we must ensure that
  we do not infer the same definition again, so we "remember" already
  inferred definitions in the environment now.
2024-05-06 15:17:01 -04:00
KtorZ 7b71389519 Change pretty-printing of unbound variable to '?'
Until now, we would pretty-print unbound variable the same way we would pretty-print generics. This turned out to be very confusing when debugging, as they have a quite different semantic and it helps to visualize unbound types in definitions.
2024-05-06 15:17:01 -04:00
KtorZ ef70c6b8a8 Re-use generic id across builtin type-definitions.
This was somehow wrong and corrected by codegen later on, but we should be re-using the same generic id across an entire definition if the variable refers to the same element.
2024-05-06 15:17:01 -04:00
KtorZ 1070347203 Panic when encountering unknown generics.
This should not happen; if it does, it's an error from the type-checker. So instead of silently swallowing the error and adopting a behavior which is only _sometimes_ right, it is better to fail loudly and investigate.
2024-05-06 15:17:01 -04:00
microproofs b2661ef90a Better error message for compile time evaluation 2024-05-06 11:58:32 -04:00
microproofs a44ed4c1a8 Change prelude Map to AList 2024-05-04 14:04:12 -04:00
KtorZ b1f0dfdacd Implement parser & formatter for Pair annotations. 2024-05-04 14:04:12 -04:00
microproofs 58779401e8 fix: formatting was eating the space in pair after the , 2024-05-04 14:04:12 -04:00
microproofs fc0e88018e Chore:
Refactor get_uplc_type to account for constr types that don't exactly resolve to a uplc type
Check arg_stack in uplc generator has only 1 argument at the end of the generation
warning fixes
2024-05-04 14:04:12 -04:00
KtorZ 1091eba3c3 Review & fix acceptance tests
Temporarily using the 'specialize-dict-key' branch from the stdlib
  which makes use of Pair where relevant. Once this is merged back into
  'main' we should update the acceptance test toml files to keep getting
  them automatically upgraded.

  This commit also fixes an oversight in the reification of data-types
  now properly distinguishing between pairs and 2-tuples.

  Co-authored-by: Microproofs <kasey.white@cardanofoundation.org>
2024-05-04 14:04:12 -04:00
KtorZ 7cb548a749 Fix ordinal index on pairs 2024-05-04 14:04:12 -04:00
KtorZ 2cb2c7fa1f Add dedicated 'Pair' typed and untyped expression
Before this commit, we would parse 'Pair' as a user-defined
  data-types, and thus piggybacking on that whole record system. While
  perhaps handy for some things, it's also semantically wrong and
  induces a lot more complexity in codegen which now needs to
  systematically distinguish every data-type access between pairs, and
  others.

  So it's better to have it as a separate expression, and handle it
  similar to tuples (since it's fundamentally a 2-tuple with a special
  serialization).
2024-05-04 14:04:12 -04:00
KtorZ 92a1da69d9 Add (possibly temporary) assertion on record access in codegen 2024-05-04 14:04:12 -04:00
KtorZ 3dd94983bd Revert "fixing more pair issues"
This reverts commit b76cc7436294cd73e7bbaf656c76a8f8b0ad56a9.
2024-05-04 14:04:12 -04:00
microproofs 46c7cb797a fixing more pair issues 2024-05-04 14:04:12 -04:00
microproofs ebe415cfc9 fix errors 2024-05-04 14:04:12 -04:00
KtorZ 5c59b816ea Add parser for 'Pair' pattern
And a few more tests along the way for others. Note that it is important here that we try to parse for a 'Pair' BEFORE we try to parse for a constructor pattern. Because the latter would swallow any Pair pattern.
2024-05-04 14:04:12 -04:00
KtorZ 91a7e77ab4 Add 'Pair' pattern and rework internals to use it.
Currently, pattern-matching on 'Pair' is handled by treating Pair as a
  record, which comes as slightly odd given that it isn't actually a
  record and isn't user-defined. Thus now, every use of a record must
  distinguish between Pairs and other kind of records -- which screams
  for another variant constructor instead.

  We cannot use `Tuple` either for this, because then we have no ways to
  tell 2-tuples apart from pairs, which is the whole point here. So the
  most sensical thing to do is to define a new pattern `Pair` which is
  akin to tuples, but simpler since we know the number of elements and
  it's always 2.
2024-05-04 14:04:12 -04:00
KtorZ 897b5d1d7e Ensure type-aliases pretty-printing also work with Pair. 2024-05-04 14:04:12 -04:00
KtorZ 3020af7cd7 Revert 'unify' implementation back to its more elegant form
And add support for Pair.
2024-05-04 14:04:12 -04:00
KtorZ cbf3ef2854 Add new Prelude alias: 'Map' 2024-05-04 14:04:12 -04:00
microproofs 7b5ad961e2 fix: found issue with record access on Pairs 2024-05-04 14:04:12 -04:00
microproofs 30dd1f60e7 small simplification 2024-05-04 14:04:12 -04:00
microproofs 75b076552c feat: Do a major overhaul on how we check types to allow for match patterns instead of if statements
Also fix one more test
2024-05-04 14:04:12 -04:00
microproofs 3c332ca42a Few more places in codegen where we need to be able to deal with Pair records 2024-05-04 14:04:12 -04:00
microproofs 26f68c2fb4 fix: found various unify and type issues while running tests 2024-05-04 14:04:12 -04:00
microproofs fd226be51f add Pair type to prelude 2024-05-04 14:04:12 -04:00
microproofs a8c8cf41cf Finishing up codegen changes for pair 2024-05-04 14:04:12 -04:00
microproofs 963d275bb8 continue progress on pair adding 2024-05-04 14:04:12 -04:00
microproofs 21b60896f0 remove wild card match from tree functions
Start working on supporting Pair clauses
2024-05-04 14:04:12 -04:00
microproofs f950ae7d3d WIP: add new opcodes to Air and AirTree and update parts of codegen to handle the new pair type 2024-05-04 14:04:12 -04:00
microproofs 9e78f0fc2a update for latest main 2024-05-04 14:04:12 -04:00
microproofs 61a021f9e3 update pair to handle alias 2024-05-04 14:04:12 -04:00
microproofs d05d8e7de6 Start working on separating pairs from 2 tuples in Aiken
co-authored-by: KtorZ <matthias.benkort@gmail.com>
2024-05-04 14:04:12 -04:00
KtorZ db8eb6a108
Provide more context for some panics
Actually ran into them both, will open issues about those in a bit.
2024-05-01 12:04:47 +02:00
KtorZ 925a11be69
Check for args length when comparing types. Duh!
Fixes #917.
2024-05-01 10:48:15 +02:00
Micah Kendall ff4ddfbe1b Simplifying PR per reviewers request 2024-04-12 21:40:27 -04:00
Micah Kendall d39dbd6697 fmt 2024-04-12 21:40:27 -04:00
Micah Kendall d25b8f91c7 feat: Emit keyword 2024-04-12 21:40:27 -04:00
rvcas b27fcf38e5
fix(check): collapse_links on tuple_index access closes #905 2024-04-02 19:45:16 -04:00
rvcas 7c5b9aa35e
feat(lsp): find_node for TypedArgVia 2024-04-02 19:22:19 -04:00
rvcas d22ee6e086
chore: remove useless clone 2024-04-02 19:04:33 -04:00
rvcas e02bc2a58a
feat(lsp): find_node should traverse tail of list 2024-04-02 17:55:04 -04:00
rvcas b5f27026e2
fix: confusing public validator closes #902 2024-03-29 11:32:04 -04:00
rvcas ce2c723d0c
chore: remove some dbg macros 2024-03-29 11:28:22 -04:00
microproofs a5a0734629 fix: casting a field type to Data with expect and traces on was assuming the raw Data was of type constr 2024-03-27 15:52:23 -04:00
rvcas 075668b52e
chore: Release 2024-03-25 22:09:37 -04:00
KtorZ a3f7b48ec3 Allow downcasting to data in piped function calls.
We have been a bit too strict on disallowing 'allow_cast' propagations. This is really only problematic for nested elements like Tuple's elements or App's args. However, for linked and unbound var it is probably okay, and it certainly is as well for function arguments.
2024-03-25 11:57:13 -04:00
KtorZ 4e8042fd06
chore: Release 2024-03-22 16:10:17 +01:00
KtorZ 96387e3437
Fixes #767
Co-authored-by: @rvcas <x@rvcas.dev>
2024-03-22 16:05:32 +01:00
rvcas a09069b828
fix: binop associativity formatting
it seems we can fix this by changing which side
gets subtracted by 1 depending on the op associativity.
BinOp::Or & BinOp::And are right associative while the
other bin ops are left associative.

closes #893

Co-authored-by: Kasey White <kwhitemsg@gmail.com>
2024-03-21 20:12:49 -04:00
KtorZ 0f9dbfd874
Fixes #883. 2024-03-21 18:20:19 +01:00
rvcas ee280bc309 fix: only allow casting on top level Data 2024-03-21 11:59:34 -04:00
rvcas c20ff6b160 fix: contains_opaque was never intended to be used for type equality 2024-03-21 11:59:34 -04:00
KtorZ 5cec2544b3 Nonsensical prints to be removed. 2024-03-21 11:59:34 -04:00
KtorZ 25e9db4f6c Rename t1 -> lhs, t2 -> rhs in unify. 2024-03-21 11:59:34 -04:00
KtorZ dc9bab4f5c Add extra test case. 2024-03-21 11:59:34 -04:00
KtorZ bee2b712de Fixes #881. 2024-03-21 11:59:34 -04:00
rvcas 4f8e900aac
fix: Discard not taken into account in backpassing
closes #890

Co-authored-by: Kasey White <kwhitemsg@gmail.com>
2024-03-20 17:53:17 -04:00
rvcas 898ef74457
fix: spans for backpassing args
closes #882

Co-authored-by: Kasey White <kwhitemsg@gmail.com>
2024-03-20 17:27:17 -04:00
microproofs 61936cb91e fix(codegen): Add tracing when checking for a constr vs another primitive 2024-03-17 16:25:17 -04:00
KtorZ cdf564fc9d
Expand 'ExpectOnOpaqueType' error help and label. 2024-03-14 11:20:34 +01:00
KtorZ 3055c5ef52
Do not allow casting when rhs or lhs contain an opaque type.
Also slightly extended the check test 'framework' to allow registering side-dependency and using them from another module. This allows to check the interplay between opaque type from within and outside of their host module.
2024-03-14 11:00:17 +01:00
rvcas 191a3e9134
chore: weird thing from rebase 2024-03-13 20:21:33 -04:00
rvcas e71470747f
feat: fix some tests and add a failing one 2024-03-13 20:18:56 -04:00
KtorZ 9127dcdd6e
Add note on the type-casting check. 2024-03-13 20:18:56 -04:00
KtorZ 8f31b45e36
Fix allow_casting condition in unification
We should allow casting from any type to any type. Or at the very least, allow it for well-known types like List.
2024-03-13 20:18:56 -04:00
KtorZ f10cf73905
Rework 'is_opaque' to also check for inner types.
Also removed the duplication in infer_assignment and moved the check down.
2024-03-13 20:18:56 -04:00
KtorZ 22b618116e
rename function argument for clarity
is_assignment was a bit confusing to me since we do actually categorize expect as 'assignment'. So this is more about whether this is a *let* assignment. Hence 'is_let'.
2024-03-13 20:18:55 -04:00
KtorZ 502a13756a
remove irrelevant comment. 2024-03-13 20:18:55 -04:00
KtorZ 961806617f
Add more failing tests for expecting on into opaque types. 2024-03-13 20:18:55 -04:00
KtorZ 3820d2af14
Remove potentially problematic use of ".." in pattern-match
Discard pattern are _dangerous_ is used recklessly. The problem comes
  from maintenance and when adding new fields. We usually don't get any
  compiler warnings which may lead to missing spots and confusing
  behaviors.

  So I have, in some cases, inline discard to explicitly list all
  fields. That's a bit more cumbersome to write but hopefully will catch
  a few things for us in the future.
2024-03-13 20:18:51 -04:00
rvcas 7af4ef53ab
feat: block expects on opaque types 2024-03-13 20:17:54 -04:00
microproofs 1d72838f83 fix: awkward assignment formatting
Co-authored-by: Lucas Rosa <x@rvcas.dev>
2024-03-13 19:10:06 -04:00
microproofs b16880a170 feat(annotation): not passing annotation into lambda when backpassing
Co-authored-by: Lucas Rosa <x@rvcas.dev>
2024-03-13 19:08:53 -04:00
rvcas 7b32d4ae30 chore: add a test for formatting assignment patterns 2024-03-12 08:10:33 -04:00
rvcas 945b4155cd fix(assignment-patterns): allow trailing 2024-03-12 08:10:33 -04:00
rvcas 97247ce949 chore: assignment patterns refactor tuple into struct 2024-03-12 08:10:33 -04:00
rvcas b6b52ba508 feat(backpassing): implements multi patterns
The main trick here was transforming Assignment
to contain `Vec<UntypedPattern, Option<Annotation>>`
in a field called patterns. This then meant that I
could remove the `pattern` and `annotation` field
from `Assignment`. The parser handles `=` and `<-`
just fine because in the future `=` with multi
patterns will mean some kind of optimization on tuples.
But, since we don't have that optimization yet, when
someone uses multi patterns with an `=` there will be an
error returned from the type checker right where `infer_seq`
looks for `backpassing`. From there the rest of the work
was in `Project::backpassing` where I only needed to rework
some things to work with a list of patterns instead of just one.
2024-03-12 08:10:33 -04:00
KtorZ 7e8e959251
Fix spans and error reporting for backpassing. 2024-03-11 00:20:29 +01:00
KtorZ a57dcf3307
Allow backpassing with expect. 2024-03-11 00:20:29 +01:00
KtorZ 435dd0d213
Refactor AssignmentKind to allow backpassing on both let and expect.
The 3rd kind of assignment kind (Bind) is gone and now reflected through a boolean parameter. Note that this parameter is completely erased by the type-checker so that the rest of the pipeline (i.e. code-generation) doesn't have to make any assumption. They simply can't see a backpassing let or expect.
2024-03-11 00:16:23 +01:00
KtorZ df898bf239
Rework monadic-bind into function backpassing.
This is more holistic and less awkward than having monadic bind working only with some pre-defined type. Backpassing work with _any_ function, and can be implemented relatively easily by rewriting the AST on-the-fly.

  Also, it is far easier to explain than trying to explain what a monadic bind is, how its behavior differs from type to type and why it isn't generally available for any monadic type.
2024-03-11 00:16:22 +01:00
KtorZ 1f530f3b24
Experiment with monadic bind. 2024-03-11 00:16:22 +01:00
KtorZ c169596c76
preserve type-aliases from annotations on calls. 2024-03-10 00:38:03 +01:00
KtorZ 191e4d47b3
Remove dead-code: 'Layer' 2024-03-09 23:14:44 +01:00
Matthias Benkort ec18127191
Merge pull request #869 from aiken-lang/non-serialisable-types
Forbid non-serializable inhabitants in compound data-types.
2024-03-09 22:39:41 +01:00
KtorZ 80a9393db7
Add --include-dependencies to 'aiken docs'
Fixes #867.
2024-03-09 22:35:38 +01:00
KtorZ ee54266d1f
Forbid non-serializable inhabitants in compound data-types. 2024-03-09 22:25:51 +01:00
KtorZ 37627e3527
Fix indentation of pipelines. 2024-03-09 20:44:51 +01:00
KtorZ d581183cc6
Fix formatter discarding nul bytes. 2024-03-09 18:59:35 +01:00
microproofs b761d6a76d fix: function aliases were leading to free uniques 2024-03-09 12:46:12 -05:00
microproofs bffa678178 fix: mutually recursive zero arg functions needed to have their function bodies delayed 2024-03-09 10:04:30 -05:00
microproofs c51741cc35 fix: mutually recursive zero arg function calls were reaching an unreachable 2024-03-08 22:58:03 -05:00
KtorZ 96da70149d
Count labels in properties.
We'll piggyback on the tracing capabilities of the VM to provide labelling for prop tests. To ensure we do not interfere with normal traces, we only count traces that starts with a NUL byte as label. That convention is assumed to be known of the companion fuzz library that should then provide the labelling capabilities as a dedicated function.
2024-03-09 01:28:29 +01:00
KtorZ d6cc9bdfbe
Allow implicit discard when right-hand side is Void.
This is the most intuitive/expected behavior. Otherwise, it forces a pointless let-binding to 'Void' or into a discard.
2024-03-09 01:28:29 +01:00
rvcas d55b7844f0 feat: impl serde for TypeAliasAnnotation 2024-03-08 19:19:07 -05:00
rvcas 836e853827 fix: bring back vec1 2024-03-08 19:19:07 -05:00
rvcas 9d99b509b2 chore: this should be gone 2024-03-08 19:19:07 -05:00
rvcas fe6710935d feat: impl serde on errythang 2024-03-08 19:19:07 -05:00
KtorZ a578728a94
Resolve type aliases based on inferred types.
Before this commit, we would always show the 'declared form' of type aliases, with their generic, non-instantiated parameters. This now tries to unify the annotation with the underlying inferred type to provide even better alias pretty printing.
2024-03-08 16:01:21 +01:00
KtorZ ed9f5c6ef7
Preserve TypeAlias in types for better context/feedback. 2024-03-08 15:59:33 +01:00
KtorZ 877d10ef22
Use inferred Fuzzer inner type for unify error when possible. 2024-03-08 15:57:41 +01:00
microproofs bf429fbdbf remove unused import 2024-03-08 00:12:44 -05:00
microproofs dcec8ecfe6 remove unused special function 2024-03-08 00:12:44 -05:00
microproofs 541d96f558 remove comment line 2024-03-08 00:12:44 -05:00
microproofs 275db2fd11 update tests 2024-03-08 00:12:44 -05:00
microproofs ae396c0224 Fix opaque type destructuring in code gen 2024-03-08 00:12:44 -05:00
rvcas fab6d5aff7
chore: fix fmt 2024-03-07 19:32:33 -05:00
KtorZ 23a22a65cb
Handle (recursive) generic types during reification.
Also moved a bunch of functions from code-gen back into _tipo_, as
  they're better suited and generic enough to be reused elsewhere.
2024-03-07 18:07:52 +01:00
microproofs a3fbe6c155 fix tests 2024-03-06 23:27:10 -05:00
microproofs e217423145 mixed up pair builtin 2024-03-06 23:27:10 -05:00
microproofs bdd84dc952 fixing the tests lead to me create a new function for converting from data 2024-03-06 23:27:10 -05:00
microproofs 892da06e14 add more runtime checking for a few of the data to primitive conversions 2024-03-06 23:27:10 -05:00
KtorZ bff822ea7f
Rework unit test report to leverage new reification
And also provide slightly better errors when traces, or trace-if-false operators are present.
2024-03-07 01:20:40 +01:00