diff --git a/crates/sema/src/eval.rs b/crates/sema/src/eval.rs index 2f47936..ab357b1 100644 --- a/crates/sema/src/eval.rs +++ b/crates/sema/src/eval.rs @@ -62,9 +62,7 @@ impl<'gcx> ConstantEvaluator<'gcx> { fn eval_expr(&mut self, expr: &hir::Expr<'_>) -> EvalResult<'gcx> { let expr = expr.peel_parens(); match expr.kind { - // hir::ExprKind::Array(_) => { - // unimplemented!() - // } + // hir::ExprKind::Array(_) => unimplemented!(), // hir::ExprKind::Assign(_, _, _) => unimplemented!(), hir::ExprKind::Binary(l, bin_op, r) => { let l = self.try_eval(l)?; @@ -74,7 +72,12 @@ impl<'gcx> ConstantEvaluator<'gcx> { // hir::ExprKind::Call(_, _) => unimplemented!(), // hir::ExprKind::CallOptions(_, _) => unimplemented!(), // hir::ExprKind::Delete(_) => unimplemented!(), - hir::ExprKind::Ident(&[hir::Res::Item(hir::ItemId::Variable(v))]) => { + hir::ExprKind::Ident(res) => { + // Ignore invalid overloads since they will get correctly detected later. + let Some(v) = res.iter().find_map(|res| res.as_variable()) else { + return Err(EE::NonConstantVar.into()); + }; + let v = self.gcx.hir.variable(v); if v.mutability != Some(hir::VarMut::Constant) { return Err(EE::NonConstantVar.into()); diff --git a/crates/sema/src/hir.rs b/crates/sema/src/hir.rs index 89fdc7c..755544f 100644 --- a/crates/sema/src/hir.rs +++ b/crates/sema/src/hir.rs @@ -1025,7 +1025,7 @@ impl LoopSource { } /// Resolved name. -#[derive(Clone, Copy, PartialEq, Eq, From, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, From, EnumIs)] pub enum Res { /// A resolved item. Item(ItemId), @@ -1091,8 +1091,12 @@ impl Res { } } - pub fn is_err(&self) -> bool { - matches!(self, Self::Err(_)) + pub fn as_variable(&self) -> Option { + if let Self::Item(id) = self { + id.as_variable() + } else { + None + } } } diff --git a/tests/ui/typeck/eval.sol b/tests/ui/typeck/eval.sol index 53a04e6..8375c50 100644 --- a/tests/ui/typeck/eval.sol +++ b/tests/ui/typeck/eval.sol @@ -8,6 +8,9 @@ uint constant tooBigLiteral = 11579208923731619542357098500868790785326998466564 contract C { uint constant zero = x - x; + uint public constant zeroPublic = x / x - 1; + uint[zero] public zeroArray; //~ ERROR: array length must be greater than zero + uint[zeroPublic + 1] public oneArray; uint[bigLiteral] public big; uint[bigLiteral + 1] public tooBig1; //~ ERROR: evaluation of constant value failed @@ -25,10 +28,11 @@ contract C { function g(uint[0] memory) public {} //~ ERROR: array length must be greater than zero function h(uint[zero] memory) public {} //~ ERROR: array length must be greater than zero + function h2(uint[zeroPublic] memory) public {} //~ ERROR: array length must be greater than zero function i(uint[block.timestamp] memory) public {} //~ ERROR: evaluation of constant value failed function j(uint["lol"] memory) public {} //~ ERROR: evaluation of constant value failed function k(uint[--x] memory) public {} //~ ERROR: evaluation of constant value failed function l(uint[stateVar] memory) public {} //~ ERROR: evaluation of constant value failed - function l(uint[stateVarPublic] memory) public {} //~ ERROR: evaluation of constant value failed + function m(uint[stateVarPublic] memory) public {} //~ ERROR: evaluation of constant value failed } diff --git a/tests/ui/typeck/eval.stderr b/tests/ui/typeck/eval.stderr index 3a5f86b..cfbbaa2 100644 --- a/tests/ui/typeck/eval.stderr +++ b/tests/ui/typeck/eval.stderr @@ -54,6 +54,13 @@ LL | function h(uint[zero] memory) public {} | ^^^^ | +error: array length must be greater than zero + --> ROOT/tests/ui/typeck/eval.sol:LL:CC + | +LL | function h2(uint[zeroPublic] memory) public {} + | ^^^^^^^^^^ + | + error: evaluation of constant value failed --> ROOT/tests/ui/typeck/eval.sol:LL:CC | @@ -93,10 +100,17 @@ LL | function l(uint[stateVar] memory) public {} error: evaluation of constant value failed --> ROOT/tests/ui/typeck/eval.sol:LL:CC | -LL | function l(uint[stateVarPublic] memory) public {} +LL | function m(uint[stateVarPublic] memory) public {} | -------------- | | - | note: unsupported expression + | note: only constant variables are allowed + | + +error: array length must be greater than zero + --> ROOT/tests/ui/typeck/eval.sol:LL:CC + | +LL | uint[zero] public zeroArray; + | ^^^^ | error: evaluation of constant value failed @@ -120,5 +134,5 @@ LL | uint[tooBigLiteral] public tooBig2; | ^^^^^^^^^^^^^ | -error: aborting due to 13 previous errors +error: aborting due to 15 previous errors