Skip to content

Commit 50c7e0f

Browse files
committed
fix(lints): Feature-gate the im_a_teapot lint
1 parent a1f8e45 commit 50c7e0f

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

src/cargo/core/features.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ impl FromStr for Edition {
343343
}
344344
}
345345

346-
#[derive(PartialEq)]
346+
#[derive(Debug, PartialEq)]
347347
enum Status {
348348
Stable,
349349
Unstable,
@@ -387,11 +387,11 @@ macro_rules! features {
387387
$(
388388
$(#[$attr])*
389389
#[doc = concat!("\n\n\nSee <https://doc.rust-lang.org/nightly/cargo/", $docs, ">.")]
390-
pub fn $feature() -> &'static Feature {
390+
pub const fn $feature() -> &'static Feature {
391391
fn get(features: &Features) -> bool {
392392
stab!($stab) == Status::Stable || features.$feature
393393
}
394-
static FEAT: Feature = Feature {
394+
const FEAT: Feature = Feature {
395395
name: stringify!($feature),
396396
stability: stab!($stab),
397397
version: $version,
@@ -512,6 +512,7 @@ features! {
512512
}
513513

514514
/// Status and metadata for a single unstable feature.
515+
#[derive(Debug)]
515516
pub struct Feature {
516517
/// Feature name. This is valid Rust identifier so no dash only underscore.
517518
name: &'static str,

src/cargo/util/lints.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::core::dependency::DepKind;
22
use crate::core::FeatureValue::Dep;
3-
use crate::core::{Edition, FeatureValue, Package};
3+
use crate::core::{Edition, Feature, FeatureValue, Manifest, Package};
44
use crate::util::interning::InternedString;
55
use crate::{CargoResult, GlobalContext};
66
use annotate_snippets::{Level, Snippet};
@@ -13,10 +13,10 @@ use std::path::Path;
1313
use toml_edit::ImDocument;
1414

1515
fn get_span(document: &ImDocument<String>, path: &[&str], get_value: bool) -> Option<Range<usize>> {
16-
let mut table = document.as_item().as_table_like().unwrap();
16+
let mut table = document.as_item().as_table_like()?;
1717
let mut iter = path.into_iter().peekable();
1818
while let Some(key) = iter.next() {
19-
let (key, item) = table.get_key_value(key).unwrap();
19+
let (key, item) = table.get_key_value(key)?;
2020
if iter.peek().is_none() {
2121
return if get_value {
2222
item.span()
@@ -82,6 +82,7 @@ pub struct Lint {
8282
pub groups: &'static [LintGroup],
8383
pub default_level: LintLevel,
8484
pub edition_lint_opts: Option<(Edition, LintLevel)>,
85+
pub feature_gate: Option<&'static Feature>,
8586
}
8687

8788
impl Lint {
@@ -121,6 +122,12 @@ impl Lint {
121122
.map(|(_, (l, r, _))| (l, r))
122123
.unwrap()
123124
}
125+
126+
/// Returns true if the lint is feature gated and the feature is not enabled
127+
fn is_feature_gated(&self, manifest: &Manifest) -> bool {
128+
self.feature_gate
129+
.map_or(false, |f| !manifest.unstable_features().is_enabled(f))
130+
}
124131
}
125132

126133
#[derive(Copy, Clone, Debug, PartialEq)]
@@ -164,7 +171,7 @@ impl From<TomlLintLevel> for LintLevel {
164171
}
165172
}
166173

167-
#[derive(Copy, Clone, Debug)]
174+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
168175
pub enum LintLevelReason {
169176
Default,
170177
Edition(Edition),
@@ -228,6 +235,7 @@ const IM_A_TEAPOT: Lint = Lint {
228235
groups: &[TEST_DUMMY_UNSTABLE],
229236
default_level: LintLevel::Allow,
230237
edition_lint_opts: None,
238+
feature_gate: Some(Feature::test_dummy_unstable()),
231239
};
232240

233241
pub fn check_im_a_teapot(
@@ -240,6 +248,11 @@ pub fn check_im_a_teapot(
240248
) -> CargoResult<()> {
241249
let manifest = pkg.manifest();
242250
let (lint_level, reason) = IM_A_TEAPOT.level(pkg_lints, ws_lints, manifest.edition());
251+
252+
if IM_A_TEAPOT.is_feature_gated(manifest) {
253+
return Ok(());
254+
}
255+
243256
if lint_level == LintLevel::Allow {
244257
return Ok(());
245258
}
@@ -295,6 +308,7 @@ const IMPLICIT_FEATURES: Lint = Lint {
295308
groups: &[],
296309
default_level: LintLevel::Allow,
297310
edition_lint_opts: None,
311+
feature_gate: None,
298312
};
299313

300314
pub fn check_implicit_features(
@@ -373,6 +387,7 @@ const UNUSED_OPTIONAL_DEPENDENCY: Lint = Lint {
373387
groups: &[],
374388
default_level: LintLevel::Warn,
375389
edition_lint_opts: None,
390+
feature_gate: None,
376391
};
377392

378393
pub fn unused_dependencies(

tests/testsuite/lints_table.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,3 +1078,33 @@ implicit-features = "warn"
10781078
)
10791079
.run();
10801080
}
1081+
1082+
#[cargo_test]
1083+
fn check_feature_gated() {
1084+
let p = project()
1085+
.file(
1086+
"Cargo.toml",
1087+
r#"
1088+
[package]
1089+
name = "foo"
1090+
version = "0.0.1"
1091+
edition = "2015"
1092+
authors = []
1093+
1094+
[lints.cargo]
1095+
im-a-teapot = "warn"
1096+
"#,
1097+
)
1098+
.file("src/lib.rs", "")
1099+
.build();
1100+
1101+
p.cargo("check -Zcargo-lints")
1102+
.masquerade_as_nightly_cargo(&["cargo-lints"])
1103+
.with_stderr(
1104+
"\
1105+
[CHECKING] foo v0.0.1 ([CWD])
1106+
[FINISHED] [..]
1107+
",
1108+
)
1109+
.run();
1110+
}

0 commit comments

Comments
 (0)