Skip to content

semantic: incorrect identification of label as unused #12680

@overlookmotel

Description

@overlookmotel
label: while (true) {
  f = function() {
    label: while (true) {
      break label;
    }
  };
  break label;
}

Both labels are used here, each by a break label statement. But linter produces an error:

! eslint(no-unused-labels): 'label:' is defined but never used.
   ,-[:1:1]
 1 | label: while (true) {
   : ^^^^^
 2 |   f = function() {
   `----

Playground

Cause looks like it's in SemanticBuilder:

pub struct UnusedLabels<'a> {
pub scopes: Vec<LabeledScope<'a>>,
pub curr_scope: usize,
pub labels: Vec<NodeId>,
}
impl<'a> UnusedLabels<'a> {
pub fn add(&mut self, name: &'a str) {
self.scopes.push(LabeledScope { name, used: false, parent: self.curr_scope });
self.curr_scope = self.scopes.len() - 1;
}
pub fn reference(&mut self, name: &'a str) {
let scope = self.scopes.iter_mut().rev().find(|x| x.name == name);
if let Some(scope) = scope {
scope.used = true;
}
}
pub fn mark_unused(&mut self, current_node_id: NodeId) {
let scope = &self.scopes[self.curr_scope];
if !scope.used {
self.labels.push(current_node_id);
}
self.curr_scope = scope.parent;
}
}

I'm not sure why UnusedLabels contains a curr_scope field, and mark_unused updates it - on the face of it, it looks like this complication is unnecessary and mark_unused could just pop the last item off scopes. But I assume there's a reason it's written like this that I don't understand.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions