From a63baa0357209f01eaf8d8510ef4f0aba7108c3c Mon Sep 17 00:00:00 2001 From: Tobias Tom Hodapp Date: Sun, 12 Jan 2025 01:34:49 +0100 Subject: [PATCH 1/4] Implement Display proxy structs --- src/dev_aid/lsp/hover_info.rs | 10 +- src/flattening/mod.rs | 14 ++- src/flattening/typechecking.rs | 4 +- src/instantiation/concrete_typecheck.rs | 6 +- src/to_string.rs | 142 ++++++++++++++++-------- src/typing/abstract_type.rs | 20 +++- src/typing/concrete_type.rs | 11 +- 7 files changed, 145 insertions(+), 62 deletions(-) diff --git a/src/dev_aid/lsp/hover_info.rs b/src/dev_aid/lsp/hover_info.rs index d5fd520..f33bffd 100644 --- a/src/dev_aid/lsp/hover_info.rs +++ b/src/dev_aid/lsp/hover_info.rs @@ -60,7 +60,7 @@ impl<'l> HoverCollector<'l> { if wire.original_instruction != id { continue; } - let typ_str = wire.typ.to_string(&self.linker.types); + let typ_str = wire.typ.display(&self.linker.types); let name_str = &wire.name; let latency_str = if wire.absolute_latency != CALCULATE_LATENCY_LATER { format!("{}", wire.absolute_latency) @@ -126,7 +126,7 @@ pub fn hover(info: LocationInfo, linker: &Linker, file_data: &FileData) -> Vec Vec { hover.sus_code( - typ.to_string(&linker.types, &link_info.template_arguments), + typ.display(&linker.types, &link_info.template_arguments).to_string(), ); } LocationInfo::TemplateInput(in_obj, link_info, _template_id, template_arg) => { @@ -207,7 +207,7 @@ pub fn hover(info: LocationInfo, linker: &Linker, file_data: &FileData) -> Vec global_ref.get_total_span() } } + pub fn display<'a, TypVec: Index, TemplateVec: TemplateNameGetter>(&'a self, + linker_types: &'a TypVec, + template_names: &'a TemplateVec, + ) -> impl Display + 'a { + WrittenTypeDisplay { + inner: self, + linker_types, + template_names, + } + } } /// Little helper struct that tells us what kind of declaration it is. Is it a Port, Template argument, A struct field, or just a regular temporary? diff --git a/src/flattening/typechecking.rs b/src/flattening/typechecking.rs index 8c2dc04..3dbfd9e 100644 --- a/src/flattening/typechecking.rs +++ b/src/flattening/typechecking.rs @@ -571,8 +571,8 @@ pub fn apply_types( let _ = found.fully_substitute(&type_checker.type_substitutor); let _ = expected.fully_substitute(&type_checker.type_substitutor); - let expected_name = expected.to_string(types, &type_checker.template_type_names); - let found_name = found.to_string(types, &type_checker.template_type_names); + let expected_name = expected.display(types, &type_checker.template_type_names).to_string(); + let found_name = found.display(types, &type_checker.template_type_names).to_string(); errors .error(span, format!("Typing Error: {context} expects a {expected_name} but was given a {found_name}")) .add_info_list(infos); diff --git a/src/instantiation/concrete_typecheck.rs b/src/instantiation/concrete_typecheck.rs index ee8718c..12138fb 100644 --- a/src/instantiation/concrete_typecheck.rs +++ b/src/instantiation/concrete_typecheck.rs @@ -109,7 +109,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> { fn finalize(&mut self) { for (_id, w) in &mut self.wires { if w.typ.fully_substitute(&self.type_substitutor) == false { - let typ_as_str = w.typ.to_string(&self.linker.types); + let typ_as_str = w.typ.display(&self.linker.types); let span = self.md.get_instruction_span(w.original_instruction); self.errors.error(span, format!("Could not finalize this type, some parameters were still unknown: {typ_as_str}")); @@ -122,8 +122,8 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> { let _ = found.fully_substitute(&self.type_substitutor); let _ = expected.fully_substitute(&self.type_substitutor); - let expected_name = expected.to_string(&self.linker.types); - let found_name = found.to_string(&self.linker.types); + let expected_name = expected.display(&self.linker.types).to_string(); + let found_name = found.display(&self.linker.types).to_string(); self.errors .error(span, format!("Typing Error: {context} expects a {expected_name} but was given a {found_name}")) .add_info_list(infos); diff --git a/src/to_string.rs b/src/to_string.rs index 3f33184..8146f63 100644 --- a/src/to_string.rs +++ b/src/to_string.rs @@ -2,14 +2,14 @@ use crate::prelude::*; use crate::{file_position::FileText, pretty_print_many_spans, value::Value}; -use crate::flattening::{DomainInfo, Interface, InterfaceToDomainMap, Module, StructType, WrittenType}; +use crate::flattening::{ + DomainInfo, Interface, InterfaceToDomainMap, Module, StructType, WrittenType, +}; use crate::linker::{FileData, LinkInfo}; use crate::typing::{ abstract_type::{AbstractType, DomainType}, concrete_type::ConcreteType, - template::{ - ConcreteTemplateArg, ConcreteTemplateArgs, TemplateInputs, - }, + template::{ConcreteTemplateArg, ConcreteTemplateArgs, TemplateInputs}, }; use std::{ @@ -39,61 +39,95 @@ impl TemplateNameGetter for TemplateInputs { } } -impl WrittenType { - pub fn to_string< - TypVec: Index, - TemplateVec: TemplateNameGetter, - >( - &self, - linker_types: &TypVec, - template_names: &TemplateVec, - ) -> String { - match self { - WrittenType::Error(_) => "{error}".to_owned(), - WrittenType::TemplateVariable(_, id) => template_names.get_template_name(*id).to_owned(), - WrittenType::Named(named_type) => linker_types[named_type.id].link_info.get_full_name(), +#[derive(Debug)] +pub struct WrittenTypeDisplay< + 'a, + TypVec: Index, + TemplateVec: TemplateNameGetter, +> { + pub inner: &'a WrittenType, + pub linker_types: &'a TypVec, + pub template_names: &'a TemplateVec, +} + +impl<'a, TypVec: Index, TemplateVec: TemplateNameGetter> Display + for WrittenTypeDisplay<'a, TypVec, TemplateVec> +{ + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self.inner { + WrittenType::Error(_) => f.write_str("{error"), + WrittenType::TemplateVariable(_, id) => { + f.write_str(self.template_names.get_template_name(*id)) + } + WrittenType::Named(named_type) => { + f.write_str(&self.linker_types[named_type.id].link_info.get_full_name()) + } WrittenType::Array(_, sub) => { - sub.deref().0.to_string(linker_types, template_names) + "[]" + write!( + f, + "{}[]", + sub.deref() + .0 + .display(self.linker_types, self.template_names) + ) } } } } -impl AbstractType { - pub fn to_string< - TypVec: Index, - TemplateVec: TemplateNameGetter, - >( - &self, - linker_types: &TypVec, - template_names: &TemplateVec, - ) -> String { - match self { - AbstractType::Unknown(id) => format!("{id:?}"), - AbstractType::Template(id) => template_names.get_template_name(*id).to_owned(), - AbstractType::Named(id) => linker_types[*id].link_info.get_full_name(), - AbstractType::Array(sub) => sub.deref().to_string(linker_types, template_names) + "[]", +#[derive(Debug)] +pub struct AbstractTypeDisplay< + 'a, + TypVec: Index, + TemplateVec: TemplateNameGetter, +> { + pub inner: &'a AbstractType, + pub linker_types: &'a TypVec, + pub template_names: &'a TemplateVec, +} + +impl, TemplateVec: TemplateNameGetter> Display + for AbstractTypeDisplay<'_, TypVec, TemplateVec> +{ + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self.inner { + AbstractType::Unknown(id) => write!(f, "{id:?}"), + AbstractType::Template(id) => f.write_str(self.template_names.get_template_name(*id)), + AbstractType::Named(id) => { + f.write_str(&self.linker_types[*id].link_info.get_full_name()) + } + AbstractType::Array(sub) => write!( + f, + "{}[]", + sub.deref().display(self.linker_types, self.template_names) + ), } } } -impl ConcreteType { - pub fn to_string>( - &self, - linker_types: &TypVec, - ) -> String { - match self { - ConcreteType::Named(name) => linker_types[*name].link_info.get_full_name(), +#[derive(Debug)] +pub struct ConcreteTypeDisplay<'a, T: Index> { + pub inner: &'a ConcreteType, + pub linker_types: &'a T, +} + +impl> Display for ConcreteTypeDisplay<'_, T> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self.inner { + ConcreteType::Named(name) => { + f.write_str(&self.linker_types[*name].link_info.get_full_name()) + } ConcreteType::Array(arr_box) => { let (elem_typ, arr_size) = arr_box.deref(); - format!( + write!( + f, "{}[{}]", - elem_typ.to_string(linker_types), + elem_typ.display(self.linker_types), arr_size.unwrap_value().unwrap_integer() ) } - ConcreteType::Value(v) => format!("{{concrete_type_{v}}}"), - ConcreteType::Unknown(u) => format!("{{{u:?}}}"), + ConcreteType::Value(v) => write!(f, "{{concrete_type_{v}}}"), + ConcreteType::Unknown(u) => write!(f, "{{{u:?}}}"), } } } @@ -224,9 +258,11 @@ impl Module { pub fn pretty_print_concrete_instance( target_link_info: &LinkInfo, given_template_args: &ConcreteTemplateArgs, - linker_types: &TypVec + linker_types: &TypVec, ) -> String -where TypVec: Index { +where + TypVec: Index, +{ assert!(given_template_args.len() == target_link_info.template_arguments.len()); let object_full_name = target_link_info.get_full_name(); if given_template_args.len() == 0 { @@ -240,10 +276,22 @@ where TypVec: Index { write!(result, " {}: ", arg_in_target.name).unwrap(); match arg { ConcreteTemplateArg::Type(concrete_type, how_do_we_know_the_template_arg) => { - write!(result, "type {} /* {} */,\n", concrete_type.to_string(linker_types), how_do_we_know_the_template_arg.to_str()).unwrap(); + write!( + result, + "type {} /* {} */,\n", + concrete_type.display(linker_types), + how_do_we_know_the_template_arg.to_str() + ) + .unwrap(); } ConcreteTemplateArg::Value(typed_value, how_do_we_know_the_template_arg) => { - write!(result, "{} /* {} */,\n", typed_value.value.to_string(), how_do_we_know_the_template_arg.to_str()).unwrap(); + write!( + result, + "{} /* {} */,\n", + typed_value.value.to_string(), + how_do_we_know_the_template_arg.to_str() + ) + .unwrap(); } ConcreteTemplateArg::NotProvided => { write!(result, "/* Could not infer */\n").unwrap(); diff --git a/src/typing/abstract_type.rs b/src/typing/abstract_type.rs index 071923b..c4d5da6 100644 --- a/src/typing/abstract_type.rs +++ b/src/typing/abstract_type.rs @@ -2,13 +2,14 @@ use crate::alloc::ArenaAllocator; use crate::prelude::*; use crate::value::Value; -use std::ops::Deref; +use std::fmt::Display; +use std::ops::{Deref, Index}; use super::template::{GlobalReference, TemplateAbstractTypes, TemplateInputs}; use super::type_inference::{DomainVariableID, DomainVariableIDMarker, TypeSubstitutor, TypeVariableID, TypeVariableIDMarker, UnifyErrorReport}; use crate::flattening::{BinaryOperator, StructType, TypingAllocator, UnaryOperator, WrittenType}; use crate::linker::get_builtin_type; -use crate::to_string::map_to_type_names; +use crate::to_string::{map_to_type_names, AbstractTypeDisplay, TemplateNameGetter}; /// This contains only the information that can be easily type-checked. /// @@ -23,6 +24,19 @@ pub enum AbstractType { Array(Box), } +impl AbstractType { + pub fn display<'a, TypVec: Index, TemplateVec: TemplateNameGetter>(&'a self, + linker_types: &'a TypVec, + template_names: &'a TemplateVec, +) -> impl Display + 'a { + AbstractTypeDisplay { + inner: self, + linker_types, + template_names, + } + } +} + pub const BOOL_TYPE: AbstractType = AbstractType::Named(get_builtin_type("bool")); pub const INT_TYPE: AbstractType = AbstractType::Named(get_builtin_type("int")); @@ -322,7 +336,7 @@ impl TypeUnifier { 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) == false { - let typ_as_string = typ.to_string(types, &self.template_type_names); + let typ_as_string = typ.display(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 8c462b8..8655c24 100644 --- a/src/typing/concrete_type.rs +++ b/src/typing/concrete_type.rs @@ -1,6 +1,9 @@ +use crate::flattening::StructType; use crate::prelude::*; +use crate::to_string::ConcreteTypeDisplay; -use std::ops::Deref; +use std::fmt::Display; +use std::ops::{Deref, Index}; use crate::linker::get_builtin_type; use crate:: @@ -46,4 +49,10 @@ impl ConcreteType { ConcreteType::Unknown(_) => true, } } + pub fn display<'a>(&'a self, linker_types: &'a impl Index) -> impl Display + 'a { + ConcreteTypeDisplay { + inner: self, + linker_types, + } + } } From f36300faf392bbc030ac09d98b1a779fc800532c Mon Sep 17 00:00:00 2001 From: Tobias Tom Hodapp Date: Sun, 12 Jan 2025 01:41:22 +0100 Subject: [PATCH 2/4] Removed unused --- src/to_string.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/to_string.rs b/src/to_string.rs index 8146f63..721d81a 100644 --- a/src/to_string.rs +++ b/src/to_string.rs @@ -269,7 +269,6 @@ where return format!("{object_full_name} #()"); } - use std::fmt::Write; let mut result = format!("{object_full_name} #(\n"); for (id, arg) in given_template_args { let arg_in_target = &target_link_info.template_arguments[id]; From 9f05312218cd2491f48e5100ae504f14c5d68c7a Mon Sep 17 00:00:00 2001 From: Tobias Tom Hodapp Date: Sun, 12 Jan 2025 02:48:07 +0100 Subject: [PATCH 3/4] Made fields private --- src/flattening/mod.rs | 14 +------- src/to_string.rs | 64 ++++++++++++++++++++++++++++++++----- src/typing/abstract_type.rs | 17 +--------- src/typing/concrete_type.rs | 12 +------ 4 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/flattening/mod.rs b/src/flattening/mod.rs index 22b76f9..2988876 100644 --- a/src/flattening/mod.rs +++ b/src/flattening/mod.rs @@ -8,13 +8,11 @@ mod lints; use crate::alloc::UUIDAllocator; use crate::prelude::*; -use crate::to_string::{TemplateNameGetter, WrittenTypeDisplay}; use crate::typing::abstract_type::DomainType; use crate::typing::type_inference::{DomainVariableIDMarker, TypeVariableIDMarker}; use std::cell::OnceCell; -use std::fmt::Display; -use std::ops::{Deref, Index}; +use std::ops::Deref; pub use flatten::flatten_all_modules; pub use initialization::gather_initial_file_data; @@ -480,16 +478,6 @@ impl WrittenType { WrittenType::Named(global_ref) => global_ref.get_total_span() } } - pub fn display<'a, TypVec: Index, TemplateVec: TemplateNameGetter>(&'a self, - linker_types: &'a TypVec, - template_names: &'a TemplateVec, - ) -> impl Display + 'a { - WrittenTypeDisplay { - inner: self, - linker_types, - template_names, - } - } } /// Little helper struct that tells us what kind of declaration it is. Is it a Port, Template argument, A struct field, or just a regular temporary? diff --git a/src/to_string.rs b/src/to_string.rs index 721d81a..4d5b1a3 100644 --- a/src/to_string.rs +++ b/src/to_string.rs @@ -45,9 +45,9 @@ pub struct WrittenTypeDisplay< TypVec: Index, TemplateVec: TemplateNameGetter, > { - pub inner: &'a WrittenType, - pub linker_types: &'a TypVec, - pub template_names: &'a TemplateVec, + inner: &'a WrittenType, + linker_types: &'a TypVec, + template_names: &'a TemplateVec, } impl<'a, TypVec: Index, TemplateVec: TemplateNameGetter> Display @@ -75,15 +75,33 @@ impl<'a, TypVec: Index, TemplateVec: TemplateName } } +impl WrittenType { + pub fn display< + 'a, + TypVec: Index, + TemplateVec: TemplateNameGetter, + >( + &'a self, + linker_types: &'a TypVec, + template_names: &'a TemplateVec, + ) -> impl Display + 'a { + WrittenTypeDisplay { + inner: self, + linker_types, + template_names, + } + } +} + #[derive(Debug)] pub struct AbstractTypeDisplay< 'a, TypVec: Index, TemplateVec: TemplateNameGetter, > { - pub inner: &'a AbstractType, - pub linker_types: &'a TypVec, - pub template_names: &'a TemplateVec, + inner: &'a AbstractType, + linker_types: &'a TypVec, + template_names: &'a TemplateVec, } impl, TemplateVec: TemplateNameGetter> Display @@ -105,10 +123,28 @@ impl, TemplateVec: TemplateNameGett } } +impl AbstractType { + pub fn display< + 'a, + TypVec: Index, + TemplateVec: TemplateNameGetter, + >( + &'a self, + linker_types: &'a TypVec, + template_names: &'a TemplateVec, + ) -> impl Display + 'a { + AbstractTypeDisplay { + inner: self, + linker_types, + template_names, + } + } +} + #[derive(Debug)] pub struct ConcreteTypeDisplay<'a, T: Index> { - pub inner: &'a ConcreteType, - pub linker_types: &'a T, + inner: &'a ConcreteType, + linker_types: &'a T, } impl> Display for ConcreteTypeDisplay<'_, T> { @@ -132,6 +168,18 @@ impl> Display for ConcreteTypeDisplay<'_ } } +impl ConcreteType { + pub fn display<'a>( + &'a self, + linker_types: &'a impl Index, + ) -> impl Display + 'a { + ConcreteTypeDisplay { + inner: self, + linker_types, + } + } +} + impl Display for Value { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { diff --git a/src/typing/abstract_type.rs b/src/typing/abstract_type.rs index c4d5da6..81ea9cb 100644 --- a/src/typing/abstract_type.rs +++ b/src/typing/abstract_type.rs @@ -1,9 +1,7 @@ use crate::alloc::ArenaAllocator; use crate::prelude::*; use crate::value::Value; - -use std::fmt::Display; -use std::ops::{Deref, Index}; +use std::ops::Deref; use super::template::{GlobalReference, TemplateAbstractTypes, TemplateInputs}; use super::type_inference::{DomainVariableID, DomainVariableIDMarker, TypeSubstitutor, TypeVariableID, TypeVariableIDMarker, UnifyErrorReport}; @@ -24,19 +22,6 @@ pub enum AbstractType { Array(Box), } -impl AbstractType { - pub fn display<'a, TypVec: Index, TemplateVec: TemplateNameGetter>(&'a self, - linker_types: &'a TypVec, - template_names: &'a TemplateVec, -) -> impl Display + 'a { - AbstractTypeDisplay { - inner: self, - linker_types, - template_names, - } - } -} - pub const BOOL_TYPE: AbstractType = AbstractType::Named(get_builtin_type("bool")); pub const INT_TYPE: AbstractType = AbstractType::Named(get_builtin_type("int")); diff --git a/src/typing/concrete_type.rs b/src/typing/concrete_type.rs index 8655c24..27afcdc 100644 --- a/src/typing/concrete_type.rs +++ b/src/typing/concrete_type.rs @@ -1,9 +1,5 @@ -use crate::flattening::StructType; use crate::prelude::*; -use crate::to_string::ConcreteTypeDisplay; - -use std::fmt::Display; -use std::ops::{Deref, Index}; +use std::ops::Deref; use crate::linker::get_builtin_type; use crate:: @@ -49,10 +45,4 @@ impl ConcreteType { ConcreteType::Unknown(_) => true, } } - pub fn display<'a>(&'a self, linker_types: &'a impl Index) -> impl Display + 'a { - ConcreteTypeDisplay { - inner: self, - linker_types, - } - } } From 58c00f587efcf5a71ce224c2a75d9a0b1c1c8e52 Mon Sep 17 00:00:00 2001 From: Tobias Tom Hodapp Date: Sun, 12 Jan 2025 02:52:00 +0100 Subject: [PATCH 4/4] Fixed merge error --- src/to_string.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/to_string.rs b/src/to_string.rs index 4d5b1a3..1dde784 100644 --- a/src/to_string.rs +++ b/src/to_string.rs @@ -331,11 +331,11 @@ where ) .unwrap(); } - ConcreteTemplateArg::Value(typed_value, how_do_we_know_the_template_arg) => { + ConcreteTemplateArg::Value(value, how_do_we_know_the_template_arg) => { write!( result, "{} /* {} */,\n", - typed_value.value.to_string(), + value.to_string(), how_do_we_know_the_template_arg.to_str() ) .unwrap();