in starlark/src/analysis/names.rs [236:279]
fn use_ignored(
codemap: &CodeMap,
scope: &Scope,
root: Option<&Scope>,
res: &mut Vec<LintT<NameWarning>>,
) {
match root {
None => {
// Things at the top level can be ignored and used
for x in &scope.inner {
if let Bind::Scope(x) = x {
use_ignored(codemap, x, Some(scope), res)
}
}
}
Some(root) => {
// You can only use _ variables which are defined at the root,
// and thus must be free in this scope.
// If you use _foo, but foo is already in this scope, you may have been avoiding shadowing.
for x in &scope.inner {
match x {
Bind::Get(x) if x.starts_with('_') => {
// There are two permissible reasons to use an underscore variable
let defined_at_root =
|| root.bound.contains_key(&x.node) && scope.free.contains_key(&x.node);
let shadows = || {
let suffix = x.trim_start_match('_');
scope.free.contains_key(suffix) || scope.bound.contains_key(suffix)
};
if !defined_at_root() && !shadows() {
res.push(LintT::new(
codemap,
x.span,
NameWarning::UsingIgnored(x.node.clone()),
))
}
}
Bind::Scope(x) => use_ignored(codemap, x, Some(root), res),
_ => {}
}
}
}
}
}