in starlark/src/analysis/names.rs [112:144]
fn duplicate_assign(
codemap: &CodeMap,
scope: &Scope,
top: bool,
res: &mut Vec<LintT<NameWarning>>,
) {
// If I see two set's, without any intervening flow or get, the first one was pointless
let mut warnings: HashMap<&str, _> = HashMap::new();
let mut captured: HashSet<&str> = HashSet::new(); // those captured by child scopes
for x in &scope.inner {
match x {
Bind::Set(reason, x) => {
let ignored = !top && x.0.starts_with('_');
if !ignored && !captured.contains(x.0.as_str()) {
if let Some((span, typ)) = warnings.insert(&x.node.0, (x.span, *reason)) {
res.push(NameWarning::unused(typ, codemap, span, x.0.clone()))
}
}
}
Bind::Get(x) => {
warnings.remove(x.node.as_str());
}
Bind::Scope(scope) => {
duplicate_assign(codemap, scope, false, res);
for x in scope.free.keys() {
warnings.remove(x.as_str());
captured.insert(x.as_str());
}
}
Bind::Flow => warnings.clear(),
}
}
}