Skip to content

Rust: use all features by default #19551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions rust/codeql-extractor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ options:
cargo_features:
title: Cargo features to turn on
description: >
Comma-separated list of features to turn on. If any value is `*` all features
are turned on. By default only default cargo features are enabled. Can be
repeated.
Comma-separated list of features to turn on. By default all features are enabled.
If any features are specified, then only those features are enabled. The `default`
feature must be explicitly specified if only default features are desired.
Can be repeated.
type: array
cargo_cfg_overrides:
title: Cargo cfg overrides
Expand Down
28 changes: 18 additions & 10 deletions rust/extractor/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,23 @@ impl Config {
}
}

Copy link
Preview

Copilot AI May 22, 2025

Choose a reason for hiding this comment

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

Add a doc comment for cargo_features() to explain its behavior, particularly how default features and the deprecated '*' wildcard are handled.

Suggested change
/// Determines the Cargo features to be used based on the configuration.
///
/// - If the `cargo_features` list is empty or contains the deprecated `'*'` wildcard,
/// all features are enabled (`CargoFeatures::All`).
/// - Otherwise, a subset of features is selected (`CargoFeatures::Selected`):
/// - The `features` list excludes the `default` feature.
/// - The `no_default_features` flag is set to `true` if the `default` feature is not present
/// in the `cargo_features` list.
///
/// # Note
/// The `'*'` wildcard is deprecated but retained for backward compatibility.

Copilot uses AI. Check for mistakes.

fn cargo_features(&self) -> CargoFeatures {
// '*' is to be considered deprecated but still kept in for backward compatibility
if self.cargo_features.is_empty() || self.cargo_features.iter().any(|f| f == "*") {
CargoFeatures::All
} else {
CargoFeatures::Selected {
features: self
.cargo_features
.iter()
.filter(|f| *f != "default")
.cloned()
.collect(),
no_default_features: !self.cargo_features.iter().any(|f| f == "default"),
}
}
}

pub fn to_cargo_config(&self, dir: &AbsPath) -> (CargoConfig, LoadCargoConfig) {
let sysroot = self.sysroot(dir);
(
Expand Down Expand Up @@ -159,16 +176,7 @@ impl Config {
.unwrap_or_else(|| self.scratch_dir.join("target")),
)
.ok(),
features: if self.cargo_features.is_empty() {
Default::default()
} else if self.cargo_features.contains(&"*".to_string()) {
CargoFeatures::All
} else {
CargoFeatures::Selected {
features: self.cargo_features.clone(),
no_default_features: false,
}
},
features: self.cargo_features(),
target: self.cargo_target.clone(),
cfg_overrides: to_cfg_overrides(&self.cargo_cfg_overrides),
wrap_rustc_in_build_scripts: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest

@pytest.mark.ql_test(expected=".all.expected")
def test_default(codeql, rust):
codeql.database.create()

Expand All @@ -8,10 +9,33 @@ def test_default(codeql, rust):
pytest.param(p,
marks=pytest.mark.ql_test(expected=f".{e}.expected"))
for p, e in (
("default", "none"),
("foo", "foo"),
("bar", "bar"),
("*", "all"),
("foo,bar", "all"))
("foo,bar", "all"),
("default,foo", "foo"),
("default,bar", "bar"),
)
])
def test_features(codeql, rust, features):
codeql.database.create(extractor_option=f"cargo_features={features}")

@pytest.mark.parametrize("features",
[
pytest.param(p,
marks=pytest.mark.ql_test(expected=f".{e}.expected"))
for p, e in (
("default", "foo"),
("foo", "foo"),
("bar", "bar"),
("*", "all"),
("foo,bar", "all"),
("default,foo", "foo"),
("default,bar", "all"),
)
])
def test_features_with_default(codeql, rust, features):
with open("Cargo.toml", "a") as f:
print('default = ["foo"]', file=f)
codeql.database.create(extractor_option=f"cargo_features={features}")