@@ -64,12 +64,22 @@ msrv_aliases! {
64
64
1 , 15 , 0 { MAYBE_BOUND_IN_WHERE }
65
65
}
66
66
67
- /// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]`
68
67
#[ derive( Debug , Clone ) ]
69
- pub struct Msrv {
70
- stack : Vec < RustcVersion > ,
68
+ enum MsrvInner {
69
+ One ( RustcVersion ) ,
70
+ Stacked ( Vec < RustcVersion > ) ,
71
71
}
72
72
73
+ impl Default for MsrvInner {
74
+ fn default ( ) -> Self {
75
+ Self :: Stacked ( Vec :: new ( ) )
76
+ }
77
+ }
78
+
79
+ /// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]`
80
+ #[ derive( Debug , Clone ) ]
81
+ pub struct Msrv ( MsrvInner ) ;
82
+
73
83
impl fmt:: Display for Msrv {
74
84
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
75
85
if let Some ( msrv) = self . current ( ) {
@@ -87,14 +97,14 @@ impl<'de> Deserialize<'de> for Msrv {
87
97
{
88
98
let v = String :: deserialize ( deserializer) ?;
89
99
parse_version ( Symbol :: intern ( & v) )
90
- . map ( |v| Msrv { stack : vec ! [ v ] } )
100
+ . map ( |v| Msrv ( MsrvInner :: One ( v ) ) )
91
101
. ok_or_else ( || serde:: de:: Error :: custom ( "not a valid Rust version" ) )
92
102
}
93
103
}
94
104
95
105
impl Msrv {
96
106
pub fn empty ( ) -> Msrv {
97
- Msrv { stack : Vec :: new ( ) }
107
+ Msrv ( MsrvInner :: Stacked ( Vec :: new ( ) ) )
98
108
}
99
109
100
110
pub fn read_cargo ( & mut self , sess : & Session ) {
@@ -103,7 +113,7 @@ impl Msrv {
103
113
. and_then ( |v| parse_version ( Symbol :: intern ( & v) ) ) ;
104
114
105
115
match ( self . current ( ) , cargo_msrv) {
106
- ( None , Some ( cargo_msrv) ) => self . stack = vec ! [ cargo_msrv] ,
116
+ ( None , Some ( cargo_msrv) ) => self . 0 = MsrvInner :: One ( cargo_msrv) ,
107
117
( Some ( clippy_msrv) , Some ( cargo_msrv) ) => {
108
118
if clippy_msrv != cargo_msrv {
109
119
sess. dcx ( ) . warn ( format ! (
@@ -116,7 +126,10 @@ impl Msrv {
116
126
}
117
127
118
128
pub fn current ( & self ) -> Option < RustcVersion > {
119
- self . stack . last ( ) . copied ( )
129
+ match & self . 0 {
130
+ MsrvInner :: One ( ver) => Some ( * ver) ,
131
+ MsrvInner :: Stacked ( vec) => vec. last ( ) . copied ( ) ,
132
+ }
120
133
}
121
134
122
135
pub fn meets ( & self , required : RustcVersion ) -> bool {
@@ -152,13 +165,25 @@ impl Msrv {
152
165
153
166
pub fn check_attributes ( & mut self , sess : & Session , attrs : & [ Attribute ] ) {
154
167
if let Some ( version) = Self :: parse_attr ( sess, attrs) {
155
- self . stack . push ( version) ;
168
+ self . 0 = match std:: mem:: take ( & mut self . 0 ) {
169
+ MsrvInner :: One ( old) => MsrvInner :: Stacked ( vec ! [ old, version] ) ,
170
+ MsrvInner :: Stacked ( mut stack) => {
171
+ stack. push ( version) ;
172
+ MsrvInner :: Stacked ( stack)
173
+ } ,
174
+ } ;
156
175
}
157
176
}
158
177
159
178
pub fn check_attributes_post ( & mut self , sess : & Session , attrs : & [ Attribute ] ) {
160
179
if Self :: parse_attr ( sess, attrs) . is_some ( ) {
161
- self . stack . pop ( ) ;
180
+ self . 0 = match std:: mem:: take ( & mut self . 0 ) {
181
+ MsrvInner :: One ( _) => MsrvInner :: Stacked ( Vec :: new ( ) ) ,
182
+ MsrvInner :: Stacked ( mut vec) => {
183
+ vec. pop ( ) ;
184
+ MsrvInner :: Stacked ( vec)
185
+ } ,
186
+ }
162
187
}
163
188
}
164
189
}
0 commit comments