mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-11-03 21:16:16 +01:00 
			
		
		
		
	improve/fix errors in #include
This commit is contained in:
		
							parent
							
								
									12925fed67
								
							
						
					
					
						commit
						b6d708db3d
					
				@ -69,17 +69,14 @@ fn main() {
 | 
			
		||||
    });
 | 
			
		||||
    let (mut info_parsed, mut info_run, mut info_check) = config.infos();
 | 
			
		||||
    let mut source = match args.command {
 | 
			
		||||
        Command::Run { file } => {
 | 
			
		||||
            let str = match fs::read_to_string(&file) {
 | 
			
		||||
        Command::Run { file } => match Source::new_from_file(PathBuf::from(&file)) {
 | 
			
		||||
            Ok(s) => s,
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                eprintln!("Can't read file {file:?}: {e}");
 | 
			
		||||
                exit(10);
 | 
			
		||||
            }
 | 
			
		||||
            };
 | 
			
		||||
            Source::new(str)
 | 
			
		||||
        }
 | 
			
		||||
        Command::Exec { source } => Source::new(source),
 | 
			
		||||
        },
 | 
			
		||||
        Command::Exec { source } => Source::new_from_string(source),
 | 
			
		||||
    };
 | 
			
		||||
    let parsed = match parse(&mut source) {
 | 
			
		||||
        Ok(v) => v,
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
use std::fmt::Display;
 | 
			
		||||
use std::fmt::{Debug, Display};
 | 
			
		||||
 | 
			
		||||
use colored::Colorize;
 | 
			
		||||
use line_span::LineSpans;
 | 
			
		||||
@ -35,7 +35,6 @@ impl SourceRange {
 | 
			
		||||
        self.end
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct CheckError(Vec<CheckErrorComponent>);
 | 
			
		||||
#[allow(non_upper_case_globals)]
 | 
			
		||||
pub mod error_colors {
 | 
			
		||||
@ -65,10 +64,10 @@ pub mod error_colors {
 | 
			
		||||
    pub const AssignTo: Color = InitTo;
 | 
			
		||||
    pub const AssignTargetNonReference: Color = Color::BrightYellow;
 | 
			
		||||
}
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
enum CheckErrorComponent {
 | 
			
		||||
    Message(String),
 | 
			
		||||
    Error(CheckError),
 | 
			
		||||
    ErrorWithSrc(CheckErrorWithSrc),
 | 
			
		||||
    Source(Vec<(SourceRange, Option<colored::Color>)>),
 | 
			
		||||
}
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
@ -86,6 +85,12 @@ pub struct CheckErrorDisplay<'a> {
 | 
			
		||||
    pub show_comments: bool,
 | 
			
		||||
}
 | 
			
		||||
#[cfg(feature = "parse")]
 | 
			
		||||
pub struct CheckErrorWithSrc {
 | 
			
		||||
    e: CheckError,
 | 
			
		||||
    src: Source,
 | 
			
		||||
    pub show_comments: bool,
 | 
			
		||||
}
 | 
			
		||||
#[cfg(feature = "parse")]
 | 
			
		||||
impl<'a> CheckErrorDisplay<'a> {
 | 
			
		||||
    pub fn show_comments(mut self, show_comments: bool) -> Self {
 | 
			
		||||
        self.show_comments = show_comments;
 | 
			
		||||
@ -93,6 +98,13 @@ impl<'a> CheckErrorDisplay<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#[cfg(feature = "parse")]
 | 
			
		||||
impl CheckErrorWithSrc {
 | 
			
		||||
    pub fn show_comments(mut self, show_comments: bool) -> Self {
 | 
			
		||||
        self.show_comments = show_comments;
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#[cfg(feature = "parse")]
 | 
			
		||||
impl Display for CheckErrorDisplay<'_> {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        self.e.human_readable(
 | 
			
		||||
@ -107,6 +119,21 @@ impl Display for CheckErrorDisplay<'_> {
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#[cfg(feature = "parse")]
 | 
			
		||||
impl Display for CheckErrorWithSrc {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        self.e.human_readable(
 | 
			
		||||
            f,
 | 
			
		||||
            Some(&self.src),
 | 
			
		||||
            &CheckErrorHRConfig {
 | 
			
		||||
                indent_start: String::new(),
 | 
			
		||||
                indent_default: String::new(),
 | 
			
		||||
                indent_end: String::new(),
 | 
			
		||||
                show_comments: self.show_comments,
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
impl CheckError {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        CheckError(vec![])
 | 
			
		||||
@ -121,6 +148,13 @@ impl CheckError {
 | 
			
		||||
    pub(crate) fn err(self, e: Self) -> Self {
 | 
			
		||||
        self.add(CheckErrorComponent::Error(e))
 | 
			
		||||
    }
 | 
			
		||||
    pub(crate) fn err_with_src(self, e: CheckError, src: Source) -> Self {
 | 
			
		||||
        self.add(CheckErrorComponent::ErrorWithSrc(CheckErrorWithSrc {
 | 
			
		||||
            e,
 | 
			
		||||
            src,
 | 
			
		||||
            show_comments: true,
 | 
			
		||||
        }))
 | 
			
		||||
    }
 | 
			
		||||
    pub(crate) fn src(self, s: Vec<(SourceRange, Option<colored::Color>)>) -> Self {
 | 
			
		||||
        self.add(CheckErrorComponent::Source(s))
 | 
			
		||||
    }
 | 
			
		||||
@ -148,6 +182,8 @@ impl CheckError {
 | 
			
		||||
        src: Option<&Source>,
 | 
			
		||||
        cfg: &CheckErrorHRConfig,
 | 
			
		||||
    ) -> std::fmt::Result {
 | 
			
		||||
        use crate::parsing::SourceFrom;
 | 
			
		||||
 | 
			
		||||
        let len = self.0.len();
 | 
			
		||||
        for (i, component) in self.0.iter().enumerate() {
 | 
			
		||||
            macro_rules! indent {
 | 
			
		||||
@ -170,6 +206,14 @@ impl CheckError {
 | 
			
		||||
                    cfg.indent_end.push_str("└");
 | 
			
		||||
                    err.human_readable(f, src, &cfg)?;
 | 
			
		||||
                }
 | 
			
		||||
                CheckErrorComponent::ErrorWithSrc(err) => {
 | 
			
		||||
                    let mut cfg = cfg.clone();
 | 
			
		||||
                    cfg.indent_start.push_str(&"│".bright_yellow().to_string());
 | 
			
		||||
                    cfg.indent_default
 | 
			
		||||
                        .push_str(&"│".bright_yellow().to_string());
 | 
			
		||||
                    cfg.indent_end.push_str(&"└".bright_yellow().to_string());
 | 
			
		||||
                    err.e.human_readable(f, Some(&err.src), &cfg)?;
 | 
			
		||||
                }
 | 
			
		||||
                CheckErrorComponent::Source(highlights) => {
 | 
			
		||||
                    if let Some(src) = src {
 | 
			
		||||
                        let start = highlights.iter().map(|v| v.0.start.pos()).min();
 | 
			
		||||
@ -218,21 +262,27 @@ impl CheckError {
 | 
			
		||||
                                    }
 | 
			
		||||
                                })
 | 
			
		||||
                                .count();
 | 
			
		||||
                            let src_from = match src.src_from() {
 | 
			
		||||
                                SourceFrom::File(path) => format!(" [{}]", path.to_string_lossy()),
 | 
			
		||||
                                SourceFrom::Unspecified => String::with_capacity(0),
 | 
			
		||||
                            };
 | 
			
		||||
                            if first_line_nr == last_line_nr {
 | 
			
		||||
                                writeln!(
 | 
			
		||||
                                    f,
 | 
			
		||||
                                    "{}Line {first_line_nr} ({}..{})",
 | 
			
		||||
                                    "{}Line {first_line_nr} ({}..{}){}",
 | 
			
		||||
                                    indent!(),
 | 
			
		||||
                                    start_with_comments + 1 - first_line_start,
 | 
			
		||||
                                    end_with_comments - last_line_start,
 | 
			
		||||
                                    src_from,
 | 
			
		||||
                                )?;
 | 
			
		||||
                            } else {
 | 
			
		||||
                                writeln!(
 | 
			
		||||
                                    f,
 | 
			
		||||
                                    "{}Lines {first_line_nr}-{last_line_nr} ({}..{})",
 | 
			
		||||
                                    "{}Lines {first_line_nr}-{last_line_nr} ({}..{}){}",
 | 
			
		||||
                                    indent!(),
 | 
			
		||||
                                    start_with_comments + 1 - first_line_start,
 | 
			
		||||
                                    end_with_comments - last_line_start,
 | 
			
		||||
                                    src_from,
 | 
			
		||||
                                )?;
 | 
			
		||||
                            }
 | 
			
		||||
                            let lines = if cfg.show_comments {
 | 
			
		||||
@ -306,3 +356,13 @@ impl From<String> for CheckError {
 | 
			
		||||
        Self::new().msg(value)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
impl Debug for CheckError {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        write!(f, "{self}")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
impl Display for CheckError {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        write!(f, "{}", self.display_no_src())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use std::{fmt::Debug, path::PathBuf, sync::Arc};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    errors::{CheckError, SourcePos},
 | 
			
		||||
@ -19,6 +19,7 @@ pub fn parse(src: &mut Source) -> Result<Box<dyn program::parsed::MersStatement>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Source {
 | 
			
		||||
    src_from: SourceFrom,
 | 
			
		||||
    src_raw_len: usize,
 | 
			
		||||
    src_og: String,
 | 
			
		||||
    src: String,
 | 
			
		||||
@ -27,8 +28,38 @@ pub struct Source {
 | 
			
		||||
    i: usize,
 | 
			
		||||
    sections: Vec<SectionMarker>,
 | 
			
		||||
}
 | 
			
		||||
impl Clone for Source {
 | 
			
		||||
    fn clone(&self) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            src_from: self.src_from.clone(),
 | 
			
		||||
            src_raw_len: self.src_raw_len,
 | 
			
		||||
            src_og: self.src_og.clone(),
 | 
			
		||||
            src: self.src.clone(),
 | 
			
		||||
            comments: self.comments.clone(),
 | 
			
		||||
            i: self.i,
 | 
			
		||||
            sections: vec![],
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
impl Debug for Source {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        write!(f, "Src: {:?}", self.src_from)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub enum SourceFrom {
 | 
			
		||||
    File(PathBuf),
 | 
			
		||||
    Unspecified,
 | 
			
		||||
}
 | 
			
		||||
impl Source {
 | 
			
		||||
    pub fn new(source: String) -> Self {
 | 
			
		||||
    pub fn new_from_file(path: PathBuf) -> std::io::Result<Self> {
 | 
			
		||||
        let content = std::fs::read_to_string(&path)?;
 | 
			
		||||
        Ok(Self::new(SourceFrom::File(path), content))
 | 
			
		||||
    }
 | 
			
		||||
    pub fn new_from_string(source: String) -> Self {
 | 
			
		||||
        Self::new(SourceFrom::Unspecified, source)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn new(src_from: SourceFrom, source: String) -> Self {
 | 
			
		||||
        let mut src = String::with_capacity(source.len());
 | 
			
		||||
        let mut comment = (0, String::new());
 | 
			
		||||
        let mut comments = Vec::new();
 | 
			
		||||
@ -88,6 +119,7 @@ impl Source {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Self {
 | 
			
		||||
            src_from,
 | 
			
		||||
            src_raw_len: source.len(),
 | 
			
		||||
            src_og: source,
 | 
			
		||||
            src,
 | 
			
		||||
@ -228,6 +260,10 @@ impl Source {
 | 
			
		||||
        o
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn src_from(&self) -> &SourceFrom {
 | 
			
		||||
        &self.src_from
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn pos_in_og(&self, mut pos: usize, inclusive: bool) -> usize {
 | 
			
		||||
        for (start, comment) in &self.comments {
 | 
			
		||||
            if *start < pos || (inclusive && *start == pos) {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
 | 
			
		||||
use super::{Source, SourcePos};
 | 
			
		||||
use crate::{
 | 
			
		||||
@ -154,13 +154,21 @@ pub fn parse_no_chain(
 | 
			
		||||
                    src.skip_whitespace();
 | 
			
		||||
                    let string_in_src = src.get_pos();
 | 
			
		||||
                    if src.next_char() == Some('"') {
 | 
			
		||||
                        let s = parse_string(src, string_in_src)?;
 | 
			
		||||
                        match fs::read_to_string(&s) {
 | 
			
		||||
                            Ok(s) => {
 | 
			
		||||
                        let file_path = parse_string(src, string_in_src)?;
 | 
			
		||||
                        match Source::new_from_file(PathBuf::from(&file_path)) {
 | 
			
		||||
                            Ok(mut inner_src) => {
 | 
			
		||||
                                return Ok(Some(Box::new(
 | 
			
		||||
                                    program::parsed::include_mers::IncludeMers {
 | 
			
		||||
                                        pos_in_src: (pos_in_src, src.get_pos()).into(),
 | 
			
		||||
                                        include: super::parse(&mut Source::new(s))?,
 | 
			
		||||
                                        include: match super::parse(&mut inner_src) {
 | 
			
		||||
                                            Ok(v) => v,
 | 
			
		||||
                                            Err(e) => {
 | 
			
		||||
                                                return Err(
 | 
			
		||||
                                                    CheckError::new().err_with_src(e, inner_src)
 | 
			
		||||
                                                )
 | 
			
		||||
                                            }
 | 
			
		||||
                                        },
 | 
			
		||||
                                        inner_src,
 | 
			
		||||
                                    },
 | 
			
		||||
                                )));
 | 
			
		||||
                            }
 | 
			
		||||
@ -173,7 +181,7 @@ pub fn parse_no_chain(
 | 
			
		||||
                                            Some(error_colors::HashIncludeCantLoadFile),
 | 
			
		||||
                                        ),
 | 
			
		||||
                                    ])
 | 
			
		||||
                                    .msg(format!("Can't load file '{s}': {e}")));
 | 
			
		||||
                                    .msg(format!("Can't load file '{file_path}': {e}")));
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ impl MersStatement for Chain {
 | 
			
		||||
            pos_in_src: self.pos_in_src,
 | 
			
		||||
            first: self.first.compile(info, comp)?,
 | 
			
		||||
            chained: self.chained.compile(info, comp)?,
 | 
			
		||||
            as_part_of_include: None,
 | 
			
		||||
        }))
 | 
			
		||||
    }
 | 
			
		||||
    fn source_range(&self) -> SourceRange {
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ use crate::{
 | 
			
		||||
    data::{self, Data},
 | 
			
		||||
    errors::{error_colors, CheckError, SourceRange},
 | 
			
		||||
    info::{self, Local},
 | 
			
		||||
    parsing::Source,
 | 
			
		||||
    program::{self},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -15,6 +16,7 @@ use super::{CompInfo, MersStatement};
 | 
			
		||||
pub struct IncludeMers {
 | 
			
		||||
    pub pos_in_src: SourceRange,
 | 
			
		||||
    pub include: Box<dyn MersStatement>,
 | 
			
		||||
    pub inner_src: Source,
 | 
			
		||||
}
 | 
			
		||||
impl MersStatement for IncludeMers {
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
@ -25,13 +27,21 @@ impl MersStatement for IncludeMers {
 | 
			
		||||
        info: &mut info::Info<super::Local>,
 | 
			
		||||
        comp: CompInfo,
 | 
			
		||||
    ) -> Result<Box<dyn program::run::MersStatement>, CheckError> {
 | 
			
		||||
        let compiled: Arc<Box<dyn crate::program::run::MersStatement>> = match self.include.compile(info, comp) {
 | 
			
		||||
        let compiled: Arc<Box<dyn crate::program::run::MersStatement>> =
 | 
			
		||||
            match self.include.compile(info, comp) {
 | 
			
		||||
                Ok(v) => Arc::new(v),
 | 
			
		||||
                Err(e) => {
 | 
			
		||||
                    return Err(CheckError::new()
 | 
			
		||||
                    .src(vec![(self.pos_in_src, Some(error_colors::HashIncludeErrorInIncludedFile))])
 | 
			
		||||
                    .msg("Error in inner mers statement! (note: inner errors may refer to a different file)".color(error_colors::HashIncludeErrorInIncludedFile).to_string())
 | 
			
		||||
                .err(e))
 | 
			
		||||
                        .src(vec![(
 | 
			
		||||
                            self.pos_in_src,
 | 
			
		||||
                            Some(error_colors::HashIncludeErrorInIncludedFile),
 | 
			
		||||
                        )])
 | 
			
		||||
                        .msg(
 | 
			
		||||
                            "Error in #include! (note: inner errors may refer to a different file)"
 | 
			
		||||
                                .color(error_colors::HashIncludeErrorInIncludedFile)
 | 
			
		||||
                                .to_string(),
 | 
			
		||||
                        )
 | 
			
		||||
                        .err_with_src(e, self.inner_src.clone()))
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        let compiled2 = Arc::clone(&compiled);
 | 
			
		||||
@ -50,6 +60,7 @@ impl MersStatement for IncludeMers {
 | 
			
		||||
                    run: Arc::new(move |_, i| compiled2.run(&mut i.duplicate())),
 | 
			
		||||
                },
 | 
			
		||||
            }),
 | 
			
		||||
            as_part_of_include: Some(self.inner_src.clone()),
 | 
			
		||||
        }))
 | 
			
		||||
    }
 | 
			
		||||
    fn source_range(&self) -> SourceRange {
 | 
			
		||||
 | 
			
		||||
@ -31,8 +31,8 @@ impl MersStatement for AssignTo {
 | 
			
		||||
                return Err(CheckError::new()
 | 
			
		||||
                    .src(vec![
 | 
			
		||||
                        (self.pos_in_src, None),
 | 
			
		||||
                        (self.target.source_range(), Some(error_colors::InitFrom)),
 | 
			
		||||
                        (self.source.source_range(), Some(error_colors::InitTo)),
 | 
			
		||||
                        (self.target.source_range(), Some(error_colors::InitTo)),
 | 
			
		||||
                        (self.source.source_range(), Some(error_colors::InitFrom)),
 | 
			
		||||
                    ])
 | 
			
		||||
                    .msg(format!("Cannot initialize:"))
 | 
			
		||||
                    .err(e))
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ use colored::Colorize;
 | 
			
		||||
use crate::{
 | 
			
		||||
    data::{Data, Type},
 | 
			
		||||
    errors::{error_colors, CheckError, SourceRange},
 | 
			
		||||
    parsing::Source,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::MersStatement;
 | 
			
		||||
@ -14,6 +15,7 @@ pub struct Chain {
 | 
			
		||||
    pub pos_in_src: SourceRange,
 | 
			
		||||
    pub first: Box<dyn MersStatement>,
 | 
			
		||||
    pub chained: Box<dyn MersStatement>,
 | 
			
		||||
    pub as_part_of_include: Option<Source>,
 | 
			
		||||
}
 | 
			
		||||
impl MersStatement for Chain {
 | 
			
		||||
    fn check_custom(
 | 
			
		||||
@ -35,7 +37,20 @@ impl MersStatement for Chain {
 | 
			
		||||
                match (func.0)(&arg) {
 | 
			
		||||
                    Ok(t) => o.add(Arc::new(t)),
 | 
			
		||||
                    Err(e) => {
 | 
			
		||||
                        return Err(CheckError::new()
 | 
			
		||||
                        return Err(if let Some(inner_src) = &self.as_part_of_include {
 | 
			
		||||
                            CheckError::new()
 | 
			
		||||
                                .src(vec![(
 | 
			
		||||
                                    self.pos_in_src,
 | 
			
		||||
                                    Some(error_colors::HashIncludeErrorInIncludedFile),
 | 
			
		||||
                                )])
 | 
			
		||||
                                .msg(
 | 
			
		||||
                                    "Error in #include:"
 | 
			
		||||
                                        .color(error_colors::HashIncludeErrorInIncludedFile)
 | 
			
		||||
                                        .to_string(),
 | 
			
		||||
                                )
 | 
			
		||||
                                .err_with_src(e, inner_src.clone())
 | 
			
		||||
                        } else {
 | 
			
		||||
                            CheckError::new()
 | 
			
		||||
                                .src(vec![
 | 
			
		||||
                                    (self.pos_in_src, None),
 | 
			
		||||
                                    (
 | 
			
		||||
@ -49,7 +64,8 @@ impl MersStatement for Chain {
 | 
			
		||||
                                    "this function".color(error_colors::Function),
 | 
			
		||||
                                    arg.to_string().color(error_colors::FunctionArgument)
 | 
			
		||||
                                ))
 | 
			
		||||
                            .err(e))
 | 
			
		||||
                                .err(e)
 | 
			
		||||
                        })
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,20 @@ impl MersStatement for Tuple {
 | 
			
		||||
                            ).into());
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    return Err(format!("can't init a {} with a value of type {}, which is part of {} - only tuples can be assigned to tuples", "tuple".color(error_colors::InitTo), t.to_string().color(error_colors::InitFrom), init_to.to_string().color(error_colors::InitFrom)).into());
 | 
			
		||||
                    return Err(format!(
 | 
			
		||||
                        "can't init a {} with type {}{} - only tuples can be assigned to tuples",
 | 
			
		||||
                        "tuple".color(error_colors::InitTo),
 | 
			
		||||
                        t.to_string().color(error_colors::InitFrom),
 | 
			
		||||
                        if print_is_part_of {
 | 
			
		||||
                            format!(
 | 
			
		||||
                                ", which is part of {}",
 | 
			
		||||
                                init_to.to_string().color(error_colors::InitFrom)
 | 
			
		||||
                            )
 | 
			
		||||
                        } else {
 | 
			
		||||
                            format!("")
 | 
			
		||||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
                    .into());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Some(vec)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user