I don't even know the priority between && and ||. If I'm using both, I use parentheses just so it's more explicit. "a && b || c" should flag a linter, IMO, with "(a && b) || c" or "a && (b || c)" being required.
Convert them to arithmetic. If you ignore the casting, a && b is just a * b a || b is just a + b Now you remember the precedence between them (except in broken languages, of which the only notable one is shell).
All binary messages in Smalltalk (messages with selectors consisting of punctuation, like !@+-, including punctuation sequences like "+-&|", if you want) have the same precedence, and the keyword variants (which short-circuit, using block arguments) and: and or: also have the same precedence (one level lower than the binary/punctuation messages), but because they take block arguments, are usually disambiguated:
a | (b & c) "parens needed to ensure b & c is evaluated first"
ifTrue: [self doSomething]
ifFalse: [
"because the and: is sent in a block arg to or:, it won't be evaluated unless or:'s receiver is false"
(self hasPendingTask or: [self updateTaskQueue and: [self hasPendingTask]])
ifTrue: [self processTask]]
Smalltalk is extremely elegant, powerful, and simple. 6 reserved words, 3 levels of operator precedence, and not much syntax to learn. It's what r5rs Scheme should have been.