Skip to content

Commit dcc4b99

Browse files
committed
Turn INCOMPLETE_FEATURES into a lint.
1 parent 4eeaaa7 commit dcc4b99

File tree

3 files changed

+39
-16
lines changed

3 files changed

+39
-16
lines changed

src/librustc_lint/builtin.rs

+34-3
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,12 @@ use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext};
3333
use rustc::util::nodemap::FxHashSet;
3434

3535
use syntax::tokenstream::{TokenTree, TokenStream};
36-
use syntax::ast;
36+
use syntax::ast::{self, Expr};
3737
use syntax::ptr::P;
38-
use syntax::ast::Expr;
3938
use syntax::attr::{self, HasAttrs, AttributeTemplate};
4039
use syntax::source_map::Spanned;
4140
use syntax::edition::Edition;
42-
use syntax::feature_gate::{AttributeGate, AttributeType};
41+
use syntax::feature_gate::{self, AttributeGate, AttributeType};
4342
use syntax::feature_gate::{Stability, deprecated_attributes};
4443
use syntax_pos::{BytePos, Span, SyntaxContext};
4544
use syntax::symbol::{Symbol, kw, sym};
@@ -1831,3 +1830,35 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements {
18311830
}
18321831
}
18331832
}
1833+
1834+
declare_lint! {
1835+
pub INCOMPLETE_FEATURES,
1836+
Warn,
1837+
"incomplete features that may function improperly in some or all cases"
1838+
}
1839+
1840+
declare_lint_pass!(
1841+
/// Check for used feature gates in `INCOMPLETE_FEATURES` in `feature_gate.rs`.
1842+
IncompleteFeatures => [INCOMPLETE_FEATURES]
1843+
);
1844+
1845+
impl EarlyLintPass for IncompleteFeatures {
1846+
fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
1847+
let features = cx.sess.features_untracked();
1848+
features.declared_lang_features
1849+
.iter().map(|(name, span, _)| (name, span))
1850+
.chain(features.declared_lib_features.iter().map(|(name, span)| (name, span)))
1851+
.filter(|(name, _)| feature_gate::INCOMPLETE_FEATURES.iter().any(|f| name == &f))
1852+
.for_each(|(name, &span)| {
1853+
cx.struct_span_lint(
1854+
INCOMPLETE_FEATURES,
1855+
span,
1856+
&format!(
1857+
"the feature `{}` is incomplete and may cause the compiler to crash",
1858+
name,
1859+
)
1860+
)
1861+
.emit();
1862+
});
1863+
}
1864+
}

src/librustc_lint/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ macro_rules! early_lint_passes {
9797
DeprecatedAttr: DeprecatedAttr::new(),
9898
WhileTrue: WhileTrue,
9999
NonAsciiIdents: NonAsciiIdents,
100+
IncompleteFeatures: IncompleteFeatures,
100101
]);
101102
)
102103
}

src/libsyntax/feature_gate.rs

+4-13
Original file line numberDiff line numberDiff line change
@@ -569,10 +569,10 @@ declare_features! (
569569
// -------------------------------------------------------------------------
570570
);
571571

572-
// Some features are known to be incomplete and using them is likely to have
573-
// unanticipated results, such as compiler crashes. We warn the user about these
574-
// to alert them.
575-
const INCOMPLETE_FEATURES: &[Symbol] = &[
572+
/// Some features are known to be incomplete and using them is likely to have
573+
/// unanticipated results, such as compiler crashes. We warn the user about these
574+
/// to alert them.
575+
pub const INCOMPLETE_FEATURES: &[Symbol] = &[
576576
sym::impl_trait_in_bindings,
577577
sym::generic_associated_types,
578578
sym::const_generics,
@@ -2338,15 +2338,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
23382338
}
23392339

23402340
let name = mi.name_or_empty();
2341-
if INCOMPLETE_FEATURES.iter().any(|f| name == *f) {
2342-
span_handler.struct_span_warn(
2343-
mi.span(),
2344-
&format!(
2345-
"the feature `{}` is incomplete and may cause the compiler to crash",
2346-
name
2347-
)
2348-
).emit();
2349-
}
23502341

23512342
if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
23522343
if *edition <= crate_edition {

0 commit comments

Comments
 (0)