mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 04:44:44 +00:00
Merge pull request #232 from erg-lang/split-err-msg
Split error messages
This commit is contained in:
commit
2caa6b6ec9
15 changed files with 1652 additions and 1006 deletions
|
@ -241,7 +241,8 @@ impl Context {
|
|||
match subr {
|
||||
ConstSubr::User(_user) => todo!(),
|
||||
ConstSubr::Builtin(builtin) => builtin.call(args, self).map_err(|mut e| {
|
||||
e.0.loc = loc;
|
||||
// TODO: Is it possible to get 0?
|
||||
e.0.sub_messages.get_mut(0).unwrap().loc = loc;
|
||||
EvalErrors::from(EvalError::new(
|
||||
*e.0,
|
||||
self.cfg.input.clone(),
|
||||
|
|
|
@ -6,29 +6,39 @@ use crate::context::Context;
|
|||
use crate::ty::constructors::{and, mono};
|
||||
use crate::ty::value::{EvalValueResult, GenTypeObj, TypeObj, ValueObj};
|
||||
use crate::ty::ValueArgs;
|
||||
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
||||
use erg_common::style::{RED, RESET, YELLOW};
|
||||
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
|
||||
use erg_common::style::{Color, StyledStr, StyledString, THEME};
|
||||
|
||||
const ERR: Color = THEME.colors.error;
|
||||
const WARN: Color = THEME.colors.warning;
|
||||
|
||||
const SUP_ERR: StyledStr = StyledStr::new("Super", Some(ERR), None);
|
||||
const SUP_WARN: StyledStr = StyledStr::new("Super", Some(WARN), None);
|
||||
const CLASS_ERR: StyledStr = StyledStr::new("Class", Some(ERR), None);
|
||||
const REQ_ERR: StyledStr = StyledStr::new("Requirement", Some(ERR), None);
|
||||
const REQ_WARN: StyledStr = StyledStr::new("Requirement", Some(WARN), None);
|
||||
|
||||
/// Requirement: Type, Impl := Type -> ClassType
|
||||
pub fn class_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueObj> {
|
||||
let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!("{REQ_ERR} is not passed"),
|
||||
line!() as usize,
|
||||
ErrorKind::TypeError,
|
||||
Location::Unknown,
|
||||
format!("{RED}Requirement{RESET} is not passed"),
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
let Some(require) = require.as_type() else {
|
||||
let require = StyledString::new(&format!("{}", require), Some(ERR), None);
|
||||
return Err(ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!(
|
||||
"non-type object {require} is passed to {REQ_WARN}",
|
||||
),
|
||||
line!() as usize,
|
||||
ErrorKind::TypeError,
|
||||
Location::Unknown,
|
||||
format!(
|
||||
"non-type object {RED}{require}{RESET} is passed to {YELLOW}Requirement{RESET}",
|
||||
),
|
||||
None,
|
||||
).into());
|
||||
};
|
||||
let impls = args.remove_left_or_key("Impl");
|
||||
|
@ -40,23 +50,25 @@ pub fn class_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueOb
|
|||
/// Super: ClassType, Impl := Type, Additional := Type -> ClassType
|
||||
pub fn inherit_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueObj> {
|
||||
let sup = args.remove_left_or_key("Super").ok_or_else(|| {
|
||||
let sup = StyledStr::new("Super", Some(ERR), None);
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!("{sup} is not passed"),
|
||||
line!() as usize,
|
||||
ErrorKind::KeyError,
|
||||
Location::Unknown,
|
||||
format!("{RED}Super{RESET} is not passed"),
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
let Some(sup) = sup.as_type() else {
|
||||
let sup_ty = StyledString::new(&format!("{}", sup), Some(ERR), None);
|
||||
return Err(ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!(
|
||||
"non-class object {sup_ty} is passed to {SUP_WARN}",
|
||||
),
|
||||
line!() as usize,
|
||||
ErrorKind::TypeError,
|
||||
Location::Unknown,
|
||||
format!(
|
||||
"non-class object {RED}{sup}{RESET} is passed to {YELLOW}Super{RESET}",
|
||||
),
|
||||
None,
|
||||
).into());
|
||||
};
|
||||
let impls = args.remove_left_or_key("Impl");
|
||||
|
@ -74,11 +86,11 @@ pub fn inherit_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<Value
|
|||
pub fn inheritable_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<ValueObj> {
|
||||
let class = args.remove_left_or_key("Class").ok_or_else(|| {
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!("{CLASS_ERR} is not passed"),
|
||||
line!() as usize,
|
||||
ErrorKind::KeyError,
|
||||
Location::Unknown,
|
||||
format!("{RED}Class{RESET} is not passed"),
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
match class {
|
||||
|
@ -106,22 +118,23 @@ pub fn inheritable_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<
|
|||
pub fn trait_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueObj> {
|
||||
let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!("{REQ_ERR} is not passed"),
|
||||
line!() as usize,
|
||||
ErrorKind::KeyError,
|
||||
Location::Unknown,
|
||||
format!("{RED}Requirement{RESET} is not passed"),
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
let Some(require) = require.as_type() else {
|
||||
let require = StyledString::new(&format!("{}", require), Some(ERR), None);
|
||||
return Err(ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!(
|
||||
"non-type object {require} is passed to {REQ_WARN}",
|
||||
),
|
||||
line!() as usize,
|
||||
ErrorKind::TypeError,
|
||||
Location::Unknown,
|
||||
format!(
|
||||
"non-type object {RED}{require}{RESET} is passed to {YELLOW}Requirement{RESET}",
|
||||
),
|
||||
None,
|
||||
).into());
|
||||
};
|
||||
let impls = args.remove_left_or_key("Impl");
|
||||
|
@ -134,22 +147,23 @@ pub fn trait_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueOb
|
|||
pub fn subsume_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueObj> {
|
||||
let sup = args.remove_left_or_key("Super").ok_or_else(|| {
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!("{SUP_ERR} is not passed"),
|
||||
line!() as usize,
|
||||
ErrorKind::KeyError,
|
||||
Location::Unknown,
|
||||
format!("{RED}Super{RESET} is not passed"),
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
let Some(sup) = sup.as_type() else {
|
||||
let sup = StyledString::new(&format!("{}", sup), Some(ERR), None);
|
||||
return Err(ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!(
|
||||
"non-trait object {sup} is passed to {SUP_WARN}",
|
||||
),
|
||||
line!() as usize,
|
||||
ErrorKind::TypeError,
|
||||
Location::Unknown,
|
||||
format!(
|
||||
"non-trait object {RED}{sup}{RESET} is passed to {YELLOW}Super{RESET}",
|
||||
),
|
||||
None,
|
||||
).into());
|
||||
};
|
||||
let impls = args.remove_left_or_key("Impl");
|
||||
|
@ -171,16 +185,16 @@ pub fn __array_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<
|
|||
Ok(v.clone())
|
||||
} else {
|
||||
Err(ErrorCore::new(
|
||||
line!() as usize,
|
||||
ErrorKind::IndexError,
|
||||
Location::Unknown,
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!(
|
||||
"[{}] has {} elements, but accessed {}th element",
|
||||
erg_common::fmt_vec(&slf),
|
||||
slf.len(),
|
||||
index
|
||||
),
|
||||
None,
|
||||
line!() as usize,
|
||||
ErrorKind::IndexError,
|
||||
Location::Unknown,
|
||||
)
|
||||
.into())
|
||||
}
|
||||
|
@ -210,11 +224,11 @@ pub fn __dict_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<V
|
|||
Ok(v.clone())
|
||||
} else {
|
||||
Err(ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!("{slf} has no key {index}"),
|
||||
line!() as usize,
|
||||
ErrorKind::IndexError,
|
||||
Location::Unknown,
|
||||
format!("{slf} has no key {index}"),
|
||||
None,
|
||||
)
|
||||
.into())
|
||||
}
|
||||
|
@ -235,11 +249,11 @@ pub fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult
|
|||
Ok(ValueObj::Nat(start + index))
|
||||
} else {
|
||||
Err(ErrorCore::new(
|
||||
vec![SubMessage::only_loc(Location::Unknown)],
|
||||
format!("Index out of range: {}", index),
|
||||
line!() as usize,
|
||||
ErrorKind::IndexError,
|
||||
Location::Unknown,
|
||||
format!("Index out of range: {index}"),
|
||||
None,
|
||||
)
|
||||
.into())
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use erg_common::config::Input;
|
||||
use erg_common::env::erg_pystd_path;
|
||||
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
||||
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
|
||||
use erg_common::levenshtein::get_similar_name;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
|
@ -756,13 +756,21 @@ impl Context {
|
|||
TyCheckErrors::new(
|
||||
errs.into_iter()
|
||||
.map(|e| {
|
||||
// HACK: dname.loc()はダミーLocationしか返さないので、エラーならop.loc()で上書きする
|
||||
let mut sub_msges = Vec::new();
|
||||
for sub_msg in e.core.sub_messages {
|
||||
sub_msges.push(SubMessage::ambiguous_new(
|
||||
// HACK: dname.loc()はダミーLocationしか返さないので、エラーならop.loc()で上書きする
|
||||
bin.loc(),
|
||||
vec![],
|
||||
sub_msg.get_hint(),
|
||||
));
|
||||
}
|
||||
let core = ErrorCore::new(
|
||||
sub_msges,
|
||||
e.core.main_message,
|
||||
e.core.errno,
|
||||
e.core.kind,
|
||||
bin.loc(),
|
||||
e.core.desc,
|
||||
e.core.hint,
|
||||
e.core.loc,
|
||||
);
|
||||
TyCheckError::new(core, self.cfg.input.clone(), e.caused_by)
|
||||
})
|
||||
|
@ -797,12 +805,20 @@ impl Context {
|
|||
TyCheckErrors::new(
|
||||
errs.into_iter()
|
||||
.map(|e| {
|
||||
let mut sub_msges = Vec::new();
|
||||
for sub_msg in e.core.sub_messages {
|
||||
sub_msges.push(SubMessage::ambiguous_new(
|
||||
unary.loc(),
|
||||
vec![],
|
||||
sub_msg.get_hint(),
|
||||
));
|
||||
}
|
||||
let core = ErrorCore::new(
|
||||
sub_msges,
|
||||
e.core.main_message,
|
||||
e.core.errno,
|
||||
e.core.kind,
|
||||
unary.loc(),
|
||||
e.core.desc,
|
||||
e.core.hint,
|
||||
e.core.loc,
|
||||
);
|
||||
TyCheckError::new(core, self.cfg.input.clone(), e.caused_by)
|
||||
})
|
||||
|
@ -1052,7 +1068,8 @@ impl Context {
|
|||
TyCheckError::type_mismatch_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
e.core.loc,
|
||||
// TODO: Is it possible to get 0?
|
||||
e.core.sub_messages.get(0).unwrap().loc,
|
||||
e.caused_by,
|
||||
&name[..],
|
||||
Some(nth),
|
||||
|
@ -1107,7 +1124,8 @@ impl Context {
|
|||
TyCheckError::type_mismatch_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
e.core.loc,
|
||||
// TODO: Is it possible to get 0?
|
||||
e.core.sub_messages.get(0).unwrap().loc,
|
||||
e.caused_by,
|
||||
&name[..],
|
||||
Some(nth),
|
||||
|
@ -1164,7 +1182,8 @@ impl Context {
|
|||
TyCheckError::type_mismatch_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
e.core.loc,
|
||||
// TODO: Is it possible to get 0?
|
||||
e.core.sub_messages.get(0).unwrap().loc,
|
||||
e.caused_by,
|
||||
&name[..],
|
||||
Some(nth),
|
||||
|
|
|
@ -416,7 +416,8 @@ impl Context {
|
|||
TyCheckError::return_type_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
e.core.loc,
|
||||
// TODO: is it possible to get 0?
|
||||
e.core.sub_messages.get(0).unwrap().loc,
|
||||
e.caused_by,
|
||||
readable_name(name.inspect()),
|
||||
spec_ret_t,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue