mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-17 00:50:16 +00:00
Switch to Rust 2024 edition (#18129)
This commit is contained in:
parent
e67b35743a
commit
9ae698fe30
1082 changed files with 4211 additions and 3300 deletions
|
@ -115,7 +115,7 @@ where
|
|||
#[expect(unsafe_code)]
|
||||
unsafe impl<T> salsa::Update for AstNodeRef<T> {
|
||||
unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool {
|
||||
let old_ref = &mut (*old_pointer);
|
||||
let old_ref = unsafe { &mut (*old_pointer) };
|
||||
|
||||
if old_ref.parsed == new_value.parsed && old_ref.node.eq(&new_value.node) {
|
||||
false
|
||||
|
|
|
@ -17,7 +17,7 @@ pub(crate) mod tests {
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::program::{Program, SearchPathSettings};
|
||||
use crate::{default_lint_registry, ProgramSettings, PythonPlatform};
|
||||
use crate::{ProgramSettings, PythonPlatform, default_lint_registry};
|
||||
|
||||
use super::Db;
|
||||
use crate::lint::{LintRegistry, RuleSelection};
|
||||
|
|
|
@ -3,14 +3,14 @@ use rustc_hash::FxHashSet;
|
|||
use ruff_db::files::File;
|
||||
use ruff_db::parsed::parsed_module;
|
||||
use ruff_python_ast::name::Name;
|
||||
use ruff_python_ast::statement_visitor::{walk_stmt, StatementVisitor};
|
||||
use ruff_python_ast::statement_visitor::{StatementVisitor, walk_stmt};
|
||||
use ruff_python_ast::{self as ast};
|
||||
|
||||
use crate::semantic_index::ast_ids::HasScopedExpressionId;
|
||||
use crate::semantic_index::symbol::ScopeId;
|
||||
use crate::semantic_index::{global_scope, semantic_index, SemanticIndex};
|
||||
use crate::types::{infer_expression_types, Truthiness, Type};
|
||||
use crate::{resolve_module, Db, ModuleName};
|
||||
use crate::semantic_index::{SemanticIndex, global_scope, semantic_index};
|
||||
use crate::types::{Truthiness, Type, infer_expression_types};
|
||||
use crate::{Db, ModuleName, resolve_module};
|
||||
|
||||
#[allow(clippy::ref_option)]
|
||||
fn dunder_all_names_cycle_recover(
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::lint::{LintRegistry, LintRegistryBuilder};
|
|||
use crate::suppression::{INVALID_IGNORE_COMMENT, UNKNOWN_RULE, UNUSED_IGNORE_COMMENT};
|
||||
pub use db::Db;
|
||||
pub use module_name::ModuleName;
|
||||
pub use module_resolver::{resolve_module, system_module_search_paths, KnownModule, Module};
|
||||
pub use module_resolver::{KnownModule, Module, resolve_module, system_module_search_paths};
|
||||
pub use program::{Program, ProgramSettings, PythonPath, SearchPathSettings};
|
||||
pub use python_platform::PythonPlatform;
|
||||
pub use semantic_model::{HasType, SemanticModel};
|
||||
|
|
|
@ -65,7 +65,7 @@ use std::cmp::Ordering;
|
|||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
|
||||
use ruff_index::{newtype_index, IndexVec};
|
||||
use ruff_index::{IndexVec, newtype_index};
|
||||
|
||||
/// A handle to an association list. Use [`ListStorage`] to access its elements, and
|
||||
/// [`ListBuilder`] to construct other lists based on this one.
|
||||
|
|
|
@ -2,11 +2,11 @@ use std::iter::FusedIterator;
|
|||
|
||||
pub use module::{KnownModule, Module};
|
||||
pub use resolver::resolve_module;
|
||||
pub(crate) use resolver::{file_to_module, SearchPaths};
|
||||
pub(crate) use resolver::{SearchPaths, file_to_module};
|
||||
use ruff_db::system::SystemPath;
|
||||
|
||||
use crate::module_resolver::resolver::search_paths;
|
||||
use crate::Db;
|
||||
use crate::module_resolver::resolver::search_paths;
|
||||
use resolver::SearchPathIterator;
|
||||
|
||||
mod module;
|
||||
|
|
|
@ -5,11 +5,11 @@ use std::sync::Arc;
|
|||
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
|
||||
use ruff_db::files::{system_path_to_file, vendored_path_to_file, File, FileError};
|
||||
use ruff_db::files::{File, FileError, system_path_to_file, vendored_path_to_file};
|
||||
use ruff_db::system::{System, SystemPath, SystemPathBuf};
|
||||
use ruff_db::vendored::{VendoredPath, VendoredPathBuf};
|
||||
|
||||
use super::typeshed::{typeshed_versions, TypeshedVersionsParseError, TypeshedVersionsQueryResult};
|
||||
use super::typeshed::{TypeshedVersionsParseError, TypeshedVersionsQueryResult, typeshed_versions};
|
||||
use crate::db::Db;
|
||||
use crate::module_name::ModuleName;
|
||||
use crate::module_resolver::resolver::ResolverContext;
|
||||
|
@ -923,10 +923,12 @@ mod tests {
|
|||
assert!(asyncio_regular_package.is_regular_package(&resolver));
|
||||
// Paths to directories don't resolve to VfsFiles
|
||||
assert_eq!(asyncio_regular_package.to_file(&resolver), None);
|
||||
assert!(asyncio_regular_package
|
||||
.join("__init__.pyi")
|
||||
.to_file(&resolver)
|
||||
.is_some());
|
||||
assert!(
|
||||
asyncio_regular_package
|
||||
.join("__init__.pyi")
|
||||
.to_file(&resolver)
|
||||
.is_some()
|
||||
);
|
||||
|
||||
// The `asyncio` package exists on Python 3.8, but the `asyncio.tasks` submodule does not,
|
||||
// according to the `VERSIONS` file in our typeshed mock:
|
||||
|
@ -1056,10 +1058,12 @@ mod tests {
|
|||
assert!(collections_regular_package.is_regular_package(&resolver));
|
||||
// (This is still `None`, as directories don't resolve to `Vfs` files)
|
||||
assert_eq!(collections_regular_package.to_file(&resolver), None);
|
||||
assert!(collections_regular_package
|
||||
.join("__init__.pyi")
|
||||
.to_file(&resolver)
|
||||
.is_some());
|
||||
assert!(
|
||||
collections_regular_package
|
||||
.join("__init__.pyi")
|
||||
.to_file(&resolver)
|
||||
.is_some()
|
||||
);
|
||||
|
||||
// ...and so should the `asyncio.tasks` submodule (though it's still not a directory):
|
||||
let asyncio_tasks_module = stdlib_path.join("asyncio/tasks.pyi");
|
||||
|
|
|
@ -13,7 +13,7 @@ use ruff_python_ast::PythonVersion;
|
|||
|
||||
use crate::db::Db;
|
||||
use crate::module_name::ModuleName;
|
||||
use crate::module_resolver::typeshed::{vendored_typeshed_versions, TypeshedVersions};
|
||||
use crate::module_resolver::typeshed::{TypeshedVersions, vendored_typeshed_versions};
|
||||
use crate::site_packages::{PythonEnvironment, SitePackagesDiscoveryError, SysPrefixPathOrigin};
|
||||
use crate::{Program, PythonPath, SearchPathSettings};
|
||||
|
||||
|
@ -639,7 +639,9 @@ fn resolve_name(db: &dyn Db, name: &ModuleName) -> Option<(SearchPath, ResolvedM
|
|||
match resolve_module_in_search_path(&resolver_state, &stub_name, search_path) {
|
||||
Ok(resolved_module) => {
|
||||
if resolved_module.package_kind.is_root() && resolved_module.kind.is_module() {
|
||||
tracing::trace!("Search path '{search_path} contains a module named `{stub_name}` but a standalone module isn't a valid stub.");
|
||||
tracing::trace!(
|
||||
"Search path '{search_path} contains a module named `{stub_name}` but a standalone module isn't a valid stub."
|
||||
);
|
||||
} else {
|
||||
return Some((search_path.clone(), resolved_module));
|
||||
}
|
||||
|
@ -904,12 +906,12 @@ impl fmt::Display for RelaxedModuleName {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ruff_db::files::{system_path_to_file, File, FilePath};
|
||||
use ruff_db::Db;
|
||||
use ruff_db::files::{File, FilePath, system_path_to_file};
|
||||
use ruff_db::system::{DbWithTestSystem as _, DbWithWritableSystem as _};
|
||||
use ruff_db::testing::{
|
||||
assert_const_function_query_was_not_run, assert_function_query_was_not_run,
|
||||
};
|
||||
use ruff_db::Db;
|
||||
use ruff_python_ast::PythonVersion;
|
||||
|
||||
use crate::db::tests::TestDb;
|
||||
|
@ -1456,7 +1458,7 @@ mod tests {
|
|||
fn symlink() -> anyhow::Result<()> {
|
||||
use anyhow::Context;
|
||||
|
||||
use crate::{program::Program, PythonPlatform};
|
||||
use crate::{PythonPlatform, program::Program};
|
||||
use ruff_db::system::{OsSystem, SystemPath};
|
||||
|
||||
use crate::db::tests::TestDb;
|
||||
|
@ -1553,17 +1555,18 @@ mod tests {
|
|||
|
||||
let foo_module2 = resolve_module(&db, &foo_module_name);
|
||||
|
||||
assert!(!db
|
||||
.take_salsa_events()
|
||||
.iter()
|
||||
.any(|event| { matches!(event.kind, salsa::EventKind::WillExecute { .. }) }));
|
||||
assert!(
|
||||
!db.take_salsa_events()
|
||||
.iter()
|
||||
.any(|event| { matches!(event.kind, salsa::EventKind::WillExecute { .. }) })
|
||||
);
|
||||
|
||||
assert_eq!(Some(foo_module), foo_module2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adding_file_on_which_module_resolution_depends_invalidates_previously_failing_query_that_now_succeeds(
|
||||
) -> anyhow::Result<()> {
|
||||
fn adding_file_on_which_module_resolution_depends_invalidates_previously_failing_query_that_now_succeeds()
|
||||
-> anyhow::Result<()> {
|
||||
let TestCase { mut db, src, .. } = TestCaseBuilder::new().build();
|
||||
let foo_path = src.join("foo.py");
|
||||
|
||||
|
@ -1582,8 +1585,8 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn removing_file_on_which_module_resolution_depends_invalidates_previously_successful_query_that_now_fails(
|
||||
) -> anyhow::Result<()> {
|
||||
fn removing_file_on_which_module_resolution_depends_invalidates_previously_successful_query_that_now_fails()
|
||||
-> anyhow::Result<()> {
|
||||
const SRC: &[FileSpec] = &[("foo.py", "x = 1"), ("foo/__init__.py", "x = 2")];
|
||||
|
||||
let TestCase { mut db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build();
|
||||
|
@ -1968,8 +1971,11 @@ not_a_directory
|
|||
assert!(search_paths.contains(
|
||||
&&SearchPath::first_party(db.system(), SystemPathBuf::from("/src")).unwrap()
|
||||
));
|
||||
assert!(!search_paths
|
||||
.contains(&&SearchPath::editable(db.system(), SystemPathBuf::from("/src")).unwrap()));
|
||||
assert!(
|
||||
!search_paths.contains(
|
||||
&&SearchPath::editable(db.system(), SystemPathBuf::from("/src")).unwrap()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2087,11 +2093,13 @@ not_a_directory
|
|||
// Now lookup the same module using the lowercase `a` and it should resolve to the file in the system site-packages
|
||||
let a_module_name = ModuleName::new_static("a").unwrap();
|
||||
let a_module = resolve_module(&db, &a_module_name).expect("a.py to resolve");
|
||||
assert!(a_module
|
||||
.file()
|
||||
.path(&db)
|
||||
.as_str()
|
||||
.ends_with("src/a/__init__.py"),);
|
||||
assert!(
|
||||
a_module
|
||||
.file()
|
||||
.path(&db)
|
||||
.as_str()
|
||||
.ends_with("src/a/__init__.py"),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ use std::str::FromStr;
|
|||
use ruff_python_ast::PythonVersion;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::Program;
|
||||
use crate::db::Db;
|
||||
use crate::module_name::ModuleName;
|
||||
use crate::Program;
|
||||
|
||||
pub(in crate::module_resolver) fn vendored_typeshed_versions(db: &dyn Db) -> TypeshedVersions {
|
||||
TypeshedVersions::from_str(
|
||||
|
@ -237,7 +237,7 @@ impl FromStr for TypeshedVersions {
|
|||
return Err(TypeshedVersionsParseError {
|
||||
line_number: Some(line_number),
|
||||
reason,
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::Db;
|
||||
use crate::module_resolver::SearchPaths;
|
||||
use crate::python_platform::PythonPlatform;
|
||||
use crate::site_packages::SysPrefixPathOrigin;
|
||||
use crate::Db;
|
||||
|
||||
use anyhow::Context;
|
||||
use ruff_db::system::{SystemPath, SystemPathBuf};
|
||||
|
|
|
@ -58,9 +58,9 @@ impl Default for PythonPlatform {
|
|||
mod schema {
|
||||
use crate::PythonPlatform;
|
||||
use schemars::_serde_json::Value;
|
||||
use schemars::gen::SchemaGenerator;
|
||||
use schemars::schema::{Metadata, Schema, SchemaObject, SubschemaValidation};
|
||||
use schemars::JsonSchema;
|
||||
use schemars::r#gen::SchemaGenerator;
|
||||
use schemars::schema::{Metadata, Schema, SchemaObject, SubschemaValidation};
|
||||
|
||||
impl JsonSchema for PythonPlatform {
|
||||
fn schema_name() -> String {
|
||||
|
|
|
@ -7,13 +7,14 @@ use ruff_index::{IndexSlice, IndexVec};
|
|||
|
||||
use ruff_python_parser::semantic_errors::SemanticSyntaxError;
|
||||
use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
|
||||
use salsa::plumbing::AsId;
|
||||
use salsa::Update;
|
||||
use salsa::plumbing::AsId;
|
||||
|
||||
use crate::Db;
|
||||
use crate::module_name::ModuleName;
|
||||
use crate::node_key::NodeKey;
|
||||
use crate::semantic_index::ast_ids::node_key::ExpressionNodeKey;
|
||||
use crate::semantic_index::ast_ids::AstIds;
|
||||
use crate::semantic_index::ast_ids::node_key::ExpressionNodeKey;
|
||||
use crate::semantic_index::builder::SemanticIndexBuilder;
|
||||
use crate::semantic_index::definition::{Definition, DefinitionNodeKey, Definitions};
|
||||
use crate::semantic_index::expression::Expression;
|
||||
|
@ -23,7 +24,6 @@ use crate::semantic_index::symbol::{
|
|||
SymbolTable,
|
||||
};
|
||||
use crate::semantic_index::use_def::{EagerSnapshotKey, ScopedEagerSnapshotId, UseDefMap};
|
||||
use crate::Db;
|
||||
|
||||
pub mod ast_ids;
|
||||
mod builder;
|
||||
|
@ -542,11 +542,12 @@ impl FusedIterator for ChildrenIter<'_> {}
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ruff_db::files::{system_path_to_file, File};
|
||||
use ruff_db::files::{File, system_path_to_file};
|
||||
use ruff_db::parsed::parsed_module;
|
||||
use ruff_python_ast::{self as ast};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use crate::Db;
|
||||
use crate::db::tests::{TestDb, TestDbBuilder};
|
||||
use crate::semantic_index::ast_ids::{HasScopedUseId, ScopedUseId};
|
||||
use crate::semantic_index::definition::{Definition, DefinitionKind};
|
||||
|
@ -555,7 +556,6 @@ mod tests {
|
|||
};
|
||||
use crate::semantic_index::use_def::UseDefMap;
|
||||
use crate::semantic_index::{global_scope, semantic_index, symbol_table, use_def_map};
|
||||
use crate::Db;
|
||||
|
||||
impl UseDefMap<'_> {
|
||||
fn first_public_binding(&self, symbol: ScopedSymbolId) -> Option<Definition<'_>> {
|
||||
|
@ -1106,7 +1106,10 @@ def func():
|
|||
let global_table = index.symbol_table(FileScopeId::global());
|
||||
|
||||
assert_eq!(names(&global_table), vec!["func"]);
|
||||
let [(func_scope1_id, func_scope_1), (func_scope2_id, func_scope_2)] = index
|
||||
let [
|
||||
(func_scope1_id, func_scope_1),
|
||||
(func_scope2_id, func_scope_2),
|
||||
] = index
|
||||
.child_scopes(FileScopeId::global())
|
||||
.collect::<Vec<_>>()[..]
|
||||
else {
|
||||
|
@ -1345,7 +1348,9 @@ match subject:
|
|||
assert!(global_table.symbol_by_name("Foo").unwrap().is_used());
|
||||
assert_eq!(
|
||||
names(global_table),
|
||||
vec!["subject", "a", "b", "c", "d", "e", "f", "g", "h", "Foo", "i", "j", "k", "l"]
|
||||
vec![
|
||||
"subject", "a", "b", "c", "d", "e", "f", "g", "h", "Foo", "i", "j", "k", "l"
|
||||
]
|
||||
);
|
||||
|
||||
let use_def = use_def_map(&db, global_scope_id);
|
||||
|
|
|
@ -4,10 +4,10 @@ use ruff_index::newtype_index;
|
|||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::ExprRef;
|
||||
|
||||
use crate::Db;
|
||||
use crate::semantic_index::ast_ids::node_key::ExpressionNodeKey;
|
||||
use crate::semantic_index::semantic_index;
|
||||
use crate::semantic_index::symbol::ScopeId;
|
||||
use crate::Db;
|
||||
|
||||
/// AST ids for a single scope.
|
||||
///
|
||||
|
|
|
@ -6,10 +6,10 @@ use rustc_hash::{FxHashMap, FxHashSet};
|
|||
|
||||
use ruff_db::files::File;
|
||||
use ruff_db::parsed::ParsedModule;
|
||||
use ruff_db::source::{source_text, SourceText};
|
||||
use ruff_db::source::{SourceText, source_text};
|
||||
use ruff_index::IndexVec;
|
||||
use ruff_python_ast::name::Name;
|
||||
use ruff_python_ast::visitor::{walk_expr, walk_pattern, walk_stmt, Visitor};
|
||||
use ruff_python_ast::visitor::{Visitor, walk_expr, walk_pattern, walk_stmt};
|
||||
use ruff_python_ast::{self as ast, PySourceType, PythonVersion};
|
||||
use ruff_python_parser::semantic_errors::{
|
||||
SemanticSyntaxChecker, SemanticSyntaxContext, SemanticSyntaxError, SemanticSyntaxErrorKind,
|
||||
|
@ -20,8 +20,9 @@ use crate::ast_node_ref::AstNodeRef;
|
|||
use crate::module_name::ModuleName;
|
||||
use crate::module_resolver::resolve_module;
|
||||
use crate::node_key::NodeKey;
|
||||
use crate::semantic_index::ast_ids::node_key::ExpressionNodeKey;
|
||||
use crate::semantic_index::SemanticIndex;
|
||||
use crate::semantic_index::ast_ids::AstIdsBuilder;
|
||||
use crate::semantic_index::ast_ids::node_key::ExpressionNodeKey;
|
||||
use crate::semantic_index::definition::{
|
||||
AnnotatedAssignmentDefinitionKind, AnnotatedAssignmentDefinitionNodeRef,
|
||||
AssignmentDefinitionKind, AssignmentDefinitionNodeRef, ComprehensionDefinitionKind,
|
||||
|
@ -47,7 +48,6 @@ use crate::semantic_index::use_def::{
|
|||
use crate::semantic_index::visibility_constraints::{
|
||||
ScopedVisibilityConstraintId, VisibilityConstraintsBuilder,
|
||||
};
|
||||
use crate::semantic_index::SemanticIndex;
|
||||
use crate::unpack::{Unpack, UnpackKind, UnpackPosition, UnpackValue};
|
||||
use crate::{Db, Program};
|
||||
|
||||
|
@ -438,8 +438,7 @@ impl<'db> SemanticIndexBuilder<'db> {
|
|||
let (definition, num_definitions) =
|
||||
self.push_additional_definition(symbol, definition_node);
|
||||
debug_assert_eq!(
|
||||
num_definitions,
|
||||
1,
|
||||
num_definitions, 1,
|
||||
"Attempted to create multiple `Definition`s associated with AST node {definition_node:?}"
|
||||
);
|
||||
definition
|
||||
|
@ -2489,7 +2488,10 @@ impl SemanticSyntaxContext for SemanticIndexBuilder<'_> {
|
|||
NodeWithScopeKind::DictComprehension(node) => &node.generators,
|
||||
_ => continue,
|
||||
};
|
||||
if generators.iter().all(|gen| !gen.is_async) {
|
||||
if generators
|
||||
.iter()
|
||||
.all(|comprehension| !comprehension.is_async)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ use ruff_db::parsed::ParsedModule;
|
|||
use ruff_python_ast as ast;
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use crate::Db;
|
||||
use crate::ast_node_ref::AstNodeRef;
|
||||
use crate::node_key::NodeKey;
|
||||
use crate::semantic_index::symbol::{FileScopeId, ScopeId, ScopedSymbolId};
|
||||
use crate::unpack::{Unpack, UnpackPosition};
|
||||
use crate::Db;
|
||||
|
||||
/// A definition of a symbol.
|
||||
///
|
||||
|
@ -308,7 +308,7 @@ impl<'db> DefinitionNodeRef<'db> {
|
|||
alias_index,
|
||||
is_reexported,
|
||||
}) => DefinitionKind::Import(ImportDefinitionKind {
|
||||
node: AstNodeRef::new(parsed, node),
|
||||
node: unsafe { AstNodeRef::new(parsed, node) },
|
||||
alias_index,
|
||||
is_reexported,
|
||||
}),
|
||||
|
@ -318,28 +318,28 @@ impl<'db> DefinitionNodeRef<'db> {
|
|||
alias_index,
|
||||
is_reexported,
|
||||
}) => DefinitionKind::ImportFrom(ImportFromDefinitionKind {
|
||||
node: AstNodeRef::new(parsed, node),
|
||||
node: unsafe { AstNodeRef::new(parsed, node) },
|
||||
alias_index,
|
||||
is_reexported,
|
||||
}),
|
||||
DefinitionNodeRef::ImportStar(star_import) => {
|
||||
let StarImportDefinitionNodeRef { node, symbol_id } = star_import;
|
||||
DefinitionKind::StarImport(StarImportDefinitionKind {
|
||||
node: AstNodeRef::new(parsed, node),
|
||||
node: unsafe { AstNodeRef::new(parsed, node) },
|
||||
symbol_id,
|
||||
})
|
||||
}
|
||||
DefinitionNodeRef::Function(function) => {
|
||||
DefinitionKind::Function(AstNodeRef::new(parsed, function))
|
||||
DefinitionKind::Function(unsafe { AstNodeRef::new(parsed, function) })
|
||||
}
|
||||
DefinitionNodeRef::Class(class) => {
|
||||
DefinitionKind::Class(AstNodeRef::new(parsed, class))
|
||||
DefinitionKind::Class(unsafe { AstNodeRef::new(parsed, class) })
|
||||
}
|
||||
DefinitionNodeRef::TypeAlias(type_alias) => {
|
||||
DefinitionKind::TypeAlias(AstNodeRef::new(parsed, type_alias))
|
||||
DefinitionKind::TypeAlias(unsafe { AstNodeRef::new(parsed, type_alias) })
|
||||
}
|
||||
DefinitionNodeRef::NamedExpression(named) => {
|
||||
DefinitionKind::NamedExpression(AstNodeRef::new(parsed, named))
|
||||
DefinitionKind::NamedExpression(unsafe { AstNodeRef::new(parsed, named) })
|
||||
}
|
||||
DefinitionNodeRef::Assignment(AssignmentDefinitionNodeRef {
|
||||
unpack,
|
||||
|
@ -347,8 +347,8 @@ impl<'db> DefinitionNodeRef<'db> {
|
|||
target,
|
||||
}) => DefinitionKind::Assignment(AssignmentDefinitionKind {
|
||||
target_kind: TargetKind::from(unpack),
|
||||
value: AstNodeRef::new(parsed.clone(), value),
|
||||
target: AstNodeRef::new(parsed, target),
|
||||
value: unsafe { AstNodeRef::new(parsed.clone(), value) },
|
||||
target: unsafe { AstNodeRef::new(parsed, target) },
|
||||
}),
|
||||
DefinitionNodeRef::AnnotatedAssignment(AnnotatedAssignmentDefinitionNodeRef {
|
||||
node: _,
|
||||
|
@ -356,12 +356,14 @@ impl<'db> DefinitionNodeRef<'db> {
|
|||
value,
|
||||
target,
|
||||
}) => DefinitionKind::AnnotatedAssignment(AnnotatedAssignmentDefinitionKind {
|
||||
target: AstNodeRef::new(parsed.clone(), target),
|
||||
annotation: AstNodeRef::new(parsed.clone(), annotation),
|
||||
value: value.map(|v| AstNodeRef::new(parsed, v)),
|
||||
target: unsafe { AstNodeRef::new(parsed.clone(), target) },
|
||||
annotation: unsafe { AstNodeRef::new(parsed.clone(), annotation) },
|
||||
value: value.map(|v| unsafe { AstNodeRef::new(parsed, v) }),
|
||||
}),
|
||||
DefinitionNodeRef::AugmentedAssignment(augmented_assignment) => {
|
||||
DefinitionKind::AugmentedAssignment(AstNodeRef::new(parsed, augmented_assignment))
|
||||
DefinitionKind::AugmentedAssignment(unsafe {
|
||||
AstNodeRef::new(parsed, augmented_assignment)
|
||||
})
|
||||
}
|
||||
DefinitionNodeRef::For(ForStmtDefinitionNodeRef {
|
||||
unpack,
|
||||
|
@ -370,8 +372,8 @@ impl<'db> DefinitionNodeRef<'db> {
|
|||
is_async,
|
||||
}) => DefinitionKind::For(ForStmtDefinitionKind {
|
||||
target_kind: TargetKind::from(unpack),
|
||||
iterable: AstNodeRef::new(parsed.clone(), iterable),
|
||||
target: AstNodeRef::new(parsed, target),
|
||||
iterable: unsafe { AstNodeRef::new(parsed.clone(), iterable) },
|
||||
target: unsafe { AstNodeRef::new(parsed, target) },
|
||||
is_async,
|
||||
}),
|
||||
DefinitionNodeRef::Comprehension(ComprehensionDefinitionNodeRef {
|
||||
|
@ -382,19 +384,23 @@ impl<'db> DefinitionNodeRef<'db> {
|
|||
is_async,
|
||||
}) => DefinitionKind::Comprehension(ComprehensionDefinitionKind {
|
||||
target_kind: TargetKind::from(unpack),
|
||||
iterable: AstNodeRef::new(parsed.clone(), iterable),
|
||||
target: AstNodeRef::new(parsed, target),
|
||||
iterable: unsafe { AstNodeRef::new(parsed.clone(), iterable) },
|
||||
target: unsafe { AstNodeRef::new(parsed, target) },
|
||||
first,
|
||||
is_async,
|
||||
}),
|
||||
DefinitionNodeRef::VariadicPositionalParameter(parameter) => {
|
||||
DefinitionKind::VariadicPositionalParameter(AstNodeRef::new(parsed, parameter))
|
||||
DefinitionKind::VariadicPositionalParameter(unsafe {
|
||||
AstNodeRef::new(parsed, parameter)
|
||||
})
|
||||
}
|
||||
DefinitionNodeRef::VariadicKeywordParameter(parameter) => {
|
||||
DefinitionKind::VariadicKeywordParameter(AstNodeRef::new(parsed, parameter))
|
||||
DefinitionKind::VariadicKeywordParameter(unsafe {
|
||||
AstNodeRef::new(parsed, parameter)
|
||||
})
|
||||
}
|
||||
DefinitionNodeRef::Parameter(parameter) => {
|
||||
DefinitionKind::Parameter(AstNodeRef::new(parsed, parameter))
|
||||
DefinitionKind::Parameter(unsafe { AstNodeRef::new(parsed, parameter) })
|
||||
}
|
||||
DefinitionNodeRef::WithItem(WithItemDefinitionNodeRef {
|
||||
unpack,
|
||||
|
@ -403,8 +409,8 @@ impl<'db> DefinitionNodeRef<'db> {
|
|||
is_async,
|
||||
}) => DefinitionKind::WithItem(WithItemDefinitionKind {
|
||||
target_kind: TargetKind::from(unpack),
|
||||
context_expr: AstNodeRef::new(parsed.clone(), context_expr),
|
||||
target: AstNodeRef::new(parsed, target),
|
||||
context_expr: unsafe { AstNodeRef::new(parsed.clone(), context_expr) },
|
||||
target: unsafe { AstNodeRef::new(parsed, target) },
|
||||
is_async,
|
||||
}),
|
||||
DefinitionNodeRef::MatchPattern(MatchPatternDefinitionNodeRef {
|
||||
|
@ -412,25 +418,25 @@ impl<'db> DefinitionNodeRef<'db> {
|
|||
identifier,
|
||||
index,
|
||||
}) => DefinitionKind::MatchPattern(MatchPatternDefinitionKind {
|
||||
pattern: AstNodeRef::new(parsed.clone(), pattern),
|
||||
identifier: AstNodeRef::new(parsed, identifier),
|
||||
pattern: unsafe { AstNodeRef::new(parsed.clone(), pattern) },
|
||||
identifier: unsafe { AstNodeRef::new(parsed, identifier) },
|
||||
index,
|
||||
}),
|
||||
DefinitionNodeRef::ExceptHandler(ExceptHandlerDefinitionNodeRef {
|
||||
handler,
|
||||
is_star,
|
||||
}) => DefinitionKind::ExceptHandler(ExceptHandlerDefinitionKind {
|
||||
handler: AstNodeRef::new(parsed, handler),
|
||||
handler: unsafe { AstNodeRef::new(parsed, handler) },
|
||||
is_star,
|
||||
}),
|
||||
DefinitionNodeRef::TypeVar(node) => {
|
||||
DefinitionKind::TypeVar(AstNodeRef::new(parsed, node))
|
||||
DefinitionKind::TypeVar(unsafe { AstNodeRef::new(parsed, node) })
|
||||
}
|
||||
DefinitionNodeRef::ParamSpec(node) => {
|
||||
DefinitionKind::ParamSpec(AstNodeRef::new(parsed, node))
|
||||
DefinitionKind::ParamSpec(unsafe { AstNodeRef::new(parsed, node) })
|
||||
}
|
||||
DefinitionNodeRef::TypeVarTuple(node) => {
|
||||
DefinitionKind::TypeVarTuple(AstNodeRef::new(parsed, node))
|
||||
DefinitionKind::TypeVarTuple(unsafe { AstNodeRef::new(parsed, node) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
//! static visibility of a binding, and the reachability of a statement.
|
||||
|
||||
use ruff_db::files::File;
|
||||
use ruff_index::{newtype_index, IndexVec};
|
||||
use ruff_index::{IndexVec, newtype_index};
|
||||
use ruff_python_ast::Singleton;
|
||||
|
||||
use crate::db::Db;
|
||||
|
|
|
@ -24,11 +24,11 @@ use ruff_db::{files::File, parsed::parsed_module};
|
|||
use ruff_python_ast::{
|
||||
self as ast,
|
||||
name::Name,
|
||||
visitor::{walk_expr, walk_pattern, walk_stmt, Visitor},
|
||||
visitor::{Visitor, walk_expr, walk_pattern, walk_stmt},
|
||||
};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::{module_name::ModuleName, resolve_module, Db};
|
||||
use crate::{Db, module_name::ModuleName, resolve_module};
|
||||
|
||||
fn exports_cycle_recover(
|
||||
_db: &dyn Db,
|
||||
|
|
|
@ -5,16 +5,16 @@ use bitflags::bitflags;
|
|||
use hashbrown::hash_map::RawEntryMut;
|
||||
use ruff_db::files::File;
|
||||
use ruff_db::parsed::ParsedModule;
|
||||
use ruff_index::{newtype_index, IndexVec};
|
||||
use ruff_index::{IndexVec, newtype_index};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::name::Name;
|
||||
use rustc_hash::FxHasher;
|
||||
|
||||
use crate::Db;
|
||||
use crate::ast_node_ref::AstNodeRef;
|
||||
use crate::node_key::NodeKey;
|
||||
use crate::semantic_index::visibility_constraints::ScopedVisibilityConstraintId;
|
||||
use crate::semantic_index::{semantic_index, SemanticIndex, SymbolMap};
|
||||
use crate::Db;
|
||||
use crate::semantic_index::{SemanticIndex, SymbolMap, semantic_index};
|
||||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub struct Symbol {
|
||||
|
@ -426,40 +426,42 @@ impl NodeWithScopeRef<'_> {
|
|||
/// The node wrapped by `self` must be a child of `module`.
|
||||
#[expect(unsafe_code)]
|
||||
pub(super) unsafe fn to_kind(self, module: ParsedModule) -> NodeWithScopeKind {
|
||||
match self {
|
||||
NodeWithScopeRef::Module => NodeWithScopeKind::Module,
|
||||
NodeWithScopeRef::Class(class) => {
|
||||
NodeWithScopeKind::Class(AstNodeRef::new(module, class))
|
||||
}
|
||||
NodeWithScopeRef::Function(function) => {
|
||||
NodeWithScopeKind::Function(AstNodeRef::new(module, function))
|
||||
}
|
||||
NodeWithScopeRef::TypeAlias(type_alias) => {
|
||||
NodeWithScopeKind::TypeAlias(AstNodeRef::new(module, type_alias))
|
||||
}
|
||||
NodeWithScopeRef::TypeAliasTypeParameters(type_alias) => {
|
||||
NodeWithScopeKind::TypeAliasTypeParameters(AstNodeRef::new(module, type_alias))
|
||||
}
|
||||
NodeWithScopeRef::Lambda(lambda) => {
|
||||
NodeWithScopeKind::Lambda(AstNodeRef::new(module, lambda))
|
||||
}
|
||||
NodeWithScopeRef::FunctionTypeParameters(function) => {
|
||||
NodeWithScopeKind::FunctionTypeParameters(AstNodeRef::new(module, function))
|
||||
}
|
||||
NodeWithScopeRef::ClassTypeParameters(class) => {
|
||||
NodeWithScopeKind::ClassTypeParameters(AstNodeRef::new(module, class))
|
||||
}
|
||||
NodeWithScopeRef::ListComprehension(comprehension) => {
|
||||
NodeWithScopeKind::ListComprehension(AstNodeRef::new(module, comprehension))
|
||||
}
|
||||
NodeWithScopeRef::SetComprehension(comprehension) => {
|
||||
NodeWithScopeKind::SetComprehension(AstNodeRef::new(module, comprehension))
|
||||
}
|
||||
NodeWithScopeRef::DictComprehension(comprehension) => {
|
||||
NodeWithScopeKind::DictComprehension(AstNodeRef::new(module, comprehension))
|
||||
}
|
||||
NodeWithScopeRef::GeneratorExpression(generator) => {
|
||||
NodeWithScopeKind::GeneratorExpression(AstNodeRef::new(module, generator))
|
||||
unsafe {
|
||||
match self {
|
||||
NodeWithScopeRef::Module => NodeWithScopeKind::Module,
|
||||
NodeWithScopeRef::Class(class) => {
|
||||
NodeWithScopeKind::Class(AstNodeRef::new(module, class))
|
||||
}
|
||||
NodeWithScopeRef::Function(function) => {
|
||||
NodeWithScopeKind::Function(AstNodeRef::new(module, function))
|
||||
}
|
||||
NodeWithScopeRef::TypeAlias(type_alias) => {
|
||||
NodeWithScopeKind::TypeAlias(AstNodeRef::new(module, type_alias))
|
||||
}
|
||||
NodeWithScopeRef::TypeAliasTypeParameters(type_alias) => {
|
||||
NodeWithScopeKind::TypeAliasTypeParameters(AstNodeRef::new(module, type_alias))
|
||||
}
|
||||
NodeWithScopeRef::Lambda(lambda) => {
|
||||
NodeWithScopeKind::Lambda(AstNodeRef::new(module, lambda))
|
||||
}
|
||||
NodeWithScopeRef::FunctionTypeParameters(function) => {
|
||||
NodeWithScopeKind::FunctionTypeParameters(AstNodeRef::new(module, function))
|
||||
}
|
||||
NodeWithScopeRef::ClassTypeParameters(class) => {
|
||||
NodeWithScopeKind::ClassTypeParameters(AstNodeRef::new(module, class))
|
||||
}
|
||||
NodeWithScopeRef::ListComprehension(comprehension) => {
|
||||
NodeWithScopeKind::ListComprehension(AstNodeRef::new(module, comprehension))
|
||||
}
|
||||
NodeWithScopeRef::SetComprehension(comprehension) => {
|
||||
NodeWithScopeKind::SetComprehension(AstNodeRef::new(module, comprehension))
|
||||
}
|
||||
NodeWithScopeRef::DictComprehension(comprehension) => {
|
||||
NodeWithScopeKind::DictComprehension(AstNodeRef::new(module, comprehension))
|
||||
}
|
||||
NodeWithScopeRef::GeneratorExpression(generator) => {
|
||||
NodeWithScopeKind::GeneratorExpression(AstNodeRef::new(module, generator))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@
|
|||
//! [`SemanticIndexBuilder`](crate::semantic_index::builder::SemanticIndexBuilder), e.g. where it
|
||||
//! visits a `StmtIf` node.
|
||||
|
||||
use ruff_index::{newtype_index, IndexVec};
|
||||
use ruff_index::{IndexVec, newtype_index};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use self::symbol_state::{
|
||||
|
@ -264,6 +264,7 @@ use self::symbol_state::{
|
|||
ScopedDefinitionId, SymbolBindings, SymbolDeclarations, SymbolState,
|
||||
};
|
||||
use crate::node_key::NodeKey;
|
||||
use crate::semantic_index::EagerSnapshotResult;
|
||||
use crate::semantic_index::ast_ids::ScopedUseId;
|
||||
use crate::semantic_index::definition::Definition;
|
||||
use crate::semantic_index::narrowing_constraints::{
|
||||
|
@ -276,8 +277,7 @@ use crate::semantic_index::symbol::{FileScopeId, ScopeKind, ScopedSymbolId};
|
|||
use crate::semantic_index::visibility_constraints::{
|
||||
ScopedVisibilityConstraintId, VisibilityConstraints, VisibilityConstraintsBuilder,
|
||||
};
|
||||
use crate::semantic_index::EagerSnapshotResult;
|
||||
use crate::types::{infer_narrowing_constraint, IntersectionBuilder, Truthiness, Type};
|
||||
use crate::types::{IntersectionBuilder, Truthiness, Type, infer_narrowing_constraint};
|
||||
|
||||
mod symbol_state;
|
||||
|
||||
|
@ -604,15 +604,14 @@ impl<'db> ConstraintsIterator<'_, 'db> {
|
|||
if constraint_tys.is_empty() {
|
||||
base_ty
|
||||
} else {
|
||||
let intersection_ty = constraint_tys
|
||||
constraint_tys
|
||||
.into_iter()
|
||||
.rev()
|
||||
.fold(
|
||||
IntersectionBuilder::new(db).add_positive(base_ty),
|
||||
IntersectionBuilder::add_positive,
|
||||
)
|
||||
.build();
|
||||
intersection_ty
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
use itertools::{EitherOrBoth, Itertools};
|
||||
use ruff_index::newtype_index;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
|
||||
use crate::semantic_index::narrowing_constraints::{
|
||||
NarrowingConstraintsBuilder, ScopedNarrowingConstraint, ScopedNarrowingConstraintPredicate,
|
||||
|
|
|
@ -178,15 +178,15 @@ use std::cmp::Ordering;
|
|||
use ruff_index::{Idx, IndexVec};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::Db;
|
||||
use crate::dunder_all::dunder_all_names;
|
||||
use crate::semantic_index::expression::Expression;
|
||||
use crate::semantic_index::predicate::{
|
||||
PatternPredicate, PatternPredicateKind, Predicate, PredicateNode, Predicates, ScopedPredicateId,
|
||||
};
|
||||
use crate::semantic_index::symbol_table;
|
||||
use crate::symbol::{imported_symbol, RequiresExplicitReExport};
|
||||
use crate::types::{infer_expression_type, Truthiness, Type};
|
||||
use crate::Db;
|
||||
use crate::symbol::{RequiresExplicitReExport, imported_symbol};
|
||||
use crate::types::{Truthiness, Type, infer_expression_type};
|
||||
|
||||
/// A ternary formula that defines under what conditions a binding is visible. (A ternary formula
|
||||
/// is just like a boolean formula, but with `Ambiguous` as a third potential result. See the
|
||||
|
|
|
@ -4,12 +4,12 @@ use ruff_python_ast as ast;
|
|||
use ruff_python_ast::{Expr, ExprRef};
|
||||
use ruff_source_file::LineIndex;
|
||||
|
||||
use crate::Db;
|
||||
use crate::module_name::ModuleName;
|
||||
use crate::module_resolver::{resolve_module, Module};
|
||||
use crate::module_resolver::{Module, resolve_module};
|
||||
use crate::semantic_index::ast_ids::HasScopedExpressionId;
|
||||
use crate::semantic_index::semantic_index;
|
||||
use crate::types::{binding_type, infer_scope_types, Type};
|
||||
use crate::Db;
|
||||
use crate::types::{Type, binding_type, infer_scope_types};
|
||||
|
||||
pub struct SemanticModel<'db> {
|
||||
db: &'db dyn Db,
|
||||
|
|
|
@ -238,7 +238,9 @@ System site-packages will not be used for module resolution.",
|
|||
}
|
||||
}
|
||||
|
||||
tracing::debug!("Resolved site-packages directories for this virtual environment are: {site_packages_directories:?}");
|
||||
tracing::debug!(
|
||||
"Resolved site-packages directories for this virtual environment are: {site_packages_directories:?}"
|
||||
);
|
||||
Ok(site_packages_directories)
|
||||
}
|
||||
}
|
||||
|
@ -275,7 +277,9 @@ impl SystemEnvironment {
|
|||
root_path, None, system,
|
||||
)?];
|
||||
|
||||
tracing::debug!("Resolved site-packages directories for this environment are: {site_packages_directories:?}");
|
||||
tracing::debug!(
|
||||
"Resolved site-packages directories for this environment are: {site_packages_directories:?}"
|
||||
);
|
||||
Ok(site_packages_directories)
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +294,9 @@ pub(crate) enum SitePackagesDiscoveryError {
|
|||
NoPyvenvCfgFile(SysPrefixPathOrigin, #[source] io::Error),
|
||||
#[error("Failed to parse the pyvenv.cfg file at {0} because {1}")]
|
||||
PyvenvCfgParseError(SystemPathBuf, PyvenvCfgParseErrorKind),
|
||||
#[error("Failed to search the `lib` directory of the Python installation at {1} for `site-packages`")]
|
||||
#[error(
|
||||
"Failed to search the `lib` directory of the Python installation at {1} for `site-packages`"
|
||||
)]
|
||||
CouldNotReadLibDirectory(#[source] io::Error, SysPrefixPath),
|
||||
#[error("Could not find the `site-packages` directory for the Python installation at {0}")]
|
||||
NoSitePackagesDirFound(SysPrefixPath),
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use crate::lint::{GetLintError, Level, LintMetadata, LintRegistry, LintStatus};
|
||||
use crate::types::TypeCheckDiagnostics;
|
||||
use crate::{declare_lint, lint::LintId, Db};
|
||||
use crate::{Db, declare_lint, lint::LintId};
|
||||
use ruff_db::diagnostic::{Annotation, Diagnostic, DiagnosticId, Span};
|
||||
use ruff_db::{files::File, parsed::parsed_module, source::source_text};
|
||||
use ruff_python_parser::TokenKind;
|
||||
use ruff_python_trivia::Cursor;
|
||||
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fmt::Formatter;
|
||||
|
|
|
@ -4,15 +4,15 @@ use crate::dunder_all::dunder_all_names;
|
|||
use crate::module_resolver::file_to_module;
|
||||
use crate::semantic_index::definition::Definition;
|
||||
use crate::semantic_index::symbol::{ScopeId, ScopedSymbolId};
|
||||
use crate::semantic_index::{global_scope, use_def_map, DeclarationWithConstraint};
|
||||
use crate::semantic_index::{
|
||||
symbol_table, BindingWithConstraints, BindingWithConstraintsIterator, DeclarationsIterator,
|
||||
BindingWithConstraints, BindingWithConstraintsIterator, DeclarationsIterator, symbol_table,
|
||||
};
|
||||
use crate::semantic_index::{DeclarationWithConstraint, global_scope, use_def_map};
|
||||
use crate::types::{
|
||||
binding_type, declaration_type, todo_type, KnownClass, Truthiness, Type, TypeAndQualifiers,
|
||||
TypeQualifiers, UnionBuilder, UnionType,
|
||||
KnownClass, Truthiness, Type, TypeAndQualifiers, TypeQualifiers, UnionBuilder, UnionType,
|
||||
binding_type, declaration_type, todo_type,
|
||||
};
|
||||
use crate::{resolve_module, Db, KnownModule, Program};
|
||||
use crate::{Db, KnownModule, Program, resolve_module};
|
||||
|
||||
pub(crate) use implicit_globals::{
|
||||
module_type_implicit_global_declaration, module_type_implicit_global_symbol,
|
||||
|
@ -824,7 +824,9 @@ fn symbol_from_bindings_impl<'db>(
|
|||
if let Some(first) = types.next() {
|
||||
let boundness = match unbound_visibility() {
|
||||
Truthiness::AlwaysTrue => {
|
||||
unreachable!("If we have at least one binding, the scope-start should not be definitely visible")
|
||||
unreachable!(
|
||||
"If we have at least one binding, the scope-start should not be definitely visible"
|
||||
)
|
||||
}
|
||||
Truthiness::AlwaysFalse => Boundness::Bound,
|
||||
Truthiness::Ambiguous => Boundness::PossiblyUnbound,
|
||||
|
@ -915,7 +917,9 @@ fn symbol_from_declarations_impl<'db>(
|
|||
if conflicting.is_empty() {
|
||||
let boundness = match undeclared_visibility {
|
||||
Truthiness::AlwaysTrue => {
|
||||
unreachable!("If we have at least one declaration, the scope-start should not be definitely visible")
|
||||
unreachable!(
|
||||
"If we have at least one declaration, the scope-start should not be definitely visible"
|
||||
)
|
||||
}
|
||||
Truthiness::AlwaysFalse => Boundness::Bound,
|
||||
Truthiness::Ambiguous => Boundness::PossiblyUnbound,
|
||||
|
@ -965,7 +969,7 @@ mod implicit_globals {
|
|||
use crate::symbol::SymbolAndQualifiers;
|
||||
use crate::types::{KnownClass, Type};
|
||||
|
||||
use super::{symbol_from_declarations, Symbol, SymbolFromDeclarationsResult};
|
||||
use super::{Symbol, SymbolFromDeclarationsResult, symbol_from_declarations};
|
||||
|
||||
pub(crate) fn module_type_implicit_global_declaration<'db>(
|
||||
db: &'db dyn Db,
|
||||
|
|
|
@ -12,7 +12,7 @@ use diagnostic::{
|
|||
UNAVAILABLE_IMPLICIT_SUPER_ARGUMENTS,
|
||||
};
|
||||
use ruff_db::diagnostic::{
|
||||
create_semantic_syntax_diagnostic, Annotation, Severity, Span, SubDiagnostic,
|
||||
Annotation, Severity, Span, SubDiagnostic, create_semantic_syntax_diagnostic,
|
||||
};
|
||||
use ruff_db::files::{File, FileRange};
|
||||
use ruff_python_ast::name::Name;
|
||||
|
@ -21,8 +21,8 @@ use ruff_text_size::{Ranged, TextRange};
|
|||
use type_ordering::union_or_intersection_elements_ordering;
|
||||
|
||||
pub(crate) use self::builder::{IntersectionBuilder, UnionBuilder};
|
||||
pub(crate) use self::diagnostic::register_lints;
|
||||
pub use self::diagnostic::TypeCheckDiagnostics;
|
||||
pub(crate) use self::diagnostic::register_lints;
|
||||
pub(crate) use self::display::TypeArrayDisplay;
|
||||
pub(crate) use self::infer::{
|
||||
infer_deferred_types, infer_definition_types, infer_expression_type, infer_expression_types,
|
||||
|
@ -32,14 +32,14 @@ pub(crate) use self::narrow::ClassInfoConstraintFunction;
|
|||
pub(crate) use self::signatures::{CallableSignature, Signature, Signatures};
|
||||
pub(crate) use self::subclass_of::{SubclassOfInner, SubclassOfType};
|
||||
use crate::module_name::ModuleName;
|
||||
use crate::module_resolver::{file_to_module, resolve_module, KnownModule};
|
||||
use crate::module_resolver::{KnownModule, file_to_module, resolve_module};
|
||||
use crate::semantic_index::ast_ids::{HasScopedExpressionId, HasScopedUseId};
|
||||
use crate::semantic_index::definition::Definition;
|
||||
use crate::semantic_index::symbol::ScopeId;
|
||||
use crate::semantic_index::{imported_modules, semantic_index};
|
||||
use crate::suppression::check_suppressions;
|
||||
use crate::symbol::{
|
||||
imported_symbol, symbol_from_bindings, Boundness, Symbol, SymbolAndQualifiers,
|
||||
Boundness, Symbol, SymbolAndQualifiers, imported_symbol, symbol_from_bindings,
|
||||
};
|
||||
use crate::types::call::{Bindings, CallArgumentTypes, CallableBinding};
|
||||
pub(crate) use crate::types::class_base::ClassBase;
|
||||
|
@ -960,11 +960,7 @@ impl<'db> Type<'db> {
|
|||
|
||||
#[must_use]
|
||||
pub fn negate_if(&self, db: &'db dyn Db, yes: bool) -> Type<'db> {
|
||||
if yes {
|
||||
self.negate(db)
|
||||
} else {
|
||||
*self
|
||||
}
|
||||
if yes { self.negate(db) } else { *self }
|
||||
}
|
||||
|
||||
/// Return a "normalized" version of `self` that ensures that equivalent types have the same Salsa ID.
|
||||
|
@ -5614,12 +5610,12 @@ impl<'db> InvalidTypeExpression<'db> {
|
|||
"`{ty}` requires at least two arguments when used in a type expression",
|
||||
ty = ty.display(self.db)
|
||||
),
|
||||
InvalidTypeExpression::Protocol => f.write_str(
|
||||
"`typing.Protocol` is not allowed in type expressions"
|
||||
),
|
||||
InvalidTypeExpression::Generic => f.write_str(
|
||||
"`typing.Generic` is not allowed in type expressions"
|
||||
),
|
||||
InvalidTypeExpression::Protocol => {
|
||||
f.write_str("`typing.Protocol` is not allowed in type expressions")
|
||||
}
|
||||
InvalidTypeExpression::Generic => {
|
||||
f.write_str("`typing.Generic` is not allowed in type expressions")
|
||||
}
|
||||
InvalidTypeExpression::TypeQualifier(qualifier) => write!(
|
||||
f,
|
||||
"Type qualifier `{q}` is not allowed in type expressions (only in annotation expressions)",
|
||||
|
@ -6491,11 +6487,7 @@ impl Truthiness {
|
|||
}
|
||||
|
||||
pub(crate) const fn negate_if(self, condition: bool) -> Self {
|
||||
if condition {
|
||||
self.negate()
|
||||
} else {
|
||||
self
|
||||
}
|
||||
if condition { self.negate() } else { self }
|
||||
}
|
||||
|
||||
pub(crate) fn and(self, other: Self) -> Self {
|
||||
|
@ -8336,7 +8328,7 @@ impl<'db> BoundSuperType<'db> {
|
|||
return owner
|
||||
.into_type()
|
||||
.find_name_in_mro_with_policy(db, name, policy)
|
||||
.expect("Calling `find_name_in_mro` on dynamic type should return `Some`")
|
||||
.expect("Calling `find_name_in_mro` on dynamic type should return `Some`");
|
||||
}
|
||||
SuperOwnerKind::Class(class) => class,
|
||||
SuperOwnerKind::Instance(instance) => instance.class,
|
||||
|
@ -8373,7 +8365,7 @@ static_assertions::assert_eq_size!(Type, [u8; 16]);
|
|||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use super::*;
|
||||
use crate::db::tests::{setup_db, TestDbBuilder};
|
||||
use crate::db::tests::{TestDbBuilder, setup_db};
|
||||
use crate::symbol::{
|
||||
global_symbol, known_module_symbol, typing_extensions_symbol, typing_symbol,
|
||||
};
|
||||
|
@ -8510,16 +8502,20 @@ pub(crate) mod tests {
|
|||
assert!(UnionType::from_elements(&db, vec![todo1, todo2]).is_todo());
|
||||
|
||||
// And similar for intersection types:
|
||||
assert!(IntersectionBuilder::new(&db)
|
||||
.add_positive(todo1)
|
||||
.add_positive(todo2)
|
||||
.build()
|
||||
.is_todo());
|
||||
assert!(IntersectionBuilder::new(&db)
|
||||
.add_positive(todo1)
|
||||
.add_negative(todo2)
|
||||
.build()
|
||||
.is_todo());
|
||||
assert!(
|
||||
IntersectionBuilder::new(&db)
|
||||
.add_positive(todo1)
|
||||
.add_positive(todo2)
|
||||
.build()
|
||||
.is_todo()
|
||||
);
|
||||
assert!(
|
||||
IntersectionBuilder::new(&db)
|
||||
.add_positive(todo1)
|
||||
.add_negative(todo2)
|
||||
.build()
|
||||
.is_todo()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -8575,7 +8571,11 @@ pub(crate) mod tests {
|
|||
.definition(&db);
|
||||
|
||||
assert_eq!(
|
||||
KnownFunction::try_from_definition_and_name(&db, function_definition, function_name),
|
||||
KnownFunction::try_from_definition_and_name(
|
||||
&db,
|
||||
function_definition,
|
||||
function_name
|
||||
),
|
||||
Some(function),
|
||||
"The strum `EnumString` implementation appears to be incorrect for `{function_name}`"
|
||||
);
|
||||
|
|
|
@ -20,9 +20,9 @@ use crate::types::diagnostic::{
|
|||
use crate::types::generics::{Specialization, SpecializationBuilder, SpecializationError};
|
||||
use crate::types::signatures::{Parameter, ParameterForm};
|
||||
use crate::types::{
|
||||
todo_type, BoundMethodType, DataclassParams, DataclassTransformerParams, FunctionDecorators,
|
||||
FunctionType, KnownClass, KnownFunction, KnownInstanceType, MethodWrapperKind,
|
||||
PropertyInstanceType, TupleType, UnionType, WrapperDescriptorKind,
|
||||
BoundMethodType, DataclassParams, DataclassTransformerParams, FunctionDecorators, FunctionType,
|
||||
KnownClass, KnownFunction, KnownInstanceType, MethodWrapperKind, PropertyInstanceType,
|
||||
TupleType, UnionType, WrapperDescriptorKind, todo_type,
|
||||
};
|
||||
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, SubDiagnostic};
|
||||
use ruff_python_ast as ast;
|
||||
|
@ -305,24 +305,33 @@ impl<'db> Bindings<'db> {
|
|||
|
||||
Type::WrapperDescriptor(WrapperDescriptorKind::PropertyDunderGet) => {
|
||||
match overload.parameter_types() {
|
||||
[Some(property @ Type::PropertyInstance(_)), Some(instance), ..]
|
||||
if instance.is_none(db) =>
|
||||
{
|
||||
[
|
||||
Some(property @ Type::PropertyInstance(_)),
|
||||
Some(instance),
|
||||
..,
|
||||
] if instance.is_none(db) => {
|
||||
overload.set_return_type(*property);
|
||||
}
|
||||
[Some(Type::PropertyInstance(property)), Some(Type::KnownInstance(KnownInstanceType::TypeAliasType(
|
||||
type_alias,
|
||||
))), ..]
|
||||
if property.getter(db).is_some_and(|getter| {
|
||||
getter
|
||||
.into_function_literal()
|
||||
.is_some_and(|f| f.name(db) == "__name__")
|
||||
}) =>
|
||||
[
|
||||
Some(Type::PropertyInstance(property)),
|
||||
Some(Type::KnownInstance(KnownInstanceType::TypeAliasType(
|
||||
type_alias,
|
||||
))),
|
||||
..,
|
||||
] if property.getter(db).is_some_and(|getter| {
|
||||
getter
|
||||
.into_function_literal()
|
||||
.is_some_and(|f| f.name(db) == "__name__")
|
||||
}) =>
|
||||
{
|
||||
overload
|
||||
.set_return_type(Type::string_literal(db, type_alias.name(db)));
|
||||
}
|
||||
[Some(Type::PropertyInstance(property)), Some(Type::KnownInstance(KnownInstanceType::TypeVar(typevar))), ..] => {
|
||||
[
|
||||
Some(Type::PropertyInstance(property)),
|
||||
Some(Type::KnownInstance(KnownInstanceType::TypeVar(typevar))),
|
||||
..,
|
||||
] => {
|
||||
match property
|
||||
.getter(db)
|
||||
.and_then(Type::into_function_literal)
|
||||
|
@ -411,8 +420,12 @@ impl<'db> Bindings<'db> {
|
|||
}
|
||||
|
||||
Type::WrapperDescriptor(WrapperDescriptorKind::PropertyDunderSet) => {
|
||||
if let [Some(Type::PropertyInstance(property)), Some(instance), Some(value), ..] =
|
||||
overload.parameter_types()
|
||||
if let [
|
||||
Some(Type::PropertyInstance(property)),
|
||||
Some(instance),
|
||||
Some(value),
|
||||
..,
|
||||
] = overload.parameter_types()
|
||||
{
|
||||
if let Some(setter) = property.setter(db) {
|
||||
if let Err(_call_error) = setter.try_call(
|
||||
|
@ -739,8 +752,18 @@ impl<'db> Bindings<'db> {
|
|||
}
|
||||
|
||||
Some(KnownFunction::Dataclass) => {
|
||||
if let [init, repr, eq, order, unsafe_hash, frozen, match_args, kw_only, slots, weakref_slot] =
|
||||
overload.parameter_types()
|
||||
if let [
|
||||
init,
|
||||
repr,
|
||||
eq,
|
||||
order,
|
||||
unsafe_hash,
|
||||
frozen,
|
||||
match_args,
|
||||
kw_only,
|
||||
slots,
|
||||
weakref_slot,
|
||||
] = overload.parameter_types()
|
||||
{
|
||||
let mut params = DataclassParams::empty();
|
||||
|
||||
|
@ -780,8 +803,14 @@ impl<'db> Bindings<'db> {
|
|||
}
|
||||
|
||||
Some(KnownFunction::DataclassTransform) => {
|
||||
if let [eq_default, order_default, kw_only_default, frozen_default, _field_specifiers, _kwargs] =
|
||||
overload.parameter_types()
|
||||
if let [
|
||||
eq_default,
|
||||
order_default,
|
||||
kw_only_default,
|
||||
frozen_default,
|
||||
_field_specifiers,
|
||||
_kwargs,
|
||||
] = overload.parameter_types()
|
||||
{
|
||||
let mut params = DataclassTransformerParams::empty();
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@ use std::hash::BuildHasherDefault;
|
|||
use std::sync::{LazyLock, Mutex};
|
||||
|
||||
use super::{
|
||||
class_base::ClassBase, infer_expression_type, infer_unpack_types, IntersectionBuilder,
|
||||
KnownFunction, MemberLookupPolicy, Mro, MroError, MroIterator, SubclassOfType, Truthiness,
|
||||
Type, TypeQualifiers,
|
||||
IntersectionBuilder, KnownFunction, MemberLookupPolicy, Mro, MroError, MroIterator,
|
||||
SubclassOfType, Truthiness, Type, TypeQualifiers, class_base::ClassBase, infer_expression_type,
|
||||
infer_unpack_types,
|
||||
};
|
||||
use crate::semantic_index::definition::Definition;
|
||||
use crate::semantic_index::DeclarationWithConstraint;
|
||||
use crate::semantic_index::definition::Definition;
|
||||
use crate::types::generics::{GenericContext, Specialization, TypeMapping};
|
||||
use crate::types::signatures::{Parameter, Parameters};
|
||||
use crate::types::{
|
||||
|
@ -15,6 +15,7 @@ use crate::types::{
|
|||
TypeVarInstance,
|
||||
};
|
||||
use crate::{
|
||||
Db, FxOrderSet, KnownModule, Program,
|
||||
module_resolver::file_to_module,
|
||||
semantic_index::{
|
||||
ast_ids::HasScopedExpressionId,
|
||||
|
@ -25,14 +26,13 @@ use crate::{
|
|||
symbol_table, use_def_map,
|
||||
},
|
||||
symbol::{
|
||||
class_symbol, known_module_symbol, symbol_from_bindings, symbol_from_declarations,
|
||||
Boundness, LookupError, LookupResult, Symbol, SymbolAndQualifiers,
|
||||
Boundness, LookupError, LookupResult, Symbol, SymbolAndQualifiers, class_symbol,
|
||||
known_module_symbol, symbol_from_bindings, symbol_from_declarations,
|
||||
},
|
||||
types::{
|
||||
definition_expression_type, CallArgumentTypes, CallError, CallErrorKind, DynamicType,
|
||||
MetaclassCandidate, TupleType, UnionBuilder, UnionType,
|
||||
CallArgumentTypes, CallError, CallErrorKind, DynamicType, MetaclassCandidate, TupleType,
|
||||
UnionBuilder, UnionType, definition_expression_type,
|
||||
},
|
||||
Db, FxOrderSet, KnownModule, Program,
|
||||
};
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools as _;
|
||||
|
@ -1570,7 +1570,9 @@ impl<'db> ClassLiteral<'db> {
|
|||
Truthiness::Ambiguous => {
|
||||
return Symbol::possibly_unbound(annotation_ty);
|
||||
}
|
||||
Truthiness::AlwaysFalse => unreachable!("If the attribute assignments are all invisible, inference of their types should be skipped"),
|
||||
Truthiness::AlwaysFalse => unreachable!(
|
||||
"If the attribute assignments are all invisible, inference of their types should be skipped"
|
||||
),
|
||||
}
|
||||
}
|
||||
DefinitionKind::Assignment(assign) => {
|
||||
|
@ -2778,7 +2780,7 @@ impl<'db> KnownClassLookupError<'db> {
|
|||
f,
|
||||
"Error looking up `{class}` in typeshed on Python {python_version}: \
|
||||
expected to find a fully bound symbol, but found one that is possibly unbound",
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::Db;
|
||||
use crate::types::generics::{GenericContext, Specialization, TypeMapping};
|
||||
use crate::types::{
|
||||
todo_type, ClassType, DynamicType, KnownClass, KnownInstanceType, MroError, MroIterator, Type,
|
||||
ClassType, DynamicType, KnownClass, KnownInstanceType, MroError, MroIterator, Type, todo_type,
|
||||
};
|
||||
use crate::Db;
|
||||
|
||||
/// Enumeration of the possible kinds of types we allow in class bases.
|
||||
///
|
||||
|
|
|
@ -8,14 +8,14 @@ use ruff_db::{
|
|||
};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use super::{binding_type, Type, TypeCheckDiagnostics};
|
||||
use super::{Type, TypeCheckDiagnostics, binding_type};
|
||||
|
||||
use crate::lint::LintSource;
|
||||
use crate::semantic_index::symbol::ScopeId;
|
||||
use crate::{
|
||||
Db,
|
||||
lint::{LintId, LintMetadata},
|
||||
suppression::suppressions,
|
||||
Db,
|
||||
};
|
||||
use crate::{semantic_index::semantic_index, types::FunctionDecorators};
|
||||
|
||||
|
@ -48,7 +48,9 @@ impl<'db> InferContext<'db> {
|
|||
file: scope.file(db),
|
||||
diagnostics: std::cell::RefCell::new(TypeCheckDiagnostics::default()),
|
||||
no_type_check: InNoTypeCheck::default(),
|
||||
bomb: DebugDropBomb::new("`InferContext` needs to be explicitly consumed by calling `::finish` to prevent accidental loss of diagnostics."),
|
||||
bomb: DebugDropBomb::new(
|
||||
"`InferContext` needs to be explicitly consumed by calling `::finish` to prevent accidental loss of diagnostics.",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@ use super::{ClassLiteral, KnownClass};
|
|||
use crate::db::Db;
|
||||
use crate::lint::{Level, LintRegistryBuilder, LintStatus};
|
||||
use crate::suppression::FileSuppressionId;
|
||||
use crate::types::LintDiagnosticGuard;
|
||||
use crate::types::string_annotation::{
|
||||
BYTE_STRING_TYPE_ANNOTATION, ESCAPE_CHARACTER_IN_FORWARD_ANNOTATION, FSTRING_TYPE_ANNOTATION,
|
||||
IMPLICIT_CONCATENATED_STRING_TYPE_ANNOTATION, INVALID_SYNTAX_IN_FORWARD_ANNOTATION,
|
||||
RAW_STRING_TYPE_ANNOTATION,
|
||||
};
|
||||
use crate::types::LintDiagnosticGuard;
|
||||
use crate::types::{protocol_class::ProtocolClassLiteral, KnownFunction, KnownInstanceType, Type};
|
||||
use crate::{declare_lint, Program};
|
||||
use crate::types::{KnownFunction, KnownInstanceType, Type, protocol_class::ProtocolClassLiteral};
|
||||
use crate::{Program, declare_lint};
|
||||
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, SubDiagnostic};
|
||||
use ruff_python_ast::{self as ast, AnyNodeRef};
|
||||
use ruff_python_stdlib::builtins::version_builtin_was_added;
|
||||
|
|
|
@ -768,10 +768,10 @@ impl Display for DisplayStringLiteralType<'_> {
|
|||
mod tests {
|
||||
use ruff_python_ast::name::Name;
|
||||
|
||||
use crate::Db;
|
||||
use crate::db::tests::setup_db;
|
||||
use crate::symbol::typing_extensions_symbol;
|
||||
use crate::types::{KnownClass, Parameter, Parameters, Signature, StringLiteralType, Type};
|
||||
use crate::Db;
|
||||
|
||||
#[test]
|
||||
fn string_literal_display() {
|
||||
|
|
|
@ -7,8 +7,8 @@ use crate::types::class_base::ClassBase;
|
|||
use crate::types::instance::{NominalInstanceType, Protocol, ProtocolInstanceType};
|
||||
use crate::types::signatures::{Parameter, Parameters, Signature};
|
||||
use crate::types::{
|
||||
declaration_type, todo_type, KnownInstanceType, Type, TypeVarBoundOrConstraints,
|
||||
TypeVarInstance, TypeVarVariance, UnionType,
|
||||
KnownInstanceType, Type, TypeVarBoundOrConstraints, TypeVarInstance, TypeVarVariance,
|
||||
UnionType, declaration_type, todo_type,
|
||||
};
|
||||
use crate::{Db, FxOrderSet};
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ use itertools::{Either, Itertools};
|
|||
use ruff_db::diagnostic::{Annotation, DiagnosticId, Severity};
|
||||
use ruff_db::files::File;
|
||||
use ruff_db::parsed::parsed_module;
|
||||
use ruff_python_ast::visitor::{walk_expr, Visitor};
|
||||
use ruff_python_ast::visitor::{Visitor, walk_expr};
|
||||
use ruff_python_ast::{self as ast, AnyNodeRef, ExprContext};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
@ -58,40 +58,39 @@ use crate::semantic_index::narrowing_constraints::ConstraintKey;
|
|||
use crate::semantic_index::symbol::{
|
||||
FileScopeId, NodeWithScopeKind, NodeWithScopeRef, ScopeId, ScopeKind, ScopedSymbolId,
|
||||
};
|
||||
use crate::semantic_index::{semantic_index, EagerSnapshotResult, SemanticIndex};
|
||||
use crate::semantic_index::{EagerSnapshotResult, SemanticIndex, semantic_index};
|
||||
use crate::symbol::{
|
||||
builtins_module_scope, builtins_symbol, explicit_global_symbol, global_symbol,
|
||||
module_type_implicit_global_declaration, module_type_implicit_global_symbol, symbol,
|
||||
symbol_from_bindings, symbol_from_declarations, typing_extensions_symbol, Boundness,
|
||||
LookupError,
|
||||
Boundness, LookupError, builtins_module_scope, builtins_symbol, explicit_global_symbol,
|
||||
global_symbol, module_type_implicit_global_declaration, module_type_implicit_global_symbol,
|
||||
symbol, symbol_from_bindings, symbol_from_declarations, typing_extensions_symbol,
|
||||
};
|
||||
use crate::types::call::{Argument, Bindings, CallArgumentTypes, CallArguments, CallError};
|
||||
use crate::types::class::{MetaclassErrorKind, SliceLiteral};
|
||||
use crate::types::diagnostic::{
|
||||
self, report_implicit_return_type, report_invalid_arguments_to_annotated,
|
||||
report_invalid_arguments_to_callable, report_invalid_assignment,
|
||||
report_invalid_attribute_assignment, report_invalid_generator_function_return_type,
|
||||
report_invalid_return_type, report_possibly_unbound_attribute, TypeCheckDiagnostics,
|
||||
CALL_NON_CALLABLE, CALL_POSSIBLY_UNBOUND_METHOD, CONFLICTING_DECLARATIONS,
|
||||
self, CALL_NON_CALLABLE, CALL_POSSIBLY_UNBOUND_METHOD, CONFLICTING_DECLARATIONS,
|
||||
CONFLICTING_METACLASS, CYCLIC_CLASS_DEFINITION, DIVISION_BY_ZERO, INCONSISTENT_MRO,
|
||||
INVALID_ARGUMENT_TYPE, INVALID_ASSIGNMENT, INVALID_ATTRIBUTE_ACCESS, INVALID_BASE,
|
||||
INVALID_DECLARATION, INVALID_GENERIC_CLASS, INVALID_LEGACY_TYPE_VARIABLE,
|
||||
INVALID_PARAMETER_DEFAULT, INVALID_TYPE_FORM, INVALID_TYPE_VARIABLE_CONSTRAINTS,
|
||||
POSSIBLY_UNBOUND_IMPORT, UNDEFINED_REVEAL, UNRESOLVED_ATTRIBUTE, UNRESOLVED_IMPORT,
|
||||
UNSUPPORTED_OPERATOR,
|
||||
POSSIBLY_UNBOUND_IMPORT, TypeCheckDiagnostics, UNDEFINED_REVEAL, UNRESOLVED_ATTRIBUTE,
|
||||
UNRESOLVED_IMPORT, UNSUPPORTED_OPERATOR, report_implicit_return_type,
|
||||
report_invalid_arguments_to_annotated, report_invalid_arguments_to_callable,
|
||||
report_invalid_assignment, report_invalid_attribute_assignment,
|
||||
report_invalid_generator_function_return_type, report_invalid_return_type,
|
||||
report_possibly_unbound_attribute,
|
||||
};
|
||||
use crate::types::generics::GenericContext;
|
||||
use crate::types::mro::MroErrorKind;
|
||||
use crate::types::unpacker::{UnpackResult, Unpacker};
|
||||
use crate::types::{
|
||||
binding_type, todo_type, CallDunderError, CallableSignature, CallableType, ClassLiteral,
|
||||
ClassType, DataclassParams, DynamicType, FunctionDecorators, FunctionType, GenericAlias,
|
||||
IntersectionBuilder, IntersectionType, KnownClass, KnownFunction, KnownInstanceType,
|
||||
MemberLookupPolicy, MetaclassCandidate, Parameter, ParameterForm, Parameters, Signature,
|
||||
Signatures, StringLiteralType, SubclassOfType, Symbol, SymbolAndQualifiers, Truthiness,
|
||||
TupleType, Type, TypeAliasType, TypeAndQualifiers, TypeArrayDisplay, TypeQualifiers,
|
||||
TypeVarBoundOrConstraints, TypeVarInstance, TypeVarKind, TypeVarVariance, UnionBuilder,
|
||||
UnionType,
|
||||
CallDunderError, CallableSignature, CallableType, ClassLiteral, ClassType, DataclassParams,
|
||||
DynamicType, FunctionDecorators, FunctionType, GenericAlias, IntersectionBuilder,
|
||||
IntersectionType, KnownClass, KnownFunction, KnownInstanceType, MemberLookupPolicy,
|
||||
MetaclassCandidate, Parameter, ParameterForm, Parameters, Signature, Signatures,
|
||||
StringLiteralType, SubclassOfType, Symbol, SymbolAndQualifiers, Truthiness, TupleType, Type,
|
||||
TypeAliasType, TypeAndQualifiers, TypeArrayDisplay, TypeQualifiers, TypeVarBoundOrConstraints,
|
||||
TypeVarInstance, TypeVarKind, TypeVarVariance, UnionBuilder, UnionType, binding_type,
|
||||
todo_type,
|
||||
};
|
||||
use crate::unpack::{Unpack, UnpackPosition};
|
||||
use crate::util::subscript::{PyIndex, PySlice};
|
||||
|
@ -99,19 +98,19 @@ use crate::{Db, FxOrderSet};
|
|||
|
||||
use super::context::{InNoTypeCheck, InferContext};
|
||||
use super::diagnostic::{
|
||||
report_attempted_protocol_instantiation, report_bad_argument_to_get_protocol_members,
|
||||
report_duplicate_bases, report_index_out_of_bounds, report_invalid_exception_caught,
|
||||
report_invalid_exception_cause, report_invalid_exception_raised,
|
||||
report_invalid_type_checking_constant, report_non_subscriptable,
|
||||
report_possibly_unresolved_reference,
|
||||
INVALID_METACLASS, INVALID_OVERLOAD, INVALID_PROTOCOL, REDUNDANT_CAST, STATIC_ASSERT_ERROR,
|
||||
SUBCLASS_OF_FINAL_CLASS, TYPE_ASSERTION_FAILURE, report_attempted_protocol_instantiation,
|
||||
report_bad_argument_to_get_protocol_members, report_duplicate_bases,
|
||||
report_index_out_of_bounds, report_invalid_exception_caught, report_invalid_exception_cause,
|
||||
report_invalid_exception_raised, report_invalid_type_checking_constant,
|
||||
report_non_subscriptable, report_possibly_unresolved_reference,
|
||||
report_runtime_check_against_non_runtime_checkable_protocol, report_slice_step_size_zero,
|
||||
report_unresolved_reference, INVALID_METACLASS, INVALID_OVERLOAD, INVALID_PROTOCOL,
|
||||
REDUNDANT_CAST, STATIC_ASSERT_ERROR, SUBCLASS_OF_FINAL_CLASS, TYPE_ASSERTION_FAILURE,
|
||||
report_unresolved_reference,
|
||||
};
|
||||
use super::generics::{GenericContextOrigin, LegacyGenericBase};
|
||||
use super::slots::check_class_slots;
|
||||
use super::string_annotation::{
|
||||
parse_string_annotation, BYTE_STRING_TYPE_ANNOTATION, FSTRING_TYPE_ANNOTATION,
|
||||
BYTE_STRING_TYPE_ANNOTATION, FSTRING_TYPE_ANNOTATION, parse_string_annotation,
|
||||
};
|
||||
use super::subclass_of::SubclassOfInner;
|
||||
use super::{BoundSuperError, BoundSuperType, ClassBase};
|
||||
|
@ -1422,10 +1421,12 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
}
|
||||
|
||||
fn add_binding(&mut self, node: AnyNodeRef, binding: Definition<'db>, ty: Type<'db>) {
|
||||
debug_assert!(binding
|
||||
.kind(self.db())
|
||||
.category(self.context.in_stub())
|
||||
.is_binding());
|
||||
debug_assert!(
|
||||
binding
|
||||
.kind(self.db())
|
||||
.category(self.context.in_stub())
|
||||
.is_binding()
|
||||
);
|
||||
|
||||
let file_scope_id = binding.file_scope(self.db());
|
||||
let symbol_table = self.index.symbol_table(file_scope_id);
|
||||
|
@ -1508,10 +1509,12 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
declaration: Definition<'db>,
|
||||
ty: TypeAndQualifiers<'db>,
|
||||
) {
|
||||
debug_assert!(declaration
|
||||
.kind(self.db())
|
||||
.category(self.context.in_stub())
|
||||
.is_declaration());
|
||||
debug_assert!(
|
||||
declaration
|
||||
.kind(self.db())
|
||||
.category(self.context.in_stub())
|
||||
.is_declaration()
|
||||
);
|
||||
let use_def = self.index.use_def_map(declaration.file_scope(self.db()));
|
||||
let prior_bindings = use_def.bindings_at_declaration(declaration);
|
||||
// unbound_ty is Never because for this check we don't care about unbound
|
||||
|
@ -1556,14 +1559,18 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
definition: Definition<'db>,
|
||||
declared_and_inferred_ty: &DeclaredAndInferredType<'db>,
|
||||
) {
|
||||
debug_assert!(definition
|
||||
.kind(self.db())
|
||||
.category(self.context.in_stub())
|
||||
.is_binding());
|
||||
debug_assert!(definition
|
||||
.kind(self.db())
|
||||
.category(self.context.in_stub())
|
||||
.is_declaration());
|
||||
debug_assert!(
|
||||
definition
|
||||
.kind(self.db())
|
||||
.category(self.context.in_stub())
|
||||
.is_binding()
|
||||
);
|
||||
debug_assert!(
|
||||
definition
|
||||
.kind(self.db())
|
||||
.category(self.context.in_stub())
|
||||
.is_declaration()
|
||||
);
|
||||
|
||||
let (declared_ty, inferred_ty) = match *declared_and_inferred_ty {
|
||||
DeclaredAndInferredType::AreTheSame(ty) => (ty.into(), ty),
|
||||
|
@ -1764,12 +1771,16 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
if let Some(returns) = function.returns.as_deref() {
|
||||
fn is_stub_suite(suite: &[ast::Stmt]) -> bool {
|
||||
match suite {
|
||||
[ast::Stmt::Expr(ast::StmtExpr { value: first, .. }), ast::Stmt::Expr(ast::StmtExpr { value: second, .. }), ..] => {
|
||||
first.is_string_literal_expr() && second.is_ellipsis_literal_expr()
|
||||
}
|
||||
[ast::Stmt::Expr(ast::StmtExpr { value, .. }), ast::Stmt::Pass(_), ..] => {
|
||||
value.is_string_literal_expr()
|
||||
}
|
||||
[
|
||||
ast::Stmt::Expr(ast::StmtExpr { value: first, .. }),
|
||||
ast::Stmt::Expr(ast::StmtExpr { value: second, .. }),
|
||||
..,
|
||||
] => first.is_string_literal_expr() && second.is_ellipsis_literal_expr(),
|
||||
[
|
||||
ast::Stmt::Expr(ast::StmtExpr { value, .. }),
|
||||
ast::Stmt::Pass(_),
|
||||
..,
|
||||
] => value.is_string_literal_expr(),
|
||||
[ast::Stmt::Expr(ast::StmtExpr { value, .. }), ..] => {
|
||||
value.is_ellipsis_literal_expr() || value.is_string_literal_expr()
|
||||
}
|
||||
|
@ -4338,7 +4349,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
} = expression;
|
||||
let ty = self.infer_expression(expression);
|
||||
|
||||
if let Some(ref format_spec) = format_spec {
|
||||
if let Some(format_spec) = format_spec {
|
||||
for element in format_spec.elements.expressions() {
|
||||
self.infer_expression(&element.expression);
|
||||
}
|
||||
|
@ -5206,8 +5217,15 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
continue;
|
||||
};
|
||||
|
||||
let [Some(name_param), constraints, bound, default, contravariant, covariant, _infer_variance] =
|
||||
overload.parameter_types()
|
||||
let [
|
||||
Some(name_param),
|
||||
constraints,
|
||||
bound,
|
||||
default,
|
||||
contravariant,
|
||||
covariant,
|
||||
_infer_variance,
|
||||
] = overload.parameter_types()
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
@ -6278,11 +6296,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
);
|
||||
|
||||
if is_last {
|
||||
if done {
|
||||
Type::Never
|
||||
} else {
|
||||
ty
|
||||
}
|
||||
if done { Type::Never } else { ty }
|
||||
} else {
|
||||
let truthiness = ty.try_bool(self.db()).unwrap_or_else(|err| {
|
||||
err.report_diagnostic(&self.context, range);
|
||||
|
@ -7173,14 +7187,14 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
let literal_value = literal_ty.value(self.db());
|
||||
|
||||
let chars: Vec<_> = literal_value.chars().collect();
|
||||
let result = if let Ok(new_chars) = chars.py_slice(start, stop, step) {
|
||||
|
||||
if let Ok(new_chars) = chars.py_slice(start, stop, step) {
|
||||
let literal: String = new_chars.collect();
|
||||
Type::string_literal(self.db(), &literal)
|
||||
} else {
|
||||
report_slice_step_size_zero(&self.context, value_node.into());
|
||||
Type::unknown()
|
||||
};
|
||||
result
|
||||
}
|
||||
}
|
||||
// Ex) Given `b"value"[1]`, return `b"a"`
|
||||
(Type::BytesLiteral(literal_ty), Type::IntLiteral(int), _)
|
||||
|
@ -8474,8 +8488,8 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
}
|
||||
_ => {
|
||||
// NB: This calls `infer_expression` instead of `infer_type_expression`.
|
||||
let argument_type = self.infer_expression(arguments_slice);
|
||||
argument_type
|
||||
|
||||
self.infer_expression(arguments_slice)
|
||||
}
|
||||
},
|
||||
KnownInstanceType::CallableTypeOf => match arguments_slice {
|
||||
|
@ -8723,7 +8737,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
| ast::Expr::BytesLiteral(_)
|
||||
| ast::Expr::BooleanLiteral(_)
|
||||
| ast::Expr::NoneLiteral(_)) => self.infer_expression(literal),
|
||||
literal @ ast::Expr::NumberLiteral(ref number) if number.value.is_int() => {
|
||||
literal @ ast::Expr::NumberLiteral(number) if number.value.is_int() => {
|
||||
self.infer_expression(literal)
|
||||
}
|
||||
// For enum values
|
||||
|
@ -8737,7 +8751,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
.unwrap_or(Type::unknown())
|
||||
}
|
||||
// for negative and positive numbers
|
||||
ast::Expr::UnaryOp(ref u)
|
||||
ast::Expr::UnaryOp(u)
|
||||
if matches!(u.op, ast::UnaryOp::USub | ast::UnaryOp::UAdd)
|
||||
&& u.operand.is_number_literal_expr() =>
|
||||
{
|
||||
|
@ -9027,14 +9041,14 @@ fn contains_string_literal(expr: &ast::Expr) -> bool {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::db::tests::{setup_db, TestDb};
|
||||
use crate::db::tests::{TestDb, setup_db};
|
||||
use crate::semantic_index::definition::Definition;
|
||||
use crate::semantic_index::symbol::FileScopeId;
|
||||
use crate::semantic_index::{global_scope, semantic_index, symbol_table, use_def_map};
|
||||
use crate::symbol::global_symbol;
|
||||
use crate::types::check_types;
|
||||
use ruff_db::diagnostic::Diagnostic;
|
||||
use ruff_db::files::{system_path_to_file, File};
|
||||
use ruff_db::files::{File, system_path_to_file};
|
||||
use ruff_db::system::DbWithWritableSystem as _;
|
||||
use ruff_db::testing::{assert_function_query_was_not_run, assert_function_query_was_run};
|
||||
|
||||
|
|
|
@ -364,9 +364,9 @@ impl<'db> Protocol<'db> {
|
|||
}
|
||||
|
||||
mod synthesized_protocol {
|
||||
use crate::types::TypeVarInstance;
|
||||
use crate::types::generics::TypeMapping;
|
||||
use crate::types::protocol_class::ProtocolInterface;
|
||||
use crate::types::TypeVarInstance;
|
||||
use crate::{Db, FxOrderSet};
|
||||
|
||||
/// A "synthesized" protocol type that is dissociated from a class definition in source code.
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use super::generics::GenericContext;
|
||||
use super::{class::KnownClass, ClassType, Truthiness, Type, TypeAliasType, TypeVarInstance};
|
||||
use super::{ClassType, Truthiness, Type, TypeAliasType, TypeVarInstance, class::KnownClass};
|
||||
use crate::db::Db;
|
||||
use crate::module_resolver::{file_to_module, KnownModule};
|
||||
use crate::module_resolver::{KnownModule, file_to_module};
|
||||
use ruff_db::files::File;
|
||||
|
||||
/// Enumeration of specific runtime symbols that are special enough
|
||||
|
|
|
@ -3,10 +3,10 @@ use std::ops::Deref;
|
|||
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::Db;
|
||||
use crate::types::class_base::ClassBase;
|
||||
use crate::types::generics::Specialization;
|
||||
use crate::types::{ClassLiteral, ClassType, Type};
|
||||
use crate::Db;
|
||||
|
||||
/// The inferred method resolution order of a given class.
|
||||
///
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::Db;
|
||||
use crate::semantic_index::ast_ids::HasScopedExpressionId;
|
||||
use crate::semantic_index::expression::Expression;
|
||||
use crate::semantic_index::predicate::{
|
||||
|
@ -7,10 +8,9 @@ use crate::semantic_index::symbol::{ScopeId, ScopedSymbolId, SymbolTable};
|
|||
use crate::semantic_index::symbol_table;
|
||||
use crate::types::infer::infer_same_file_expression_type;
|
||||
use crate::types::{
|
||||
infer_expression_types, IntersectionBuilder, KnownClass, SubclassOfType, Truthiness, Type,
|
||||
UnionBuilder,
|
||||
IntersectionBuilder, KnownClass, SubclassOfType, Truthiness, Type, UnionBuilder,
|
||||
infer_expression_types,
|
||||
};
|
||||
use crate::Db;
|
||||
|
||||
use ruff_python_stdlib::identifiers::is_identifier;
|
||||
|
||||
|
@ -860,7 +860,7 @@ impl<'db> NarrowingConstraintsBuilder<'db> {
|
|||
}
|
||||
(BoolOp::Or, true) | (BoolOp::And, false) => {
|
||||
let (first, rest) = sub_constraints.split_first_mut()?;
|
||||
if let Some(ref mut first) = first {
|
||||
if let Some(first) = first {
|
||||
for rest_constraint in rest {
|
||||
if let Some(rest_constraint) = rest_constraint {
|
||||
merge_constraints_or(first, rest_constraint, self.db);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::db::tests::{setup_db, TestDb};
|
||||
use crate::db::tests::{TestDb, setup_db};
|
||||
use std::sync::{Arc, Mutex, OnceLock};
|
||||
|
||||
static CACHED_DB: OnceLock<Arc<Mutex<TestDb>>> = OnceLock::new();
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
use std::{collections::HashMap, slice::Iter};
|
||||
|
||||
use itertools::EitherOrBoth;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
|
||||
use super::{definition_expression_type, DynamicType, Type};
|
||||
use super::{DynamicType, Type, definition_expression_type};
|
||||
use crate::semantic_index::definition::Definition;
|
||||
use crate::types::generics::{GenericContext, Specialization, TypeMapping};
|
||||
use crate::types::{todo_type, ClassLiteral, TypeVarInstance};
|
||||
use crate::types::{ClassLiteral, TypeVarInstance, todo_type};
|
||||
use crate::{Db, FxOrderSet};
|
||||
use ruff_python_ast::{self as ast, name::Name};
|
||||
|
||||
|
@ -1503,7 +1503,7 @@ pub(crate) enum ParameterForm {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::db::tests::{setup_db, TestDb};
|
||||
use crate::db::tests::{TestDb, setup_db};
|
||||
use crate::symbol::global_symbol;
|
||||
use crate::types::{FunctionSignature, FunctionType, KnownClass};
|
||||
use ruff_db::system::DbWithWritableSystem as _;
|
||||
|
@ -1604,11 +1604,13 @@ mod tests {
|
|||
|
||||
let sig = func.internal_signature(&db);
|
||||
|
||||
let [Parameter {
|
||||
annotated_type,
|
||||
kind: ParameterKind::PositionalOrKeyword { name, .. },
|
||||
..
|
||||
}] = &sig.parameters.value[..]
|
||||
let [
|
||||
Parameter {
|
||||
annotated_type,
|
||||
kind: ParameterKind::PositionalOrKeyword { name, .. },
|
||||
..
|
||||
},
|
||||
] = &sig.parameters.value[..]
|
||||
else {
|
||||
panic!("expected one positional-or-keyword parameter");
|
||||
};
|
||||
|
@ -1638,11 +1640,13 @@ mod tests {
|
|||
|
||||
let sig = func.internal_signature(&db);
|
||||
|
||||
let [Parameter {
|
||||
annotated_type,
|
||||
kind: ParameterKind::PositionalOrKeyword { name, .. },
|
||||
..
|
||||
}] = &sig.parameters.value[..]
|
||||
let [
|
||||
Parameter {
|
||||
annotated_type,
|
||||
kind: ParameterKind::PositionalOrKeyword { name, .. },
|
||||
..
|
||||
},
|
||||
] = &sig.parameters.value[..]
|
||||
else {
|
||||
panic!("expected one positional-or-keyword parameter");
|
||||
};
|
||||
|
@ -1672,15 +1676,18 @@ mod tests {
|
|||
|
||||
let sig = func.internal_signature(&db);
|
||||
|
||||
let [Parameter {
|
||||
annotated_type: a_annotated_ty,
|
||||
kind: ParameterKind::PositionalOrKeyword { name: a_name, .. },
|
||||
..
|
||||
}, Parameter {
|
||||
annotated_type: b_annotated_ty,
|
||||
kind: ParameterKind::PositionalOrKeyword { name: b_name, .. },
|
||||
..
|
||||
}] = &sig.parameters.value[..]
|
||||
let [
|
||||
Parameter {
|
||||
annotated_type: a_annotated_ty,
|
||||
kind: ParameterKind::PositionalOrKeyword { name: a_name, .. },
|
||||
..
|
||||
},
|
||||
Parameter {
|
||||
annotated_type: b_annotated_ty,
|
||||
kind: ParameterKind::PositionalOrKeyword { name: b_name, .. },
|
||||
..
|
||||
},
|
||||
] = &sig.parameters.value[..]
|
||||
else {
|
||||
panic!("expected two positional-or-keyword parameters");
|
||||
};
|
||||
|
@ -1715,15 +1722,18 @@ mod tests {
|
|||
|
||||
let sig = func.internal_signature(&db);
|
||||
|
||||
let [Parameter {
|
||||
annotated_type: a_annotated_ty,
|
||||
kind: ParameterKind::PositionalOrKeyword { name: a_name, .. },
|
||||
..
|
||||
}, Parameter {
|
||||
annotated_type: b_annotated_ty,
|
||||
kind: ParameterKind::PositionalOrKeyword { name: b_name, .. },
|
||||
..
|
||||
}] = &sig.parameters.value[..]
|
||||
let [
|
||||
Parameter {
|
||||
annotated_type: a_annotated_ty,
|
||||
kind: ParameterKind::PositionalOrKeyword { name: a_name, .. },
|
||||
..
|
||||
},
|
||||
Parameter {
|
||||
annotated_type: b_annotated_ty,
|
||||
kind: ParameterKind::PositionalOrKeyword { name: b_name, .. },
|
||||
..
|
||||
},
|
||||
] = &sig.parameters.value[..]
|
||||
else {
|
||||
panic!("expected two positional-or-keyword parameters");
|
||||
};
|
||||
|
|
|
@ -3,8 +3,8 @@ use std::cmp::Ordering;
|
|||
use crate::db::Db;
|
||||
|
||||
use super::{
|
||||
class_base::ClassBase, subclass_of::SubclassOfInner, DynamicType, KnownInstanceType,
|
||||
SuperOwnerKind, TodoType, Type,
|
||||
DynamicType, KnownInstanceType, SuperOwnerKind, TodoType, Type, class_base::ClassBase,
|
||||
subclass_of::SubclassOfInner,
|
||||
};
|
||||
|
||||
/// Return an [`Ordering`] that describes the canonical order in which two types should appear
|
||||
|
|
|
@ -5,11 +5,11 @@ use rustc_hash::FxHashMap;
|
|||
|
||||
use ruff_python_ast::{self as ast, AnyNodeRef};
|
||||
|
||||
use crate::Db;
|
||||
use crate::semantic_index::ast_ids::{HasScopedExpressionId, ScopedExpressionId};
|
||||
use crate::semantic_index::symbol::ScopeId;
|
||||
use crate::types::{infer_expression_types, todo_type, Type, TypeCheckDiagnostics};
|
||||
use crate::types::{Type, TypeCheckDiagnostics, infer_expression_types, todo_type};
|
||||
use crate::unpack::{UnpackKind, UnpackValue};
|
||||
use crate::Db;
|
||||
|
||||
use super::context::InferContext;
|
||||
use super::diagnostic::INVALID_ASSIGNMENT;
|
||||
|
|
|
@ -2,11 +2,11 @@ use ruff_db::files::File;
|
|||
use ruff_python_ast::{self as ast, AnyNodeRef};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use crate::Db;
|
||||
use crate::ast_node_ref::AstNodeRef;
|
||||
use crate::semantic_index::ast_ids::{HasScopedExpressionId, ScopedExpressionId};
|
||||
use crate::semantic_index::expression::Expression;
|
||||
use crate::semantic_index::symbol::{FileScopeId, ScopeId};
|
||||
use crate::Db;
|
||||
|
||||
/// This ingredient represents a single unpacking.
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue