1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
mod accepted;
mod active;
mod builtin_attrs;
mod removed;
use rustc_span::{edition::Edition, symbol::Symbol, Span};
use std::fmt;
use std::num::NonZeroU32;
#[derive(Clone, Copy)]
pub enum State {
Accepted,
Active { set: fn(&mut Features, Span) },
Removed { reason: Option<&'static str> },
Stabilized { reason: Option<&'static str> },
}
impl fmt::Debug for State {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
State::Accepted { .. } => write!(f, "accepted"),
State::Active { .. } => write!(f, "active"),
State::Removed { .. } => write!(f, "removed"),
State::Stabilized { .. } => write!(f, "stabilized"),
}
}
}
#[derive(Debug, Clone)]
pub struct Feature {
pub state: State,
pub name: Symbol,
pub since: &'static str,
issue: Option<u32>,
pub edition: Option<Edition>,
description: &'static str,
}
impl Feature {
fn issue(&self) -> Option<NonZeroU32> {
self.issue.and_then(NonZeroU32::new)
}
}
#[derive(Copy, Clone, Debug)]
pub enum Stability {
Unstable,
Deprecated(&'static str, Option<&'static str>),
}
#[derive(Clone, Copy, Hash)]
pub enum UnstableFeatures {
Disallow,
Allow,
Cheat,
}
impl UnstableFeatures {
pub fn from_environment() -> UnstableFeatures {
let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
let bootstrap = std::env::var("RUSTC_BOOTSTRAP").is_ok();
match (disable_unstable_features, bootstrap) {
(_, true) => UnstableFeatures::Cheat,
(true, _) => UnstableFeatures::Disallow,
(false, _) => UnstableFeatures::Allow,
}
}
pub fn is_nightly_build(&self) -> bool {
match *self {
UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
UnstableFeatures::Disallow => false,
}
}
}
fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> {
if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.name == feature) {
info.issue()
} else {
let found = ACCEPTED_FEATURES
.iter()
.chain(REMOVED_FEATURES)
.chain(STABLE_REMOVED_FEATURES)
.find(|t| t.name == feature);
match found {
Some(found) => found.issue(),
None => panic!("feature `{}` is not declared anywhere", feature),
}
}
}
pub enum GateIssue {
Language,
Library(Option<NonZeroU32>),
}
pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZeroU32> {
match issue {
GateIssue::Language => find_lang_feature_issue(feature),
GateIssue::Library(lib) => lib,
}
}
pub use accepted::ACCEPTED_FEATURES;
pub use active::{Features, ACTIVE_FEATURES, INCOMPLETE_FEATURES};
pub use builtin_attrs::{
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, AttributeGate, AttributeTemplate,
AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
};
pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};