From d200f24cf0064ce35f4e36e82a44fdd1438fca91 Mon Sep 17 00:00:00 2001 From: Lennart Van Hirtum Date: Tue, 19 Nov 2024 21:27:41 +0100 Subject: [PATCH] FUCK YEAH, TEMPLATE INFERENCE! :tad --- src/flattening/typechecking.rs | 4 +- src/instantiation/concrete_typecheck.rs | 84 ++++++++++- src/typing/abstract_type.rs | 4 +- src/typing/concrete_type.rs | 11 ++ src/typing/type_inference.rs | 29 ++-- test.sus | 8 +- test.sus_errors.txt | 181 ++++++++++++++---------- test.sus_output.txt | 10 +- 8 files changed, 234 insertions(+), 97 deletions(-) diff --git a/src/flattening/typechecking.rs b/src/flattening/typechecking.rs index d7651de..43401f6 100644 --- a/src/flattening/typechecking.rs +++ b/src/flattening/typechecking.rs @@ -580,8 +580,8 @@ pub fn apply_types( ); } for FailedUnification{mut found, mut expected, span, context} in type_checker.domain_substitutor.extract_errors() { - found.fully_substitute(&type_checker.domain_substitutor).unwrap(); - expected.fully_substitute(&type_checker.domain_substitutor).unwrap(); + assert!(found.fully_substitute(&type_checker.domain_substitutor)); + assert!(expected.fully_substitute(&type_checker.domain_substitutor)); let expected_name = format!("{expected:?}"); let found_name = format!("{found:?}"); diff --git a/src/instantiation/concrete_typecheck.rs b/src/instantiation/concrete_typecheck.rs index f11e17c..b98bb45 100644 --- a/src/instantiation/concrete_typecheck.rs +++ b/src/instantiation/concrete_typecheck.rs @@ -1,5 +1,9 @@ -use crate::typing::template::ConcreteTemplateArg; +use std::ops::Deref; + +use crate::flattening::{DeclarationPortInfo, WireReferenceRoot, WireSource, WrittenType}; +use crate::linker::LinkInfo; +use crate::typing::template::{ConcreteTemplateArg, HowDoWeKnowTheTemplateArg}; use crate::typing::{ concrete_type::{ConcreteType, BOOL_CONCRETE_TYPE, INT_CONCRETE_TYPE}, delayed_constraint::{DelayedConstraint, DelayedConstraintStatus, DelayedConstraintsList}, @@ -103,7 +107,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> { fn finalize(&mut self) { for (_id, w) in &mut self.wires { - if let Err(()) = w.typ.fully_substitute(&self.type_substitutor) { + if w.typ.fully_substitute(&self.type_substitutor) == false { let typ_as_str = w.typ.to_string(&self.linker.types); let span = self.md.get_instruction_span(w.original_instruction); @@ -146,8 +150,84 @@ struct SubmoduleTypecheckConstraint { sm_id: SubModuleID } +/// Part of Template Value Inference. +/// +/// Specifically, for code like this: +/// +/// ```sus +/// module add_all #(int Size) { +/// input int[Size] arr // We're targeting the 'Size' within the array size +/// output int total +/// } +/// ``` +fn can_wire_can_be_value_inferred(link_info: &LinkInfo, flat_wire: FlatID) -> Option { + let wire = link_info.instructions[flat_wire].unwrap_wire(); + let WireSource::WireRef(wr) = &wire.source else {return None}; + if !wr.path.is_empty() {return None} // Must be a plain, no fuss reference to a de + let WireReferenceRoot::LocalDecl(wire_declaration, _span) = &wr.root else {return None}; + let template_arg_decl = link_info.instructions[*wire_declaration].unwrap_wire_declaration(); + let DeclarationPortInfo::GenerativeInput(template_id) = &template_arg_decl.is_port else {return None}; + Some(*template_id) +} + +fn try_to_attach_value_to_template_arg(template_wire_referernce: FlatID, found_value: &ConcreteType, template_args: &mut ConcreteTemplateArgs, submodule_link_info: &LinkInfo) { + let ConcreteType::Value(v) = found_value else {return}; // We don't have a value to assign + if let Some(template_id) = can_wire_can_be_value_inferred(submodule_link_info, template_wire_referernce) { + if let ConcreteTemplateArg::NotProvided = &template_args[template_id] { + template_args[template_id] = ConcreteTemplateArg::Value(TypedValue::from_value(v.clone()), HowDoWeKnowTheTemplateArg::Inferred) + } + } +} + +fn infer_parameters_by_walking_type(port_wr_typ: &WrittenType, connected_typ: &ConcreteType, template_args: &mut ConcreteTemplateArgs, submodule_link_info: &LinkInfo) { + match port_wr_typ { + WrittenType::Error(_) => {} // Can't continue, bad written type + WrittenType::Named(_) => {} // Seems we've run out of type to check + WrittenType::Array(_span, written_arr_box) => { + let ConcreteType::Array(concrete_arr_box) = connected_typ else {return}; // Can't continue, type not worked out. TODO should we seed concrete types with derivates from AbstractTypes? + let (written_arr, written_size_var, _) = written_arr_box.deref(); + let (concrete_arr, concrete_size) = concrete_arr_box.deref(); + + infer_parameters_by_walking_type(written_arr, concrete_arr, template_args, submodule_link_info); // Recurse down + + try_to_attach_value_to_template_arg(*written_size_var, concrete_size, template_args, submodule_link_info); // Potential place for template inference! + } + WrittenType::TemplateVariable(_span, template_id) => { + if !connected_typ.contains_unknown() { + if let ConcreteTemplateArg::NotProvided = &template_args[*template_id] { + template_args[*template_id] = ConcreteTemplateArg::Type(connected_typ.clone(), HowDoWeKnowTheTemplateArg::Inferred) + } + } + } + } +} + +impl SubmoduleTypecheckConstraint { + fn try_infer_parameters(&mut self, context: &mut InstantiationContext) { + let sm = &mut context.submodules[self.sm_id]; + + let sub_module = &context.linker.modules[sm.module_uuid]; + + for (id, p) in sm.port_map.iter_valids() { + let wire = &context.wires[p.maps_to_wire]; + + let mut wire_typ_clone = wire.typ.clone(); + wire_typ_clone.fully_substitute(&context.type_substitutor); + + let port_decl_instr = sub_module.ports[id].declaration_instruction; + let port_decl = sub_module.link_info.instructions[port_decl_instr].unwrap_wire_declaration(); + + infer_parameters_by_walking_type(&port_decl.typ_expr, &wire_typ_clone, &mut sm.template_args, &sub_module.link_info); + } + } + +} + impl DelayedConstraint> for SubmoduleTypecheckConstraint { fn try_apply(&mut self, context : &mut InstantiationContext) -> DelayedConstraintStatus { + // Try to infer template arguments based on the connections to the ports of the module + self.try_infer_parameters(context); + let sm = &context.submodules[self.sm_id]; let submod_instr = context.md.link_info.instructions[sm.original_instruction].unwrap_submodule(); diff --git a/src/typing/abstract_type.rs b/src/typing/abstract_type.rs index 77da5c9..9a9f16c 100644 --- a/src/typing/abstract_type.rs +++ b/src/typing/abstract_type.rs @@ -310,12 +310,12 @@ impl TypeUnifier { pub fn finalize_domain_type(&mut self, typ_domain: &mut DomainType) { use super::type_inference::HindleyMilner; - typ_domain.fully_substitute(&self.domain_substitutor).unwrap(); + assert!(typ_domain.fully_substitute(&self.domain_substitutor) == true); } pub fn finalize_abstract_type(&mut self, types: &ArenaAllocator, typ: &mut AbstractType, span: Span, errors: &ErrorCollector) { use super::type_inference::HindleyMilner; - if typ.fully_substitute(&self.type_substitutor).is_err() { + if typ.fully_substitute(&self.type_substitutor) == false { let typ_as_string = typ.to_string(types, &self.template_type_names); errors.error(span, format!("Could not fully figure out the type of this object. {typ_as_string}")); } diff --git a/src/typing/concrete_type.rs b/src/typing/concrete_type.rs index c855e2e..8c462b8 100644 --- a/src/typing/concrete_type.rs +++ b/src/typing/concrete_type.rs @@ -35,4 +35,15 @@ impl ConcreteType { let (sub, _sz) = arr_box.deref(); sub } + pub fn contains_unknown(&self) -> bool { + match self { + ConcreteType::Named(_) => false, + ConcreteType::Value(_) => false, + ConcreteType::Array(arr_box) => { + let (arr_arr, arr_size) = arr_box.deref(); + arr_arr.contains_unknown() || arr_size.contains_unknown() + } + ConcreteType::Unknown(_) => true, + } + } } diff --git a/src/typing/type_inference.rs b/src/typing/type_inference.rs index 60bfa5e..818c021 100644 --- a/src/typing/type_inference.rs +++ b/src/typing/type_inference.rs @@ -170,10 +170,10 @@ pub trait HindleyMilner : Sized { /// This is never called by the user, only by [TypeSubstitutor::unify] fn unify_all_args bool>(left : &Self, right : &Self, unify : &mut F) -> bool; - /// Has to be implemented per + /// Has to be implemented separately per type /// - /// Returns Ok(()) when no variables remain - fn fully_substitute(&mut self, substitutor: &TypeSubstitutor) -> Result<(), ()>; + /// Returns true when no Unknowns remain + fn fully_substitute(&mut self, substitutor: &TypeSubstitutor) -> bool; } @@ -205,15 +205,15 @@ impl HindleyMilner for AbstractType { } } - fn fully_substitute(&mut self, substitutor: &TypeSubstitutor) -> Result<(), ()> { + fn fully_substitute(&mut self, substitutor: &TypeSubstitutor) -> bool { match self { - AbstractType::Template(_) => Ok(()), // Template Name is included in get_hm_info - AbstractType::Named(_) => Ok(()), // Name is included in get_hm_info + AbstractType::Named(_) | AbstractType::Template(_) => true, // Template Name & Name is included in get_hm_info AbstractType::Array(arr_typ) => { arr_typ.fully_substitute(substitutor) }, AbstractType::Unknown(var) => { - *self = substitutor.substitution_map[var.get_hidden_value()].get().ok_or(())?.clone(); + let Some(replacement) = substitutor.substitution_map[var.get_hidden_value()].get() else {return false}; + *self = replacement.clone(); self.fully_substitute(substitutor) } } @@ -236,10 +236,10 @@ impl HindleyMilner for DomainType { true } - /// For domains, always returns Ok(()). Or rather it should, since any leftover unconnected domains should be assigned an ID of their own by the type checker - fn fully_substitute(&mut self, substitutor: &TypeSubstitutor) -> Result<(), ()> { + /// For domains, always returns true. Or rather it should, since any leftover unconnected domains should be assigned an ID of their own by the type checker + fn fully_substitute(&mut self, substitutor: &TypeSubstitutor) -> bool { match self { - DomainType::Generative | DomainType::Physical(_) => Ok(()), // Do nothing, These are done already + DomainType::Generative | DomainType::Physical(_) => true, // Do nothing, These are done already DomainType::DomainVariable(var) => { *self = substitutor.substitution_map[var.get_hidden_value()].get().expect("It's impossible for domain variables to remain, as any unset domain variable would have been replaced with a new physical domain").clone(); self.fully_substitute(substitutor) @@ -282,16 +282,17 @@ impl HindleyMilner for ConcreteType { } } - fn fully_substitute(&mut self, substitutor: &TypeSubstitutor) -> Result<(), ()> { + fn fully_substitute(&mut self, substitutor: &TypeSubstitutor) -> bool { match self { - ConcreteType::Named(_) | ConcreteType::Value(_) => Ok(()), // Already included in get_hm_info + ConcreteType::Named(_) | ConcreteType::Value(_) => true, // Don't need to do anything, this is already final ConcreteType::Array(arr_typ) => { let (arr_typ, arr_sz) = arr_typ.deref_mut(); - arr_typ.fully_substitute(substitutor)?; + arr_typ.fully_substitute(substitutor) && arr_sz.fully_substitute(substitutor) }, ConcreteType::Unknown(var) => { - *self = substitutor.substitution_map[var.get_hidden_value()].get().ok_or(())?.clone(); + let Some(replacement) = substitutor.substitution_map[var.get_hidden_value()].get() else {return false}; + *self = replacement.clone(); self.fully_substitute(substitutor) } } diff --git a/test.sus b/test.sus index 04df34a..448da52 100644 --- a/test.sus +++ b/test.sus @@ -847,8 +847,14 @@ module replicate #(T, int NUM_REPLS) { } module use_replicate { - replicate #(NUM_REPLS: 50, NUM_REPLS: 30, T: type bool) a + //replicate #(NUM_REPLS: 50, NUM_REPLS: 30, T: type bool) a replicate #(NUM_REPLS: 20, T: type int[30]) b + replicate c + + int val = 3 + + c.data = val + int[30] out = c.result } module permute_t #(T, int SIZE, int[SIZE] SOURCES) { diff --git a/test.sus_errors.txt b/test.sus_errors.txt index 3a887bb..362524d 100644 --- a/test.sus_errors.txt +++ b/test.sus_errors.txt @@ -622,7 +622,7 @@ Warning: Unused Variable: This variable does not affect the output ports of this │ ╰──── Unused Variable: This variable does not affect the output ports of this module ─────╯ Error: Could not fully instantiate ::FIFO #( - T: /* Could not infer */ + T: type ::bool[20] /* inferred */, DEPTH: /* Could not infer */ READY_SLACK: /* Could not infer */ ) @@ -631,7 +631,7 @@ Error: Could not fully instantiate ::FIFO #( 649 │ FIFO fiii │ ──┬─ │ ╰─── Could not fully instantiate ::FIFO #( - T: /* Could not infer */ + T: type ::bool[20] /* inferred */, DEPTH: /* Could not infer */ READY_SLACK: /* Could not infer */ ) @@ -1007,207 +1007,238 @@ Warning: Unused port 'o' │ │ │ ╰── c declared here ─────╯ -Error: 'NUM_REPLS' has already been defined previously - ╭─[test.sus:850:29] +Warning: Unused Variable: This variable does not affect the output ports of this module + ╭─[test.sus:854:6] + │ + 854 │ int val = 3 + │ ─┬─ + │ ╰─── Unused Variable: This variable does not affect the output ports of this module +─────╯ +Warning: Unused Variable: This variable does not affect the output ports of this module + ╭─[test.sus:857:10] + │ + 857 │ int[30] out = c.result + │ ─┬─ + │ ╰─── Unused Variable: This variable does not affect the output ports of this module +─────╯ +Warning: Unused port 'data' + ╭─[test.sus:851:2] │ - 850 │ replicate #(NUM_REPLS: 50, NUM_REPLS: 30, T: type bool) a - │ ────┬──── ────┬──── - │ ╰───────────────────── Defined here previously - │ │ - │ ╰────── 'NUM_REPLS' has already been defined previously + 840 │ input T data + │ ──┬─ + │ ╰─── Port 'data' declared here + │ + 851 │ replicate #(NUM_REPLS: 20, T: type int[30]) b + │ ─────────────────────┬───────────────────── ┬ + │ ╰───────────────────────── Unused port 'data' + │ │ + │ ╰── b declared here +─────╯ +Warning: Unused port 'result' + ╭─[test.sus:851:2] + │ + 842 │ output T[NUM_REPLS] result + │ ───┬── + │ ╰──── Port 'result' declared here + │ + 851 │ replicate #(NUM_REPLS: 20, T: type int[30]) b + │ ─────────────────────┬───────────────────── ┬ + │ ╰───────────────────────── Unused port 'result' + │ │ + │ ╰── b declared here ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:863:13] + ╭─[test.sus:869:13] │ - 863 │ gen int[8] SOURCES + 869 │ gen int[8] SOURCES │ ───┬─── │ ╰───── Unused Variable: This variable does not affect the output ports of this module ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:875:9] + ╭─[test.sus:881:9] │ - 875 │ int[2] inArr + 881 │ int[2] inArr │ ──┬── │ ╰──── Unused Variable: This variable does not affect the output ports of this module ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:882:9] + ╭─[test.sus:888:9] │ - 882 │ int[8] beep = permut.permute(SOURCES) + 888 │ int[8] beep = permut.permute(SOURCES) │ ──┬─ │ ╰─── Unused Variable: This variable does not affect the output ports of this module ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:886:28] + ╭─[test.sus:892:28] │ - 886 │ interface from : bool[32] instr + 892 │ interface from : bool[32] instr │ ──┬── │ ╰──── Unused Variable: This variable does not affect the output ports of this module ─────╯ Error: While parsing 'if_statement', parser found a syntax error in a node of type 'ERROR' - ╭─[test.sus:898:23] + ╭─[test.sus:904:23] │ - 898 │ ╭─▶ if decoder.is_jump() : int target_addr { + 904 │ ╭─▶ if decoder.is_jump() : int target_addr { │ │ ────────┬──────── │ │ ╰────────── While parsing 'if_statement', parser found a syntax error in a node of type 'ERROR' ┆ ┆ - 900 │ ├─▶ } + 906 │ ├─▶ } │ │ │ ╰─────────── Parent node 'if_statement' ─────╯ Error: While parsing 'if_statement', parser found a syntax error in a node of type 'ERROR' - ╭─[test.sus:901:23] + ╭─[test.sus:907:23] │ - 901 │ ╭─▶ if decoder.is_load() : int reg_to, int addr { + 907 │ ╭─▶ if decoder.is_load() : int reg_to, int addr { │ │ ───────────┬────────── │ │ ╰──────────── While parsing 'if_statement', parser found a syntax error in a node of type 'ERROR' ┆ ┆ - 903 │ ├─▶ } + 909 │ ├─▶ } │ │ │ ╰─────────── Parent node 'if_statement' ─────╯ Error: While parsing 'if_statement', parser found a syntax error in a node of type 'ERROR' - ╭─[test.sus:904:5] + ╭─[test.sus:910:5] │ - 904 │ ╭─▶ if decoder.is_arith() : int reg_a, int reg_b, Operator op { + 910 │ ╭─▶ if decoder.is_arith() : int reg_a, int reg_b, Operator op { │ │ ─────────────────────────┬───────────────────────── │ │ ╰─────────────────────────── While parsing 'if_statement', parser found a syntax error in a node of type 'ERROR' ┆ ┆ - 906 │ ├─▶ } + 912 │ ├─▶ } │ │ │ ╰─────────── Parent node 'if_statement' ─────╯ Error: A function called in this context may only return one result. Split this function call into a separate line instead. - ╭─[test.sus:898:5] + ╭─[test.sus:904:5] │ - 887 │ interface is_jump + 893 │ interface is_jump │ ───┬─── │ ╰───── Interface 'is_jump' defined here │ - 898 │ if decoder.is_jump() : int target_addr { + 904 │ if decoder.is_jump() : int target_addr { │ ────────┬──────── │ ╰────────── A function called in this context may only return one result. Split this function call into a separate line instead. ─────╯ Error: A function called in this context may only return one result. Split this function call into a separate line instead. - ╭─[test.sus:901:5] + ╭─[test.sus:907:5] │ - 888 │ interface is_load + 894 │ interface is_load │ ───┬─── │ ╰───── Interface 'is_load' defined here │ - 901 │ if decoder.is_load() : int reg_to, int addr { + 907 │ if decoder.is_load() : int reg_to, int addr { │ ────────┬──────── │ ╰────────── A function called in this context may only return one result. Split this function call into a separate line instead. ─────╯ Error: No Global of the name 'op' was found. Did you forget to import it? - ╭─[test.sus:904:57] + ╭─[test.sus:910:57] │ - 904 │ if decoder.is_arith() : int reg_a, int reg_b, Operator op { + 910 │ if decoder.is_arith() : int reg_a, int reg_b, Operator op { │ ─┬ │ ╰── No Global of the name 'op' was found. Did you forget to import it? ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:894:42] + ╭─[test.sus:900:42] │ - 894 │ interface run_instruction : bool[32] instr + 900 │ interface run_instruction : bool[32] instr │ ──┬── │ ╰──── Unused Variable: This variable does not affect the output ports of this module ─────╯ Error: ::no_main_interface does not have a main interface. You should explicitly specify an interface to access - ╭─[test.sus:917:10] + ╭─[test.sus:923:10] │ - 910 │ module no_main_interface { + 916 │ module no_main_interface { │ ────────┬──────── │ ╰────────── Module 'no_main_interface' defined here. module ::no_main_interface #(): │ - 917 │ int x = no_interface_named() + 923 │ int x = no_interface_named() │ ─────────┬──────── │ ╰────────── ::no_main_interface does not have a main interface. You should explicitly specify an interface to access ─────╯ Error: ::no_main_interface does not have a main interface. You should explicitly specify an interface to access - ╭─[test.sus:918:10] + ╭─[test.sus:924:10] │ - 910 │ module no_main_interface { + 916 │ module no_main_interface { │ ────────┬──────── │ ╰────────── Module 'no_main_interface' defined here. module ::no_main_interface #(): │ - 918 │ int y = no_main_interface() + 924 │ int y = no_main_interface() │ ────────┬──────── │ ╰────────── ::no_main_interface does not have a main interface. You should explicitly specify an interface to access ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:917:6] + ╭─[test.sus:923:6] │ - 917 │ int x = no_interface_named() + 923 │ int x = no_interface_named() │ ┬ │ ╰── Unused Variable: This variable does not affect the output ports of this module ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:918:6] + ╭─[test.sus:924:6] │ - 918 │ int y = no_main_interface() + 924 │ int y = no_main_interface() │ ┬ │ ╰── Unused Variable: This variable does not affect the output ports of this module ─────╯ Error: Typing Error: array size expects a ::int but was given a ::bool - ╭─[test.sus:922:6] + ╭─[test.sus:928:6] │ - 922 │ int[true] a + 928 │ int[true] a │ ──┬─ │ ╰─── Typing Error: array size expects a ::int but was given a ::bool ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:922:12] + ╭─[test.sus:928:12] │ - 922 │ int[true] a + 928 │ int[true] a │ ┬ │ ╰── Unused Variable: This variable does not affect the output ports of this module ─────╯ Error: Typing Error: array size expects a ::int but was given a ::bool - ╭─[test.sus:926:41] + ╭─[test.sus:932:41] │ - 926 │ interface moduleWithBadInterface : int[true] a + 932 │ interface moduleWithBadInterface : int[true] a │ ──┬─ │ ╰─── Typing Error: array size expects a ::int but was given a ::bool ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:926:47] + ╭─[test.sus:932:47] │ - 926 │ interface moduleWithBadInterface : int[true] a + 932 │ interface moduleWithBadInterface : int[true] a │ ┬ │ ╰── Unused Variable: This variable does not affect the output ports of this module ─────╯ Error: Typing Error: connection expects a ::int but was given a ::bool - ╭─[test.sus:933:11] + ╭─[test.sus:939:11] │ - 933 │ xyz[3] = true + 939 │ xyz[3] = true │ ──┬─ │ ╰─── Typing Error: connection expects a ::int but was given a ::bool ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:930:9] + ╭─[test.sus:936:9] │ - 930 │ int[3] xyz + 936 │ int[3] xyz │ ─┬─ │ ╰─── Unused Variable: This variable does not affect the output ports of this module ─────╯ Error: BEEEP is not a valid template argument of ::SUM_UP - ╭─[test.sus:954:38] + ╭─[test.sus:960:38] │ - 937 │ const int SUM_UP #(int SIZE, int[SIZE] DATA) { + 943 │ const int SUM_UP #(int SIZE, int[SIZE] DATA) { │ ───┬── │ ╰──── 'SUM_UP' defined here │ - 954 │ gen int X = SUM_UP #(SIZE: 4, DATA, BEEEP: 3) + 960 │ gen int X = SUM_UP #(SIZE: 4, DATA, BEEEP: 3) │ ──┬── │ ╰──── BEEEP is not a valid template argument of ::SUM_UP ─────╯ Error: ABC is not a valid template argument of ::int - ╭─[test.sus:956:8] + ╭─[test.sus:962:8] │ - 956 │ int #(ABC) x + 962 │ int #(ABC) x │ ─┬─ │ ╰─── ABC is not a valid template argument of ::int │ @@ -1218,44 +1249,44 @@ Error: ABC is not a valid template argument of ::int │ ╰─── 'int' defined here ─────╯ Error: ABC does not name a Type or a Value. - ╭─[test.sus:956:8] + ╭─[test.sus:962:8] │ - 956 │ int #(ABC) x + 962 │ int #(ABC) x │ ─┬─ │ ╰─── ABC does not name a Type or a Value. ─────╯ Error: Could not fully figure out the type of this object. type_variable_21 - ╭─[test.sus:954:14] + ╭─[test.sus:960:14] │ - 954 │ gen int X = SUM_UP #(SIZE: 4, DATA, BEEEP: 3) + 960 │ gen int X = SUM_UP #(SIZE: 4, DATA, BEEEP: 3) │ ────────────────┬──────────────── │ ╰────────────────── Could not fully figure out the type of this object. type_variable_21 ─────╯ Error: Could not fully figure out the type of this object. type_variable_22 - ╭─[test.sus:954:14] + ╭─[test.sus:960:14] │ - 954 │ gen int X = SUM_UP #(SIZE: 4, DATA, BEEEP: 3) + 960 │ gen int X = SUM_UP #(SIZE: 4, DATA, BEEEP: 3) │ ────────────────┬──────────────── │ ╰────────────────── Could not fully figure out the type of this object. type_variable_22 ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:947:13] + ╭─[test.sus:953:13] │ - 947 │ gen int[5] DATA + 953 │ gen int[5] DATA │ ──┬─ │ ╰─── Unused Variable: This variable does not affect the output ports of this module ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:954:10] + ╭─[test.sus:960:10] │ - 954 │ gen int X = SUM_UP #(SIZE: 4, DATA, BEEEP: 3) + 960 │ gen int X = SUM_UP #(SIZE: 4, DATA, BEEEP: 3) │ ┬ │ ╰── Unused Variable: This variable does not affect the output ports of this module ─────╯ Warning: Unused Variable: This variable does not affect the output ports of this module - ╭─[test.sus:956:13] + ╭─[test.sus:962:13] │ - 956 │ int #(ABC) x + 962 │ int #(ABC) x │ ┬ │ ╰── Unused Variable: This variable does not affect the output ports of this module ─────╯ diff --git a/test.sus_output.txt b/test.sus_output.txt index 17b2946..e2d081d 100644 --- a/test.sus_output.txt +++ b/test.sus_output.txt @@ -470,7 +470,15 @@ Latency Counting tree_add Latency Counting tree_add Latency Counting tree_add Latency Counting make_tree_add -Not Instantiating use_replicate due to flattening errors +Instantiating use_replicate +Concrete Typechecking use_replicate +Instantiating replicate +Concrete Typechecking replicate +Latency Counting replicate +Instantiating replicate +Concrete Typechecking replicate +Latency Counting replicate +Latency Counting use_replicate Instantiating use_permute Concrete Typechecking use_permute Instantiating permute_t