Skip to content

Commit 4b99ee5

Browse files
tritaoJoshuaBatty
andauthored
Add ProgramId to root module. (#6959)
## Description Adds `ProgramId` to root module to be used in the trait coherence work. Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
1 parent 49d0eb4 commit 4b99ee5

File tree

8 files changed

+71
-28
lines changed

8 files changed

+71
-28
lines changed

forc-pkg/src/pkg.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use std::{
2828
str::FromStr,
2929
sync::{atomic::AtomicBool, Arc},
3030
};
31+
use sway_core::namespace::Root;
3132
pub use sway_core::Programs;
3233
use sway_core::{
3334
abi_generation::{
@@ -50,7 +51,7 @@ use sway_core::{set_bytecode_configurables_offset, PrintAsm, PrintIr};
5051
use sway_error::{error::CompileError, handler::Handler, warning::CompileWarning};
5152
use sway_features::ExperimentalFeatures;
5253
use sway_types::constants::{CORE, STD};
53-
use sway_types::{Ident, Span, Spanned};
54+
use sway_types::{Ident, ProgramId, Span, Spanned};
5455
use sway_utils::{constants, time_expr, PerformanceData, PerformanceMetric};
5556
use tracing::{debug, info};
5657

@@ -1581,13 +1582,15 @@ pub fn sway_build_config(
15811582
///
15821583
/// `contract_id_value` should only be Some when producing the `dependency_namespace` for a contract with tests enabled.
15831584
/// This allows us to provide a contract's `CONTRACT_ID` constant to its own unit tests.
1585+
#[allow(clippy::too_many_arguments)]
15841586
pub fn dependency_namespace(
15851587
lib_namespace_map: &HashMap<NodeIx, namespace::Root>,
15861588
compiled_contract_deps: &CompiledContractDeps,
15871589
graph: &Graph,
15881590
node: NodeIx,
15891591
engines: &Engines,
15901592
contract_id_value: Option<ContractIdConst>,
1593+
program_id: ProgramId,
15911594
experimental: ExperimentalFeatures,
15921595
) -> Result<namespace::Root, vec1::Vec1<CompileError>> {
15931596
// TODO: Clean this up when config-time constants v1 are removed.
@@ -1597,11 +1600,12 @@ pub fn dependency_namespace(
15971600
namespace::namespace_with_contract_id(
15981601
engines,
15991602
name.clone(),
1603+
program_id,
16001604
contract_id_value,
16011605
experimental,
16021606
)?
16031607
} else {
1604-
namespace::namespace_without_contract_id(name.clone())
1608+
Root::new(name.clone(), None, program_id, false)
16051609
};
16061610

16071611
// Add direct dependencies.
@@ -1629,6 +1633,7 @@ pub fn dependency_namespace(
16291633
namespace::namespace_with_contract_id(
16301634
engines,
16311635
name.clone(),
1636+
program_id,
16321637
contract_id_value,
16331638
experimental,
16341639
)?
@@ -2444,6 +2449,10 @@ pub fn build(
24442449
..profile.clone()
24452450
};
24462451

2452+
let program_id = engines
2453+
.se()
2454+
.get_or_create_program_id_from_manifest_path(&manifest.entry_path());
2455+
24472456
// `ContractIdConst` is a None here since we do not yet have a
24482457
// contract ID value at this point.
24492458
let dep_namespace = match dependency_namespace(
@@ -2453,6 +2462,7 @@ pub fn build(
24532462
node,
24542463
&engines,
24552464
None,
2465+
program_id,
24562466
experimental,
24572467
) {
24582468
Ok(o) => o,
@@ -2510,6 +2520,10 @@ pub fn build(
25102520
profile.clone()
25112521
};
25122522

2523+
let program_id = engines
2524+
.se()
2525+
.get_or_create_program_id_from_manifest_path(&manifest.entry_path());
2526+
25132527
// Note that the contract ID value here is only Some if tests are enabled.
25142528
let dep_namespace = match dependency_namespace(
25152529
&lib_namespace_map,
@@ -2518,6 +2532,7 @@ pub fn build(
25182532
node,
25192533
&engines,
25202534
contract_id_value.clone(),
2535+
program_id,
25212536
experimental,
25222537
) {
25232538
Ok(o) => o,
@@ -2617,13 +2632,18 @@ pub fn check(
26172632
let contract_id_value =
26182633
(idx == plan.compilation_order.len() - 1).then(|| DUMMY_CONTRACT_ID.to_string());
26192634

2635+
let program_id = engines
2636+
.se()
2637+
.get_or_create_program_id_from_manifest_path(&manifest.entry_path());
2638+
26202639
let dep_namespace = dependency_namespace(
26212640
&lib_namespace_map,
26222641
&compiled_contract_deps,
26232642
&plan.graph,
26242643
node,
26252644
engines,
26262645
contract_id_value,
2646+
program_id,
26272647
experimental,
26282648
)
26292649
.expect("failed to create dependency namespace");

sway-core/src/ir_generation/const_eval.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,7 @@ mod tests {
16691669
use sway_error::handler::Handler;
16701670
use sway_features::ExperimentalFeatures;
16711671
use sway_ir::Kind;
1672+
use sway_types::ProgramId;
16721673

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

sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3167,6 +3167,7 @@ mod tests {
31673167
use super::*;
31683168
use crate::{Engines, ExperimentalFeatures};
31693169
use sway_error::type_error::TypeError;
3170+
use sway_types::ProgramId;
31703171
use symbol_collection_context::SymbolCollectionContext;
31713172

31723173
fn do_type_check(
@@ -3177,10 +3178,9 @@ mod tests {
31773178
experimental: ExperimentalFeatures,
31783179
) -> Result<ty::TyExpression, ErrorEmitted> {
31793180
let root_module_name = sway_types::Ident::new_no_span("do_type_check_test".to_string());
3180-
let root_module = namespace::Root::new(root_module_name, None, false);
3181+
let root_module = namespace::Root::new(root_module_name, None, ProgramId::new(0), false);
31813182
let collection_ctx_ns = Namespace::new(handler, engines, root_module.clone(), true)?;
31823183
let mut collection_ctx = SymbolCollectionContext::new(collection_ctx_ns);
3183-
31843184
let mut namespace = Namespace::new(handler, engines, root_module, true)?;
31853185
let ctx =
31863186
TypeCheckContext::from_root(&mut namespace, &mut collection_ctx, engines, experimental)

sway-core/src/semantic_analysis/namespace/contract_helpers.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use sway_error::{
44
handler::{ErrorEmitted, Handler},
55
};
66
use sway_parse::{lex, Parser};
7-
use sway_types::{constants::CONTRACT_ID, Spanned};
7+
use sway_types::{constants::CONTRACT_ID, ProgramId, Spanned};
88

99
use crate::{
1010
language::{
@@ -18,19 +18,15 @@ use crate::{
1818
Engines, Ident, Namespace,
1919
};
2020

21-
/// Factory function for contracts
22-
pub fn namespace_without_contract_id(package_name: Ident) -> Root {
23-
Root::new(package_name, None, false)
24-
}
25-
2621
/// Factory function for contracts
2722
pub fn namespace_with_contract_id(
2823
engines: &Engines,
2924
package_name: Ident,
25+
program_id: ProgramId,
3026
contract_id_value: String,
3127
experimental: crate::ExperimentalFeatures,
3228
) -> Result<Root, vec1::Vec1<CompileError>> {
33-
let root = Root::new(package_name, None, true);
29+
let root = Root::new(package_name, None, program_id, true);
3430
let handler = <_>::default();
3531
bind_contract_id_in_root_module(&handler, engines, contract_id_value, root, experimental)
3632
.map_err(|_| {

sway-core/src/semantic_analysis/namespace/root.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use sway_error::{
1818
error::CompileError,
1919
handler::{ErrorEmitted, Handler},
2020
};
21-
use sway_types::{span::Span, Spanned};
21+
use sway_types::{span::Span, ProgramId, Spanned};
2222
use sway_utils::iter_prefixes;
2323

2424
#[derive(Clone, Debug)]
@@ -163,6 +163,8 @@ impl ResolvedDeclaration {
163163
pub struct Root {
164164
// The contents of the package being compiled.
165165
current_package: Module,
166+
// Program id for the package.
167+
program_id: ProgramId,
166168
// True if the current package is a contract, false otherwise.
167169
is_contract_package: bool,
168170
// The external dependencies of the current package. Note that an external package is
@@ -179,11 +181,17 @@ impl Root {
179181
// and `package_root_with_contract_id` are supplied in `contract_helpers`.
180182
//
181183
// External packages must be added afterwards by calling `add_external`
182-
pub(crate) fn new(package_name: Ident, span: Option<Span>, is_contract_package: bool) -> Self {
184+
pub fn new(
185+
package_name: Ident,
186+
span: Option<Span>,
187+
program_id: ProgramId,
188+
is_contract_package: bool,
189+
) -> Self {
183190
// The root module must be public
184191
let module = Module::new(package_name, Visibility::Public, span, &vec![]);
185192
Self {
186193
current_package: module,
194+
program_id,
187195
is_contract_package,
188196
external_packages: Default::default(),
189197
}
@@ -225,6 +233,10 @@ impl Root {
225233
self.current_package.name()
226234
}
227235

236+
pub fn program_id(&self) -> ProgramId {
237+
self.program_id
238+
}
239+
228240
fn check_path_is_in_current_package(&self, mod_path: &ModulePathBuf) -> bool {
229241
!mod_path.is_empty() && mod_path[0] == *self.current_package.name()
230242
}

sway-lsp/src/core/session.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl Session {
134134
) -> Result<(), LanguageServerError> {
135135
let _p = tracing::trace_span!("garbage_collect").entered();
136136
let path = self.sync.temp_dir()?;
137-
let program_id = { engines.se().get_program_id(&path) };
137+
let program_id = { engines.se().get_program_id_from_manifest_path(&path) };
138138
if let Some(program_id) = program_id {
139139
engines.clear_program(&program_id);
140140
}
@@ -669,7 +669,11 @@ pub(crate) fn program_id_from_path(
669669
engines: &Engines,
670670
) -> Result<ProgramId, DirectoryError> {
671671
let program_id = sway_utils::find_parent_manifest_dir(path)
672-
.and_then(|manifest_path| engines.se().get_program_id(&manifest_path))
672+
.and_then(|manifest_path| {
673+
engines
674+
.se()
675+
.get_program_id_from_manifest_path(&manifest_path)
676+
})
673677
.ok_or_else(|| DirectoryError::ProgramIdNotFound {
674678
path: path.to_string_lossy().to_string(),
675679
})?;

sway-types/src/source_engine.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,8 @@ impl SourceEngine {
6060
return source_map.get(path).copied().unwrap();
6161
}
6262
}
63-
let manifest_path = sway_utils::find_parent_manifest_dir(path).unwrap_or(path.clone());
64-
let program_id = {
65-
let mut module_map = self.manifest_path_to_program_map.write();
66-
*module_map.entry(manifest_path.clone()).or_insert_with(|| {
67-
let mut next_id = self.next_program_id.write();
68-
*next_id += 1;
69-
ProgramId::new(*next_id)
70-
})
71-
};
7263

64+
let program_id = self.get_or_create_program_id_from_manifest_path(path);
7365
self.get_source_id_with_program_id(path, program_id)
7466
}
7567

@@ -113,8 +105,22 @@ impl SourceEngine {
113105
}
114106

115107
/// This function provides the [ProgramId] corresponding to a specified manifest file path.
116-
pub fn get_program_id(&self, path: &PathBuf) -> Option<ProgramId> {
117-
self.manifest_path_to_program_map.read().get(path).copied()
108+
pub fn get_program_id_from_manifest_path(&self, path: &PathBuf) -> Option<ProgramId> {
109+
let manifest_path = sway_utils::find_parent_manifest_dir(path).unwrap_or(path.clone());
110+
self.manifest_path_to_program_map
111+
.read()
112+
.get(&manifest_path)
113+
.copied()
114+
}
115+
116+
pub fn get_or_create_program_id_from_manifest_path(&self, path: &PathBuf) -> ProgramId {
117+
let manifest_path = sway_utils::find_parent_manifest_dir(path).unwrap_or(path.clone());
118+
let mut module_map = self.manifest_path_to_program_map.write();
119+
*module_map.entry(manifest_path.clone()).or_insert_with(|| {
120+
let mut next_id = self.next_program_id.write();
121+
*next_id += 1;
122+
ProgramId::new(*next_id)
123+
})
118124
}
119125

120126
/// Returns the [PathBuf] associated with the provided [ProgramId], if it exists in the manifest_path_to_program_map.

test/src/ir_generation/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use std::{
88
use anyhow::Result;
99
use colored::Colorize;
1010
use sway_core::{
11-
compile_ir_context_to_finalized_asm, compile_to_ast, ir_generation::compile_program, namespace,
11+
compile_ir_context_to_finalized_asm, compile_to_ast,
12+
ir_generation::compile_program,
13+
namespace::{self, Root},
1214
BuildTarget, Engines,
1315
};
1416
use sway_error::handler::Handler;
@@ -18,6 +20,7 @@ use sway_ir::{
1820
create_fn_inline_pass, register_known_passes, PassGroup, PassManager, ARG_DEMOTION_NAME,
1921
CONST_DEMOTION_NAME, DCE_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME,
2022
};
23+
use sway_types::ProgramId;
2124

2225
use crate::RunConfig;
2326

@@ -241,7 +244,7 @@ pub(super) async fn run(
241244

242245
let sway_str = String::from_utf8_lossy(&sway_str);
243246
let handler = Handler::default();
244-
let mut initial_namespace = namespace::namespace_without_contract_id(core_lib_name.clone());
247+
let mut initial_namespace = Root::new(core_lib_name.clone(), None, ProgramId::new(0), false);
245248
initial_namespace.add_external("core".to_owned(), core_root.clone());
246249
let compile_res = compile_to_ast(
247250
&handler,

0 commit comments

Comments
 (0)