I'm having trouble with pcase's behavior. (pcase "a" ((or (pred symbolp) name) (let ((foo 'bar)) name))) throws an error. It shouldn't. (Note that the dummy "let" is necessary to force the pcase code generation to use a function call). I believe the culprit is the code around this comment in pcase.el ;; If some of `vars' were not found in `prevvars', that's ;; OK it just means those vars aren't present in all ;; branches, so they can be used within the pattern ;; (e.g. by a `guard/let/pred') but not in the branch. I believe that's incorrect: using the variable in a condition-case should work, as should conditional shadowing of an existing binding, as in this case: (let ((name "default")) (pcase "a" ((or (pred symbolp) name) name))) (which works), or this case: (let ((name "default")) (pcase "a" ((or (pred symbolp) name) (let ((foo 'bar)) name)))) (which doesn't). I believe the right fix is not to share code for the same branch if it uses different variables, as in the attached patch. It's possible this increases codegen complexity in some construed cases, but in practice that shouldn't be a problem.