Skip to content

Commit

Permalink
Add support for compiler experimental features
Browse files Browse the repository at this point in the history
commit-id:480c1b28
  • Loading branch information
tomek0123456789 committed Dec 22, 2023
1 parent b5615b2 commit c9feaae
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 1 deletion.
1 change: 1 addition & 0 deletions scarb-metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ readme = "README.md"
repository.workspace = true

[dependencies]
cairo-lang-filesystem.workspace = true
camino.workspace = true
derive_builder = { workspace = true, optional = true }
semver.workspace = true
Expand Down
4 changes: 4 additions & 0 deletions scarb-metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//! With the `command` feature (enabled by default), this crate also exposes an ergonomic interface
//! to collect metadata from Scarb: [`MetadataCommand`].
use cairo_lang_filesystem::db::ExperimentalFeaturesConfig;
use std::collections::{BTreeMap, HashMap};
use std::fmt;
use std::ops::Index;
Expand Down Expand Up @@ -231,6 +232,9 @@ pub struct PackageMetadata {
#[serde(flatten)]
pub manifest_metadata: ManifestMetadata,

/// Compiler experimental features allowed for this package.
pub experimental_features: ExperimentalFeaturesConfig,

/// Additional data not captured by deserializer.
#[cfg_attr(feature = "builder", builder(default))]
#[serde(flatten)]
Expand Down
12 changes: 11 additions & 1 deletion scarb/src/compiler/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,17 @@ fn build_project_config(unit: &CompilationUnit) -> Result<ProjectConfig> {
component.cairo_package_name(),
CrateSettings {
edition: component.package.manifest.edition,
experimental_features: Default::default(),
experimental_features: cairo_lang_filesystem::db::ExperimentalFeaturesConfig {
negative_impls: component
.package
.manifest
.metadata
.experimental
.clone()
.unwrap_or_default()
.negative_impls
.unwrap_or_default(),
},
},
)
})
Expand Down
2 changes: 2 additions & 0 deletions scarb/src/core/manifest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ pub struct ManifestMetadata {
#[serde(rename = "tool")]
pub tool_metadata: Option<BTreeMap<SmolStr, Value>>,
pub cairo_version: Option<VersionReq>,
/// Allow experimental features.
pub experimental: Option<ScarbExperimentalFeaturesConfig>,
}

impl ManifestBuilder {
Expand Down
14 changes: 14 additions & 0 deletions scarb/src/core/manifest/toml_manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ pub struct PackageInheritableFields {
pub readme: Option<PathOrBool>,
pub repository: Option<String>,
pub cairo_version: Option<VersionReq>,
pub experimental: Option<ScarbExperimentalFeaturesConfig>,
}

macro_rules! get_field {
Expand Down Expand Up @@ -147,6 +148,7 @@ impl PackageInheritableFields {
get_field!(license_file, Utf8PathBuf);
get_field!(repository, String);
get_field!(edition, Edition);
get_field!(experimental, ScarbExperimentalFeaturesConfig);

pub fn readme(&self, workspace_root: &Utf8Path, package_root: &Utf8Path) -> Result<PathOrBool> {
let Ok(Some(readme)) = readme_for_package(workspace_root, self.readme.as_ref()) else {
Expand Down Expand Up @@ -198,6 +200,13 @@ pub struct TomlPackage {
/// **UNSTABLE** This package does not depend on Cairo's `core`.
pub no_core: Option<bool>,
pub cairo_version: Option<MaybeWorkspaceField<VersionReq>>,
pub experimental: Option<MaybeWorkspaceField<ScarbExperimentalFeaturesConfig>>,
}

#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct ScarbExperimentalFeaturesConfig {
pub negative_impls: Option<bool>,
}

#[derive(Clone, Debug, Serialize, Eq, PartialEq)]
Expand Down Expand Up @@ -547,6 +556,11 @@ impl TomlManifest {
.clone()
.map(|mw| mw.resolve("cairo_version", || inheritable_package.cairo_version()))
.transpose()?,
experimental: package
.experimental
.clone()
.map(|mw| mw.resolve("experimental", || inheritable_package.experimental()))
.transpose()?,
};

let edition = package
Expand Down
1 change: 1 addition & 0 deletions scarb/src/core/publishing/manifest_normalization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ fn generate_package(pkg: &Package) -> Box<TomlPackage> {
repository: metadata.repository.clone().map(MaybeWorkspace::Defined),
no_core: summary.no_core.then_some(true),
cairo_version: metadata.cairo_version.clone().map(MaybeWorkspace::Defined),
experimental: metadata.experimental.clone().map(MaybeWorkspace::Defined),
})
}

Expand Down
13 changes: 13 additions & 0 deletions scarb/src/ops/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::{BTreeMap, HashMap};

use anyhow::{bail, Result};
use cairo_lang_filesystem::db::ExperimentalFeaturesConfig;
use itertools::Itertools;
use semver::{Version, VersionReq};
use smol_str::SmolStr;
Expand Down Expand Up @@ -135,6 +136,17 @@ fn collect_package_metadata(package: &Package) -> m::PackageMetadata {

let edition = edition_variant(package.manifest.edition);

let experimental_features = ExperimentalFeaturesConfig {
negative_impls: package
.manifest
.metadata
.experimental
.clone()
.unwrap_or_default()
.negative_impls
.unwrap_or_default(),
};

m::PackageMetadataBuilder::default()
.id(wrap_package_id(package.id))
.name(package.id.name.clone())
Expand All @@ -146,6 +158,7 @@ fn collect_package_metadata(package: &Package) -> m::PackageMetadata {
.dependencies(dependencies)
.targets(targets)
.manifest_metadata(manifest_metadata)
.experimental_features(experimental_features)
.build()
.unwrap()
}
Expand Down
32 changes: 32 additions & 0 deletions scarb/tests/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1199,3 +1199,35 @@ fn includes_edition() {
}
panic!("Package not found in metadata!");
}

#[test]
fn includes_experimental_features() {
let t = assert_fs::TempDir::new().unwrap();
ProjectBuilder::start()
.name("hello")
.version("0.1.0")
.manifest_extra(indoc! {
r#"
[package.experimental]
negative-impls = true
"#
})
.build(&t);

let metadata = Scarb::quick_snapbox()
.arg("--json")
.arg("metadata")
.arg("--format-version")
.arg("1")
.current_dir(&t)
.stdout_json::<Metadata>();

assert!(
packages_by_name(metadata)
.get("hello")
.unwrap()
.clone()
.experimental_features
.negative_impls
)
}
9 changes: 9 additions & 0 deletions website/docs/reference/manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,15 @@ Keys are human-readable link names, and values are URLs.
"We're hiring" = "https://swmansion.com/careers/"
```

### `experimental`

This field is responsible for setting experimental flags to be used on the package for the compiler.

```toml
[package.experimental]
negative-impls = true
```

## `[dependencies]`

See [Specifying Dependencies](./specifying-dependencies) page.
Expand Down
1 change: 1 addition & 0 deletions website/docs/reference/workspaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Keys that are supported:
- `readme`
- `repository`
- `cairo-version`
- `experimental`

(See [manifest](./manifest) for more information on the meaning of inheritable keys.)

Expand Down

0 comments on commit c9feaae

Please sign in to comment.