Browse Source

lang: Add error message when Mint and TokenAccount with `init` are not ordered correctly (#2484)

CanardMandarin 2 years ago
parent
commit
714d524863
1 changed files with 19 additions and 1 deletions
  1. 19 1
      lang/syn/src/parser/accounts/mod.rs

+ 19 - 1
lang/syn/src/parser/accounts/mod.rs

@@ -126,7 +126,7 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {
             }
         }
 
-        for field in init_fields {
+        for (pos, field) in init_fields.iter().enumerate() {
             // Get payer for init-ed account
             let associated_payer_name = match field.constraints.init.clone().unwrap().payer {
                 // composite payer, check not supported
@@ -178,6 +178,24 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {
                         ));
                     }
                 }
+
+                // Make sure initialiazed token accounts are always declared after their corresponding mint.
+                InitKind::Mint { .. } => {
+                    if init_fields.iter().enumerate().any(|(f_pos, f)| {
+                        match &f.constraints.init.as_ref().unwrap().kind {
+                            InitKind::Token { mint, .. }
+                            | InitKind::AssociatedToken { mint, .. } => {
+                                field.ident == mint.to_token_stream().to_string() && pos > f_pos
+                            }
+                            _ => false,
+                        }
+                    }) {
+                        return Err(ParseError::new(
+                            field.ident.span(),
+                            "because of the init constraint, the mint has to be declared before the corresponding token account",
+                        ));
+                    }
+                }
                 _ => (),
             }
         }