Skip to content

Commit

Permalink
Merge branch 'master' into xunilrj/fix-extract-type-parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaBatty authored Feb 27, 2025
2 parents 99fc195 + 4b99ee5 commit df058f0
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 28 deletions.
24 changes: 22 additions & 2 deletions forc-pkg/src/pkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use std::{
str::FromStr,
sync::{atomic::AtomicBool, Arc},
};
use sway_core::namespace::Root;
pub use sway_core::Programs;
use sway_core::{
abi_generation::{
Expand All @@ -50,7 +51,7 @@ use sway_core::{set_bytecode_configurables_offset, PrintAsm, PrintIr};
use sway_error::{error::CompileError, handler::Handler, warning::CompileWarning};
use sway_features::ExperimentalFeatures;
use sway_types::constants::{CORE, STD};
use sway_types::{Ident, Span, Spanned};
use sway_types::{Ident, ProgramId, Span, Spanned};
use sway_utils::{constants, time_expr, PerformanceData, PerformanceMetric};
use tracing::{debug, info};

Expand Down Expand Up @@ -1581,13 +1582,15 @@ pub fn sway_build_config(
///
/// `contract_id_value` should only be Some when producing the `dependency_namespace` for a contract with tests enabled.
/// This allows us to provide a contract's `CONTRACT_ID` constant to its own unit tests.
#[allow(clippy::too_many_arguments)]
pub fn dependency_namespace(
lib_namespace_map: &HashMap<NodeIx, namespace::Root>,
compiled_contract_deps: &CompiledContractDeps,
graph: &Graph,
node: NodeIx,
engines: &Engines,
contract_id_value: Option<ContractIdConst>,
program_id: ProgramId,
experimental: ExperimentalFeatures,
) -> Result<namespace::Root, vec1::Vec1<CompileError>> {
// TODO: Clean this up when config-time constants v1 are removed.
Expand All @@ -1597,11 +1600,12 @@ pub fn dependency_namespace(
namespace::namespace_with_contract_id(
engines,
name.clone(),
program_id,
contract_id_value,
experimental,
)?
} else {
namespace::namespace_without_contract_id(name.clone())
Root::new(name.clone(), None, program_id, false)
};

// Add direct dependencies.
Expand Down Expand Up @@ -1629,6 +1633,7 @@ pub fn dependency_namespace(
namespace::namespace_with_contract_id(
engines,
name.clone(),
program_id,
contract_id_value,
experimental,
)?
Expand Down Expand Up @@ -2444,6 +2449,10 @@ pub fn build(
..profile.clone()
};

let program_id = engines
.se()
.get_or_create_program_id_from_manifest_path(&manifest.entry_path());

// `ContractIdConst` is a None here since we do not yet have a
// contract ID value at this point.
let dep_namespace = match dependency_namespace(
Expand All @@ -2453,6 +2462,7 @@ pub fn build(
node,
&engines,
None,
program_id,
experimental,
) {
Ok(o) => o,
Expand Down Expand Up @@ -2510,6 +2520,10 @@ pub fn build(
profile.clone()
};

let program_id = engines
.se()
.get_or_create_program_id_from_manifest_path(&manifest.entry_path());

// Note that the contract ID value here is only Some if tests are enabled.
let dep_namespace = match dependency_namespace(
&lib_namespace_map,
Expand All @@ -2518,6 +2532,7 @@ pub fn build(
node,
&engines,
contract_id_value.clone(),
program_id,
experimental,
) {
Ok(o) => o,
Expand Down Expand Up @@ -2617,13 +2632,18 @@ pub fn check(
let contract_id_value =
(idx == plan.compilation_order.len() - 1).then(|| DUMMY_CONTRACT_ID.to_string());

let program_id = engines
.se()
.get_or_create_program_id_from_manifest_path(&manifest.entry_path());

let dep_namespace = dependency_namespace(
&lib_namespace_map,
&compiled_contract_deps,
&plan.graph,
node,
engines,
contract_id_value,
program_id,
experimental,
)
.expect("failed to create dependency namespace");
Expand Down
2 changes: 2 additions & 0 deletions sway-core/src/ir_generation/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,7 @@ mod tests {
use sway_error::handler::Handler;
use sway_features::ExperimentalFeatures;
use sway_ir::Kind;
use sway_types::ProgramId;

/// This function validates if an expression can be converted to [Constant].
///
Expand All @@ -1691,6 +1692,7 @@ mod tests {
let core_lib = namespace::Root::new(
sway_types::Ident::new_no_span("assert_is_constant_test".to_string()),
None,
ProgramId::new(0),
false,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3167,6 +3167,7 @@ mod tests {
use super::*;
use crate::{Engines, ExperimentalFeatures};
use sway_error::type_error::TypeError;
use sway_types::ProgramId;
use symbol_collection_context::SymbolCollectionContext;

fn do_type_check(
Expand All @@ -3177,10 +3178,9 @@ mod tests {
experimental: ExperimentalFeatures,
) -> Result<ty::TyExpression, ErrorEmitted> {
let root_module_name = sway_types::Ident::new_no_span("do_type_check_test".to_string());
let root_module = namespace::Root::new(root_module_name, None, false);
let root_module = namespace::Root::new(root_module_name, None, ProgramId::new(0), false);
let collection_ctx_ns = Namespace::new(handler, engines, root_module.clone(), true)?;
let mut collection_ctx = SymbolCollectionContext::new(collection_ctx_ns);

let mut namespace = Namespace::new(handler, engines, root_module, true)?;
let ctx =
TypeCheckContext::from_root(&mut namespace, &mut collection_ctx, engines, experimental)
Expand Down
10 changes: 3 additions & 7 deletions sway-core/src/semantic_analysis/namespace/contract_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use sway_error::{
handler::{ErrorEmitted, Handler},
};
use sway_parse::{lex, Parser};
use sway_types::{constants::CONTRACT_ID, Spanned};
use sway_types::{constants::CONTRACT_ID, ProgramId, Spanned};

use crate::{
language::{
Expand All @@ -18,19 +18,15 @@ use crate::{
Engines, Ident, Namespace,
};

/// Factory function for contracts
pub fn namespace_without_contract_id(package_name: Ident) -> Root {
Root::new(package_name, None, false)
}

/// Factory function for contracts
pub fn namespace_with_contract_id(
engines: &Engines,
package_name: Ident,
program_id: ProgramId,
contract_id_value: String,
experimental: crate::ExperimentalFeatures,
) -> Result<Root, vec1::Vec1<CompileError>> {
let root = Root::new(package_name, None, true);
let root = Root::new(package_name, None, program_id, true);
let handler = <_>::default();
bind_contract_id_in_root_module(&handler, engines, contract_id_value, root, experimental)
.map_err(|_| {
Expand Down
16 changes: 14 additions & 2 deletions sway-core/src/semantic_analysis/namespace/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use sway_error::{
error::CompileError,
handler::{ErrorEmitted, Handler},
};
use sway_types::{span::Span, Spanned};
use sway_types::{span::Span, ProgramId, Spanned};
use sway_utils::iter_prefixes;

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -163,6 +163,8 @@ impl ResolvedDeclaration {
pub struct Root {
// The contents of the package being compiled.
current_package: Module,
// Program id for the package.
program_id: ProgramId,
// True if the current package is a contract, false otherwise.
is_contract_package: bool,
// The external dependencies of the current package. Note that an external package is
Expand All @@ -179,11 +181,17 @@ impl Root {
// and `package_root_with_contract_id` are supplied in `contract_helpers`.
//
// External packages must be added afterwards by calling `add_external`
pub(crate) fn new(package_name: Ident, span: Option<Span>, is_contract_package: bool) -> Self {
pub fn new(
package_name: Ident,
span: Option<Span>,
program_id: ProgramId,
is_contract_package: bool,
) -> Self {
// The root module must be public
let module = Module::new(package_name, Visibility::Public, span, &vec![]);
Self {
current_package: module,
program_id,
is_contract_package,
external_packages: Default::default(),
}
Expand Down Expand Up @@ -225,6 +233,10 @@ impl Root {
self.current_package.name()
}

pub fn program_id(&self) -> ProgramId {
self.program_id
}

fn check_path_is_in_current_package(&self, mod_path: &ModulePathBuf) -> bool {
!mod_path.is_empty() && mod_path[0] == *self.current_package.name()
}
Expand Down
8 changes: 6 additions & 2 deletions sway-lsp/src/core/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ impl Session {
) -> Result<(), LanguageServerError> {
let _p = tracing::trace_span!("garbage_collect").entered();
let path = self.sync.temp_dir()?;
let program_id = { engines.se().get_program_id(&path) };
let program_id = { engines.se().get_program_id_from_manifest_path(&path) };
if let Some(program_id) = program_id {
engines.clear_program(&program_id);
}
Expand Down Expand Up @@ -669,7 +669,11 @@ pub(crate) fn program_id_from_path(
engines: &Engines,
) -> Result<ProgramId, DirectoryError> {
let program_id = sway_utils::find_parent_manifest_dir(path)
.and_then(|manifest_path| engines.se().get_program_id(&manifest_path))
.and_then(|manifest_path| {
engines
.se()
.get_program_id_from_manifest_path(&manifest_path)
})
.ok_or_else(|| DirectoryError::ProgramIdNotFound {
path: path.to_string_lossy().to_string(),
})?;
Expand Down
28 changes: 17 additions & 11 deletions sway-types/src/source_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,8 @@ impl SourceEngine {
return source_map.get(path).copied().unwrap();
}
}
let manifest_path = sway_utils::find_parent_manifest_dir(path).unwrap_or(path.clone());
let program_id = {
let mut module_map = self.manifest_path_to_program_map.write();
*module_map.entry(manifest_path.clone()).or_insert_with(|| {
let mut next_id = self.next_program_id.write();
*next_id += 1;
ProgramId::new(*next_id)
})
};

let program_id = self.get_or_create_program_id_from_manifest_path(path);
self.get_source_id_with_program_id(path, program_id)
}

Expand Down Expand Up @@ -113,8 +105,22 @@ impl SourceEngine {
}

/// This function provides the [ProgramId] corresponding to a specified manifest file path.
pub fn get_program_id(&self, path: &PathBuf) -> Option<ProgramId> {
self.manifest_path_to_program_map.read().get(path).copied()
pub fn get_program_id_from_manifest_path(&self, path: &PathBuf) -> Option<ProgramId> {
let manifest_path = sway_utils::find_parent_manifest_dir(path).unwrap_or(path.clone());
self.manifest_path_to_program_map
.read()
.get(&manifest_path)
.copied()
}

pub fn get_or_create_program_id_from_manifest_path(&self, path: &PathBuf) -> ProgramId {
let manifest_path = sway_utils::find_parent_manifest_dir(path).unwrap_or(path.clone());
let mut module_map = self.manifest_path_to_program_map.write();
*module_map.entry(manifest_path.clone()).or_insert_with(|| {
let mut next_id = self.next_program_id.write();
*next_id += 1;
ProgramId::new(*next_id)
})
}

/// Returns the [PathBuf] associated with the provided [ProgramId], if it exists in the manifest_path_to_program_map.
Expand Down
7 changes: 5 additions & 2 deletions test/src/ir_generation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use std::{
use anyhow::Result;
use colored::Colorize;
use sway_core::{
compile_ir_context_to_finalized_asm, compile_to_ast, ir_generation::compile_program, namespace,
compile_ir_context_to_finalized_asm, compile_to_ast,
ir_generation::compile_program,
namespace::{self, Root},
BuildTarget, Engines,
};
use sway_error::handler::Handler;
Expand All @@ -18,6 +20,7 @@ use sway_ir::{
create_fn_inline_pass, register_known_passes, PassGroup, PassManager, ARG_DEMOTION_NAME,
CONST_DEMOTION_NAME, DCE_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME,
};
use sway_types::ProgramId;

use crate::RunConfig;

Expand Down Expand Up @@ -241,7 +244,7 @@ pub(super) async fn run(

let sway_str = String::from_utf8_lossy(&sway_str);
let handler = Handler::default();
let mut initial_namespace = namespace::namespace_without_contract_id(core_lib_name.clone());
let mut initial_namespace = Root::new(core_lib_name.clone(), None, ProgramId::new(0), false);
initial_namespace.add_external("core".to_owned(), core_root.clone());
let compile_res = compile_to_ast(
&handler,
Expand Down

0 comments on commit df058f0

Please sign in to comment.