Skip to content

Commit

Permalink
feat: underscores and literals validation (#165)
Browse files Browse the repository at this point in the history
* feat: remove trailing underscores

* literals

* fix

* fix: remove print statement

* fix: suggestions

* demo expr recursed

* Update crates/sema/src/ast_passes.rs

---------

Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
  • Loading branch information
TilakMaddy and DaniPopes authored Dec 12, 2024
1 parent 6d905ab commit 2876a11
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 7 deletions.
45 changes: 38 additions & 7 deletions crates/sema/src/ast_passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,38 @@ impl<'sess> AstValidator<'sess, '_> {
.emit();
}
}

fn check_underscores_in_number_literals(&self, lit: &ast::Lit) {
let ast::LitKind::Number(_) = lit.kind else {
return;
};
let literal_span = lit.span;
let literal_str = lit.symbol.as_str();

let error_help_msg = {
if literal_str.ends_with('_') {
Some("remove trailing underscores")
} else if literal_str.contains("__") {
Some("only 1 consecutive underscore `_` is allowed between digits")
} else if literal_str.contains("._") || literal_str.contains("_.") {
Some("remove underscores in front of the fraction part")
} else if literal_str.contains("_e") {
Some("remove underscores at the end of the mantissa")
} else if literal_str.contains("e_") {
Some("remove underscores in front of the exponent")
} else {
None
}
};

if let Some(error_help_msg) = error_help_msg {
self.dcx()
.err("invalid use of underscores in number literal")
.span(literal_span)
.help(error_help_msg)
.emit();
}
}
}

impl<'ast> Visit<'ast> for AstValidator<'_, 'ast> {
Expand Down Expand Up @@ -329,12 +361,11 @@ impl<'ast> Visit<'ast> for AstValidator<'_, 'ast> {
self.walk_using_directive(using)
}

// Intentionally override unused default implementations to reduce bloat.
fn visit_expr(&mut self, _expr: &'ast ast::Expr<'ast>) -> ControlFlow<Self::BreakValue> {
ControlFlow::Continue(())
}

fn visit_ty(&mut self, _ty: &'ast ast::Type<'ast>) -> ControlFlow<Self::BreakValue> {
ControlFlow::Continue(())
fn visit_expr(&mut self, expr: &'ast ast::Expr<'ast>) -> ControlFlow<Self::BreakValue> {
let ast::Expr { kind, .. } = expr;
if let ast::ExprKind::Lit(lit, _) = kind {
self.check_underscores_in_number_literals(lit);
}
self.walk_expr(expr)
}
}
14 changes: 14 additions & 0 deletions tests/ui/resolve/literals_underscores.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
contract LT {
uint256 a = 1000_; //~ERROR: invalid use of underscores in number literal
uint256 b = 100__0; //~ERROR: invalid use of underscores in number literal
uint256 c = 1_.4e10; //~ERROR: invalid use of underscores in number literal
uint256 d = 3.4_e10; //~ERROR: invalid use of underscores in number literal
uint256 e = 3.4e_10; //~ERROR: invalid use of underscores in number literal

// exception
uint256 f = 3._4e10; // Does not show up

uint256 g = 1_.4e10 + 3.4e_10; //~ERROR: invalid use of underscores in number literal
//~^ERROR: invalid use of underscores in number literal

}
58 changes: 58 additions & 0 deletions tests/ui/resolve/literals_underscores.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
error: invalid use of underscores in number literal
--> ROOT/tests/ui/resolve/literals_underscores.sol:LL:CC
|
LL | uint256 a = 1000_;
| ^^^^^
|
= help: remove trailing underscores

error: invalid use of underscores in number literal
--> ROOT/tests/ui/resolve/literals_underscores.sol:LL:CC
|
LL | uint256 b = 100__0;
| ^^^^^^
|
= help: only 1 consecutive underscore `_` is allowed between digits

error: invalid use of underscores in number literal
--> ROOT/tests/ui/resolve/literals_underscores.sol:LL:CC
|
LL | uint256 c = 1_.4e10;
| ^^^^^^^
|
= help: remove underscores in front of the fraction part

error: invalid use of underscores in number literal
--> ROOT/tests/ui/resolve/literals_underscores.sol:LL:CC
|
LL | uint256 d = 3.4_e10;
| ^^^^^^^
|
= help: remove underscores at the end of the mantissa

error: invalid use of underscores in number literal
--> ROOT/tests/ui/resolve/literals_underscores.sol:LL:CC
|
LL | uint256 e = 3.4e_10;
| ^^^^^^^
|
= help: remove underscores in front of the exponent

error: invalid use of underscores in number literal
--> ROOT/tests/ui/resolve/literals_underscores.sol:LL:CC
|
LL | uint256 g = 1_.4e10 + 3.4e_10;
| ^^^^^^^
|
= help: remove underscores in front of the fraction part

error: invalid use of underscores in number literal
--> ROOT/tests/ui/resolve/literals_underscores.sol:LL:CC
|
LL | uint256 g = 1_.4e10 + 3.4e_10;
| ^^^^^^^
|
= help: remove underscores in front of the exponent

error: aborting due to 7 previous errors

0 comments on commit 2876a11

Please sign in to comment.