From 02c9d65a6ddd31220492e025f66f44856a16fdd0 Mon Sep 17 00:00:00 2001 From: Christopher Chang <51393127+chriscerie@users.noreply.github.com> Date: Sat, 2 Dec 2023 09:39:17 -0800 Subject: [PATCH 1/4] Lint against approximated constants --- CHANGELOG.md | 2 + docs/src/SUMMARY.md | 1 + docs/src/lints/approx_constant.md | 17 ++++ selene-lib/src/lints.rs | 1 + selene-lib/src/lints/approx_constant.rs | 87 +++++++++++++++++++ .../lints/approx_constant/approx_constant.lua | 18 ++++ .../approx_constant/approx_constant.stderr | 42 +++++++++ 7 files changed, 168 insertions(+) create mode 100644 docs/src/lints/approx_constant.md create mode 100644 selene-lib/src/lints/approx_constant.rs create mode 100644 selene-lib/tests/lints/approx_constant/approx_constant.lua create mode 100644 selene-lib/tests/lints/approx_constant/approx_constant.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 6583717b..a66aa21d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased](https://github.com/Kampfkarren/selene/compare/0.26.1...HEAD) +### Added +- Added new [`approx_constant`](https://kampfkarren.github.io/selene/lints/approx_constant.html) lint, which will check for number literals that approximate constants. ## [0.26.1](https://github.com/Kampfkarren/selene/releases/tag/0.26.1) - 2023-11-11 ### Fixed diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 51fcca18..22894eb4 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -14,6 +14,7 @@ - [Contributing](./contributing.md) - [Lints](./lints/index.md) - [almost_swapped](./lints/almost_swapped.md) + - [approx_constant](./lints/approx_constant.md) - [constant_table_comparison](./lints/constant_table_comparison.md) - [deprecated](./lints/deprecated.md) - [divide_by_zero](./lints/divide_by_zero.md) diff --git a/docs/src/lints/approx_constant.md b/docs/src/lints/approx_constant.md new file mode 100644 index 00000000..e1ffd23c --- /dev/null +++ b/docs/src/lints/approx_constant.md @@ -0,0 +1,17 @@ +# approx_constant +## What it does +Checks for number literals that approximate constants. + +## Why this is bad +Using constants provided by the Lua standard library is more precise. + +## Example +```lua +local x = 3.14 +``` + +...should be written as... + +```lua +local x = math.pi +``` diff --git a/selene-lib/src/lints.rs b/selene-lib/src/lints.rs index fa42553c..17a3b62f 100644 --- a/selene-lib/src/lints.rs +++ b/selene-lib/src/lints.rs @@ -8,6 +8,7 @@ use full_moon::{ast::Ast, node::Node}; use serde::de::DeserializeOwned; pub mod almost_swapped; +pub mod approx_constant; pub mod bad_string_escape; pub mod compare_nan; pub mod constant_table_comparison; diff --git a/selene-lib/src/lints/approx_constant.rs b/selene-lib/src/lints/approx_constant.rs new file mode 100644 index 00000000..c83ce6bd --- /dev/null +++ b/selene-lib/src/lints/approx_constant.rs @@ -0,0 +1,87 @@ +use super::*; +use std::convert::Infallible; + +use full_moon::{ast::Ast, tokenizer::TokenType, visitors::Visitor}; + +pub struct ApproxConstantLint; + +impl Lint for ApproxConstantLint { + type Config = (); + type Error = Infallible; + + const SEVERITY: Severity = Severity::Warning; + const LINT_TYPE: LintType = LintType::Correctness; + + fn new((): Self::Config) -> Result { + Ok(ApproxConstantLint) + } + + fn pass(&self, ast: &Ast, _: &Context, _: &AstContext) -> Vec { + let mut visitor = ApproxConstantVisitor { + approx_constants: Vec::new(), + }; + + visitor.visit_ast(ast); + + visitor + .approx_constants + .iter() + .map(|constant| { + Diagnostic::new( + "approx_constant", + format!("`{}` is more precise", constant.constant), + Label::new(constant.range), + ) + }) + .collect() + } +} + +struct ApproxConstantVisitor { + approx_constants: Vec, +} + +struct ApproximatedConstant { + range: (usize, usize), + constant: String, +} + +impl Visitor for ApproxConstantVisitor { + fn visit_number(&mut self, token: &full_moon::tokenizer::Token) { + if let TokenType::Number { text } = token.token_type() { + if is_approx_const(std::f64::consts::PI, text, 3) { + self.approx_constants.push(ApproximatedConstant { + range: (token.start_position().bytes(), token.end_position().bytes()), + constant: "math.pi".to_string(), + }); + } + } + } +} + +#[must_use] +fn is_approx_const(constant: f64, value: &str, min_digits: usize) -> bool { + if value.len() <= min_digits { + false + } else if constant.to_string().starts_with(value) { + // The value is a truncated constant + true + } else { + let round_const = format!("{constant:.*}", value.len() - 2); + value == round_const + } +} + +#[cfg(test)] +mod tests { + use super::{super::test_util::test_lint, *}; + + #[test] + fn test_approx_constant() { + test_lint( + ApproxConstantLint::new(()).unwrap(), + "approx_constant", + "approx_constant", + ); + } +} diff --git a/selene-lib/tests/lints/approx_constant/approx_constant.lua b/selene-lib/tests/lints/approx_constant/approx_constant.lua new file mode 100644 index 00000000..ce8d2987 --- /dev/null +++ b/selene-lib/tests/lints/approx_constant/approx_constant.lua @@ -0,0 +1,18 @@ +local good = 3 +local good = 3.1 +local good = 3.13 +local good = 3.15 +local good = 3.1417 +local good = 3.14159266 + +local good = 0x314 +local good = 3_14 + +local bad = 3.14 +local bad = 3.141 +local bad = 3.142 +local bad = 3.1415 +local bad = 3.14159265 + +local bad = 3.14 + 1 +local bad = f(3.14 + 1) diff --git a/selene-lib/tests/lints/approx_constant/approx_constant.stderr b/selene-lib/tests/lints/approx_constant/approx_constant.stderr new file mode 100644 index 00000000..e84a8fcd --- /dev/null +++ b/selene-lib/tests/lints/approx_constant/approx_constant.stderr @@ -0,0 +1,42 @@ +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:11:13 + │ +11 │ local bad = 3.14 + │ ^^^^ + +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:12:13 + │ +12 │ local bad = 3.141 + │ ^^^^^ + +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:13:13 + │ +13 │ local bad = 3.142 + │ ^^^^^ + +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:14:13 + │ +14 │ local bad = 3.1415 + │ ^^^^^^ + +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:15:13 + │ +15 │ local bad = 3.14159265 + │ ^^^^^^^^^^ + +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:17:13 + │ +17 │ local bad = 3.14 + 1 + │ ^^^^ + +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:18:15 + │ +18 │ local bad = f(3.14 + 1) + │ ^^^^ + From d2e3e4986abe1a2833e6848c6d5cccd5a059bc2f Mon Sep 17 00:00:00 2001 From: Christopher Chang <51393127+chriscerie@users.noreply.github.com> Date: Sat, 2 Dec 2023 09:46:13 -0800 Subject: [PATCH 2/4] Test negative --- .../lints/approx_constant/approx_constant.lua | 3 ++ .../approx_constant/approx_constant.stderr | 40 ++++++++++++------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/selene-lib/tests/lints/approx_constant/approx_constant.lua b/selene-lib/tests/lints/approx_constant/approx_constant.lua index ce8d2987..bf22d7cf 100644 --- a/selene-lib/tests/lints/approx_constant/approx_constant.lua +++ b/selene-lib/tests/lints/approx_constant/approx_constant.lua @@ -2,6 +2,7 @@ local good = 3 local good = 3.1 local good = 3.13 local good = 3.15 +local good = -3.15 local good = 3.1417 local good = 3.14159266 @@ -10,9 +11,11 @@ local good = 3_14 local bad = 3.14 local bad = 3.141 +local bad = -3.141 local bad = 3.142 local bad = 3.1415 local bad = 3.14159265 local bad = 3.14 + 1 local bad = f(3.14 + 1) +local bad = f(-3.14 + 1) diff --git a/selene-lib/tests/lints/approx_constant/approx_constant.stderr b/selene-lib/tests/lints/approx_constant/approx_constant.stderr index e84a8fcd..9743cf84 100644 --- a/selene-lib/tests/lints/approx_constant/approx_constant.stderr +++ b/selene-lib/tests/lints/approx_constant/approx_constant.stderr @@ -1,42 +1,54 @@ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:11:13 + ┌─ approx_constant.lua:12:13 │ -11 │ local bad = 3.14 +12 │ local bad = 3.14 │ ^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:12:13 + ┌─ approx_constant.lua:13:13 │ -12 │ local bad = 3.141 +13 │ local bad = 3.141 │ ^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:13:13 + ┌─ approx_constant.lua:14:14 + │ +14 │ local bad = -3.141 + │ ^^^^^ + +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:15:13 │ -13 │ local bad = 3.142 +15 │ local bad = 3.142 │ ^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:14:13 + ┌─ approx_constant.lua:16:13 │ -14 │ local bad = 3.1415 +16 │ local bad = 3.1415 │ ^^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:15:13 + ┌─ approx_constant.lua:17:13 │ -15 │ local bad = 3.14159265 +17 │ local bad = 3.14159265 │ ^^^^^^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:17:13 + ┌─ approx_constant.lua:19:13 │ -17 │ local bad = 3.14 + 1 +19 │ local bad = 3.14 + 1 │ ^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:18:15 + ┌─ approx_constant.lua:20:15 │ -18 │ local bad = f(3.14 + 1) +20 │ local bad = f(3.14 + 1) │ ^^^^ +error[approx_constant]: `math.pi` is more precise + ┌─ approx_constant.lua:21:16 + │ +21 │ local bad = f(-3.14 + 1) + │ ^^^^ + From 9709f3ab106f54023a26e27ac6b7502754a0e611 Mon Sep 17 00:00:00 2001 From: Christopher Chang <51393127+chriscerie@users.noreply.github.com> Date: Sat, 2 Dec 2023 09:56:53 -0800 Subject: [PATCH 3/4] Fix test --- .../lints/approx_constant/approx_constant.lua | 1 - .../approx_constant/approx_constant.stderr | 36 +++++++++---------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/selene-lib/tests/lints/approx_constant/approx_constant.lua b/selene-lib/tests/lints/approx_constant/approx_constant.lua index bf22d7cf..74111712 100644 --- a/selene-lib/tests/lints/approx_constant/approx_constant.lua +++ b/selene-lib/tests/lints/approx_constant/approx_constant.lua @@ -7,7 +7,6 @@ local good = 3.1417 local good = 3.14159266 local good = 0x314 -local good = 3_14 local bad = 3.14 local bad = 3.141 diff --git a/selene-lib/tests/lints/approx_constant/approx_constant.stderr b/selene-lib/tests/lints/approx_constant/approx_constant.stderr index 9743cf84..243ee8c0 100644 --- a/selene-lib/tests/lints/approx_constant/approx_constant.stderr +++ b/selene-lib/tests/lints/approx_constant/approx_constant.stderr @@ -1,54 +1,54 @@ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:12:13 + ┌─ approx_constant.lua:11:13 │ -12 │ local bad = 3.14 +11 │ local bad = 3.14 │ ^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:13:13 + ┌─ approx_constant.lua:12:13 │ -13 │ local bad = 3.141 +12 │ local bad = 3.141 │ ^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:14:14 + ┌─ approx_constant.lua:13:14 │ -14 │ local bad = -3.141 +13 │ local bad = -3.141 │ ^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:15:13 + ┌─ approx_constant.lua:14:13 │ -15 │ local bad = 3.142 +14 │ local bad = 3.142 │ ^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:16:13 + ┌─ approx_constant.lua:15:13 │ -16 │ local bad = 3.1415 +15 │ local bad = 3.1415 │ ^^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:17:13 + ┌─ approx_constant.lua:16:13 │ -17 │ local bad = 3.14159265 +16 │ local bad = 3.14159265 │ ^^^^^^^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:19:13 + ┌─ approx_constant.lua:18:13 │ -19 │ local bad = 3.14 + 1 +18 │ local bad = 3.14 + 1 │ ^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:20:15 + ┌─ approx_constant.lua:19:15 │ -20 │ local bad = f(3.14 + 1) +19 │ local bad = f(3.14 + 1) │ ^^^^ error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:21:16 + ┌─ approx_constant.lua:20:16 │ -21 │ local bad = f(-3.14 + 1) +20 │ local bad = f(-3.14 + 1) │ ^^^^ From 0eccb61f6b30c686ea33a678e39721a0f14e6bce Mon Sep 17 00:00:00 2001 From: Christopher Chang <51393127+chriscerie@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:56:46 -0700 Subject: [PATCH 4/4] Rename to approximated_constants --- CHANGELOG.md | 2 +- docs/src/SUMMARY.md | 2 +- ..._constant.md => approximated_constants.md} | 2 +- selene-lib/src/lints.rs | 2 +- ..._constant.rs => approximated_constants.rs} | 24 ++++----- .../approx_constant/approx_constant.stderr | 54 ------------------- .../approximated_constants.lua} | 0 .../approximated_constants.stderr | 54 +++++++++++++++++++ 8 files changed, 70 insertions(+), 70 deletions(-) rename docs/src/lints/{approx_constant.md => approximated_constants.md} (91%) rename selene-lib/src/lints/{approx_constant.rs => approximated_constants.rs} (77%) delete mode 100644 selene-lib/tests/lints/approx_constant/approx_constant.stderr rename selene-lib/tests/lints/{approx_constant/approx_constant.lua => approximated_constants/approximated_constants.lua} (100%) create mode 100644 selene-lib/tests/lints/approximated_constants/approximated_constants.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index dc35abda..794a3aca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased](https://github.com/Kampfkarren/selene/compare/0.27.1...HEAD) ### Added -- Added new [`approx_constant`](https://kampfkarren.github.io/selene/lints/approx_constant.html) lint, which will check for number literals that approximate constants. +- Added new [`approximated_constants`](https://kampfkarren.github.io/selene/lints/approximated_constants.html) lint, which will check for number literals that approximate constants. ## [0.27.1](https://github.com/Kampfkarren/selene/releases/tag/0.27.1) - 2024-04-28 ### Fixed diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 22894eb4..d5ce9d04 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -14,7 +14,7 @@ - [Contributing](./contributing.md) - [Lints](./lints/index.md) - [almost_swapped](./lints/almost_swapped.md) - - [approx_constant](./lints/approx_constant.md) + - [approximated_constants](./lints/approximated_constants.md) - [constant_table_comparison](./lints/constant_table_comparison.md) - [deprecated](./lints/deprecated.md) - [divide_by_zero](./lints/divide_by_zero.md) diff --git a/docs/src/lints/approx_constant.md b/docs/src/lints/approximated_constants.md similarity index 91% rename from docs/src/lints/approx_constant.md rename to docs/src/lints/approximated_constants.md index e1ffd23c..a8eeda50 100644 --- a/docs/src/lints/approx_constant.md +++ b/docs/src/lints/approximated_constants.md @@ -1,4 +1,4 @@ -# approx_constant +# approximated_constants ## What it does Checks for number literals that approximate constants. diff --git a/selene-lib/src/lints.rs b/selene-lib/src/lints.rs index 17a3b62f..ad33ba5a 100644 --- a/selene-lib/src/lints.rs +++ b/selene-lib/src/lints.rs @@ -8,7 +8,7 @@ use full_moon::{ast::Ast, node::Node}; use serde::de::DeserializeOwned; pub mod almost_swapped; -pub mod approx_constant; +pub mod approximated_constants; pub mod bad_string_escape; pub mod compare_nan; pub mod constant_table_comparison; diff --git a/selene-lib/src/lints/approx_constant.rs b/selene-lib/src/lints/approximated_constants.rs similarity index 77% rename from selene-lib/src/lints/approx_constant.rs rename to selene-lib/src/lints/approximated_constants.rs index c83ce6bd..47958819 100644 --- a/selene-lib/src/lints/approx_constant.rs +++ b/selene-lib/src/lints/approximated_constants.rs @@ -3,9 +3,9 @@ use std::convert::Infallible; use full_moon::{ast::Ast, tokenizer::TokenType, visitors::Visitor}; -pub struct ApproxConstantLint; +pub struct ApproximatedConstantsLint; -impl Lint for ApproxConstantLint { +impl Lint for ApproximatedConstantsLint { type Config = (); type Error = Infallible; @@ -13,22 +13,22 @@ impl Lint for ApproxConstantLint { const LINT_TYPE: LintType = LintType::Correctness; fn new((): Self::Config) -> Result { - Ok(ApproxConstantLint) + Ok(ApproximatedConstantsLint) } fn pass(&self, ast: &Ast, _: &Context, _: &AstContext) -> Vec { let mut visitor = ApproxConstantVisitor { - approx_constants: Vec::new(), + approximated_constants: Vec::new(), }; visitor.visit_ast(ast); visitor - .approx_constants + .approximated_constants .iter() .map(|constant| { Diagnostic::new( - "approx_constant", + "approximated_constants", format!("`{}` is more precise", constant.constant), Label::new(constant.range), ) @@ -38,7 +38,7 @@ impl Lint for ApproxConstantLint { } struct ApproxConstantVisitor { - approx_constants: Vec, + approximated_constants: Vec, } struct ApproximatedConstant { @@ -50,7 +50,7 @@ impl Visitor for ApproxConstantVisitor { fn visit_number(&mut self, token: &full_moon::tokenizer::Token) { if let TokenType::Number { text } = token.token_type() { if is_approx_const(std::f64::consts::PI, text, 3) { - self.approx_constants.push(ApproximatedConstant { + self.approximated_constants.push(ApproximatedConstant { range: (token.start_position().bytes(), token.end_position().bytes()), constant: "math.pi".to_string(), }); @@ -77,11 +77,11 @@ mod tests { use super::{super::test_util::test_lint, *}; #[test] - fn test_approx_constant() { + fn test_approximated_constants() { test_lint( - ApproxConstantLint::new(()).unwrap(), - "approx_constant", - "approx_constant", + ApproximatedConstantsLint::new(()).unwrap(), + "approximated_constants", + "approximated_constants", ); } } diff --git a/selene-lib/tests/lints/approx_constant/approx_constant.stderr b/selene-lib/tests/lints/approx_constant/approx_constant.stderr deleted file mode 100644 index 243ee8c0..00000000 --- a/selene-lib/tests/lints/approx_constant/approx_constant.stderr +++ /dev/null @@ -1,54 +0,0 @@ -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:11:13 - │ -11 │ local bad = 3.14 - │ ^^^^ - -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:12:13 - │ -12 │ local bad = 3.141 - │ ^^^^^ - -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:13:14 - │ -13 │ local bad = -3.141 - │ ^^^^^ - -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:14:13 - │ -14 │ local bad = 3.142 - │ ^^^^^ - -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:15:13 - │ -15 │ local bad = 3.1415 - │ ^^^^^^ - -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:16:13 - │ -16 │ local bad = 3.14159265 - │ ^^^^^^^^^^ - -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:18:13 - │ -18 │ local bad = 3.14 + 1 - │ ^^^^ - -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:19:15 - │ -19 │ local bad = f(3.14 + 1) - │ ^^^^ - -error[approx_constant]: `math.pi` is more precise - ┌─ approx_constant.lua:20:16 - │ -20 │ local bad = f(-3.14 + 1) - │ ^^^^ - diff --git a/selene-lib/tests/lints/approx_constant/approx_constant.lua b/selene-lib/tests/lints/approximated_constants/approximated_constants.lua similarity index 100% rename from selene-lib/tests/lints/approx_constant/approx_constant.lua rename to selene-lib/tests/lints/approximated_constants/approximated_constants.lua diff --git a/selene-lib/tests/lints/approximated_constants/approximated_constants.stderr b/selene-lib/tests/lints/approximated_constants/approximated_constants.stderr new file mode 100644 index 00000000..a551ca95 --- /dev/null +++ b/selene-lib/tests/lints/approximated_constants/approximated_constants.stderr @@ -0,0 +1,54 @@ +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:11:13 + │ +11 │ local bad = 3.14 + │ ^^^^ + +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:12:13 + │ +12 │ local bad = 3.141 + │ ^^^^^ + +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:13:14 + │ +13 │ local bad = -3.141 + │ ^^^^^ + +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:14:13 + │ +14 │ local bad = 3.142 + │ ^^^^^ + +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:15:13 + │ +15 │ local bad = 3.1415 + │ ^^^^^^ + +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:16:13 + │ +16 │ local bad = 3.14159265 + │ ^^^^^^^^^^ + +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:18:13 + │ +18 │ local bad = 3.14 + 1 + │ ^^^^ + +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:19:15 + │ +19 │ local bad = f(3.14 + 1) + │ ^^^^ + +error[approximated_constants]: `math.pi` is more precise + ┌─ approximated_constants.lua:20:16 + │ +20 │ local bad = f(-3.14 + 1) + │ ^^^^ +