Skip to content

Versioning#263

Open
Sdoba16 wants to merge 5 commits into
BlockstreamResearch:masterfrom
Sdoba16:feature/versions
Open

Versioning#263
Sdoba16 wants to merge 5 commits into
BlockstreamResearch:masterfrom
Sdoba16:feature/versions

Conversation

@Sdoba16
Copy link
Copy Markdown
Collaborator

@Sdoba16 Sdoba16 commented Mar 31, 2026

Closes #248

Add compiler versioning for SimplicityHL contracts

This PR introduces strict compiler version requirements

  • Version Directives: Every .simf file must now begin with a simc "..." directive. The directive is safely extracted (ignoring comments) and validated before full AST construction.
  • SemVer Ranges: Added support for standard Semantic Versioning ranges (e.g., >=0.6.0, ^0.6.0, ~0.6.0)
  • Dependency Versioning: The compiler driver now verifies version compatibility across the entire multi-file project (main.simf and all imported --dep libraries)
  • Developer Tooling: Added update_examples.py and a CI workflow to easily manage version across all examples and tests.

Syntax:

simc ">=0.6.0";

fn main() {
    ...
}

Needed simplex addition for this PR:

  • Version Installer: Tooling that will go through the dependencies and look for best fitting version to be installed. The tool will take existing versions from HL releases and install the best-fitted one.

@Sdoba16 Sdoba16 closed this Mar 31, 2026
@Sdoba16 Sdoba16 reopened this Mar 31, 2026
@Sdoba16 Sdoba16 self-assigned this Mar 31, 2026
Copy link
Copy Markdown
Contributor

@stringhandler stringhandler left a comment

Choose a reason for hiding this comment

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

Concept ACK.

I've come around to the idea that users should optionally be able to specify the compiler version. However, I don't like the pragma keyword as it deviates from rust, which we haven't done previously. Below are some suggestions.

I also don't think it should be required in the .simc, which will allow us to specify it in a project level manifest for when multiple files are included and for libraries in future. Also, the user should not be forced to provided it even in a single file scenario. This is just extra friction for new developers.

Comment thread examples/array_fold.simf Outdated
@@ -1,3 +1,5 @@
pragma version 0.5.0-rc.0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we maybe rather use a global attribute syntax

#![version("0.5.0-rc.0")]

I would also suggest naming it compiler-version or simc_version or even just simc, so that users don't think it is annotating this file with a version.

Comment thread src/error.rs Outdated
/// Records _what_ happened but not where.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum Error {
VersionMismatch {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
VersionMismatch {
SimcVersionMismatch {

I prefer stating that it's the compiler version here as well

Comment thread src/ast.rs Outdated

let insertion_point = Span::new(first_item_span.start, first_item_span.start);

return Err(Error::MissingPragma {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think pragmas should be optional

Comment thread src/error.rs Outdated
expected: String,
compiler: String,
},
MissingPragma {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think stating the compiler version should be required

@apoelstra
Copy link
Copy Markdown
Contributor

ab41fec needs rebase

@Sdoba16 Sdoba16 force-pushed the feature/versions branch 3 times, most recently from ef379ee to 975817b Compare April 6, 2026 10:59
@Sdoba16 Sdoba16 force-pushed the feature/versions branch from 975817b to 48917f7 Compare May 4, 2026 13:23
@Sdoba16 Sdoba16 requested review from apoelstra May 4, 2026 13:41
@Sdoba16 Sdoba16 force-pushed the feature/versions branch from e4551f5 to c56e75d Compare May 4, 2026 13:56
@Sdoba16 Sdoba16 marked this pull request as ready for review May 5, 2026 08:17
@Sdoba16 Sdoba16 requested a review from delta1 as a code owner May 5, 2026 08:17
@KyrylR
Copy link
Copy Markdown
Collaborator

KyrylR commented May 8, 2026

Do we have an issue for discussion this?

@Sdoba16
Copy link
Copy Markdown
Collaborator Author

Sdoba16 commented May 8, 2026

Do we have an issue for discussion this?

#248

@LesterEvSe LesterEvSe linked an issue May 15, 2026 that may be closed by this pull request
@KyrylR
Copy link
Copy Markdown
Collaborator

KyrylR commented Jun 1, 2026

Needs rebase

@apoelstra
Copy link
Copy Markdown
Contributor

c56e75d needs rebase

@Sdoba16 Sdoba16 force-pushed the feature/versions branch from c56e75d to 18ab20c Compare June 3, 2026 16:57
Comment thread doc/versioning.md Outdated

Every `.simf` file must begin with a compiler version directive:
```rust
#![compiler_version(">=0.6.0")]
Copy link
Copy Markdown
Collaborator

@LesterEvSe LesterEvSe Jun 4, 2026

Choose a reason for hiding this comment

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

This syntax suggests we have a preprocessing phase, which is not true. Since SimplicityHL is a Rust-like language, users will see #![...] and assume it works like Rust's preprocessor.

Let's avoid the confusion and switch to simc X.Y.Z. Since pragma version is not approved yet, we are looking at variants like compiler, compiler-version, or simc. In my opinion, simc is the most optimal variant because it is concise and saves keystrokes for the user.

Comment thread doc/versioning.md Outdated
Comment on lines +32 to +40
## For Compiler Contributors

If you are contributing to the SimplicityHL compiler and bumping the version in `Cargo.toml`, you must update the version directives in all examples and tests.

You can do this automatically from the project root:
```bash
python3 update_examples.py <new_version>
```
See `CONTRIBUTING.md` for more details. No newline at end of file
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Regarding the update_examples.py script and our test contracts, I do not see a strict need for pinned compiler versions here.

We can simplify our workflow by using a range like pragma version >=0.5.0 across all test files. If a specific contract introduces breaking changes or becomes incompatible in the future, we can simply bump the minimum requirement for that file alone. Otherwise, we can leave them as they are and avoid running an update script every time the compiler version changes.

@@ -0,0 +1,394 @@
use crate::driver::tests::setup_graph_raw;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's add a quick note to the docstring explaining the motivation behind this macro

Comment thread src/driver/version_tests.rs Outdated
Comment on lines +15 to +25
if $expect_success {
assert!(graph_opt.is_some() && !handler.has_errors(),
"Scenario failed unexpectedly. Errors:\n{}", handler);
} else {
assert!(graph_opt.is_none() || handler.has_errors(),
"Scenario succeeded when it should have failed.");
let expected_err: Option<&str> = $expected_err;
if let Some(err) = expected_err {
assert!(handler.to_string().contains(err),
"Expected error containing '{}' but got:\n{}", err, handler);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The nested blocks can be rewritten as follows:

if $expect_success {
    assert!(graph_opt.is_some() && !handler.has_errors(),
        "Scenario failed unexpectedly. Errors:\n{}", handler);
    return;
}

assert!(graph_opt.is_none() || handler.has_errors(),
    "Scenario succeeded when it should have failed.");

let expected_err: Option<&str> = $expected_err;
if let Some(err) = expected_err {
    assert!(handler.to_string().contains(err),
        "Expected error containing '{}' but got:\n{}", err, handler);
}

@stringhandler
Copy link
Copy Markdown
Contributor

Is it required to add the compiler version? I would say the examples should only specify the minimum version needed to compile, which for all of these would not be necessary as they don't have any breaking changes. The only ones that might need to be specified are the ones using the use and pub keywords.

It is generally fine to include a compiler version, but these look like they need to keep being updated.

@Sdoba16 Sdoba16 force-pushed the feature/versions branch from 18ab20c to cd5b1e9 Compare June 4, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Versioning

5 participants