@@ -679,6 +679,53 @@ fn symbol_from_bindings_impl<'db>(
679679 visibility_constraints. evaluate ( db, predicates, visibility_constraint) ;
680680
681681 if static_visibility. is_always_false ( ) {
682+ // We found a binding that we have statically determined to not be visible from
683+ // the use of the symbol that we are investigating. There are three interesting
684+ // cases to consider:
685+ //
686+ // ```py
687+ // def f1():
688+ // if False:
689+ // x = 1
690+ // use(x)
691+ //
692+ // def f2():
693+ // y = 1
694+ // return
695+ // use(y)
696+ //
697+ // def f3(flag: bool):
698+ // z = 1
699+ // if flag:
700+ // z = 2
701+ // return
702+ // use(z)
703+ // ```
704+ //
705+ // In the first case, there is a single binding for `x`, and due to the statically
706+ // known `False` condition, it is not visible at the use of `x`. However, we *can*
707+ // see/reach the start of the scope from `use(x)`. This means that `x` is unbound
708+ // and we should return `None`.
709+ //
710+ // In the second case, `y` is also not visible at the use of `y`, but here, we can
711+ // not see/reach the start of the scope. There is only one path of control flow,
712+ // and it passes through that binding of `y` (which we can not see). This implies
713+ // that we are in an unreachable section of code. We return `Never` in order to
714+ // silence the `unresolve-reference` diagnostic that would otherwise be emitted at
715+ // the use of `y`.
716+ //
717+ // In the third case, we have two bindings for `z`. The first one is visible, so we
718+ // consider the case that we now encounter the second binding `z = 2`, which is not
719+ // visible due to the early return. We *also* can not see the start of the scope
720+ // from `use(z)` because both paths of control flow pass through a binding of `z`.
721+ // The `z = 1` binding is visible, and so we are *not* in an unreachable section of
722+ // code. However, it is still okay to return `Never` in this case, because we will
723+ // union the types of all bindings, and `Never` will be eliminated automatically.
724+
725+ if unbound_visibility. is_always_false ( ) {
726+ // The scope-start is not visible
727+ return Some ( Type :: Never ) ;
728+ }
682729 return None ;
683730 }
684731
0 commit comments