Skip to content

Commit 46a4573

Browse files
authored
[red-knot] Add type inference for basic for loops (#13195)
1 parent 5728909 commit 46a4573

File tree

8 files changed

+331
-131
lines changed

8 files changed

+331
-131
lines changed

crates/red_knot_python_semantic/src/builtins.rs

-16
This file was deleted.

crates/red_knot_python_semantic/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ pub use python_version::PythonVersion;
1010
pub use semantic_model::{HasTy, SemanticModel};
1111

1212
pub mod ast_node_ref;
13-
mod builtins;
1413
mod db;
1514
mod module_name;
1615
mod module_resolver;
@@ -20,6 +19,7 @@ mod python_version;
2019
pub mod semantic_index;
2120
mod semantic_model;
2221
pub(crate) mod site_packages;
22+
mod stdlib;
2323
pub mod types;
2424

2525
type FxOrderSet<V> = ordermap::set::OrderSet<V, BuildHasherDefault<FxHasher>>;

crates/red_knot_python_semantic/src/semantic_model.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::module_name::ModuleName;
88
use crate::module_resolver::{resolve_module, Module};
99
use crate::semantic_index::ast_ids::HasScopedAstId;
1010
use crate::semantic_index::semantic_index;
11-
use crate::types::{definition_ty, global_symbol_ty_by_name, infer_scope_types, Type};
11+
use crate::types::{definition_ty, global_symbol_ty, infer_scope_types, Type};
1212
use crate::Db;
1313

1414
pub struct SemanticModel<'db> {
@@ -40,7 +40,7 @@ impl<'db> SemanticModel<'db> {
4040
}
4141

4242
pub fn global_symbol_ty(&self, module: &Module, symbol_name: &str) -> Type<'db> {
43-
global_symbol_ty_by_name(self.db, module.file(), symbol_name)
43+
global_symbol_ty(self.db, module.file(), symbol_name)
4444
}
4545
}
4646

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::module_name::ModuleName;
2+
use crate::module_resolver::resolve_module;
3+
use crate::semantic_index::global_scope;
4+
use crate::semantic_index::symbol::ScopeId;
5+
use crate::types::{global_symbol_ty, Type};
6+
use crate::Db;
7+
8+
/// Enumeration of various core stdlib modules, for which we have dedicated Salsa queries.
9+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10+
enum CoreStdlibModule {
11+
Builtins,
12+
Types,
13+
Typeshed,
14+
}
15+
16+
impl CoreStdlibModule {
17+
fn name(self) -> ModuleName {
18+
let module_name = match self {
19+
Self::Builtins => "builtins",
20+
Self::Types => "types",
21+
Self::Typeshed => "_typeshed",
22+
};
23+
ModuleName::new_static(module_name)
24+
.unwrap_or_else(|| panic!("{module_name} should be a valid module name!"))
25+
}
26+
}
27+
28+
/// Lookup the type of `symbol` in a given core module
29+
///
30+
/// Returns `Unbound` if the given core module cannot be resolved for some reason
31+
fn core_module_symbol_ty<'db>(
32+
db: &'db dyn Db,
33+
core_module: CoreStdlibModule,
34+
symbol: &str,
35+
) -> Type<'db> {
36+
resolve_module(db, core_module.name())
37+
.map(|module| global_symbol_ty(db, module.file(), symbol))
38+
.unwrap_or(Type::Unbound)
39+
}
40+
41+
/// Lookup the type of `symbol` in the builtins namespace.
42+
///
43+
/// Returns `Unbound` if the `builtins` module isn't available for some reason.
44+
#[inline]
45+
pub(crate) fn builtins_symbol_ty<'db>(db: &'db dyn Db, symbol: &str) -> Type<'db> {
46+
core_module_symbol_ty(db, CoreStdlibModule::Builtins, symbol)
47+
}
48+
49+
/// Lookup the type of `symbol` in the `types` module namespace.
50+
///
51+
/// Returns `Unbound` if the `types` module isn't available for some reason.
52+
#[inline]
53+
pub(crate) fn types_symbol_ty<'db>(db: &'db dyn Db, symbol: &str) -> Type<'db> {
54+
core_module_symbol_ty(db, CoreStdlibModule::Types, symbol)
55+
}
56+
57+
/// Lookup the type of `symbol` in the `_typeshed` module namespace.
58+
///
59+
/// Returns `Unbound` if the `_typeshed` module isn't available for some reason.
60+
#[inline]
61+
pub(crate) fn typeshed_symbol_ty<'db>(db: &'db dyn Db, symbol: &str) -> Type<'db> {
62+
core_module_symbol_ty(db, CoreStdlibModule::Typeshed, symbol)
63+
}
64+
65+
/// Get the scope of a core stdlib module.
66+
///
67+
/// Can return `None` if a custom typeshed is used that is missing the core module in question.
68+
fn core_module_scope(db: &dyn Db, core_module: CoreStdlibModule) -> Option<ScopeId<'_>> {
69+
resolve_module(db, core_module.name()).map(|module| global_scope(db, module.file()))
70+
}
71+
72+
/// Get the `builtins` module scope.
73+
///
74+
/// Can return `None` if a custom typeshed is used that is missing `builtins.pyi`.
75+
pub(crate) fn builtins_module_scope(db: &dyn Db) -> Option<ScopeId<'_>> {
76+
core_module_scope(db, CoreStdlibModule::Builtins)
77+
}

0 commit comments

Comments
 (0)