mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 21:34:57 +00:00
[ty] Track heap usage of salsa structs (#19790)
Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
6a05d46ef6
commit
f34b65b7a0
35 changed files with 269 additions and 124 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3073,6 +3073,7 @@ name = "ruff_memory_usage"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"get-size2",
|
||||
"ordermap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::system::file_time_now;
|
|||
/// * The last modification time of the file.
|
||||
/// * The hash of the file's content.
|
||||
/// * The revision as it comes from an external system, for example the LSP.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, get_size2::GetSize)]
|
||||
pub struct FileRevision(u128);
|
||||
|
||||
impl FileRevision {
|
||||
|
|
|
@ -289,7 +289,7 @@ impl std::panic::RefUnwindSafe for Files {}
|
|||
/// # Ordering
|
||||
/// Ordering is based on the file's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs.
|
||||
#[salsa::input]
|
||||
#[salsa::input(heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct File {
|
||||
/// The path of the file (immutable).
|
||||
|
@ -521,7 +521,7 @@ impl VirtualFile {
|
|||
// The types in here need to be public because they're salsa ingredients but we
|
||||
// don't want them to be publicly accessible. That's why we put them into a private module.
|
||||
mod private {
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, get_size2::GetSize)]
|
||||
pub enum FileStatus {
|
||||
/// The file exists.
|
||||
#[default]
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::system::{SystemPath, SystemPathBuf};
|
|||
/// The main usage of file roots is to determine a file's durability. But it can also be used
|
||||
/// to make a salsa query dependent on whether a file in a root has changed without writing any
|
||||
/// manual invalidation logic.
|
||||
#[salsa::input(debug)]
|
||||
#[salsa::input(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct FileRoot {
|
||||
/// The path of a root is guaranteed to never change.
|
||||
#[returns(deref)]
|
||||
|
@ -37,7 +37,7 @@ impl FileRoot {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub enum FileRootKind {
|
||||
/// The root of a project.
|
||||
Project,
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::fmt::{Display, Formatter};
|
|||
/// * a file stored on the [host system](crate::system::System).
|
||||
/// * a virtual file stored on the [host system](crate::system::System).
|
||||
/// * a vendored file stored in the [vendored file system](crate::vendored::VendoredFileSystem).
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, get_size2::GetSize)]
|
||||
pub enum FilePath {
|
||||
/// Path to a file on the [host system](crate::system::System).
|
||||
System(SystemPathBuf),
|
||||
|
|
|
@ -762,7 +762,7 @@ impl SystemVirtualPath {
|
|||
}
|
||||
|
||||
/// An owned, virtual path on [`System`](`super::System`) (akin to [`String`]).
|
||||
#[derive(Eq, PartialEq, Clone, Hash, PartialOrd, Ord)]
|
||||
#[derive(Eq, PartialEq, Clone, Hash, PartialOrd, Ord, get_size2::GetSize)]
|
||||
pub struct SystemVirtualPathBuf(String);
|
||||
|
||||
impl SystemVirtualPathBuf {
|
||||
|
|
|
@ -12,6 +12,7 @@ license = { workspace = true }
|
|||
|
||||
[dependencies]
|
||||
get-size2 = { workspace = true }
|
||||
ordermap = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::sync::{LazyLock, Mutex};
|
||||
|
||||
use get_size2::{GetSize, StandardTracker};
|
||||
use ordermap::OrderSet;
|
||||
|
||||
/// Returns the memory usage of the provided object, using a global tracker to avoid
|
||||
/// double-counting shared objects.
|
||||
|
@ -12,3 +13,8 @@ pub fn heap_size<T: GetSize>(value: &T) -> usize {
|
|||
.get_heap_size_with_tracker(&mut *TRACKER.lock().unwrap())
|
||||
.0
|
||||
}
|
||||
|
||||
/// An implementation of [`GetSize::get_heap_size`] for [`OrderSet`].
|
||||
pub fn order_set_heap_size<T: GetSize, S>(set: &OrderSet<T, S>) -> usize {
|
||||
(set.capacity() * T::get_stack_size()) + set.iter().map(heap_size).sum::<usize>()
|
||||
}
|
||||
|
|
|
@ -128,18 +128,49 @@ impl ProjectDatabase {
|
|||
/// to the CLI after a typechecker run.
|
||||
pub fn salsa_memory_dump(&self) -> SalsaMemoryDump {
|
||||
let memory_usage = <dyn salsa::Database>::memory_usage(self);
|
||||
let mut ingredients = memory_usage.structs;
|
||||
let mut memos = memory_usage.queries.into_iter().collect::<Vec<_>>();
|
||||
let mut ingredients = memory_usage
|
||||
.structs
|
||||
.into_iter()
|
||||
.filter(|ingredient| ingredient.count() > 0)
|
||||
.collect::<Vec<_>>();
|
||||
let mut memos = memory_usage
|
||||
.queries
|
||||
.into_iter()
|
||||
.filter(|(_, memos)| memos.count() > 0)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
ingredients.sort_by_key(|ingredient| cmp::Reverse(ingredient.size_of_fields()));
|
||||
memos.sort_by_key(|(_, memo)| cmp::Reverse(memo.size_of_fields()));
|
||||
ingredients.sort_by_key(|ingredient| {
|
||||
let heap_size = ingredient.heap_size_of_fields().unwrap_or_else(|| {
|
||||
// Salsa currently does not expose a way to track the heap size of interned
|
||||
// query arguments.
|
||||
if !ingredient.debug_name().contains("interned_arguments") {
|
||||
tracing::warn!(
|
||||
"expected `heap_size` to be provided by Salsa struct `{}`",
|
||||
ingredient.debug_name()
|
||||
);
|
||||
}
|
||||
|
||||
0
|
||||
});
|
||||
|
||||
cmp::Reverse(ingredient.size_of_fields() + heap_size)
|
||||
});
|
||||
|
||||
memos.sort_by_key(|(query, memo)| {
|
||||
let heap_size = memo.heap_size_of_fields().unwrap_or_else(|| {
|
||||
tracing::warn!("expected `heap_size` to be provided by Salsa query `{query}`");
|
||||
0
|
||||
});
|
||||
|
||||
cmp::Reverse(memo.size_of_fields() + heap_size)
|
||||
});
|
||||
|
||||
let mut total_fields = 0;
|
||||
let mut total_metadata = 0;
|
||||
for ingredient in &ingredients {
|
||||
total_metadata += ingredient.size_of_metadata();
|
||||
total_fields += ingredient.size_of_fields();
|
||||
total_fields += ingredient.heap_size_of_fields().unwrap_or(0);
|
||||
total_metadata += ingredient.size_of_metadata();
|
||||
}
|
||||
|
||||
let mut total_memo_fields = 0;
|
||||
|
@ -171,7 +202,7 @@ impl std::fmt::Debug for ProjectDatabase {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, get_size2::GetSize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize))]
|
||||
pub enum CheckMode {
|
||||
/// Checks the open files in the project.
|
||||
|
@ -281,12 +312,15 @@ impl SalsaMemoryDump {
|
|||
writeln!(f, "=======SALSA STRUCTS=======")?;
|
||||
|
||||
for ingredient in ingredients {
|
||||
let size_of_fields =
|
||||
ingredient.size_of_fields() + ingredient.heap_size_of_fields().unwrap_or(0);
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
"{:<50} metadata={:<8} fields={:<8} count={}",
|
||||
format!("`{}`", ingredient.debug_name()),
|
||||
format!("{:.2}MB", bytes_to_mb(ingredient.size_of_metadata())),
|
||||
format!("{:.2}MB", bytes_to_mb(ingredient.size_of_fields())),
|
||||
format!("{:.2}MB", bytes_to_mb(size_of_fields)),
|
||||
ingredient.count()
|
||||
)?;
|
||||
}
|
||||
|
@ -294,13 +328,16 @@ impl SalsaMemoryDump {
|
|||
writeln!(f, "=======SALSA QUERIES=======")?;
|
||||
|
||||
for (query_fn, memo) in memos {
|
||||
let size_of_fields =
|
||||
memo.size_of_fields() + memo.heap_size_of_fields().unwrap_or(0);
|
||||
|
||||
writeln!(f, "`{query_fn} -> {}`", memo.debug_name())?;
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
" metadata={:<8} fields={:<8} count={}",
|
||||
format!("{:.2}MB", bytes_to_mb(memo.size_of_metadata())),
|
||||
format!("{:.2}MB", bytes_to_mb(memo.size_of_fields())),
|
||||
format!("{:.2}MB", bytes_to_mb(size_of_fields)),
|
||||
memo.count()
|
||||
)?;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::{IOErrorDiagnostic, Project};
|
|||
/// so no query can be depending on the contents of the indexed files before that. All subsequent mutations to
|
||||
/// the indexed files must go through `IndexedMut`, which uses the Salsa setter `project.set_file_set` to
|
||||
/// ensure that Salsa always knows when the set of indexed files have changed.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, get_size2::GetSize)]
|
||||
pub struct IndexedFiles {
|
||||
state: std::sync::Mutex<State>,
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ impl Default for IndexedFiles {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, get_size2::GetSize)]
|
||||
enum State {
|
||||
/// The files of a package haven't been indexed yet.
|
||||
Lazy,
|
||||
|
@ -150,7 +150,7 @@ pub struct Indexed<'db> {
|
|||
_lifetime: PhantomData<&'db ()>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, get_size2::GetSize)]
|
||||
struct IndexedInner {
|
||||
files: FxHashSet<File>,
|
||||
diagnostics: Vec<IOErrorDiagnostic>,
|
||||
|
|
|
@ -13,7 +13,7 @@ mod portable;
|
|||
/// Path filtering based on an an exclude and include glob pattern set.
|
||||
///
|
||||
/// Exclude patterns take precedence over includes.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub struct IncludeExcludeFilter {
|
||||
include: IncludeFilter,
|
||||
exclude: ExcludeFilter,
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::glob::portable::AbsolutePortableGlobPattern;
|
|||
/// Two filters are equal if they're constructed from the same patterns (including order).
|
||||
/// Two filters that exclude the exact same files but were constructed from different patterns aren't considered
|
||||
/// equal.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub(crate) struct ExcludeFilter {
|
||||
ignore: Gitignore,
|
||||
}
|
||||
|
@ -118,10 +118,12 @@ impl ExcludeFilterBuilder {
|
|||
/// Two ignore matches are only equal if they're constructed from the same patterns (including order).
|
||||
/// Two matchers that were constructed from different patterns but result in
|
||||
/// including the same files don't compare equal.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, get_size2::GetSize)]
|
||||
struct Gitignore {
|
||||
#[get_size(ignore)]
|
||||
set: GlobSet,
|
||||
globs: Vec<IgnoreGlob>,
|
||||
#[get_size(ignore)]
|
||||
matches: Option<Arc<Pool<Vec<usize>>>>,
|
||||
}
|
||||
|
||||
|
@ -185,7 +187,7 @@ enum Match {
|
|||
Allow,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
struct IgnoreGlob {
|
||||
/// The pattern that was originally parsed.
|
||||
original: String,
|
||||
|
|
|
@ -29,13 +29,20 @@ const DFA_SIZE_LIMIT: usize = 1_000_000;
|
|||
///
|
||||
/// Because of that, two filters that include the exact same files but were
|
||||
/// constructed from different patterns (or even just order) compare unequal.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, get_size2::GetSize)]
|
||||
pub(crate) struct IncludeFilter {
|
||||
#[get_size(ignore)]
|
||||
glob_set: GlobSet,
|
||||
original_patterns: Box<[String]>,
|
||||
#[get_size(size_fn = dfa_memory_usage)]
|
||||
dfa: Option<dfa::dense::DFA<Vec<u32>>>,
|
||||
}
|
||||
|
||||
#[allow(clippy::ref_option)]
|
||||
fn dfa_memory_usage(dfa: &Option<dfa::dense::DFA<Vec<u32>>>) -> usize {
|
||||
dfa.as_ref().map(dfa::dense::DFA::memory_usage).unwrap_or(0)
|
||||
}
|
||||
|
||||
impl IncludeFilter {
|
||||
/// Whether the file matches any of the globs.
|
||||
pub(crate) fn match_file(&self, path: impl AsRef<SystemPath>) -> bool {
|
||||
|
|
|
@ -55,7 +55,7 @@ pub fn default_lints_registry() -> LintRegistry {
|
|||
/// 2. Running `ruff check` with different target versions results in different programs (settings) but
|
||||
/// it remains the same project. That's why program is a narrowed view of the project only
|
||||
/// holding on to the most fundamental settings required for checking.
|
||||
#[salsa::input]
|
||||
#[salsa::input(heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(Debug)]
|
||||
pub struct Project {
|
||||
/// The files that are open in the project, [`None`] if there are no open files.
|
||||
|
@ -636,7 +636,7 @@ impl Iterator for ProjectFilesIter<'_> {
|
|||
|
||||
impl FusedIterator for ProjectFilesIter<'_> {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, get_size2::GetSize)]
|
||||
pub struct IOErrorDiagnostic {
|
||||
file: Option<File>,
|
||||
error: IOErrorKind,
|
||||
|
@ -652,7 +652,7 @@ impl IOErrorDiagnostic {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Clone)]
|
||||
#[derive(Error, Debug, Clone, get_size2::GetSize)]
|
||||
enum IOErrorKind {
|
||||
#[error(transparent)]
|
||||
Walk(#[from] walk::WalkError),
|
||||
|
|
|
@ -19,7 +19,7 @@ pub mod pyproject;
|
|||
pub mod settings;
|
||||
pub mod value;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize))]
|
||||
pub struct ProjectMetadata {
|
||||
pub(super) name: Name,
|
||||
|
|
|
@ -36,7 +36,16 @@ use ty_python_semantic::{
|
|||
};
|
||||
|
||||
#[derive(
|
||||
Debug, Default, Clone, PartialEq, Eq, Combine, Serialize, Deserialize, OptionsMetadata,
|
||||
Debug,
|
||||
Default,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Combine,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
OptionsMetadata,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
@ -395,7 +404,16 @@ impl Options {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Default, Clone, Eq, PartialEq, Combine, Serialize, Deserialize, OptionsMetadata,
|
||||
Debug,
|
||||
Default,
|
||||
Clone,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Combine,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
OptionsMetadata,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
@ -516,7 +534,16 @@ pub struct EnvironmentOptions {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Default, Clone, Eq, PartialEq, Combine, Serialize, Deserialize, OptionsMetadata,
|
||||
Debug,
|
||||
Default,
|
||||
Clone,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Combine,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
OptionsMetadata,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
@ -679,11 +706,14 @@ impl SrcOptions {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Combine, Serialize, Deserialize, Hash)]
|
||||
#[derive(
|
||||
Debug, Default, Clone, Eq, PartialEq, Combine, Serialize, Deserialize, Hash, get_size2::GetSize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case", transparent)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct Rules {
|
||||
#[cfg_attr(feature = "schemars", schemars(with = "schema::Rules"))]
|
||||
#[get_size(ignore)] // TODO: Add `GetSize` support for `OrderMap`.
|
||||
inner: OrderMap<RangedValue<String>, RangedValue<Level>, BuildHasherDefault<FxHasher>>,
|
||||
}
|
||||
|
||||
|
@ -1002,7 +1032,9 @@ impl GlobFilterContext {
|
|||
}
|
||||
|
||||
/// The diagnostic output format.
|
||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Default, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, get_size2::GetSize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum OutputFormat {
|
||||
|
@ -1035,7 +1067,16 @@ impl From<OutputFormat> for DiagnosticFormat {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Default, Clone, Eq, PartialEq, Combine, Serialize, Deserialize, OptionsMetadata,
|
||||
Debug,
|
||||
Default,
|
||||
Clone,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Combine,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
OptionsMetadata,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
@ -1095,7 +1136,18 @@ pub struct TerminalOptions {
|
|||
/// [tool.ty.overrides.rules]
|
||||
/// possibly-unresolved-reference = "ignore"
|
||||
/// ```
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Combine, Serialize, Deserialize, RustDoc)]
|
||||
#[derive(
|
||||
Debug,
|
||||
Default,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Combine,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
RustDoc,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(transparent)]
|
||||
pub struct OverridesOptions(Vec<RangedValue<OverrideOptions>>);
|
||||
|
@ -1119,7 +1171,16 @@ impl Deref for OverridesOptions {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Default, Clone, Eq, PartialEq, Combine, Serialize, Deserialize, OptionsMetadata,
|
||||
Debug,
|
||||
Default,
|
||||
Clone,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Combine,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
OptionsMetadata,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
@ -1339,7 +1400,7 @@ impl RangedValue<OverrideOptions> {
|
|||
}
|
||||
|
||||
/// The options for an override but without the include/exclude patterns.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Combine)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Combine, get_size2::GetSize)]
|
||||
pub(super) struct InnerOverrideOptions {
|
||||
/// Raw rule options as specified in the configuration.
|
||||
/// Used when multiple overrides match a file and need to be merged.
|
||||
|
@ -1463,7 +1524,7 @@ pub enum TyTomlError {
|
|||
TomlSyntax(#[from] toml::de::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, get_size2::GetSize)]
|
||||
pub struct OptionDiagnostic {
|
||||
id: DiagnosticId,
|
||||
message: String,
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::{Db, glob::IncludeExcludeFilter};
|
|||
/// This can be achieved by adding a salsa query for the type checking specific settings.
|
||||
///
|
||||
/// Settings that are part of [`ty_python_semantic::ProgramSettings`] are not included here.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, get_size2::GetSize)]
|
||||
pub struct Settings {
|
||||
pub(super) rules: Arc<RuleSelection>,
|
||||
pub(super) terminal: TerminalSettings,
|
||||
|
@ -56,20 +56,20 @@ impl Settings {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default, get_size2::GetSize)]
|
||||
pub struct TerminalSettings {
|
||||
pub output_format: OutputFormat,
|
||||
pub error_on_warning: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub struct SrcSettings {
|
||||
pub respect_ignore_files: bool,
|
||||
pub files: IncludeExcludeFilter,
|
||||
}
|
||||
|
||||
/// A single configuration override that applies to files matching specific patterns.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub struct Override {
|
||||
/// File pattern filter to determine which files this override applies to.
|
||||
pub(super) files: IncludeExcludeFilter,
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::sync::Arc;
|
|||
use toml::Spanned;
|
||||
use ty_combine::Combine;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub enum ValueSource {
|
||||
/// Value loaded from a project's configuration file.
|
||||
///
|
||||
|
@ -84,7 +84,7 @@ impl Drop for ValueSourceGuard {
|
|||
///
|
||||
/// This ensures that two resolved configurations are identical even if the position of a value has changed
|
||||
/// or if the values were loaded from different sources.
|
||||
#[derive(Clone, serde::Serialize)]
|
||||
#[derive(Clone, serde::Serialize, get_size2::GetSize)]
|
||||
#[serde(transparent)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct RangedValue<T> {
|
||||
|
@ -325,6 +325,7 @@ where
|
|||
Ord,
|
||||
Hash,
|
||||
Combine,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[serde(transparent)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
@ -394,6 +395,7 @@ impl fmt::Display for RelativePathBuf {
|
|||
Ord,
|
||||
Hash,
|
||||
Combine,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[serde(transparent)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
|
|
@ -310,7 +310,7 @@ impl<'a> ProjectFilesWalker<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Clone)]
|
||||
#[derive(Error, Debug, Clone, get_size2::GetSize)]
|
||||
pub(crate) enum WalkError {
|
||||
#[error("`{path}`: {error}")]
|
||||
IOPathError { path: SystemPathBuf, error: String },
|
||||
|
|
|
@ -211,7 +211,7 @@ fn all_submodule_names_for_package(db: &dyn Db, file: File) -> Option<Vec<Name>>
|
|||
}
|
||||
|
||||
/// A module that resolves to a file (`lib.py` or `package/__init__.py`)
|
||||
#[salsa::tracked(debug)]
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct FileModule<'db> {
|
||||
#[returns(ref)]
|
||||
name: ModuleName,
|
||||
|
@ -226,7 +226,7 @@ pub struct FileModule<'db> {
|
|||
///
|
||||
/// Namespace packages are special because there are
|
||||
/// multiple possible paths and they have no corresponding code file.
|
||||
#[salsa::tracked(debug)]
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct NamespacePackage<'db> {
|
||||
#[returns(ref)]
|
||||
name: ModuleName,
|
||||
|
|
|
@ -45,7 +45,7 @@ pub fn resolve_real_module<'db>(db: &'db dyn Db, module_name: &ModuleName) -> Op
|
|||
}
|
||||
|
||||
/// Which files should be visible when doing a module query
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, get_size2::GetSize)]
|
||||
pub(crate) enum ModuleResolveMode {
|
||||
/// Stubs are allowed to appear.
|
||||
///
|
||||
|
@ -60,7 +60,7 @@ pub(crate) enum ModuleResolveMode {
|
|||
StubsNotAllowed,
|
||||
}
|
||||
|
||||
#[salsa::interned]
|
||||
#[salsa::interned(heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ModuleResolveModeIngredient<'db> {
|
||||
mode: ModuleResolveMode,
|
||||
|
@ -172,7 +172,7 @@ pub(crate) fn search_paths(db: &dyn Db, resolve_mode: ModuleResolveMode) -> Sear
|
|||
Program::get(db).search_paths(db).iter(db, resolve_mode)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub struct SearchPaths {
|
||||
/// Search paths that have been statically determined purely from reading
|
||||
/// ty's configuration settings. These shouldn't ever change unless the
|
||||
|
@ -643,7 +643,7 @@ impl<'db> Iterator for PthFileIterator<'db> {
|
|||
/// A thin wrapper around `ModuleName` to make it a Salsa ingredient.
|
||||
///
|
||||
/// This is needed because Salsa requires that all query arguments are salsa ingredients.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
struct ModuleNameIngredient<'db> {
|
||||
#[returns(ref)]
|
||||
pub(super) name: ModuleName,
|
||||
|
|
|
@ -74,7 +74,7 @@ pub(crate) enum TypeshedVersionsParseErrorKind {
|
|||
VersionParseError(#[from] PythonVersionDeserializationError),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub(crate) struct TypeshedVersions(FxHashMap<ModuleName, PyVersionRange>);
|
||||
|
||||
impl TypeshedVersions {
|
||||
|
@ -230,7 +230,7 @@ impl fmt::Display for TypeshedVersions {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, get_size2::GetSize)]
|
||||
pub(crate) enum PyVersionRange {
|
||||
AvailableFrom(RangeFrom<PythonVersion>),
|
||||
AvailableWithin(RangeInclusive<PythonVersion>),
|
||||
|
|
|
@ -13,7 +13,7 @@ use ruff_text_size::TextRange;
|
|||
use salsa::Durability;
|
||||
use salsa::Setter;
|
||||
|
||||
#[salsa::input(singleton)]
|
||||
#[salsa::input(singleton, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct Program {
|
||||
#[returns(ref)]
|
||||
pub python_version_with_source: PythonVersionWithSource,
|
||||
|
@ -93,7 +93,7 @@ pub struct ProgramSettings {
|
|||
pub search_paths: SearchPaths,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Default)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Default, get_size2::GetSize)]
|
||||
pub enum PythonVersionSource {
|
||||
/// Value loaded from a project's configuration file.
|
||||
ConfigFile(PythonVersionFileSource),
|
||||
|
@ -123,7 +123,7 @@ pub enum PythonVersionSource {
|
|||
|
||||
/// Information regarding the file and [`TextRange`] of the configuration
|
||||
/// from which we inferred the Python version.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, get_size2::GetSize)]
|
||||
pub struct PythonVersionFileSource {
|
||||
path: Arc<SystemPathBuf>,
|
||||
range: Option<TextRange>,
|
||||
|
@ -145,7 +145,7 @@ impl PythonVersionFileSource {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Clone)]
|
||||
#[derive(Eq, PartialEq, Debug, Clone, get_size2::GetSize)]
|
||||
pub struct PythonVersionWithSource {
|
||||
pub version: PythonVersion,
|
||||
pub source: PythonVersionSource,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/// The target platform to assume when resolving types.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, get_size2::GetSize)]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
derive(serde::Serialize, serde::Deserialize, ruff_macros::RustDoc),
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::unpack::{Unpack, UnpackPosition};
|
|||
/// because a new scope gets inserted before the `Definition` or a new place is inserted
|
||||
/// before this `Definition`. However, the ID can be considered stable and it is okay to use
|
||||
/// `Definition` in cross-module` salsa queries or as a field on other salsa tracked structs.
|
||||
#[salsa::tracked(debug)]
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct Definition<'db> {
|
||||
/// The file in which the definition occurs.
|
||||
pub file: File,
|
||||
|
@ -645,7 +645,7 @@ impl DefinitionCategory {
|
|||
/// [`DefinitionKind`] fields in salsa tracked structs should be tracked (attributed with `#[tracked]`)
|
||||
/// because the kind is a thin wrapper around [`AstNodeRef`]. See the [`AstNodeRef`] documentation
|
||||
/// for an in-depth explanation of why this is necessary.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub enum DefinitionKind<'db> {
|
||||
Import(ImportDefinitionKind),
|
||||
ImportFrom(ImportFromDefinitionKind),
|
||||
|
@ -834,7 +834,7 @@ impl DefinitionKind<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Hash, get_size2::GetSize)]
|
||||
pub(crate) enum TargetKind<'db> {
|
||||
Sequence(UnpackPosition, Unpack<'db>),
|
||||
/// Name, attribute, or subscript.
|
||||
|
@ -850,7 +850,7 @@ impl<'db> From<Option<(UnpackPosition, Unpack<'db>)>> for TargetKind<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct StarImportDefinitionKind {
|
||||
node: AstNodeRef<ast::StmtImportFrom>,
|
||||
symbol_id: ScopedSymbolId,
|
||||
|
@ -880,7 +880,7 @@ impl StarImportDefinitionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct MatchPatternDefinitionKind {
|
||||
pattern: AstNodeRef<ast::Pattern>,
|
||||
identifier: AstNodeRef<ast::Identifier>,
|
||||
|
@ -902,7 +902,7 @@ impl MatchPatternDefinitionKind {
|
|||
/// But if the target is an attribute or subscript, its definition is not in the comprehension's scope;
|
||||
/// it is in the scope in which the root variable is bound.
|
||||
/// TODO: currently we don't model this correctly and simply assume that it is in a scope outside the comprehension.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct ComprehensionDefinitionKind<'db> {
|
||||
target_kind: TargetKind<'db>,
|
||||
iterable: AstNodeRef<ast::Expr>,
|
||||
|
@ -933,7 +933,7 @@ impl<'db> ComprehensionDefinitionKind<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct ImportDefinitionKind {
|
||||
node: AstNodeRef<ast::StmtImport>,
|
||||
alias_index: usize,
|
||||
|
@ -954,7 +954,7 @@ impl ImportDefinitionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct ImportFromDefinitionKind {
|
||||
node: AstNodeRef<ast::StmtImportFrom>,
|
||||
alias_index: usize,
|
||||
|
@ -975,7 +975,7 @@ impl ImportFromDefinitionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct AssignmentDefinitionKind<'db> {
|
||||
target_kind: TargetKind<'db>,
|
||||
value: AstNodeRef<ast::Expr>,
|
||||
|
@ -996,7 +996,7 @@ impl<'db> AssignmentDefinitionKind<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct AnnotatedAssignmentDefinitionKind {
|
||||
annotation: AstNodeRef<ast::Expr>,
|
||||
value: Option<AstNodeRef<ast::Expr>>,
|
||||
|
@ -1017,7 +1017,7 @@ impl AnnotatedAssignmentDefinitionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct WithItemDefinitionKind<'db> {
|
||||
target_kind: TargetKind<'db>,
|
||||
context_expr: AstNodeRef<ast::Expr>,
|
||||
|
@ -1043,7 +1043,7 @@ impl<'db> WithItemDefinitionKind<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct ForStmtDefinitionKind<'db> {
|
||||
target_kind: TargetKind<'db>,
|
||||
iterable: AstNodeRef<ast::Expr>,
|
||||
|
@ -1069,7 +1069,7 @@ impl<'db> ForStmtDefinitionKind<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, get_size2::GetSize)]
|
||||
pub struct ExceptHandlerDefinitionKind {
|
||||
handler: AstNodeRef<ast::ExceptHandlerExceptHandler>,
|
||||
is_star: bool,
|
||||
|
|
|
@ -10,7 +10,7 @@ use salsa;
|
|||
/// a type expression. For example, in `self.x: <annotation> = <value>`, the
|
||||
/// `<annotation>` is inferred as a type expression, while `<value>` is inferred
|
||||
/// as a normal expression.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
pub(crate) enum ExpressionKind {
|
||||
Normal,
|
||||
TypeExpression,
|
||||
|
@ -31,7 +31,7 @@ pub(crate) enum ExpressionKind {
|
|||
/// * a return type of a cross-module query
|
||||
/// * a field of a type that is a return type of a cross-module query
|
||||
/// * an argument of a cross-module query
|
||||
#[salsa::tracked(debug)]
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub(crate) struct Expression<'db> {
|
||||
/// The file in which the expression occurs.
|
||||
pub(crate) file: File,
|
||||
|
|
|
@ -117,7 +117,7 @@ pub(crate) enum PredicateNode<'db> {
|
|||
StarImportPlaceholder(StarImportPlaceholderPredicate<'db>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum ClassPatternKind {
|
||||
Irrefutable,
|
||||
Refutable,
|
||||
|
@ -130,7 +130,7 @@ impl ClassPatternKind {
|
|||
}
|
||||
|
||||
/// Pattern kinds for which we support type narrowing and/or static reachability analysis.
|
||||
#[derive(Debug, Clone, Hash, PartialEq, salsa::Update)]
|
||||
#[derive(Debug, Clone, Hash, PartialEq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum PatternPredicateKind<'db> {
|
||||
Singleton(Singleton),
|
||||
Value(Expression<'db>),
|
||||
|
@ -140,7 +140,7 @@ pub(crate) enum PatternPredicateKind<'db> {
|
|||
Unsupported,
|
||||
}
|
||||
|
||||
#[salsa::tracked(debug)]
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub(crate) struct PatternPredicate<'db> {
|
||||
pub(crate) file: File,
|
||||
|
||||
|
@ -206,7 +206,7 @@ impl<'db> PatternPredicate<'db> {
|
|||
/// - If it resolves to a possibly bound symbol, then the predicate resolves to [`Truthiness::Ambiguous`]
|
||||
///
|
||||
/// [Truthiness]: [crate::types::Truthiness]
|
||||
#[salsa::tracked(debug)]
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub(crate) struct StarImportPlaceholderPredicate<'db> {
|
||||
pub(crate) importing_file: File,
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::{
|
|||
};
|
||||
|
||||
/// A cross-module identifier of a scope that can be used as a salsa query parameter.
|
||||
#[salsa::tracked(debug)]
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct ScopeId<'db> {
|
||||
pub file: File,
|
||||
|
||||
|
|
|
@ -385,7 +385,7 @@ pub(crate) use todo_type;
|
|||
/// # Ordering
|
||||
/// Ordering is based on the property instance's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the property instance was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct PropertyInstanceType<'db> {
|
||||
getter: Option<Type<'db>>,
|
||||
|
@ -6079,7 +6079,7 @@ impl<'db> From<&Type<'db>> for Type<'db> {
|
|||
/// This is represented as an enum (with some variants using `Cow`), and not an `FnMut` trait,
|
||||
/// since we sometimes have to apply type mappings lazily (e.g., to the signature of a function
|
||||
/// literal).
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub enum TypeMapping<'a, 'db> {
|
||||
/// Applies a specialization to the type
|
||||
Specialization(Specialization<'db>),
|
||||
|
@ -6610,7 +6610,7 @@ impl<'db> InvalidTypeExpression<'db> {
|
|||
}
|
||||
|
||||
/// Data regarding a `warnings.deprecated` or `typing_extensions.deprecated` decorator.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct DeprecatedInstance<'db> {
|
||||
/// The message for the deprecation
|
||||
|
@ -6622,7 +6622,7 @@ impl get_size2::GetSize for DeprecatedInstance<'_> {}
|
|||
|
||||
/// Contains information about instances of `dataclasses.Field`, typically created using
|
||||
/// `dataclasses.field()`.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct FieldInstance<'db> {
|
||||
/// The type of the default value for this field. This is derived from the `default` or
|
||||
|
@ -6648,7 +6648,7 @@ impl<'db> FieldInstance<'db> {
|
|||
|
||||
/// Whether this typevar was created via the legacy `TypeVar` constructor, using PEP 695 syntax,
|
||||
/// or an implicit typevar like `Self` was used.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub enum TypeVarKind {
|
||||
/// `T = TypeVar("T")`
|
||||
Legacy,
|
||||
|
@ -6694,7 +6694,7 @@ pub enum TypeVarKind {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the type var instance's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the type var instance was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct TypeVarInstance<'db> {
|
||||
/// The name of this TypeVar (e.g. `T`)
|
||||
|
@ -6789,7 +6789,7 @@ impl<'db> TypeVarInstance<'db> {
|
|||
}
|
||||
|
||||
/// Where a type variable is bound and usable.
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub enum BindingContext<'db> {
|
||||
/// The definition of the generic class, function, or type alias that binds this typevar.
|
||||
Definition(Definition<'db>),
|
||||
|
@ -6809,7 +6809,7 @@ impl<'db> BindingContext<'db> {
|
|||
|
||||
/// A type variable that has been bound to a generic context, and which can be specialized to a
|
||||
/// concrete type.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct BoundTypeVarInstance<'db> {
|
||||
pub typevar: TypeVarInstance<'db>,
|
||||
|
@ -6874,7 +6874,7 @@ impl<'db> BoundTypeVarInstance<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub enum TypeVarVariance {
|
||||
Invariant,
|
||||
Covariant,
|
||||
|
@ -6896,7 +6896,7 @@ impl TypeVarVariance {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
|
||||
pub enum TypeVarBoundOrConstraints<'db> {
|
||||
UpperBound(Type<'db>),
|
||||
Constraints(UnionType<'db>),
|
||||
|
@ -7916,7 +7916,7 @@ impl From<bool> for Truthiness {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the bounded method's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the bounded method was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct BoundMethodType<'db> {
|
||||
/// The function that is being bound. Corresponds to the `__func__` attribute on a
|
||||
|
@ -7992,7 +7992,7 @@ impl<'db> BoundMethodType<'db> {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the callable type's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the callable type was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct CallableType<'db> {
|
||||
#[returns(ref)]
|
||||
|
@ -8270,7 +8270,7 @@ pub enum WrapperDescriptorKind {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the module literal's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the module literal was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct ModuleLiteralType<'db> {
|
||||
/// The imported module.
|
||||
|
@ -8380,7 +8380,7 @@ impl<'db> ModuleLiteralType<'db> {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the type alias's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the alias was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct PEP695TypeAliasType<'db> {
|
||||
#[returns(ref)]
|
||||
|
@ -8427,7 +8427,7 @@ impl<'db> PEP695TypeAliasType<'db> {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the type alias's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the alias was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct BareTypeAliasType<'db> {
|
||||
#[returns(ref)]
|
||||
|
@ -8522,7 +8522,7 @@ pub(super) struct MetaclassCandidate<'db> {
|
|||
explicit_metaclass_of: ClassLiteral<'db>,
|
||||
}
|
||||
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct UnionType<'db> {
|
||||
/// The union type includes values in any of these types.
|
||||
#[returns(deref)]
|
||||
|
@ -8744,7 +8744,7 @@ impl<'db> UnionType<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=IntersectionType::heap_size)]
|
||||
pub struct IntersectionType<'db> {
|
||||
/// The intersection type includes only values in all of these types.
|
||||
#[returns(ref)]
|
||||
|
@ -8938,12 +8938,17 @@ impl<'db> IntersectionType<'db> {
|
|||
pub fn has_one_element(&self, db: &'db dyn Db) -> bool {
|
||||
(self.positive(db).len() + self.negative(db).len()) == 1
|
||||
}
|
||||
|
||||
fn heap_size((positive, negative): &(FxOrderSet<Type<'db>>, FxOrderSet<Type<'db>>)) -> usize {
|
||||
ruff_memory_usage::order_set_heap_size(positive)
|
||||
+ ruff_memory_usage::order_set_heap_size(negative)
|
||||
}
|
||||
}
|
||||
|
||||
/// # Ordering
|
||||
/// Ordering is based on the string literal's salsa-assigned id and not on its value.
|
||||
/// The id may change between runs, or when the string literal was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct StringLiteralType<'db> {
|
||||
#[returns(deref)]
|
||||
|
@ -8971,7 +8976,7 @@ impl<'db> StringLiteralType<'db> {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the byte literal's salsa-assigned id and not on its value.
|
||||
/// The id may change between runs, or when the byte literal was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct BytesLiteralType<'db> {
|
||||
#[returns(deref)]
|
||||
|
@ -8996,7 +9001,7 @@ impl<'db> BytesLiteralType<'db> {
|
|||
/// NO = 0
|
||||
/// YES = 1
|
||||
/// ```
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct EnumLiteralType<'db> {
|
||||
/// A reference to the enum class this literal belongs to
|
||||
|
@ -9017,7 +9022,7 @@ impl<'db> EnumLiteralType<'db> {
|
|||
|
||||
/// Type that represents the set of all inhabitants (`dict` instances) that conform to
|
||||
/// a given `TypedDict` schema.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct TypedDictType<'db> {
|
||||
/// A reference to the class (inheriting from `typing.TypedDict`) that specifies the
|
||||
|
@ -9104,7 +9109,7 @@ impl BoundSuperError<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, get_size2::GetSize)]
|
||||
pub enum SuperOwnerKind<'db> {
|
||||
Dynamic(DynamicType),
|
||||
Class(ClassType<'db>),
|
||||
|
@ -9193,7 +9198,7 @@ impl<'db> From<SuperOwnerKind<'db>> for Type<'db> {
|
|||
}
|
||||
|
||||
/// Represent a bound super object like `super(PivotClass, owner)`
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct BoundSuperType<'db> {
|
||||
pub pivot_class: ClassBase<'db>,
|
||||
pub owner: SuperOwnerKind<'db>,
|
||||
|
@ -9381,7 +9386,7 @@ impl<'db> BoundSuperType<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct TypeIsType<'db> {
|
||||
return_type: Type<'db>,
|
||||
/// The ID of the scope to which the place belongs
|
||||
|
|
|
@ -212,7 +212,7 @@ impl CodeGeneratorKind {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the generic aliases's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the alias was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct GenericAlias<'db> {
|
||||
pub(crate) origin: ClassLiteral<'db>,
|
||||
|
@ -1147,7 +1147,7 @@ pub(crate) struct Field<'db> {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the class's id assigned by salsa and not on the class literal's values.
|
||||
/// The id may change between runs, or when the class literal was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct ClassLiteral<'db> {
|
||||
/// Name of the class at definition
|
||||
|
@ -2998,7 +2998,7 @@ pub(super) enum SolidBaseKind {
|
|||
/// Feel free to expand this enum if you ever find yourself using the same class in multiple
|
||||
/// places.
|
||||
/// Note: good candidates are any classes in `[crate::module_resolver::module::KnownModule]`
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, get_size2::GetSize)]
|
||||
#[cfg_attr(test, derive(strum_macros::EnumIter))]
|
||||
pub enum KnownClass {
|
||||
// To figure out where an stdlib symbol is defined, you can go into `crates/ty_vendored`
|
||||
|
|
|
@ -120,6 +120,8 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl get_size2::GetSize for FunctionDecorators {}
|
||||
|
||||
impl FunctionDecorators {
|
||||
pub(super) fn from_decorator_type(db: &dyn Db, decorator_type: Type) -> Self {
|
||||
match decorator_type {
|
||||
|
@ -184,7 +186,7 @@ impl Default for DataclassTransformerParams {
|
|||
/// Ordering is based on the function's id assigned by salsa and not on the function literal's
|
||||
/// values. The id may change between runs, or when the function literal was garbage collected and
|
||||
/// recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct OverloadLiteral<'db> {
|
||||
/// Name of the function at definition.
|
||||
|
@ -406,7 +408,7 @@ impl<'db> OverloadLiteral<'db> {
|
|||
/// Ordering is based on the function's id assigned by salsa and not on the function literal's
|
||||
/// values. The id may change between runs, or when the function literal was garbage collected and
|
||||
/// recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct FunctionLiteral<'db> {
|
||||
pub(crate) last_definition: OverloadLiteral<'db>,
|
||||
|
@ -433,6 +435,9 @@ pub struct FunctionLiteral<'db> {
|
|||
inherited_generic_context: Option<GenericContext<'db>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for FunctionLiteral<'_> {}
|
||||
|
||||
fn walk_function_literal<'db, V: super::visitor::TypeVisitor<'db> + ?Sized>(
|
||||
db: &'db dyn Db,
|
||||
function: FunctionLiteral<'db>,
|
||||
|
@ -609,7 +614,7 @@ impl<'db> FunctionLiteral<'db> {
|
|||
|
||||
/// Represents a function type, which might be a non-generic function, or a specialization of a
|
||||
/// generic function.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct FunctionType<'db> {
|
||||
pub(crate) literal: FunctionLiteral<'db>,
|
||||
|
@ -1057,7 +1062,15 @@ fn last_definition_signature_cycle_initial<'db>(
|
|||
/// Non-exhaustive enumeration of known functions (e.g. `builtins.reveal_type`, ...) that might
|
||||
/// have special behavior.
|
||||
#[derive(
|
||||
Debug, Copy, Clone, PartialEq, Eq, Hash, strum_macros::EnumString, strum_macros::IntoStaticStr,
|
||||
Debug,
|
||||
Copy,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Hash,
|
||||
strum_macros::EnumString,
|
||||
strum_macros::IntoStaticStr,
|
||||
get_size2::GetSize,
|
||||
)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[cfg_attr(test, derive(strum_macros::EnumIter))]
|
||||
|
|
|
@ -89,7 +89,7 @@ pub(crate) fn bind_typevar<'db>(
|
|||
/// # Ordering
|
||||
/// Ordering is based on the context's salsa-assigned id and not on its values.
|
||||
/// The id may change between runs, or when the context was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=GenericContext::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct GenericContext<'db> {
|
||||
#[returns(ref)]
|
||||
|
@ -363,6 +363,10 @@ impl<'db> GenericContext<'db> {
|
|||
.collect();
|
||||
Self::new(db, variables)
|
||||
}
|
||||
|
||||
fn heap_size((variables,): &(FxOrderSet<BoundTypeVarInstance<'db>>,)) -> usize {
|
||||
ruff_memory_usage::order_set_heap_size(variables)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
|
@ -390,7 +394,7 @@ impl std::fmt::Display for LegacyGenericBase {
|
|||
///
|
||||
/// TODO: Handle nested specializations better, with actual parent links to the specialization of
|
||||
/// the lexically containing context.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub struct Specialization<'db> {
|
||||
pub(crate) generic_context: GenericContext<'db>,
|
||||
#[returns(deref)]
|
||||
|
@ -401,6 +405,9 @@ pub struct Specialization<'db> {
|
|||
tuple_inner: Option<TupleType<'db>>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for Specialization<'_> {}
|
||||
|
||||
pub(super) fn walk_specialization<'db, V: super::visitor::TypeVisitor<'db> + ?Sized>(
|
||||
db: &'db dyn Db,
|
||||
specialization: Specialization<'db>,
|
||||
|
@ -655,7 +662,7 @@ impl<'db> Specialization<'db> {
|
|||
///
|
||||
/// You will usually use [`Specialization`] instead of this type. This type is used when we need to
|
||||
/// substitute types for type variables before we have fully constructed a [`Specialization`].
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub struct PartialSpecialization<'a, 'db> {
|
||||
generic_context: GenericContext<'db>,
|
||||
types: Cow<'a, [Type<'db>]>,
|
||||
|
|
|
@ -70,7 +70,7 @@ impl<'db> Deref for ProtocolClassLiteral<'db> {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the protocol interface member's salsa-assigned id and not on its members.
|
||||
/// The id may change between runs, or when the protocol instance members was garbage collected and recreated.
|
||||
#[salsa::interned(debug)]
|
||||
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub(super) struct ProtocolInterface<'db> {
|
||||
#[returns(ref)]
|
||||
|
@ -241,7 +241,7 @@ impl<'db> ProtocolInterface<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, salsa::Update)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(super) struct ProtocolMemberData<'db> {
|
||||
kind: ProtocolMemberKind<'db>,
|
||||
qualifiers: TypeQualifiers,
|
||||
|
@ -319,7 +319,7 @@ impl<'db> ProtocolMemberData<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, salsa::Update, Hash)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, salsa::Update, Hash, get_size2::GetSize)]
|
||||
enum ProtocolMemberKind<'db> {
|
||||
Method(CallableType<'db>),
|
||||
Property(PropertyInstanceType<'db>),
|
||||
|
|
|
@ -125,7 +125,7 @@ impl TupleLength {
|
|||
/// # Ordering
|
||||
/// Ordering is based on the tuple's salsa-assigned id and not on its elements.
|
||||
/// The id may change between runs, or when the tuple was garbage collected and recreated.
|
||||
#[salsa::interned(debug, constructor=new_internal)]
|
||||
#[salsa::interned(debug, constructor=new_internal, heap_size=ruff_memory_usage::heap_size)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
pub struct TupleType<'db> {
|
||||
#[returns(ref)]
|
||||
|
@ -223,7 +223,7 @@ impl<'db> TupleType<'db> {
|
|||
// N.B. If this method is not Salsa-tracked, we take 10 minutes to check
|
||||
// `static-frame` as part of a mypy_primer run! This is because it's called
|
||||
// from `NominalInstanceType::class()`, which is a very hot method.
|
||||
#[salsa::tracked]
|
||||
#[salsa::tracked(heap_size=ruff_memory_usage::heap_size)]
|
||||
pub(crate) fn to_class_type(self, db: &'db dyn Db) -> ClassType<'db> {
|
||||
let tuple_class = KnownClass::Tuple
|
||||
.try_to_class_literal(db)
|
||||
|
@ -302,7 +302,7 @@ pub(crate) type TupleSpec<'db> = Tuple<Type<'db>>;
|
|||
///
|
||||
/// Our tuple representation can hold instances of any Rust type. For tuples containing Python
|
||||
/// types, use [`TupleSpec`], which defines some additional type-specific methods.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub struct FixedLengthTuple<T>(Vec<T>);
|
||||
|
||||
impl<T> FixedLengthTuple<T> {
|
||||
|
@ -516,7 +516,7 @@ impl<'db> PySlice<'db> for FixedLengthTuple<Type<'db>> {
|
|||
///
|
||||
/// Our tuple representation can hold instances of any Rust type. For tuples containing Python
|
||||
/// types, use [`TupleSpec`], which defines some additional type-specific methods.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub struct VariableLengthTuple<T> {
|
||||
pub(crate) prefix: Vec<T>,
|
||||
pub(crate) variable: T,
|
||||
|
@ -956,7 +956,7 @@ impl<'db> PyIndex<'db> for &VariableLengthTuple<Type<'db>> {
|
|||
///
|
||||
/// Our tuple representation can hold instances of any Rust type. For tuples containing Python
|
||||
/// types, use [`TupleSpec`], which defines some additional type-specific methods.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub enum Tuple<T> {
|
||||
Fixed(FixedLengthTuple<T>),
|
||||
Variable(VariableLengthTuple<T>),
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::semantic_index::scope::{FileScopeId, ScopeId};
|
|||
/// * a return type of a cross-module query
|
||||
/// * a field of a type that is a return type of a cross-module query
|
||||
/// * an argument of a cross-module query
|
||||
#[salsa::tracked(debug)]
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub(crate) struct Unpack<'db> {
|
||||
pub(crate) file: File,
|
||||
|
||||
|
@ -46,6 +46,9 @@ pub(crate) struct Unpack<'db> {
|
|||
pub(crate) value: UnpackValue<'db>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for Unpack<'_> {}
|
||||
|
||||
impl<'db> Unpack<'db> {
|
||||
pub(crate) fn target<'ast>(
|
||||
self,
|
||||
|
@ -67,7 +70,7 @@ impl<'db> Unpack<'db> {
|
|||
}
|
||||
|
||||
/// The expression that is being unpacked.
|
||||
#[derive(Clone, Copy, Debug, Hash, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) struct UnpackValue<'db> {
|
||||
/// The kind of unpack expression
|
||||
kind: UnpackKind,
|
||||
|
@ -99,7 +102,7 @@ impl<'db> UnpackValue<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum EvaluationMode {
|
||||
Sync,
|
||||
Async,
|
||||
|
@ -119,7 +122,7 @@ impl EvaluationMode {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum UnpackKind {
|
||||
/// An iterable expression like the one in a `for` loop or a comprehension.
|
||||
Iterable { mode: EvaluationMode },
|
||||
|
@ -130,7 +133,7 @@ pub(crate) enum UnpackKind {
|
|||
}
|
||||
|
||||
/// The position of the target element in an unpacking.
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, salsa::Update)]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, salsa::Update, get_size2::GetSize)]
|
||||
pub(crate) enum UnpackPosition {
|
||||
/// The target element is in the first position of the unpacking.
|
||||
First,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue