Skip to content

Commit d699576

Browse files
committed
Further fixes to unused variable detection
1 parent f1c2481 commit d699576

File tree

17 files changed

+183
-108
lines changed

17 files changed

+183
-108
lines changed

src/compiler_top.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,8 @@ impl Linker {
258258
}
259259

260260
for global_id in &global_ids {
261-
self.pass("Lints", *global_id, |pass, errors, _files| {
262-
perform_lints(pass, errors);
261+
self.pass("Lints", *global_id, |pass, errors, files| {
262+
perform_lints(pass, errors, files);
263263
});
264264
}
265265
self.checkpoint(&global_ids, AFTER_LINTS_CP);

src/debug.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub fn debug_print_span(span: Span, label: String) {
8080
eprintln!("No FileData registered!");
8181
} else {
8282
let fd: &FileData = unsafe { &*ptr };
83-
pretty_print_span(fd, span.as_range(), label);
83+
pretty_print_span(fd, span, label);
8484
}
8585
})
8686
}

src/dev_aid/ariadne_interface.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{ops::Range, path::PathBuf};
33

44
use crate::compiler_top::LinkerExtraFileInfoManager;
55
use crate::linker::FileData;
6+
use crate::prelude::Span;
67
use crate::prelude::*;
78

89
use crate::{
@@ -194,13 +195,15 @@ pub fn pretty_print_spans_in_reverse_order(file_data: &FileData, spans: Vec<Rang
194195
}
195196
}
196197

