summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_passes/src/lib_features.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_passes/src/lib_features.rs59
1 files changed, 34 insertions, 25 deletions
diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs
index e05994f13..b5843c0ae 100644
--- a/compiler/rustc_passes/src/lib_features.rs
+++ b/compiler/rustc_passes/src/lib_features.rs
@@ -5,7 +5,7 @@
//! collect them instead.
use rustc_ast::{Attribute, MetaItemKind};
-use rustc_errors::struct_span_err;
+use rustc_attr::{rust_version_symbol, VERSION_PLACEHOLDER};
use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::lib_features::LibFeatures;
@@ -14,6 +14,8 @@ use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::Symbol;
use rustc_span::{sym, Span};
+use crate::errors::{FeaturePreviouslyDeclared, FeatureStableTwice};
+
fn new_lib_features() -> LibFeatures {
LibFeatures { stable: Default::default(), unstable: Default::default() }
}
@@ -29,11 +31,16 @@ impl<'tcx> LibFeatureCollector<'tcx> {
}
fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
- let stab_attrs =
- [sym::stable, sym::unstable, sym::rustc_const_stable, sym::rustc_const_unstable];
+ let stab_attrs = [
+ sym::stable,
+ sym::unstable,
+ sym::rustc_const_stable,
+ sym::rustc_const_unstable,
+ sym::rustc_default_body_unstable,
+ ];
// Find a stability attribute: one of #[stable(…)], #[unstable(…)],
- // #[rustc_const_stable(…)], or #[rustc_const_unstable(…)].
+ // #[rustc_const_stable(…)], #[rustc_const_unstable(…)] or #[rustc_default_body_unstable].
if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.has_name(**stab_attr)) {
let meta_kind = attr.meta_kind();
if let Some(MetaItemKind::List(ref metas)) = meta_kind {
@@ -49,12 +56,21 @@ impl<'tcx> LibFeatureCollector<'tcx> {
}
}
}
+
+ if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER {
+ since = Some(rust_version_symbol());
+ }
+
if let Some(feature) = feature {
// This additional check for stability is to make sure we
// don't emit additional, irrelevant errors for malformed
// attributes.
- let is_unstable =
- matches!(*stab_attr, sym::unstable | sym::rustc_const_unstable);
+ let is_unstable = matches!(
+ *stab_attr,
+ sym::unstable
+ | sym::rustc_const_unstable
+ | sym::rustc_default_body_unstable
+ );
if since.is_some() || is_unstable {
return Some((feature, since, attr.span));
}
@@ -77,14 +93,12 @@ impl<'tcx> LibFeatureCollector<'tcx> {
(Some(since), _, false) => {
if let Some((prev_since, _)) = self.lib_features.stable.get(&feature) {
if *prev_since != since {
- self.span_feature_error(
+ self.tcx.sess.emit_err(FeatureStableTwice {
span,
- &format!(
- "feature `{}` is declared stable since {}, \
- but was previously declared stable since {}",
- feature, since, prev_since,
- ),
- );
+ feature,
+ since,
+ prev_since: *prev_since,
+ });
return;
}
}
@@ -95,22 +109,17 @@ impl<'tcx> LibFeatureCollector<'tcx> {
self.lib_features.unstable.insert(feature, span);
}
(Some(_), _, true) | (None, true, _) => {
- self.span_feature_error(
+ let declared = if since.is_some() { "stable" } else { "unstable" };
+ let prev_declared = if since.is_none() { "stable" } else { "unstable" };
+ self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
span,
- &format!(
- "feature `{}` is declared {}, but was previously declared {}",
- feature,
- if since.is_some() { "stable" } else { "unstable" },
- if since.is_none() { "stable" } else { "unstable" },
- ),
- );
+ feature,
+ declared,
+ prev_declared,
+ });
}
}
}
-
- fn span_feature_error(&self, span: Span, msg: &str) {
- struct_span_err!(self.tcx.sess, span, E0711, "{}", &msg).emit();
- }
}
impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> {