diff --git a/src/dev_aid/lsp/hover_info.rs b/src/dev_aid/lsp/hover_info.rs index 4b33f9f..5a9071b 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 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 dd4e892..1dde784 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,143 @@ impl TemplateNameGetter for TemplateInputs { } } +#[derive(Debug)] +pub struct WrittenTypeDisplay< + 'a, + TypVec: Index, + TemplateVec: TemplateNameGetter, +> { + inner: &'a WrittenType, + linker_types: &'a TypVec, + 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) => { + write!( + f, + "{}[]", + sub.deref() + .0 + .display(self.linker_types, self.template_names) + ) + } + } + } +} + impl WrittenType { - pub fn to_string< + pub fn display< + 'a, 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(), - WrittenType::Array(_, sub) => { - sub.deref().0.to_string(linker_types, template_names) + "[]" + &'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, +> { + inner: &'a AbstractType, + linker_types: &'a TypVec, + 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 AbstractType { - pub fn to_string< + pub fn display< + 'a, 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) + "[]", + &'a self, + linker_types: &'a TypVec, + template_names: &'a TemplateVec, + ) -> impl Display + 'a { + AbstractTypeDisplay { + inner: self, + linker_types, + 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> { + inner: &'a ConcreteType, + 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:?}}}"), + } + } +} + +impl ConcreteType { + pub fn display<'a>( + &'a self, + linker_types: &'a impl Index, + ) -> impl Display + 'a { + ConcreteTypeDisplay { + inner: self, + linker_types, } } } @@ -224,26 +306,39 @@ 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 { 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]; 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(value, how_do_we_know_the_template_arg) => { - write!(result, "{} /* {} */,\n", value.to_string(), how_do_we_know_the_template_arg.to_str()).unwrap(); + write!( + result, + "{} /* {} */,\n", + 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..81ea9cb 100644 --- a/src/typing/abstract_type.rs +++ b/src/typing/abstract_type.rs @@ -1,14 +1,13 @@ use crate::alloc::ArenaAllocator; use crate::prelude::*; use crate::value::Value; - use std::ops::Deref; 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. /// @@ -322,7 +321,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..27afcdc 100644 --- a/src/typing/concrete_type.rs +++ b/src/typing/concrete_type.rs @@ -1,5 +1,4 @@ use crate::prelude::*; - use std::ops::Deref; use crate::linker::get_builtin_type;