Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: kind size checks #6137

Merged
merged 72 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
4c012d3
wip: syncing TypeVariableKind with Kind, removing the temporary 'None…
michaeljklein Sep 18, 2024
93aee54
wip validating that op.function results fit in their kinds
michaeljklein Sep 19, 2024
a790553
Merge branch 'master' into michaeljklein/sync-type-var-kinds
michaeljklein Sep 19, 2024
1002bf4
wip(todo!(..)'s remain): adding kinds checks to (try_)bind_to and Typ…
michaeljklein Sep 19, 2024
10a9bf1
wip debugging tests, implemented value size check, add assertions whe…
michaeljklein Sep 20, 2024
1081c50
wip debugging, add max_value method for FieldElement, include kind in…
michaeljklein Sep 20, 2024
a9aba8c
wip: debugging
michaeljklein Sep 23, 2024
236cd61
Merge branch 'master' into michaeljklein/sync-type-var-kinds
michaeljklein Sep 23, 2024
f75fcd7
Merge branch 'master' into michaeljklein/sync-type-var-kinds
michaeljklein Sep 23, 2024
2f497bd
Merge branch 'master' into michaeljklein/sync-type-var-kinds
michaeljklein Sep 23, 2024
c056a0f
feat: kind-based size checks, evaluating to FieldElement, integral_ma…
michaeljklein Sep 23, 2024
ca62c45
wip debugging missing kinds, splitting out kind size checks, add kind…
michaeljklein Sep 24, 2024
b59241e
wip implementing Jake's suggestions, incl. moving TypeVariableKind in…
michaeljklein Sep 24, 2024
953f285
wip: add UnresolvedGeneric::type_variable_kind, propagating changes t…
michaeljklein Sep 24, 2024
2a11bbe
wip debugging, move UnsupportedNumericGenericType into its own struct…
michaeljklein Sep 25, 2024
9cb1aab
wip debugging and add Kind::Normal
michaeljklein Sep 25, 2024
1ba8e44
wip debugging failing tests, updating kinds in noirc_driver and lsp, …
michaeljklein Sep 26, 2024
9e9fde0
wip debugging (most frontend tests passing or only failing with sligh…
michaeljklein Sep 26, 2024
3204c21
wip debugging: disable substitution kind check when overwiting bound …
michaeljklein Sep 26, 2024
ad7ed34
all tests passing! use resolve_generic_kind when possible, use Kind::…
michaeljklein Sep 27, 2024
b81611b
cleanup, remove unused kind arguments from (force_)bind, simplify nex…
michaeljklein Sep 27, 2024
7790be2
Merge branch 'master' into michaeljklein/sync-type-var-kinds
michaeljklein Sep 27, 2024
306a5d7
cargo clippy / fmt
michaeljklein Sep 27, 2024
2581427
Update compiler/noirc_frontend/src/node_interner.rs
michaeljklein Sep 30, 2024
d838173
Update compiler/noirc_frontend/src/hir_def/types.rs
michaeljklein Sep 30, 2024
ceac4b0
Update compiler/noirc_frontend/src/hir_def/types.rs
michaeljklein Sep 30, 2024
0792566
Update compiler/noirc_frontend/src/hir/def_collector/errors.rs
michaeljklein Sep 30, 2024
e218ec2
Merge branch 'master' into michaeljklein/sync-type-var-kinds
TomAFrench Sep 30, 2024
a70a97b
wip debugging parameter type regression, cleanup, note issue for kind…
michaeljklein Oct 1, 2024
029f1c3
fixed numeric generic as param type
michaeljklein Oct 1, 2024
0831c61
cargo clippy / fmt
michaeljklein Oct 1, 2024
334dd1d
move tests to test sub-folders
michaeljklein Oct 1, 2024
67f6058
note issue to follow up on Kind::Any
michaeljklein Oct 1, 2024
0bcc7ee
Merge branch 'master' into michaeljklein/sync-type-var-kinds
michaeljklein Oct 1, 2024
00dd2fc
patching after merge
michaeljklein Oct 1, 2024
d0bc902
Merge branch 'michaeljklein/sync-type-var-kinds' into michaeljklein/k…
michaeljklein Oct 1, 2024
3a82c99
patch noirc_frontend/tests.rs diff from merging michaeljklein/sync-ty…
michaeljklein Oct 1, 2024
172f4a4
wip migrating to TypeVariableKind=Kind and fixing after merge
michaeljklein Oct 3, 2024
5681771
Merge branch 'master' into michaeljklein/kind-size-checks
michaeljklein Oct 3, 2024
6b28ede
wip debugging convert_type size checks
michaeljklein Oct 4, 2024
087abe0
wip debugging new size checks, adding value size checks to check_cast…
michaeljklein Oct 4, 2024
7db0f14
wip
michaeljklein Oct 7, 2024
a9c9a20
wip debugging: Constant value u32 -> FieldElement, ensure eval_global…
michaeljklein Oct 7, 2024
7f5b128
Merge branch 'master' into michaeljklein/kind-size-checks
michaeljklein Oct 7, 2024
d859bc0
wip debugging, add tests for intepreter: return type checking and let…
michaeljklein Oct 7, 2024
5a8ff67
fix follow_bindings error, follow_bindings on kind when matching, mov…
michaeljklein Oct 7, 2024
45ace88
add issue for EvaluatedGlobalPartialSizeChecks and some cleanup
michaeljklein Oct 8, 2024
6b7bc11
add tests to check large (> 2^32) Field bytes, updating tests w/ foll…
michaeljklein Oct 8, 2024
4cdce9e
Merge branch 'master' into michaeljklein/kind-size-checks
michaeljklein Oct 8, 2024
f31c8f4
patch after merge
michaeljklein Oct 8, 2024
c47d7fd
comment r.e. mul/div simplification to disable some cases
michaeljklein Oct 8, 2024
b2fa400
Merge branch 'master' into michaeljklein/kind-size-checks
michaeljklein Oct 8, 2024
9ef3738
wip cleanup
michaeljklein Oct 8, 2024
7dfdc7d
Merge branch 'master' into michaeljklein/kind-size-checks
michaeljklein Oct 9, 2024
c1c0250
cargo clippy / fmt, remaining TODO's, update wrapping_op's to checked…
michaeljklein Oct 9, 2024
b098ee5
nargo fmt
michaeljklein Oct 9, 2024
dfdbc54
Update compiler/noirc_frontend/src/elaborator/types.rs
michaeljklein Oct 9, 2024
e53e543
Update compiler/noirc_frontend/src/hir_def/types/arithmetic.rs
michaeljklein Oct 9, 2024
962dd87
Update compiler/noirc_frontend/src/parser/parser/type_expression.rs
michaeljklein Oct 9, 2024
b063d42
reverting unneeded changes to numeric_generics_type_kind_mismatch
michaeljklein Oct 9, 2024
59bfb4c
Update compiler/noirc_frontend/src/parser/parser/type_expression.rs
michaeljklein Oct 9, 2024
17b3c7e
unifying var and polymorphic int is polymorphic, simplify check_cast …
michaeljklein Oct 9, 2024
a4a1b6e
Merge branch 'master' into michaeljklein/kind-size-checks
michaeljklein Oct 9, 2024
0ff3731
disable warning check in compile_success_empty for brillig_cast and m…
michaeljklein Oct 9, 2024
efefd6b
Merge branch 'master' into michaeljklein/kind-size-checks
michaeljklein Oct 9, 2024
5601afa
fix error check in numeric_generic_as_param_type (passing)
michaeljklein Oct 9, 2024
472e9cd
Merge branch 'master' into michaeljklein/kind-size-checks
michaeljklein Oct 9, 2024
aacd45a
Update compiler/noirc_frontend/src/hir_def/types.rs
michaeljklein Oct 9, 2024
eb42951
Update compiler/noirc_frontend/src/hir_def/types.rs
michaeljklein Oct 9, 2024
f32b7bb
implement Jake's suggestion (+ extra clone) for simplifying checked_o…
michaeljklein Oct 9, 2024
51f80ea
rename EvaluatedGlobalPartialSizeChecks -> EvaluatedGlobalIsntU32 and…
michaeljklein Oct 9, 2024
9f2647a
typo
michaeljklein Oct 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions compiler/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub use visitor::Visitor;
pub use expression::*;
pub use function::*;

use acvm::FieldElement;
pub use docs::*;
use noirc_errors::Span;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -219,7 +220,7 @@ pub struct UnaryRhsMethodCall {
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum UnresolvedTypeExpression {
Variable(Path),
Constant(u32, Span),
Constant(FieldElement, Span),
BinaryOperation(
Box<UnresolvedTypeExpression>,
BinaryTypeOperator,
Expand Down Expand Up @@ -421,12 +422,13 @@ impl UnresolvedTypeExpression {
fn from_expr_helper(expr: Expression) -> Result<UnresolvedTypeExpression, Expression> {
match expr.kind {
ExpressionKind::Literal(Literal::Integer(int, _)) => match int.try_to_u32() {
Some(int) => Ok(UnresolvedTypeExpression::Constant(int, expr.span)),
Some(int) => Ok(UnresolvedTypeExpression::Constant(int.into(), expr.span)),
None => Err(expr),
},
ExpressionKind::Variable(path) => Ok(UnresolvedTypeExpression::Variable(path)),
ExpressionKind::Prefix(prefix) if prefix.operator == UnaryOp::Minus => {
let lhs = Box::new(UnresolvedTypeExpression::Constant(0, expr.span));
let lhs =
Box::new(UnresolvedTypeExpression::Constant(FieldElement::zero(), expr.span));
let rhs = Box::new(UnresolvedTypeExpression::from_expr_helper(prefix.rhs)?);
let op = BinaryTypeOperator::Subtraction;
Ok(UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, expr.span))
Expand Down
11 changes: 6 additions & 5 deletions compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use acvm::{AcirField, FieldElement};
use iter_extended::vecmap;
use noirc_errors::{Location, Span};
use regex::Regex;
Expand Down Expand Up @@ -161,7 +162,7 @@ impl<'context> Elaborator<'context> {
(Lit(int), self.polymorphic_integer_or_field())
}
Literal::Str(str) | Literal::RawStr(str, _) => {
let len = Type::Constant(str.len() as u32, Kind::u32());
let len = Type::Constant(str.len().into(), Kind::u32());
(Lit(HirLiteral::Str(str)), Type::String(Box::new(len)))
}
Literal::FmtStr(str) => self.elaborate_fmt_string(str, span),
Expand Down Expand Up @@ -203,15 +204,15 @@ impl<'context> Elaborator<'context> {
elem_id
});

let length = Type::Constant(elements.len() as u32, Kind::u32());
let length = Type::Constant(elements.len().into(), Kind::u32());
(HirArrayLiteral::Standard(elements), first_elem_type, length)
}
ArrayLiteral::Repeated { repeated_element, length } => {
let span = length.span;
let length =
UnresolvedTypeExpression::from_expr(*length, span).unwrap_or_else(|error| {
self.push_err(ResolverError::ParserError(Box::new(error)));
UnresolvedTypeExpression::Constant(0, span)
UnresolvedTypeExpression::Constant(FieldElement::zero(), span)
});

let length = self.convert_expression_type(length, &Kind::u32(), span);
Expand Down Expand Up @@ -267,7 +268,7 @@ impl<'context> Elaborator<'context> {
}
}

let len = Type::Constant(str.len() as u32, Kind::u32());
let len = Type::Constant(str.len().into(), Kind::u32());
let typ = Type::FmtString(Box::new(len), Box::new(Type::Tuple(capture_types)));
(HirExpression::Literal(HirLiteral::FmtStr(str, fmt_str_idents)), typ)
}
Expand Down Expand Up @@ -676,7 +677,7 @@ impl<'context> Elaborator<'context> {
fn elaborate_cast(&mut self, cast: CastExpression, span: Span) -> (HirExpression, Type) {
let (lhs, lhs_type) = self.elaborate_expression(cast.lhs);
let r#type = self.resolve_type(cast.r#type);
let result = self.check_cast(&lhs_type, &r#type, span);
let result = self.check_cast(&lhs, &lhs_type, &r#type, span);
let expr = HirExpression::Cast(HirCastExpression { lhs, r#type });
(expr, result)
}
Expand Down
56 changes: 50 additions & 6 deletions compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,17 @@ impl<'context> Elaborator<'context> {
.map(|let_statement| Kind::Numeric(Box::new(let_statement.r#type)))
.unwrap_or(Kind::u32());

Some(Type::Constant(self.eval_global_as_array_length(id, path), kind))
// TODO(https://github.com/noir-lang/noir/issues/6238):
// support non-u32 generics here
if !kind.unifies(&Kind::u32()) {
let error = TypeCheckError::EvaluatedGlobalIsntU32 {
expected_kind: Kind::u32().to_string(),
expr_kind: kind.to_string(),
expr_span: path.span(),
};
self.push_err(error);
}
Some(Type::Constant(self.eval_global_as_array_length(id, path).into(), kind))
}
_ => None,
}
Expand Down Expand Up @@ -833,26 +843,60 @@ impl<'context> Elaborator<'context> {
}
}

pub(super) fn check_cast(&mut self, from: &Type, to: &Type, span: Span) -> Type {
match from.follow_bindings() {
Type::Integer(..) | Type::FieldElement | Type::Bool => (),
pub(super) fn check_cast(
&mut self,
from_expr_id: &ExprId,
from: &Type,
to: &Type,
span: Span,
) -> Type {
let from_follow_bindings = from.follow_bindings();

Type::TypeVariable(var) if var.is_integer() || var.is_integer_or_field() => (),
let from_value_opt = match self.interner.expression(from_expr_id) {
HirExpression::Literal(HirLiteral::Integer(int, false)) => Some(int),

// TODO(https://github.com/noir-lang/noir/issues/6247):
// handle negative literals
_ => None,
};

let from_is_polymorphic = match from_follow_bindings {
Type::Integer(..) | Type::FieldElement | Type::Bool => false,

Type::TypeVariable(ref var) if var.is_integer() || var.is_integer_or_field() => true,
Type::TypeVariable(_) => {
// NOTE: in reality the expected type can also include bool, but for the compiler's simplicity
// we only allow integer types. If a bool is in `from` it will need an explicit type annotation.
let expected = self.polymorphic_integer_or_field();
self.unify(from, &expected, || TypeCheckError::InvalidCast {
from: from.clone(),
span,
reason: "casting from a non-integral type is unsupported".into(),
});
true
}
Type::Error => return Type::Error,
from => {
self.push_err(TypeCheckError::InvalidCast { from, span });
let reason = "casting from this type is unsupported".into();
self.push_err(TypeCheckError::InvalidCast { from, span, reason });
return Type::Error;
}
};

// TODO(https://github.com/noir-lang/noir/issues/6247):
// handle negative literals
// when casting a polymorphic value to a specifically sized type,
// check that it fits or throw a warning
if let (Some(from_value), Some(to_maximum_size)) =
(from_value_opt, to.integral_maximum_size())
{
if from_is_polymorphic && from_value > to_maximum_size {
let from = from.clone();
let to = to.clone();
let reason = format!("casting untyped value ({from_value}) to a type with a maximum size ({to_maximum_size}) that's smaller than it");
// we warn that the 'to' type is too small for the value
self.push_err(TypeCheckError::DownsizingCast { from, to, span, reason });
}
}

match to {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ impl HirArrayLiteral {
let repeated_element = Box::new(repeated_element.to_display_ast(interner));
let length = match length {
Type::Constant(length, _kind) => {
let literal = Literal::Integer((*length as u128).into(), false);
let literal = Literal::Integer(*length, false);
let expr_kind = ExpressionKind::Literal(literal);
Box::new(Expression::new(expr_kind, span))
}
Expand Down
Loading
Loading