Hint for shadowed std functions (#4402)

Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
Yip Coekjan 2024-06-22 17:02:53 +08:00 committed by GitHub
parent 49f1c85c18
commit 0fbec82035
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 2 deletions

View File

@ -128,7 +128,7 @@ impl Eval for ast::FuncCall<'_> {
(callee.eval(vm)?, args.eval(vm)?.spanned(span))
};
let func_result = callee.clone().cast::<Func>().at(callee_span);
let func_result = callee.clone().cast::<Func>();
if in_math && func_result.is_err() {
// For non-functions in math, we wrap the arguments in parentheses.
let mut body = Content::empty();
@ -148,7 +148,21 @@ impl Eval for ast::FuncCall<'_> {
));
}
let func = func_result?;
let func = func_result
.map_err(|mut err| {
if let ast::Expr::Ident(ident) = self.callee() {
let ident = ident.get();
if vm.scopes.check_std_shadowed(ident) {
err.hint(eco_format!(
"use `std.{}` to access the shadowed standard library function",
ident,
));
}
}
err
})
.at(callee_span)?;
let point = || Tracepoint::Call(func.name().map(Into::into));
let f = || {
func.call(&mut vm.engine, vm.context, args)

View File

@ -87,6 +87,14 @@ impl<'a> Scopes<'a> {
}
})?
}
/// Check if an std variable is shadowed.
pub fn check_std_shadowed(&self, var: &str) -> bool {
self.base.is_some_and(|base| base.global.scope().get(var).is_some())
&& std::iter::once(&self.top)
.chain(self.scopes.iter().rev())
.any(|scope| scope.get(var).is_some())
}
}
#[cold]

View File

@ -49,6 +49,13 @@
// Error: 2-3 expected function, found string
#x()
--- call-shadowed-builtin-function ---
#let image = "image"
// Error: 2-7 expected function, found string
// Hint: 2-7 use `std.image` to access the shadowed standard library function
#image("image")
--- call-bad-type-int-expr ---
#let f(x) = x