197-
pub fn pretty_print_span(file_data: &FileData, span: Range<usize>, label: impl ToString) {
198+
pub fn pretty_print_span(file_data: &FileData, span: Span, label: impl ToString) {
198199
let text_len = file_data.file_text.len();
199200
let mut source = NamedSource {
200201
source: Source::from(file_data.file_text.file_text.clone()),
201202
name: &file_data.file_identifier,
202203
};
203204

205+
let span = span.as_range();
206+
204207
// If span not in file, just don't print it. This happens.
205208
if span.end > text_len {
206209
println!(
@@ -223,7 +226,7 @@ pub fn pretty_print_span(file_data: &FileData, span: Range<usize>, label: impl T
223226
report.finish().print(&mut source).unwrap();
224227
}
225228

226-
pub fn pretty_print_many_spans(file_data: &FileData, spans: &[(String, Range<usize>)]) {
229+
pub fn pretty_print_many_spans(file_data: &FileData, spans: &[(String, Span)]) {
227230
let text_len = file_data.file_text.len();
228231
let mut source = NamedSource {
229232
source: Source::from(file_data.file_text.file_text.clone()),
@@ -237,9 +240,10 @@ pub fn pretty_print_many_spans(file_data: &FileData, spans: &[(String, Range<usi
237240
}
238241

239242
let mut report: ReportBuilder<'_, Range<usize>> =
240-
Report::build(ReportKind::Advice, spans[0].1.clone()).with_config(config);
243+
Report::build(ReportKind::Advice, spans[0].1.as_range()).with_config(config);
241244

242245
for (text, span) in spans.iter().rev() {
246+
let span = span.as_range();
243247
// If span not in file, just don't print it. This happens.
244248
if span.end > text_len {
245249
println!(

src/dev_aid/lsp/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,8 @@ fn assert_all_refs_of_correct_length(
318318
other_spans_file: &FileData,
319319
) {
320320
if refs.iter().any(|r| r.size() != location.size()) {
321-
let refs_vec: Vec<_> = refs.iter().map(|r| (String::new(), r.as_range())).collect();
322-
pretty_print_span(location_file, location.as_range(), "Original location Span");
321+
let refs_vec: Vec<_> = refs.iter().map(|r| (String::new(), *r)).collect();
322+
pretty_print_span(location_file, location, "Original location Span");
323323
pretty_print_many_spans(other_spans_file, &refs_vec);
324324
panic!("One of the spans was not of the same size as the original span!")
325325
}

src/file_position.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::{
2-
fmt::{Debug, Display},
2+
fmt::Debug,
33
ops::{Index, Range},
44
};
55

src/flattening/flatten.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,8 @@ impl<'l, 'c: 'l> FlatteningContext<'l, '_> {
12081208
}
12091209

12101210
fn flatten_for_statement(&mut self, cursor: &mut Cursor<'c>) {
1211+
cursor.field(field!("for_kw"));
1212+
let for_kw_span = cursor.span();
12111213
cursor.field(field!("for_decl"));
12121214
let loop_var_decl = self.flatten_declaration::<false>(
12131215
DeclarationKind::RegularGenerative { read_only: true },
@@ -1225,6 +1227,7 @@ impl<'l, 'c: 'l> FlatteningContext<'l, '_> {
12251227
.instructions
12261228
.alloc(Instruction::ForStatement(ForStatement {
12271229
parent_condition: self.current_parent_condition,
1230+
for_kw_span,
12281231
loop_var_decl,
12291232
start,
12301233
end,

src/flattening/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ pub struct IfStatement {
915915
#[derive(Debug)]
916916
pub struct ForStatement {
917917
pub parent_condition: Option<ParentCondition>,
918+
pub for_kw_span: Span,
918919
pub loop_var_decl: FlatID,
919920
pub start: FlatID,
920921
pub end: FlatID,
@@ -1059,9 +1060,8 @@ impl Instruction {
10591060
Instruction::Declaration(declaration) => declaration.name_span,
10601061
Instruction::Interface(act_trig) => act_trig.name_span,
10611062
Instruction::Expression(expression) => expression.span,
1062-
Instruction::IfStatement(_) | Instruction::ForStatement(_) => {
1063-
unreachable!("{self:?} is control flow! Shouldn't ask it's span")
1064-
}
1063+
Instruction::IfStatement(if_stm) => if_stm.if_keyword_span,
1064+
Instruction::ForStatement(for_stm) => for_stm.for_kw_span,
10651065
}
10661066
}
10671067
pub fn get_name(&self) -> &str {

src/flattening/typecheck/lints.rs

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use sus_proc_macro::get_builtin_const;
22

3+
use crate::alloc::ArenaAllocator;
4+
use crate::dev_aid::ariadne_interface::pretty_print_many_spans;
35
use crate::flattening::WriteModifiers;
4-
use crate::linker::{GlobalRef, IsExtern};
6+
use crate::linker::{FileData, GlobalRef, IsExtern};
57
use crate::prelude::*;
68
use crate::typing::abstract_type::AbstractInnerType;
79
use crate::typing::template::TemplateKind;
@@ -10,12 +12,17 @@ use super::*;
1012

1113
use super::{Expression, ExpressionOutput, ExpressionSource, Instruction, WireReferenceRoot};
1214

13-
pub fn perform_lints(pass: &mut LinkerPass, errors: &ErrorCollector) {
15+
pub fn perform_lints(
16+
pass: &mut LinkerPass,
17+
errors: &ErrorCollector,
18+
files: &ArenaAllocator<FileData, FileUUIDMarker>,
19+
) {
1420
let (working_on, globals) = pass.get_with_context();
1521
let ctx = LintContext {
1622
working_on,
1723
errors,
1824
globals,
25+
file_data: &files[working_on.get_span_file().1],
1926
};
2027
ctx.extern_objects_may_not_have_type_template_args();
2128
ctx.lint_instructions();
@@ -24,6 +31,7 @@ pub fn perform_lints(pass: &mut LinkerPass, errors: &ErrorCollector) {
2431

2532
struct LintContext<'l> {
2633
working_on: GlobalRef<'l>,
34+
file_data: &'l FileData,
2735
errors: &'l ErrorCollector<'l>,
2836
globals: GlobalResolver<'l, 'l>,
2937
}
@@ -264,6 +272,25 @@ impl LintContext<'_> {
264272
}
265273
}
266274

275+
if crate::debug::is_enabled("print-unused-vars-map") {
276+
println!("Find Unused Variables Fanins:");
277+
for (to, fanins) in &instruction_fanins {
278+
let is_target = if is_instance_used_map[to] {
279+
" target"
280+
} else {
281+
""
282+
};
283+
println!("{to:?}{is_target} <- {:?}", fanins.as_slice());
284+
}
285+
let spans: Vec<_> = self
286+
.working_on
287+
.instructions
288+
.iter()
289+
.map(|(id, instr)| (format!("{id:?}"), instr.get_span()))
290+
.collect();
291+
pretty_print_many_spans(self.file_data, &spans);
292+
}
293+
267294
// All asserts and declarations starting with '_' are also terminals
268295
for (instr_id, instr) in &self.working_on.instructions {
269296
match instr {
@@ -325,6 +352,24 @@ impl LintContext<'_> {
325352
instruction_fanins[instr_id].push(id);
326353
});
327354
}
355+
Instruction::Interface(stm) => {
356+
if let Some(lat_spec) = stm.latency_specifier {
357+
instruction_fanins[instr_id].push(lat_spec);
358+
}
359+
for id in FlatIDRange::new(stm.then_block.0, stm.else_block.1) {
360+
if let Instruction::Expression(Expression {
361+
output: ExpressionOutput::MultiWrite(writes),
362+
..
363+
}) = &self.working_on.instructions[id]
364+
{
365+
for wr in writes {
366+
if let Some(flat_root) = wr.to.root.get_root_flat() {
367+
instruction_fanins[flat_root].push(instr_id);
368+
}
369+
}
370+
}
371+
}
372+
}
328373
Instruction::Expression(expr) => {
329374
expr.source.for_each_dependency(&mut |id| {
330375
instruction_fanins[instr_id].push(id);
@@ -337,9 +382,7 @@ impl LintContext<'_> {
337382
match &fc_wr.root {
338383
WireReferenceRoot::LocalSubmodule(fc_target)
339384
| WireReferenceRoot::LocalInterface(fc_target) => {
340-
for arg in &fc.arguments {
341-
instruction_fanins[*fc_target].push(*arg);
342-
}
385+
instruction_fanins[*fc_target].push(instr_id);
343386
}
344387
WireReferenceRoot::LocalDecl(_)
345388
| WireReferenceRoot::NamedConstant(_)
@@ -364,40 +407,15 @@ impl LintContext<'_> {
364407
}
365408
Instruction::IfStatement(stm) => {
366409
for id in FlatIDRange::new(stm.then_block.0, stm.else_block.1) {
367-
if let Instruction::Expression(Expression {
368-
output: ExpressionOutput::MultiWrite(writes),
369-
..
370-
}) = &self.working_on.instructions[id]
371-
{
372-
for wr in writes {
373-
if let Some(flat_root) = wr.to.root.get_root_flat() {
374-
instruction_fanins[flat_root].push(stm.condition);
375-
}
376-
}
377-
}
378-
}
379-
}
380-
Instruction::Interface(stm) => {
381-
if let Some(lat_spec) = stm.latency_specifier {
382-
instruction_fanins[instr_id].push(lat_spec);
383-
}
384-
for id in FlatIDRange::new(stm.then_block.0, stm.else_block.1) {
385-
if let Instruction::Expression(Expression {
386-
output: ExpressionOutput::MultiWrite(writes),
387-
..
388-
}) = &self.working_on.instructions[id]
389-
{
390-
for wr in writes {
391-
if let Some(flat_root) = wr.to.root.get_root_flat() {
392-
instruction_fanins[flat_root].push(instr_id);
393-
}
394-
}
395-
}
410+
instruction_fanins[id].push(stm.condition);
396411
}
397412
}
398413
Instruction::ForStatement(stm) => {
399414
instruction_fanins[stm.loop_var_decl].push(stm.start);
400415
instruction_fanins[stm.loop_var_decl].push(stm.end);
416+
for id in stm.loop_body {
417+
instruction_fanins[id].push(stm.loop_var_decl);
418+
}
401419
}
402420
}
403421
}

src/to_string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ impl LinkInfo {
692692
}
693693
println!();
694694
let span = self.get_instruction_span(id);
695-
spans_print.push((format!("{id:?} {domain}"), span.as_range()));
695+
spans_print.push((format!("{id:?} {domain}"), span));
696696
}
697697
pretty_print_many_spans(file_data, &spans_print);
698698
}

std/control_flow.sus

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
module Iterator #(int MAX) {
33
state int #(FROM: 0, TO: MAX + 2) current_limit
44
state int #(FROM: 0, TO: MAX + 1) value_state
5-
output state bool may_next
5+
output state bool may_next'0
66
initial current_limit = 0
77
initial value_state = 0
88
initial may_next = false
99

1010
/// Requires `!may_next`
11-
action start : int #(FROM: 0, TO: MAX + 2) up_to {
11+
action start'0 : int #(FROM: 0, TO: MAX + 2) up_to'0 {
1212
current_limit = up_to
1313
value_state = 0
1414
may_next = true
1515
}
1616

1717
/// Requires `may_next`
18-
action next : -> int #(FROM: 0, TO: MAX + 1) value, bool last {
18+
action next'0 : -> int #(FROM: 0, TO: MAX + 1) value'0, bool last'0 {
1919
last = value_state == current_limit
2020
value = value_state
2121
when !last {
@@ -28,17 +28,17 @@ module Iterator #(int MAX) {
2828

2929
module FixedSizeIterator #(int TO) {
3030
state int #(FROM: 0, TO) value_state
31-
output state bool may_next
31+
output state bool may_next'0
3232
initial value_state = 0
3333
initial may_next = false
3434

3535
/// Requires `!may_next`
36-
action start {
36+
action start'0 {
3737
value_state = 0
3838
may_next = true
3939
}
4040
/// Requires `may_next`
41-
action next : -> int #(FROM: 0, TO) value, bool last {
41+
action next'0 : -> int #(FROM: 0, TO) value'0, bool last'0 {
4242
last = value_state == TO - 1
4343
value = value_state
4444
when !last {

0 commit comments

Comments
 (0)