Let's see what's happening here:
$ set -x
$ c file
+ unalias c
+ alias c=crystal file
bash: alias: file: not found
$ set +x
So, `c file` is expanded to `unalias c; alias c=crystal file` (via an intermediate expansion to `crystal file`).
`alias c=crystal file` doesn't make sense. What I think you might have wanted is for `crystal file` to be executed.
You might want to rename the aliases that switches the meanings of `c`:
alias usecrystal="alias c=crystal"
alias usecargo="alias c=cargo"
Alternatively, you may protect the command from alias expansion:
alias c="\crystal"
alias crystal="alias c=\crystal"
alias cargo="alias c=\cargo"
Or use `command` (which IMHO looks better):
alias c="command crystal"
alias crystal='alias c="command crystal"'
alias cargo='alias c="command cargo"'
The `command` command also protects from alias expansion.