Repository: astral-sh/ruff
File: crates/ruff_python_semantic/src/analyze/terminal.rs (Rust)

Code before:
                    } else {
                        // If there's an `else`, we won't fall through. If all the handlers and
                        // the `else` block return,, the `try` block also returns.
                        terminal = terminal.and_then(
                            branch_terminal.branch(Terminal::from_body(orelse, semantic)),
                        );
                    }
                }
                Stmt::With(ast::StmtWith { body, .. }) => {
                    terminal = terminal.and_then(Self::from_body(body, semantic));
                }
                Stmt::Return(_) => {
                    terminal = terminal.and_then(Terminal::RaiseOrReturn);
                }
                Stmt::Raise(raise) => {
                    // Check if this raise is NotImplementedError (only if semantic model is available)
                    let is_not_implemented = semantic
                        .and_then(|sem| {
                            raise.exc.as_ref().and_then(|exc| {
                                sem.resolve_builtin_symbol(map_callable(exc))
                                    .filter(|name| {
                                        matches!(*name, "NotImplementedError" | "NotImplemented")
                                    })
                            })
                        })
                        .is_some();

                    if is_not_implemented {
                        terminal = terminal.and_then(Terminal::RaiseNotImplemented);
                    } else {
                        terminal = terminal.and_then(Terminal::Raise);
                    }
                }
                _ => {}
            }
        }

        match terminal {
            Terminal::None => Terminal::Implicit,
            _ => terminal,
        }
    }

    /// Combine two [`Terminal`] operators, with one appearing after the other.
    fn and_then(self, other: Self) -> Self {
        match (self, other) {
            // If one of the operators is `None`, the result is the other operator.
            (Self::None, other) => other,
            (other, Self::None) => other,

            // If one of the operators is `Implicit`, the result is the other operator.

Review comment (suggestion):
I looked at the references to `from_body`, and I don't think there are any cases where a semantic model is unavailable. It's only passed as `None` in `sometimes_breaks`, but `sometimes_breaks` is only called from `from_body`, which has access to a semantic model, unless  I'm missing something.

I also think we could use `has_builtin_binding` here.

Code after:
                        // If there's no `else`, we may fall through, so only mark that this can't
                        // be a non-returning function if any of the branches return.
                        if branch_terminal.has_any_return() {
                            terminal = terminal.and_then(Terminal::ConditionalReturn);
                        }
                    } else {
                        // If there's an `else`, we won't fall through. If all the handlers and
                        // the `else` block return,, the `try` block also returns.
                        terminal = terminal.and_then(
                            branch_terminal.branch(Terminal::from_body(orelse, semantic)),
                        );
                    }
                }
                Stmt::With(ast::StmtWith { body, .. }) => {
                    terminal = terminal.and_then(Self::from_body(body, semantic));
                }
                Stmt::Return(_) => {
                    terminal = terminal.and_then(Terminal::RaiseOrReturn);
                }
                Stmt::Raise(raise) => {
                    // Check if this raise is NotImplementedError
                    let is_not_implemented = raise.exc.as_ref().is_some_and(|exc| {
                        let exc = map_callable(exc);
                        semantic.match_builtin_expr(exc, "NotImplementedError")
                    });

                    if is_not_implemented {
                        terminal = terminal.and_then(Terminal::RaiseNotImplemented);
                    } else {
                        terminal = terminal.and_then(Terminal::Raise);
                    }
                }
                _ => {}
            }
        }

        match terminal {
            Terminal::None => Terminal::Implicit,
            _ => terminal,
        }
    }

    /// Combine two [`Terminal`] operators, with one appearing after the other.
    fn and_then(self, other: Self) -> Self {
        match (self, other) {
            // If one of the operators is `None`, the result is the other operator.
            (Self::None, other) => other,
            (other, Self::None) => other,

            // If one of the operators is `Implicit`, the result is the other operator.
            (Self::Implicit, other) => other,