From 8acd693745a224cb348f50b30ccc85fbc379ac74 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Wed, 17 Apr 2024 16:45:07 -0400 Subject: [PATCH] Cleanup and distinguish unused types --- crates/rue-compiler/src/error.rs | 19 +++-- crates/rue-compiler/src/lib.rs | 2 + crates/rue-compiler/src/lowerer.rs | 5 +- crates/rue-compiler/src/optimizer.rs | 116 ++++++++++++++------------- tests.toml | 4 +- 5 files changed, 78 insertions(+), 68 deletions(-) diff --git a/crates/rue-compiler/src/error.rs b/crates/rue-compiler/src/error.rs index 1cd3943..77706e3 100644 --- a/crates/rue-compiler/src/error.rs +++ b/crates/rue-compiler/src/error.rs @@ -38,14 +38,23 @@ pub enum DiagnosticKind { #[derive(Debug, Error, Clone, PartialEq, Eq, Hash)] pub enum WarningKind { - #[error("redundant optional type")] - RedundantOptional, + #[error("marking optional types as optional again has no effect")] + UselessOptional, - #[error("redundant check against same type `{0}`")] + #[error("redundant type check against `{0}`, value is already that type")] RedundantTypeGuard(String), - #[error("unused symbol `{0}`")] - UnusedSymbol(String), + #[error("unused function `{0}`")] + UnusedFunction(String), + + #[error("unused parameter `{0}`")] + UnusedParameter(String), + + #[error("unused constant `{0}`")] + UnusedConst(String), + + #[error("unused let binding `{0}`")] + UnusedLet(String), #[error("unused type `{0}`")] UnusedType(String), diff --git a/crates/rue-compiler/src/lib.rs b/crates/rue-compiler/src/lib.rs index 9c41413..45f477b 100644 --- a/crates/rue-compiler/src/lib.rs +++ b/crates/rue-compiler/src/lib.rs @@ -1,3 +1,5 @@ +#![warn(clippy::needless_pass_by_ref_mut)] + use clvmr::{Allocator, NodePtr}; use codegen::Codegen; use lowerer::Lowerer; diff --git a/crates/rue-compiler/src/lowerer.rs b/crates/rue-compiler/src/lowerer.rs index a8ce557..e332492 100644 --- a/crates/rue-compiler/src/lowerer.rs +++ b/crates/rue-compiler/src/lowerer.rs @@ -1922,10 +1922,7 @@ impl<'a> Lowerer<'a> { .unwrap_or(self.unknown_type); if let Type::Optional(inner) = self.db.ty_raw(ty).clone() { - self.warning( - WarningKind::RedundantOptional, - optional.syntax().text_range(), - ); + self.warning(WarningKind::UselessOptional, optional.syntax().text_range()); return inner; } diff --git a/crates/rue-compiler/src/optimizer.rs b/crates/rue-compiler/src/optimizer.rs index 4c36d4b..5ebca2d 100644 --- a/crates/rue-compiler/src/optimizer.rs +++ b/crates/rue-compiler/src/optimizer.rs @@ -91,37 +91,49 @@ impl<'a> Optimizer<'a> { } } - fn compute_captures_entrypoint( + fn check_unused( &mut self, scope_id: ScopeId, - inherits_from: Option, - hir_id: HirId, + used_symbols: HashSet, + used_types: HashSet, ) { - if self.environments.contains_key(&scope_id) { - return; - } - - self.environments.insert(scope_id, Environment::default()); - let used_types = self.db.scope(scope_id).used_types().clone(); - self.env_mut(scope_id).used_types.extend(used_types); - self.env_mut(scope_id).inherits_from = inherits_from; - self.compute_captures_hir(scope_id, hir_id); - let unused_symbols: Vec = self .db .scope(scope_id) .local_symbols() .iter() - .filter(|&symbol_id| !self.env(scope_id).used_symbols.contains(symbol_id)) + .filter(|&symbol_id| !used_symbols.contains(symbol_id)) .copied() .collect(); for symbol_id in unused_symbols { if let Some(token) = self.db.symbol_token(symbol_id) { - self.warning( - WarningKind::UnusedSymbol(token.to_string()), - token.text_range(), - ); + match self.db.symbol(symbol_id).clone() { + Symbol::Function { .. } => { + self.warning( + WarningKind::UnusedFunction(token.to_string()), + token.text_range(), + ); + } + Symbol::Parameter { .. } => { + self.warning( + WarningKind::UnusedParameter(token.to_string()), + token.text_range(), + ); + } + Symbol::LetBinding { .. } => { + self.warning( + WarningKind::UnusedLet(token.to_string()), + token.text_range(), + ); + } + Symbol::ConstBinding { .. } => { + self.warning( + WarningKind::UnusedConst(token.to_string()), + token.text_range(), + ); + } + } } } @@ -130,7 +142,7 @@ impl<'a> Optimizer<'a> { .scope(scope_id) .local_types() .iter() - .filter(|&type_id| !self.env(scope_id).used_types.contains(type_id)) + .filter(|&type_id| !used_types.contains(type_id)) .copied() .collect(); @@ -144,6 +156,29 @@ impl<'a> Optimizer<'a> { } } + fn compute_captures_entrypoint( + &mut self, + scope_id: ScopeId, + inherits_from: Option, + hir_id: HirId, + ) { + if self.environments.contains_key(&scope_id) { + return; + } + + self.environments.insert(scope_id, Environment::default()); + let used_types = self.db.scope(scope_id).used_types().clone(); + self.env_mut(scope_id).used_types.extend(used_types); + self.env_mut(scope_id).inherits_from = inherits_from; + self.compute_captures_hir(scope_id, hir_id); + + self.check_unused( + scope_id, + self.env(scope_id).used_symbols.clone(), + self.env(scope_id).used_types.clone(), + ); + } + fn compute_captures_hir(&mut self, scope_id: ScopeId, hir_id: HirId) { match self.db.hir(hir_id).clone() { Hir::Unknown | Hir::Atom(_) => {} @@ -240,46 +275,13 @@ impl<'a> Optimizer<'a> { self.compute_captures_entrypoint(scope_id, None, hir_id); - let unused_symbols: Vec = self - .db - .scope(root_scope_id) - .local_symbols() - .iter() - .filter(|&symbol_id| { - !self.env(scope_id).used_symbols.contains(symbol_id) && *symbol_id != main - }) - .copied() - .collect(); + let mut used_symbols = self.env(scope_id).used_symbols.clone(); + used_symbols.insert(main); - for symbol_id in unused_symbols { - if let Some(token) = self.db.symbol_token(symbol_id) { - self.warning( - WarningKind::UnusedSymbol(token.to_string()), - token.text_range(), - ); - } - } - - let unused_types: Vec = self - .db - .scope(root_scope_id) - .local_types() - .iter() - .filter(|&type_id| { - !self.env(scope_id).used_types.contains(type_id) - && !self.db.scope(root_scope_id).used_types().contains(type_id) - }) - .copied() - .collect(); + let mut used_types = self.env(scope_id).used_types.clone(); + used_types.extend(self.db.scope(root_scope_id).used_types().clone()); - for type_id in unused_types { - if let Some(token) = self.db.type_token(type_id) { - self.warning( - WarningKind::UnusedType(token.to_string()), - token.text_range(), - ); - } - } + self.check_unused(root_scope_id, used_symbols, used_types); for symbol_id in self.db.scope(scope_id).local_symbols() { if self.db.symbol(symbol_id).is_parameter() { diff --git a/tests.toml b/tests.toml index c9ab9f9..53f598f 100644 --- a/tests.toml +++ b/tests.toml @@ -1,8 +1,8 @@ [list_types] parser_errors = [] compiler_errors = [ - "unused symbol `empty_hinted` at 3:9", - "unused symbol `empty` at 2:9", + "unused let binding `empty_hinted` at 3:9", + "unused let binding `empty` at 2:9", ] [pair_types]