mirror of
https://github.com/erg-lang/erg.git
synced 2025-07-24 13:34:52 +00:00
chore: improve messages for unexpected arguments
This commit is contained in:
parent
7c748f223a
commit
73a91dcbbb
4 changed files with 93 additions and 4 deletions
|
@ -1347,6 +1347,7 @@ impl Context {
|
|||
))
|
||||
} else {
|
||||
let unknown_arg_errors = unknown_args.into_iter().map(|arg| {
|
||||
let similar = get_similar_name(subr_ty.param_names(), arg.keyword.inspect());
|
||||
TyCheckError::unexpected_kw_arg_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1354,6 +1355,7 @@ impl Context {
|
|||
&callee.to_string(),
|
||||
self.caused_by(),
|
||||
arg.keyword.inspect(),
|
||||
similar,
|
||||
)
|
||||
});
|
||||
let duplicated_arg_errors = duplicated_args.into_iter().map(|arg| {
|
||||
|
@ -1541,6 +1543,7 @@ impl Context {
|
|||
)
|
||||
})?;
|
||||
} else {
|
||||
let similar = get_similar_name(subr_ty.param_names(), arg.keyword.inspect());
|
||||
return Err(TyCheckErrors::from(TyCheckError::unexpected_kw_arg_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1548,6 +1551,7 @@ impl Context {
|
|||
&callee.to_string(),
|
||||
self.caused_by(),
|
||||
kw_name,
|
||||
similar,
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -775,7 +775,23 @@ impl Context {
|
|||
// contravariant
|
||||
self.sub_unify(rpt.typ(), lpt.typ(), loc, param_name)?;
|
||||
} else {
|
||||
unreachable!()
|
||||
let param_name = lpt.name().map_or("_", |s| &s[..]);
|
||||
let similar_param = erg_common::levenshtein::get_similar_name(
|
||||
rsub.default_params
|
||||
.iter()
|
||||
.map(|pt| pt.name().map_or("_", |s| &s[..])),
|
||||
param_name,
|
||||
);
|
||||
return Err(TyCheckErrors::from(
|
||||
TyCheckError::default_param_not_found_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
loc.loc(),
|
||||
self.caused_by(),
|
||||
param_name,
|
||||
similar_param,
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
// covariant
|
||||
|
@ -876,7 +892,15 @@ impl Context {
|
|||
if let Some((_, sub_ty)) = sub_fields.get_key_value(&sup_field) {
|
||||
self.sub_unify(sub_ty, &sup_ty, loc, param_name)?;
|
||||
} else {
|
||||
unreachable!()
|
||||
return Err(TyCheckErrors::from(TyCheckError::no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
loc.loc(),
|
||||
self.caused_by(),
|
||||
sub,
|
||||
&sup_field.symbol,
|
||||
self.get_similar_attr(sub, &sup_field.symbol),
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -363,6 +363,46 @@ impl TyCheckError {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn default_param_not_found_error(
|
||||
input: Input,
|
||||
errno: usize,
|
||||
loc: Location,
|
||||
caused_by: String,
|
||||
param_name: &str,
|
||||
similar_name: Option<&str>,
|
||||
) -> Self {
|
||||
let hint = match similar_name {
|
||||
Some(name) => {
|
||||
let mut s = StyledStrings::default();
|
||||
switch_lang!(
|
||||
"japanese" => s.push_str("似た名前の引数があります: "),
|
||||
"simplified_chinese" => s.push_str("相似的参数: "),
|
||||
"traditional_chinese" => s.push_str("相似的參數: "),
|
||||
"english" => s.push_str("exists a similar name parameter: "),
|
||||
);
|
||||
s.push_str_with_color_and_attribute(name, HINT, ATTR);
|
||||
Some(s.to_string())
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("{param_name}という名前のデフォルト引数はありません"),
|
||||
"simplified_chinese" => format!("没有名为{param_name}的默认参数"),
|
||||
"traditional_chinese" => format!("沒有名為{param_name}的預設參數"),
|
||||
"english" => format!("there is no default parameter named {param_name}"),
|
||||
),
|
||||
errno,
|
||||
TypeError,
|
||||
loc,
|
||||
),
|
||||
input,
|
||||
caused_by,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn match_error(
|
||||
input: Input,
|
||||
errno: usize,
|
||||
|
@ -540,14 +580,27 @@ passed keyword args: {kw_args_len}"
|
|||
callee_name: &str,
|
||||
caused_by: String,
|
||||
param_name: &str,
|
||||
similar_name: Option<&str>,
|
||||
) -> Self {
|
||||
let name = StyledStr::new(readable_name(callee_name), Some(WARN), Some(ATTR));
|
||||
let found = StyledString::new(param_name, Some(ERR), Some(ATTR));
|
||||
let hint = match similar_name {
|
||||
Some(similar_name) => {
|
||||
let similar_name = StyledString::new(similar_name, Some(HINT), Some(ATTR));
|
||||
Some(switch_lang!(
|
||||
"japanese" => format!("似た名前の引数があります: {similar_name}"),
|
||||
"simplified_chinese" => format!("有相似的关参数: {similar_name}"),
|
||||
"traditional_chinese" => format!("有相似的關參數: {similar_name}"),
|
||||
"english" => format!("exists a similar name parameter: {similar_name}"),
|
||||
))
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::only_loc(loc)],
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("{name}には予期しないキーワード引数{found}が渡されています"),
|
||||
"japanese" => format!("{name}に予期しないキーワード引数{found}が渡されています"),
|
||||
"simplified_chinese" => format!("{name}得到了意外的关键字参数{found}"),
|
||||
"traditional_chinese" => format!("{name}得到了意外的關鍵字參數{found}"),
|
||||
"english" => format!("{name} got unexpected keyword argument {found}"),
|
||||
|
|
|
@ -463,6 +463,14 @@ impl SubrType {
|
|||
.chain(self.default_params.iter())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn param_names(&self) -> impl Iterator<Item = &str> + Clone {
|
||||
self.non_default_params
|
||||
.iter()
|
||||
.chain(self.var_params.as_deref().into_iter())
|
||||
.chain(self.default_params.iter())
|
||||
.map(|pt| pt.name().map_or("_", |s| &s[..]))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue