Skip to content

Commit e0c043b

Browse files
emilyaherbertotrho
andauthored
Detect infinite dependencies (#279)
* Inifinite dependencies test. * Detect infinite dependencies. * Merge file_path with build_config. * Use HashSet instead of Vec. * Use dependency config instead of build config. * Build config need not be mutable. Co-authored-by: Toby Hutton <[email protected]>
1 parent f83dd8c commit e0c043b

File tree

16 files changed

+218
-36
lines changed

16 files changed

+218
-36
lines changed

core_lang/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,8 @@ pub enum CompileError<'sc> {
682682
call_chain: String, // Pretty list of symbols, e.g., "a, b and c".
683683
span: Span<'sc>,
684684
},
685+
#[error("File {file_path} generates an infinite dependency cycle.")]
686+
InfiniteDependencies { file_path: String, span: Span<'sc> },
685687
}
686688

687689
impl<'sc> std::convert::From<TypeError<'sc>> for CompileError<'sc> {
@@ -857,6 +859,7 @@ impl<'sc> CompileError<'sc> {
857859
ArgumentParameterTypeMismatch { span, .. } => span,
858860
RecursiveCall { span, .. } => span,
859861
RecursiveCallChain { span, .. } => span,
862+
InfiniteDependencies { span, .. } => span,
860863
}
861864
}
862865

core_lang/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use semantic_analysis::{TreeType, TypedParseTree};
2626
pub mod types;
2727
pub(crate) mod utils;
2828
pub use crate::parse_tree::{Declaration, Expression, UseStatement, WhileLoop};
29-
use std::collections::HashMap;
29+
use std::collections::{HashMap, HashSet};
3030

3131
pub use crate::span::Span;
3232
pub use error::{CompileError, CompileResult, CompileWarning};
@@ -196,6 +196,7 @@ pub(crate) fn compile_inner_dependency<'sc>(
196196
initial_namespace: &Namespace<'sc>,
197197
build_config: BuildConfig,
198198
dead_code_graph: &mut ControlFlowGraph<'sc>,
199+
dependency_graph: &mut HashMap<String, HashSet<String>>,
199200
) -> CompileResult<'sc, InnerDependencyCompileResult<'sc>> {
200201
let mut warnings = Vec::new();
201202
let mut errors = Vec::new();
@@ -232,6 +233,7 @@ pub(crate) fn compile_inner_dependency<'sc>(
232233
TreeType::Library,
233234
&build_config.clone(),
234235
dead_code_graph,
236+
dependency_graph,
235237
)
236238
.ok(&mut warnings, &mut errors)
237239
.map(|value| (name, value))
@@ -277,6 +279,7 @@ pub fn compile_to_asm<'sc>(
277279
input: &'sc str,
278280
initial_namespace: &Namespace<'sc>,
279281
build_config: BuildConfig,
282+
dependency_graph: &mut HashMap<String, HashSet<String>>,
280283
) -> CompilationResult<'sc> {
281284
let mut warnings = Vec::new();
282285
let mut errors = Vec::new();
@@ -300,6 +303,7 @@ pub fn compile_to_asm<'sc>(
300303
tree_type,
301304
&build_config.clone(),
302305
&mut dead_code_graph,
306+
dependency_graph,
303307
)
304308
.ok(&mut warnings, &mut errors)
305309
})
@@ -321,6 +325,7 @@ pub fn compile_to_asm<'sc>(
321325
TreeType::Library,
322326
&build_config.clone(),
323327
&mut dead_code_graph,
328+
dependency_graph,
324329
)
325330
.ok(&mut warnings, &mut errors)
326331
.map(|value| (name, value))
@@ -450,8 +455,9 @@ pub fn compile_to_bytecode<'sc>(
450455
input: &'sc str,
451456
initial_namespace: &Namespace<'sc>,
452457
build_config: BuildConfig,
458+
dependency_graph: &mut HashMap<String, HashSet<String>>,
453459
) -> BytecodeCompilationResult<'sc> {
454-
match compile_to_asm(input, initial_namespace, build_config) {
460+
match compile_to_asm(input, initial_namespace, build_config, dependency_graph) {
455461
CompilationResult::Success {
456462
mut asm,
457463
mut warnings,

core_lang/src/semantic_analysis/ast_node/code_block.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::build_config::BuildConfig;
33
use crate::control_flow_analysis::ControlFlowGraph;
44
use crate::types::MaybeResolvedType;
55
use crate::CodeBlock;
6+
use std::collections::{HashMap, HashSet};
67

78
#[derive(Clone, Debug)]
89
pub(crate) struct TypedCodeBlock<'sc> {
@@ -24,6 +25,7 @@ impl<'sc> TypedCodeBlock<'sc> {
2425
self_type: &MaybeResolvedType<'sc>,
2526
build_config: &BuildConfig,
2627
dead_code_graph: &mut ControlFlowGraph<'sc>,
28+
dependency_graph: &mut HashMap<String, HashSet<String>>,
2729
) -> CompileResult<'sc, (Self, Option<MaybeResolvedType<'sc>>)> {
2830
let mut warnings = Vec::new();
2931
let mut errors = Vec::new();
@@ -43,6 +45,7 @@ impl<'sc> TypedCodeBlock<'sc> {
4345
self_type,
4446
build_config,
4547
dead_code_graph,
48+
dependency_graph,
4649
)
4750
.ok(&mut warnings, &mut errors)
4851
})

core_lang/src/semantic_analysis/ast_node/declaration.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::{
1313
};
1414
use crate::{control_flow_analysis::ControlFlowGraph, types::TypeInfo};
1515
use sha2::{Digest, Sha256};
16+
use std::collections::{HashMap, HashSet};
1617

1718
#[derive(Clone, Debug)]
1819
pub enum TypedDeclaration<'sc> {
@@ -508,6 +509,7 @@ impl<'sc> TypedFunctionDeclaration<'sc> {
508509
build_config: &BuildConfig,
509510
dead_code_graph: &mut ControlFlowGraph<'sc>,
510511
mode: Mode,
512+
dependency_graph: &mut HashMap<String, HashSet<String>>,
511513
) -> CompileResult<'sc, TypedFunctionDeclaration<'sc>> {
512514
let mut warnings = Vec::new();
513515
let mut errors = Vec::new();
@@ -555,7 +557,8 @@ impl<'sc> TypedFunctionDeclaration<'sc> {
555557
"Function body's return type does not match up with its return type annotation.",
556558
self_type,
557559
build_config,
558-
dead_code_graph
560+
dead_code_graph,
561+
dependency_graph
559562
),
560563
(
561564
TypedCodeBlock {

core_lang/src/semantic_analysis/ast_node/expression/enum_instantiation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub(crate) fn instantiate_enum<'sc>(
1515
self_type: &MaybeResolvedType<'sc>,
1616
build_config: &BuildConfig,
1717
dead_code_graph: &mut ControlFlowGraph<'sc>,
18+
dependency_graph: &mut HashMap<String, HashSet<String>>,
1819
) -> CompileResult<'sc, TypedExpression<'sc>> {
1920
let mut warnings = vec![];
2021
let mut errors = vec![];
@@ -69,6 +70,7 @@ pub(crate) fn instantiate_enum<'sc>(
6970
self_type,
7071
build_config,
7172
dead_code_graph,
73+
dependency_graph
7274
),
7375
return err(warnings, errors),
7476
warnings,

0 commit comments

Comments
 (0)