pub enum StabilityLevel {
// Reason for the current stability level and the relevant rust-lang issue
Unstable { reason: Option<Symbol>, issue: Option<NonZeroU32>, is_soft: bool },
- Stable { since: Symbol },
+ Stable { since: Symbol, allowed_through_unstable_modules: bool },
}
impl StabilityLevel {
let mut stab: Option<(Stability, Span)> = None;
let mut const_stab: Option<(ConstStability, Span)> = None;
let mut promotable = false;
+ let mut allowed_through_unstable_modules = false;
let diagnostic = &sess.parse_sess.span_diagnostic;
sym::unstable,
sym::stable,
sym::rustc_promotable,
+ sym::rustc_allowed_through_unstable_modules,
]
.iter()
.any(|&s| attr.has_name(s))
if attr.has_name(sym::rustc_promotable) {
promotable = true;
+ } else if attr.has_name(sym::rustc_allowed_through_unstable_modules) {
+ allowed_through_unstable_modules = true;
}
// attributes with data
else if let Some(MetaItem { kind: MetaItemKind::List(ref metas), .. }) = meta {
match (feature, since) {
(Some(feature), Some(since)) => {
- let level = Stable { since };
+ let level = Stable { since, allowed_through_unstable_modules: false };
if sym::stable == meta_name {
stab = Some((Stability { level, feature }, attr.span));
} else {
}
}
+ if allowed_through_unstable_modules {
+ if let Some((
+ Stability {
+ level: StabilityLevel::Stable { ref mut allowed_through_unstable_modules, .. },
+ ..
+ },
+ _,
+ )) = stab
+ {
+ *allowed_through_unstable_modules = true;
+ } else {
+ struct_span_err!(
+ diagnostic,
+ item_sp,
+ E0789,
+ "`rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute"
+ )
+ .emit();
+ }
+ }
+
(stab, const_stab)
}