Warn when defining a var has a built-in of the same name

This commit is contained in:
Shunsuke Shibayama 2022-12-27 11:26:15 +09:00
parent 3391d5da0b
commit 778082329a
3 changed files with 101 additions and 59 deletions

View file

@ -2035,7 +2035,8 @@ impl Context {
vec![kw("iterable", poly("Iterable", vec![ty_tp(T.clone())]))], vec![kw("iterable", poly("Iterable", vec![ty_tp(T.clone())]))],
None, None,
array_t(T.clone(), TyParam::erased(Nat)), array_t(T.clone(), TyParam::erased(Nat)),
); )
.quantify();
let t_str = nd_func(vec![kw("object", Obj)], None, Str); let t_str = nd_func(vec![kw("object", Obj)], None, Str);
let A = mono_q("A", Constraint::Uninited); let A = mono_q("A", Constraint::Uninited);
let A = mono_q("A", subtypeof(poly("Add", vec![ty_tp(A)]))); let A = mono_q("A", subtypeof(poly("Add", vec![ty_tp(A)])));

View file

@ -1995,64 +1995,6 @@ impl LowerError {
) )
} }
pub fn unused_warning(
input: Input,
errno: usize,
loc: Location,
name: &str,
caused_by: String,
) -> Self {
let name = StyledString::new(readable_name(name), Some(WARN), Some(ATTR));
Self::new(
ErrorCore::new(
vec![SubMessage::only_loc(loc)],
switch_lang!(
"japanese" => format!("{name}は使用されていません"),
"simplified_chinese" => format!("{name}未使用"),
"traditional_chinese" => format!("{name}未使用"),
"english" => format!("{name} is not used"),
),
errno,
UnusedWarning,
loc,
),
input,
caused_by,
)
}
pub fn union_return_type_warning(
input: Input,
errno: usize,
loc: Location,
caused_by: String,
fn_name: &str,
typ: &Type,
) -> Self {
let hint = switch_lang!(
"japanese" => format!("`{fn_name}(...): {typ} = ...`など明示的に戻り値型を指定してください"),
"simplified_chinese" => format!("请明确指定函数{fn_name}的返回类型,例如`{fn_name}(...): {typ} = ...`"),
"traditional_chinese" => format!("請明確指定函數{fn_name}的返回類型,例如`{fn_name}(...): {typ} = ...`"),
"english" => format!("please explicitly specify the return type of function {fn_name}, for example `{fn_name}(...): {typ} = ...`"),
);
LowerError::new(
ErrorCore::new(
vec![SubMessage::ambiguous_new(loc, vec![], Some(hint))],
switch_lang!(
"japanese" => format!("関数{fn_name}の戻り値型が単一ではありません"),
"simplified_chinese" => format!("函数{fn_name}的返回类型不是单一的"),
"traditional_chinese" => format!("函數{fn_name}的返回類型不是單一的"),
"english" => format!("the return type of function {fn_name} is not single"),
),
errno,
TypeWarning,
loc,
),
input,
caused_by,
)
}
pub fn del_error(input: Input, errno: usize, ident: &Identifier, caused_by: String) -> Self { pub fn del_error(input: Input, errno: usize, ident: &Identifier, caused_by: String) -> Self {
let name = StyledString::new(readable_name(ident.inspect()), Some(WARN), Some(ATTR)); let name = StyledString::new(readable_name(ident.inspect()), Some(WARN), Some(ATTR));
Self::new( Self::new(
@ -2476,6 +2418,92 @@ impl LowerError {
} }
} }
impl LowerWarning {
pub fn unused_warning(
input: Input,
errno: usize,
loc: Location,
name: &str,
caused_by: String,
) -> Self {
let name = StyledString::new(readable_name(name), Some(WARN), Some(ATTR));
Self::new(
ErrorCore::new(
vec![SubMessage::only_loc(loc)],
switch_lang!(
"japanese" => format!("{name}は使用されていません"),
"simplified_chinese" => format!("{name}未使用"),
"traditional_chinese" => format!("{name}未使用"),
"english" => format!("{name} is not used"),
),
errno,
UnusedWarning,
loc,
),
input,
caused_by,
)
}
pub fn union_return_type_warning(
input: Input,
errno: usize,
loc: Location,
caused_by: String,
fn_name: &str,
typ: &Type,
) -> Self {
let hint = switch_lang!(
"japanese" => format!("`{fn_name}(...): {typ} = ...`など明示的に戻り値型を指定してください"),
"simplified_chinese" => format!("请明确指定函数{fn_name}的返回类型,例如`{fn_name}(...): {typ} = ...`"),
"traditional_chinese" => format!("請明確指定函數{fn_name}的返回類型,例如`{fn_name}(...): {typ} = ...`"),
"english" => format!("please explicitly specify the return type of function {fn_name}, for example `{fn_name}(...): {typ} = ...`"),
);
LowerError::new(
ErrorCore::new(
vec![SubMessage::ambiguous_new(loc, vec![], Some(hint))],
switch_lang!(
"japanese" => format!("関数{fn_name}の戻り値型が単一ではありません"),
"simplified_chinese" => format!("函数{fn_name}的返回类型不是单一的"),
"traditional_chinese" => format!("函數{fn_name}的返回類型不是單一的"),
"english" => format!("the return type of function {fn_name} is not single"),
),
errno,
TypeWarning,
loc,
),
input,
caused_by,
)
}
pub fn builtin_exists_warning(
input: Input,
errno: usize,
loc: Location,
caused_by: String,
name: &str,
) -> Self {
let name = StyledStr::new(readable_name(name), Some(WARN), Some(ATTR));
Self::new(
ErrorCore::new(
vec![SubMessage::only_loc(loc)],
switch_lang!(
"japanese" => format!("同名の組み込み関数{name}が既に存在します"),
"simplified_chinese" => format!("已存在同名的内置函数{name}"),
"traditional_chinese" => format!("已存在同名的內置函數{name}"),
"english" => format!("a built-in function named {name} already exists"),
),
errno,
NameWarning,
loc,
),
input,
caused_by,
)
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CompileErrors(Vec<CompileError>); pub struct CompileErrors(Vec<CompileError>);

View file

@ -1059,6 +1059,19 @@ impl ASTLowerer {
self.ctx.caused_by(), self.ctx.caused_by(),
&name, &name,
))); )));
} else if self
.ctx
.get_builtins()
.and_then(|ctx| ctx.get_var_info(&name))
.is_some()
{
self.warns.push(LowerWarning::builtin_exists_warning(
self.cfg.input.clone(),
line!() as usize,
def.sig.loc(),
self.ctx.caused_by(),
&name,
));
} }
let kind = ContextKind::from(def.def_kind()); let kind = ContextKind::from(def.def_kind());
let vis = def.sig.vis(); let vis = def.sig.vis();