Skip to content

Create CrateInput and CrateConfigurationInput for CrateLongId and CrateConfiguration in preperation for salsa upgrade #7831

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: spr/main/b2dbe3c9
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/cairo-lang-defs/src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -737,11 +737,11 @@ enum CrateCached {
Virtual { name: SmolStr, file_id: FileIdCached, settings: String },
}
impl CrateCached {
fn new(crate_id: CrateLongId, _ctx: &mut DefCacheSavingContext<'_>) -> Self {
fn new(crate_id: CrateLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
match crate_id {
CrateLongId::Real { name, discriminator } => CrateCached::Real { name, discriminator },
CrateLongId::Virtual { name, file_id, settings, cache_file: _ } => {
CrateCached::Virtual { name, file_id: FileIdCached::new(file_id, _ctx), settings }
CrateCached::Virtual { name, file_id: FileIdCached::new(file_id, ctx), settings }
}
}
}
Expand Down
18 changes: 9 additions & 9 deletions crates/cairo-lang-defs/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;

use cairo_lang_diagnostics::{DiagnosticNote, Maybe, PluginFileDiagnosticNotes, ToMaybe};
use cairo_lang_filesystem::ids::{
CrateId, CrateLongId, Directory, FileId, FileKind, FileLongId, VirtualFile,
CrateId, CrateInput, Directory, FileId, FileKind, FileLongId, VirtualFile,
};
use cairo_lang_parser::db::ParserGroup;
use cairo_lang_syntax::attribute::consts::{
Expand Down Expand Up @@ -106,7 +106,7 @@ pub trait DefsGroup: ParserGroup {
#[salsa::input]
fn macro_plugin_overrides_input(
&self,
) -> Arc<OrderedHashMap<CrateLongId, Arc<[MacroPluginLongId]>>>;
) -> Arc<OrderedHashMap<CrateInput, Arc<[MacroPluginLongId]>>>;

/// Interned version of `macro_plugin_overrides_input`.
fn macro_plugin_overrides(&self) -> Arc<OrderedHashMap<CrateId, Arc<[MacroPluginId]>>>;
Expand All @@ -131,7 +131,7 @@ pub trait DefsGroup: ParserGroup {
#[salsa::input]
fn inline_macro_plugin_overrides_input(
&self,
) -> Arc<OrderedHashMap<CrateLongId, Arc<OrderedHashMap<String, InlineMacroExprPluginLongId>>>>;
) -> Arc<OrderedHashMap<CrateInput, Arc<OrderedHashMap<String, InlineMacroExprPluginLongId>>>>;

/// Interned version of `inline_macro_plugin_overrides_input`.
fn inline_macro_plugin_overrides(
Expand Down Expand Up @@ -353,7 +353,7 @@ pub fn macro_plugin_overrides(
inp.iter()
.map(|(crate_id, plugins)| {
(
crate_id.clone().intern(db),
crate_id.clone().into_crate_long_id(db).intern(db),
Arc::from(plugins.iter().map(|plugin| plugin.clone().intern(db)).collect_vec()),
)
})
Expand All @@ -369,7 +369,7 @@ pub fn inline_macro_plugin_overrides(
inp.iter()
.map(|(crate_id, plugins)| {
(
crate_id.clone().intern(db),
crate_id.clone().into_crate_long_id(db).intern(db),
Arc::new(
plugins
.iter()
Expand Down Expand Up @@ -1426,11 +1426,11 @@ pub trait DefsGroupEx: DefsGroup {
crate_id: CrateId,
plugins: Arc<[MacroPluginId]>,
) {
let crate_long_id = crate_id.lookup_intern(self);
let crate_input = self.crate_input(crate_id);
let mut overrides = self.macro_plugin_overrides_input().as_ref().clone();
let plugins =
plugins.iter().map(|plugin| self.lookup_intern_macro_plugin(*plugin)).collect();
overrides.insert(crate_long_id, plugins);
overrides.insert(crate_input, plugins);
self.set_macro_plugin_overrides_input(Arc::new(overrides));
}

Expand All @@ -1442,7 +1442,7 @@ pub trait DefsGroupEx: DefsGroup {
crate_id: CrateId,
plugins: Arc<OrderedHashMap<String, InlineMacroExprPluginId>>,
) {
let crate_id = crate_id.lookup_intern(self);
let crate_input = self.crate_input(crate_id);
let mut overrides = self.inline_macro_plugin_overrides_input().as_ref().clone();
let plugins = Arc::new(
plugins
Expand All @@ -1452,7 +1452,7 @@ pub trait DefsGroupEx: DefsGroup {
})
.collect(),
);
overrides.insert(crate_id, plugins);
overrides.insert(crate_input, plugins);
self.set_inline_macro_plugin_overrides_input(Arc::new(overrides));
}
}
Expand Down
83 changes: 61 additions & 22 deletions crates/cairo-lang-filesystem/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use smol_str::{SmolStr, ToSmolStr};
use crate::cfg::CfgSet;
use crate::flag::Flag;
use crate::ids::{
BlobId, BlobLongId, CodeMapping, CodeOrigin, CrateId, CrateLongId, Directory, FileId,
FileInput, FileLongId, FlagId, FlagLongId, VirtualFile,
BlobId, BlobLongId, CodeMapping, CodeOrigin, CrateId, CrateInput, CrateLongId, Directory,
DirectoryInput, FileId, FileInput, FileLongId, FlagId, FlagLongId, VirtualFile,
};
use crate::span::{FileSummary, TextOffset, TextSpan, TextWidth};

Expand Down Expand Up @@ -44,8 +44,28 @@ impl From<CrateIdentifier> for SmolStr {
}
}

/// A configuration per crate.
/// Same as `CrateConfiguration` but without interning the root directory.
/// This is used to avoid the need to intern the file id inside salsa database inputs.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CrateConfigurationInput {
pub root: DirectoryInput,
pub settings: CrateSettings,
pub cache_file: Option<BlobLongId>,
}

impl CrateConfigurationInput {
/// Converts the input into an [`CrateConfiguration`].
pub fn into_crate_configuration(self, db: &dyn FilesGroup) -> CrateConfiguration {
CrateConfiguration {
root: self.root.into_directory(db),
settings: self.settings,
cache_file: self.cache_file.map(|blob_long_id| blob_long_id.intern(db)),
}
}
}

/// A configuration per crate.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct CrateConfiguration {
/// The root directory of the crate.
pub root: Directory,
Expand All @@ -57,10 +77,19 @@ impl CrateConfiguration {
pub fn default_for_root(root: Directory) -> Self {
Self { root, settings: CrateSettings::default(), cache_file: None }
}

/// Converts the configuration into an [`CrateConfigurationInput`].
pub fn into_crate_configuration_input(self, db: &dyn FilesGroup) -> CrateConfigurationInput {
CrateConfigurationInput {
root: self.root.into_directory_input(db),
settings: self.settings,
cache_file: self.cache_file.map(|blob_id| blob_id.lookup_intern(db)),
}
}
}

/// Same as `CrateConfiguration` but without the root directory.
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub struct CrateSettings {
/// The name reflecting how the crate is referred to in the Cairo code e.g. `use crate_name::`.
/// If set to [`None`] then [`CrateIdentifier`] key will be used as a name.
Expand Down Expand Up @@ -137,7 +166,7 @@ impl Edition {
}

/// The settings for a dependency.
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub struct DependencySettings {
/// A unique string allowing identifying different copies of the same dependency
/// in the compilation unit.
Expand Down Expand Up @@ -191,7 +220,7 @@ pub trait FilesGroup: ExternalFiles {

/// Main input of the project. Lists all the crates configurations.
#[salsa::input]
fn crate_configs_input(&self) -> Arc<OrderedHashMap<CrateLongId, CrateConfiguration>>;
fn crate_configs_input(&self) -> Arc<OrderedHashMap<CrateInput, CrateConfigurationInput>>;

/// Interned version of `crate_configs_input`.
fn crate_configs(&self) -> Arc<OrderedHashMap<CrateId, CrateConfiguration>>;
Expand Down Expand Up @@ -237,6 +266,12 @@ pub trait FilesGroup: ExternalFiles {

/// Create an input file from an interned file id.
fn file_input(&self, file_id: FileId) -> FileInput;

/// Create an input crate from an interned crate id.
fn crate_input(&self, crt: CrateId) -> CrateInput;

/// Create an input crate configuration from a [`CrateConfiguration`].
fn crate_configuration_input(&self, config: CrateConfiguration) -> CrateConfigurationInput;
}

pub fn init_files_group(db: &mut (dyn FilesGroup + 'static)) {
Expand All @@ -262,7 +297,12 @@ pub fn crate_configs(db: &dyn FilesGroup) -> Arc<OrderedHashMap<CrateId, CrateCo
let inp = db.crate_configs_input();
Arc::new(
inp.iter()
.map(|(crate_id, config)| (crate_id.clone().intern(db), config.clone()))
.map(|(crate_input, config)| {
(
crate_input.clone().into_crate_long_id(db).intern(db),
config.clone().into_crate_configuration(db),
)
})
.collect(),
)
}
Expand All @@ -276,6 +316,17 @@ fn file_input(db: &dyn FilesGroup, file_id: FileId) -> FileInput {
file_id.lookup_intern(db).into_file_input(db)
}

fn crate_input(db: &dyn FilesGroup, crt: CrateId) -> CrateInput {
crt.lookup_intern(db).into_crate_input(db)
}

fn crate_configuration_input(
db: &dyn FilesGroup,
config: CrateConfiguration,
) -> CrateConfigurationInput {
config.clone().into_crate_configuration_input(db)
}

pub fn init_dev_corelib(db: &mut (dyn FilesGroup + 'static), core_lib_dir: PathBuf) {
db.set_crate_config(
CrateId::core(db),
Expand Down Expand Up @@ -312,10 +363,10 @@ pub trait FilesGroupEx: FilesGroup {
}
/// Sets the root directory of the crate. None value removes the crate.
fn set_crate_config(&mut self, crt: CrateId, root: Option<CrateConfiguration>) {
let crt = self.lookup_intern_crate(crt);
let crt = self.crate_input(crt);
let mut crate_configs = self.crate_configs_input().as_ref().clone();
match root {
Some(root) => crate_configs.insert(crt, root),
Some(root) => crate_configs.insert(crt, self.crate_configuration_input(root)),
None => crate_configs.swap_remove(&crt),
};
self.set_crate_configs_input(Arc::new(crate_configs));
Expand Down Expand Up @@ -397,19 +448,7 @@ fn get_flag(db: &dyn FilesGroup, id: FlagId) -> Option<Arc<Flag>> {
}

fn blob_content(db: &dyn FilesGroup, blob: BlobId) -> Option<Arc<[u8]>> {
match blob.lookup_intern(db) {
BlobLongId::OnDisk(path) => {
// This does not result in performance cost due to OS caching and the fact that salsa
// will re-execute only this single query if the file content did not change.
db.salsa_runtime().report_synthetic_read(Durability::LOW);

match fs::read(path) {
Ok(content) => Some(content.into()),
Err(_) => None,
}
}
BlobLongId::Virtual(content) => Some(content),
}
blob.lookup_intern(db).content(db)
}

/// Returns the location of the originating user code.
Expand Down
108 changes: 108 additions & 0 deletions crates/cairo-lang-filesystem/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::sync::Arc;

use cairo_lang_utils::{Intern, LookupIntern, define_short_id};
use path_clean::PathClean;
use salsa::Durability;
use serde::{Deserialize, Serialize};
use smol_str::SmolStr;

Expand All @@ -12,6 +13,38 @@ use crate::span::{TextOffset, TextSpan};

pub const CAIRO_FILE_EXTENSION: &str = "cairo";

/// Same as `CrateLongId`, but without internal interning.
/// This is used as salsa database inputs.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum CrateInput {
Real {
name: SmolStr,
discriminator: Option<SmolStr>,
},
Virtual {
name: SmolStr,
file_long_id: FileInput,
settings: String,
cache_file: Option<BlobLongId>,
},
}

impl CrateInput {
pub fn into_crate_long_id(self, db: &dyn FilesGroup) -> CrateLongId {
match self {
CrateInput::Real { name, discriminator } => CrateLongId::Real { name, discriminator },
CrateInput::Virtual { name, file_long_id, settings, cache_file } => {
CrateLongId::Virtual {
name,
file_id: file_long_id.into_file_long_id(db).intern(db),
settings,
cache_file: cache_file.map(|blob_long_id| blob_long_id.intern(db)),
}
}
}
}
}

/// A crate is a standalone file tree representing a single compilation unit.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum CrateLongId {
Expand All @@ -26,6 +59,18 @@ impl CrateLongId {
CrateLongId::Real { name, .. } | CrateLongId::Virtual { name, .. } => name.clone(),
}
}

pub fn into_crate_input(self, db: &dyn FilesGroup) -> CrateInput {
match self {
CrateLongId::Real { name, discriminator } => CrateInput::Real { name, discriminator },
CrateLongId::Virtual { name, file_id, settings, cache_file } => CrateInput::Virtual {
name,
file_long_id: file_id.lookup_intern(db).into_file_input(db),
settings,
cache_file: cache_file.map(|blob_id| blob_id.lookup_intern(db)),
},
}
}
}
define_short_id!(CrateId, CrateLongId, FilesGroup, lookup_intern_crate, intern_crate);
impl CrateId {
Expand Down Expand Up @@ -271,6 +316,33 @@ impl FileId {
}
}

/// Same as `Directory`, but without the interning inside virtual directories.
/// This is used to avoid the need to intern the file id inside salsa database inputs.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum DirectoryInput {
Real(PathBuf),
Virtual { files: BTreeMap<SmolStr, FileInput>, dirs: BTreeMap<SmolStr, Box<DirectoryInput>> },
}

impl DirectoryInput {
/// Converts the input into a [`Directory`].
pub fn into_directory(self, db: &dyn FilesGroup) -> Directory {
match self {
DirectoryInput::Real(path) => Directory::Real(path),
DirectoryInput::Virtual { files, dirs } => Directory::Virtual {
files: files
.into_iter()
.map(|(name, file_input)| (name, file_input.into_file_long_id(db).intern(db)))
.collect(),
dirs: dirs
.into_iter()
.map(|(name, dir_input)| (name, Box::new(dir_input.into_directory(db))))
.collect(),
},
}
}
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum Directory {
/// A directory on the file system.
Expand Down Expand Up @@ -306,6 +378,23 @@ impl Directory {
}
}
}

/// Converts the directory into an [`DirectoryInput`].
pub fn into_directory_input(self, db: &dyn FilesGroup) -> DirectoryInput {
match self {
Directory::Real(path) => DirectoryInput::Real(path),
Directory::Virtual { files, dirs } => DirectoryInput::Virtual {
files: files
.into_iter()
.map(|(name, file_id)| (name, file_id.lookup_intern(db).into_file_input(db)))
.collect(),
dirs: dirs
.into_iter()
.map(|(name, dir)| (name, Box::new(dir.into_directory_input(db))))
.collect(),
},
}
}
}

/// A FileId for data that is not necessarily a valid UTF-8 string.
Expand All @@ -315,6 +404,25 @@ pub enum BlobLongId {
Virtual(Arc<[u8]>),
}

impl BlobLongId {
pub fn content(self, db: &dyn FilesGroup) -> Option<Arc<[u8]>> {
match self {
BlobLongId::OnDisk(path) => {
// This does not result in performance cost due to OS caching and the fact that
// salsa will re-execute only this single query if the file content
// did not change.
db.salsa_runtime().report_synthetic_read(Durability::LOW);

match std::fs::read(path) {
Ok(content) => Some(Arc::from(content)),
Err(_) => None,
}
}
BlobLongId::Virtual(content) => Some(content),
}
}
}

define_short_id!(BlobId, BlobLongId, FilesGroup, lookup_intern_blob, intern_blob);

impl BlobId {
Expand Down
Loading