The practical reason you can't overload precedence is because it means now the parser (code for reading text into an AST) needs include part of the type system. This prevents you from creating a clean separation between the phases of compilation, greatly complicating the compiler's internals. It means that if I just want to analyse some code I can't just use
rustc's parser, but also pull in half the compiler.
The security comment was an off-the-cuff remark that being able to change precedence whenever you want is a great way to obfuscate code.
Being able to change precedence also breaks the principle of least surprise and makes the language a lot harder to learn. I'd be quite annoyed if, just by including someone else's crate, my operator precedences were switched and now the math I'm using for bit masking and register bashing is silently broken.
Overloading precedence is very different to overloading operators because, similar to how
for .. in ... is converted to
IntoIterator::into_iter(), operators are converted to calls to
Add::add() and friends by the parser. The parser doesn't actually know you've overloaded the operator, instead it'll be picked up during the type checking phase.
On the other hand, precedence is built into a language's grammar and is as integral to the language as semantic things like borrowing and move.
Rust uses slightly different precedence rules to what you may be used to from C and I'm sure there would have been very good reasoning for this decision. You can always use parentheses to force precedence, and in these sorts of ambiguous situations I'd recommend it anyway.