Repository: astral-sh/ruff
File: crates/ty_ide/src/all_symbols.rs (Rust)

Code before:
    let is_typing_extensions_available =
        resolve_real_shadowable_module(db, &typing_extensions).is_some();

    let results = std::sync::Mutex::new(Vec::new());
    {
        let modules = all_modules(db);
        let db = db.dyn_clone();
        let results = &results;
        let query = &query;

        rayon::scope(move |s| {
            // For each file, extract symbols and add them to results
            for module in modules {
                let db = db.dyn_clone();
                let Some(file) = module.file(&*db) else {
                    continue;
                };
                if !is_typing_extensions_available && module.name(&*db) == &typing_extensions {
                    continue;
                }
                s.spawn(move |_| {
                    for (_, symbol) in symbols_for_file_global_only(&*db, file).search(query) {
                        // It seems like we could do better here than
                        // locking `results` for every single symbol,
                        // but this works pretty well as it is.
                        results.lock().unwrap().push(AllSymbolInfo {
                            symbol: symbol.to_owned(),
                            module,
                            file,
                        });
                    }
                });
            }
        });
    }

    let mut results = results.into_inner().unwrap();
    results.sort_by(|s1, s2| {
        let key1 = (&s1.symbol.name, s1.file.path(db).as_str());
        let key2 = (&s2.symbol.name, s2.file.path(db).as_str());
        key1.cmp(&key2)
    });
    results
}

/// A symbol found in the workspace and dependencies, including the
/// file it was found in.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AllSymbolInfo<'db> {
    /// The symbol information.
    pub symbol: SymbolInfo<'static>,

Review comment (suggestion):
I think we should still include `typing_extensions` suggestions if it's a stub file, even if `typing_extensions` isn't installed into the environment. Stub files are never executed at runtime, so the typeshed version of `typing_extensions` is fine for them.

Ideally we would also include `typing_extensions` suggestions inside `if TYPE_CHECKING` blocks (which are also not executed at runtime), but that won't produce great results until/unless we implement https://github.com/astral-sh/ty/issues/1553, so I wouldn't worry about it too much right now.

Code after:
        return Vec::new();
    }

    let typing_extensions = ModuleName::new("typing_extensions").unwrap();
    let is_typing_extensions_available = importing_from.is_stub(db)
        || resolve_real_shadowable_module(db, &typing_extensions).is_some();

    let results = std::sync::Mutex::new(Vec::new());
    {
        let modules = all_modules(db);
        let db = db.dyn_clone();
        let results = &results;
        let query = &query;

        rayon::scope(move |s| {
            // For each file, extract symbols and add them to results
            for module in modules {
                let db = db.dyn_clone();
                let Some(file) = module.file(&*db) else {
                    continue;
                };
                // TODO: also make it available in `TYPE_CHECKING` blocks
                // (we'd need https://github.com/astral-sh/ty/issues/1553 to do this well)
                if !is_typing_extensions_available && module.name(&*db) == &typing_extensions {
                    continue;
                }
                s.spawn(move |_| {
                    for (_, symbol) in symbols_for_file_global_only(&*db, file).search(query) {
                        // It seems like we could do better here than
                        // locking `results` for every single symbol,
                        // but this works pretty well as it is.
                        results.lock().unwrap().push(AllSymbolInfo {
                            symbol: symbol.to_owned(),
                            module,
                            file,
                        });
                    }
                });
            }
        });
    }

    let mut results = results.into_inner().unwrap();
    results.sort_by(|s1, s2| {
        let key1 = (&s1.symbol.name, s1.file.path(db).as_str());
        let key2 = (&s2.symbol.name, s2.file.path(db).as_str());
        key1.cmp(&key2)
    });
    results
}