@@ -95,27 +95,27 @@ impl<'tcx> LateLintPass<'tcx> for DuplicateMutableAccounts {
95
95
// println!("{:#?}", self);
96
96
for v in self . accounts . values ( ) {
97
97
if v. len ( ) > 1 {
98
- let gen_constraints = generate_possible_expected_constraints ( v) ;
99
-
100
- for ( ( one, symmetric) , symbols) in gen_constraints {
101
- if !( self . streams . contains ( & one) || self . streams . contains ( & symmetric) ) {
102
- // get spans for offending types
103
- let mut spans: Vec < Span > = Vec :: new ( ) ;
104
- for ( sym, span) in v {
105
- if & symbols. 0 == sym || & symbols. 1 == sym {
106
- spans. push ( * span) ;
107
- }
98
+ let mut deq = VecDeque :: from ( v. to_owned ( ) ) ;
99
+ for _ in 0 ..deq. len ( ) - 1 {
100
+ let ( first, first_span) = deq. pop_front ( ) . unwrap ( ) ;
101
+ for ( other, other_span) in & deq {
102
+ let stream = create_key_check_constraint_tokenstream ( first, * other) ;
103
+ let symmetric_stream =
104
+ create_key_check_constraint_tokenstream ( * other, first) ;
105
+
106
+ if !( self . streams . contains ( & stream)
107
+ || self . streams . contains ( & symmetric_stream) )
108
+ {
109
+ // NOTE: for some reason, will only print out 2 messages, not 3
110
+ span_lint_and_help (
111
+ cx,
112
+ DUPLICATE_MUTABLE_ACCOUNTS ,
113
+ first_span,
114
+ "identical account types without a key check constraint" ,
115
+ Some ( * other_span) ,
116
+ & format ! ( "add an anchor key check constraint: #[account(constraint = {}.key() != {}.key())]" , first, other)
117
+ ) ;
108
118
}
109
-
110
- // TODO: for some reason, will only print out 2 messages, not 3
111
- span_lint_and_help (
112
- cx,
113
- DUPLICATE_MUTABLE_ACCOUNTS ,
114
- spans[ 0 ] ,
115
- "identical account types without a key check constraint" ,
116
- Some ( spans[ 1 ] ) ,
117
- & format ! ( "add an anchor key check constraint: #[account(constraint = {}.key() != {}.key())]" , symbols. 0 , symbols. 1 )
118
- ) ;
119
119
}
120
120
}
121
121
}
@@ -173,31 +173,6 @@ fn split(stream: CursorRef, delimiter: TokenKind) -> Vec<TokenStream> {
173
173
split_streams
174
174
}
175
175
176
- /// Generates a static set of possible expected key check constraints necessary for `identical_types`.
177
- /// `identical_types` is a set of identical types that must have a key check constraint. A vector of tuples
178
- /// is returned, where each element represents a particular constraint.
179
- ///
180
- /// Specifically, the first field of the tuple is a tuple of `TokenStream`s, which represent the constraint and its
181
- /// symmetric value, e.g., `a!=b` and `b!=a`. The second field of the tuple is a tuple of symbols, which
182
- /// represent the identifiers being compared. Following the previous example, this would be `(a, b)`.
183
- fn generate_possible_expected_constraints (
184
- identical_types : & [ ( Symbol , Span ) ] ,
185
- ) -> Vec < ( ( TokenStream , TokenStream ) , ( Symbol , Symbol ) ) > {
186
- let mut deq = VecDeque :: from ( identical_types. to_owned ( ) ) ;
187
- let mut gen_set = Vec :: new ( ) ;
188
-
189
- for _ in 0 ..deq. len ( ) - 1 {
190
- let first = deq. pop_front ( ) . unwrap ( ) . 0 ;
191
- // generate stream for all other values in vec
192
- for ( other, _) in & deq {
193
- let stream = create_key_check_constraint_tokenstream ( first, * other) ;
194
- let symmetric_stream = create_key_check_constraint_tokenstream ( * other, first) ;
195
- gen_set. push ( ( ( stream, symmetric_stream) , ( first, * other) ) ) ;
196
- }
197
- }
198
- gen_set
199
- }
200
-
201
176
/// Returns a `TokenStream` of form: constraint = `a`.key() != `b`.key().
202
177
fn create_key_check_constraint_tokenstream ( a : Symbol , b : Symbol ) -> TokenStream {
203
178
// TODO: may be more efficient way to do this, since the stream is effectively fixed
0 commit comments