Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 4 additions & 3 deletions compiler/noirc_driver/src/abi_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@ pub(super) fn abi_type_from_hir_type(context: &Context, typ: &Type) -> AbiType {
if binding.is_integer() || binding.is_integer_or_field() {
match &*binding.borrow() {
TypeBinding::Bound(typ) => abi_type_from_hir_type(context, typ),
TypeBinding::Unbound(_id, _kind) => {
abi_type_from_hir_type(context, &Type::default_int_or_field_type())
}
TypeBinding::Unbound(_id, _kind) => abi_type_from_hir_type(
context,
&Type::default_signed_integer_or_field_type(),
),
}
} else {
unreachable!("{typ} cannot be used in the abi")
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/elaborator/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@

match expression.kind {
ExpressionKind::Literal(Literal::Integer(value)) => {
let actual = self.interner.next_type_variable_with_kind(Kind::IntegerOrField);
let actual = self.interner.next_type_variable_with_kind(Kind::SignedIntegerOrField);
unify_with_expected_type(self, &actual);
Pattern::Int(value)
}
Expand Down Expand Up @@ -1010,7 +1010,7 @@

/// Compiles the cases and fallback cases for integer and range patterns.
///
/// Integers have an infinite number of constructors, so we specialise the

Check warning on line 1013 in compiler/noirc_frontend/src/elaborator/enums.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (specialise)
/// compilation of integer and range patterns.
fn compile_int_cases(
&mut self,
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ impl<'context> Elaborator<'context> {
let typ = if unresolved_typ.is_type_expression() {
self.resolve_type_with_kind(
unresolved_typ.clone(),
&Kind::numeric(Type::default_int_type()),
&Kind::numeric(Type::default_unsigned_integer_type()),
)
} else {
self.resolve_type(unresolved_typ.clone())
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@
}
} else {
let name = self.elaborator.interner.function_name(&function);
unreachable!("Non-builtin, lowlevel or oracle builtin fn '{name}'")

Check warning on line 269 in compiler/noirc_frontend/src/hir/comptime/interpreter.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (lowlevel)
}
}

Expand Down Expand Up @@ -1564,7 +1564,7 @@
Value::Field(value) => {
let u64: Option<u64> = value.try_to_unsigned();
u64.and_then(|value| value.try_into().ok()).ok_or_else(|| {
let typ = Type::default_int_type();
let typ = Type::default_unsigned_integer_type();
let value = SignedField::positive(value);
InterpreterError::IntegerOutOfRangeForType { value, typ, location }
})?
Expand Down
64 changes: 35 additions & 29 deletions compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,12 @@
/// Can bind to any type, except Type::Constant and Type::InfixExpr
Normal,

/// A generic integer or field type. This is a more specific kind of TypeVariable
/// A generic signed integer or field type. This is a more specific kind of TypeVariable
/// that can only be bound to Type::Field, Type::Integer, or other polymorphic integers.
/// This is the type of undecorated integer literals like `46`. Typing them in this way
/// allows them to be polymorphic over the actual integer/field type used without requiring
/// type annotations on each integer literal.
IntegerOrField,
SignedIntegerOrField,

/// A generic integer type. This is a more specific kind of TypeVariable
/// that can only be bound to Type::Integer, or other polymorphic integers.
Expand Down Expand Up @@ -202,7 +202,7 @@
fn is_field_element(&self, value_level: bool) -> bool {
match self.follow_bindings() {
Kind::Numeric(typ) => typ.is_field_element(value_level),
Kind::IntegerOrField => value_level,
Kind::SignedIntegerOrField => value_level,
_ => false,
}
}
Expand All @@ -216,7 +216,7 @@
Self::Any => Self::Any,
Self::Normal => Self::Normal,
Self::Integer => Self::Integer,
Self::IntegerOrField => Self::IntegerOrField,
Self::SignedIntegerOrField => Self::SignedIntegerOrField,
Self::Numeric(typ) => Self::numeric(typ.follow_bindings()),
}
}
Expand All @@ -225,8 +225,8 @@
/// during monomorphization.
pub(crate) fn default_type(&self) -> Option<Type> {
match self {
Kind::IntegerOrField => Some(Type::default_int_or_field_type()),
Kind::Integer => Some(Type::default_int_type()),
Kind::SignedIntegerOrField => Some(Type::default_signed_integer_or_field_type()),
Kind::Integer => Some(Type::default_unsigned_integer_type()),
Kind::Numeric(_typ) => {
// Even though we have a type here, that type cannot be used as
// the default type of a numeric generic.
Expand All @@ -240,7 +240,7 @@

fn integral_maximum_size(&self) -> Option<FieldElement> {
match self.follow_bindings() {
Kind::Any | Kind::IntegerOrField | Kind::Integer | Kind::Normal => None,
Kind::Any | Kind::SignedIntegerOrField | Kind::Integer | Kind::Normal => None,
Self::Numeric(typ) => typ.integral_maximum_size(),
}
}
Expand Down Expand Up @@ -271,7 +271,7 @@
Kind::Any => write!(f, "any"),
Kind::Normal => write!(f, "normal"),
Kind::Integer => write!(f, "int"),
Kind::IntegerOrField => write!(f, "intOrField"),
Kind::SignedIntegerOrField => write!(f, "intOrField"),
Kind::Numeric(typ) => write!(f, "numeric {}", typ),
}
}
Expand Down Expand Up @@ -907,7 +907,7 @@
matches!(binding.follow_bindings(), Type::Integer(..) | Type::FieldElement)
}
TypeBinding::Unbound(_, type_var_kind) => {
matches!(type_var_kind.follow_bindings(), Kind::IntegerOrField)
matches!(type_var_kind.follow_bindings(), Kind::SignedIntegerOrField)
}
}
}
Expand Down Expand Up @@ -961,8 +961,8 @@
match &*binding.borrow() {
TypeBinding::Unbound(_, type_var_kind) => match type_var_kind {
Kind::Any | Kind::Normal => write!(f, "{}", var.borrow()),
Kind::Integer => write!(f, "{}", Type::default_int_type()),
Kind::IntegerOrField => write!(f, "Field"),
Kind::Integer => write!(f, "{}", Type::default_unsigned_integer_type()),
Kind::SignedIntegerOrField => write!(f, "Field"),
Kind::Numeric(_typ) => write!(f, "_"),
},
TypeBinding::Bound(binding) => {
Expand Down Expand Up @@ -1094,11 +1094,11 @@
}

impl Type {
pub fn default_int_or_field_type() -> Type {
Type::FieldElement
pub fn default_signed_integer_or_field_type() -> Type {
Type::Integer(Signedness::Signed, IntegerBitSize::ThirtyTwo)
}

pub fn default_int_type() -> Type {
pub fn default_unsigned_integer_type() -> Type {
Type::Integer(Signedness::Unsigned, IntegerBitSize::ThirtyTwo)
}

Expand All @@ -1114,7 +1114,7 @@
}

pub fn polymorphic_integer_or_field(interner: &NodeInterner) -> Type {
let type_var_kind = Kind::IntegerOrField;
let type_var_kind = Kind::SignedIntegerOrField;
Self::type_variable_with_kind(interner, type_var_kind)
}

Expand Down Expand Up @@ -1181,7 +1181,7 @@
TypeVariable(var) => match &*var.borrow() {
TypeBinding::Bound(typ) => typ.is_numeric_value(),
TypeBinding::Unbound(_, type_var_kind) => {
matches!(type_var_kind, K::Integer | K::IntegerOrField)
matches!(type_var_kind, K::Integer | K::SignedIntegerOrField)
}
},
_ => false,
Expand Down Expand Up @@ -1647,7 +1647,7 @@
TypeBinding::Unbound(id, _) => *id,
};

if !self.kind().unifies(&Kind::IntegerOrField) {
if !self.kind().unifies(&Kind::SignedIntegerOrField) {
return Err(UnificationError);
}

Expand All @@ -1658,7 +1658,7 @@
Ok(())
}
Type::FieldElement if !only_integer => {
bindings.insert(target_id, (var.clone(), Kind::IntegerOrField, this));
bindings.insert(target_id, (var.clone(), Kind::SignedIntegerOrField, this));
Ok(())
}
Type::TypeVariable(self_var) => {
Expand All @@ -1669,8 +1669,8 @@
}
// Avoid infinitely recursive bindings
TypeBinding::Unbound(id, _) if *id == target_id => Ok(()),
TypeBinding::Unbound(new_target_id, Kind::IntegerOrField) => {
let type_var_kind = Kind::IntegerOrField;
TypeBinding::Unbound(new_target_id, Kind::SignedIntegerOrField) => {
let type_var_kind = Kind::SignedIntegerOrField;
if only_integer {
let var_clone = var.clone();
Kind::Integer.unify(&type_var_kind)?;
Expand All @@ -1682,7 +1682,7 @@
} else {
bindings.insert(
target_id,
(var.clone(), Kind::IntegerOrField, this.clone()),
(var.clone(), Kind::SignedIntegerOrField, this.clone()),
);
}
Ok(())
Expand All @@ -1696,7 +1696,7 @@
let var_clone = var.clone();
// Bind to the most specific type variable kind
let clone_kind =
if only_integer { Kind::Integer } else { Kind::IntegerOrField };
if only_integer { Kind::Integer } else { Kind::SignedIntegerOrField };
clone_kind.unify(type_var_kind)?;
let clone = Type::TypeVariable(var_clone);
bindings.insert(*new_target_id, (self_var.clone(), clone_kind, clone));
Expand Down Expand Up @@ -2018,7 +2018,7 @@
}

let recur_on_binding = |id, replacement: &Type| {
// Prevent recuring forever if there's a `T := T` binding

Check warning on line 2021 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (recuring)
if replacement.type_variable_id() == Some(id) {
replacement.clone()
} else {
Expand Down Expand Up @@ -2104,7 +2104,7 @@
Type::Tuple(fields)
}
Type::Forall(typevars, typ) => {
// Trying to substitute_helper a variable de, substitute_bound_typevarsfined within a nested Forall

Check warning on line 2107 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (typevarsfined)
// is usually impossible and indicative of an error in the type checker somewhere.
for var in typevars {
assert!(!type_bindings.contains_key(&var.id()));
Expand Down Expand Up @@ -2271,7 +2271,7 @@
}
}

/// Follow bindings if this is a type variable or generic to the first non-typevariable

Check warning on line 2274 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (typevariable)
/// type. Unlike `follow_bindings`, this won't recursively follow any bindings on any
/// fields or arguments of this type.
pub fn follow_bindings_shallow(&self) -> Cow<Type> {
Expand All @@ -2296,7 +2296,7 @@

/// Replace any `Type::NamedGeneric` in this type with a `Type::TypeVariable`
/// using to the same inner `TypeVariable`. This is used during monomorphization
/// to bind to named generics since they are unbindable during type checking.

Check warning on line 2299 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (unbindable)
pub fn replace_named_generics_with_type_variables(&mut self) {
match self {
Type::FieldElement
Expand Down Expand Up @@ -2404,7 +2404,9 @@
let binding = &var.1;
match &*binding.borrow() {
TypeBinding::Unbound(_, type_var_kind) => match type_var_kind {
Kind::Any | Kind::Normal | Kind::Integer | Kind::IntegerOrField => None,
Kind::Any | Kind::Normal | Kind::Integer | Kind::SignedIntegerOrField => {
None
}
Kind::Numeric(typ) => typ.integral_maximum_size(),
},
TypeBinding::Bound(typ) => typ.integral_maximum_size(),
Expand Down Expand Up @@ -2455,7 +2457,9 @@
let binding = &var.1;
match &*binding.borrow() {
TypeBinding::Unbound(_, type_var_kind) => match type_var_kind {
Kind::Any | Kind::Normal | Kind::Integer | Kind::IntegerOrField => None,
Kind::Any | Kind::Normal | Kind::Integer | Kind::SignedIntegerOrField => {
None
}
Kind::Numeric(typ) => typ.integral_minimum_size(),
},
TypeBinding::Bound(typ) => typ.integral_minimum_size(),
Expand Down Expand Up @@ -2604,9 +2608,11 @@
},
Type::TypeVariable(binding) => match &*binding.borrow() {
TypeBinding::Bound(typ) => typ.into(),
TypeBinding::Unbound(_, Kind::Integer) => Type::default_int_type().into(),
TypeBinding::Unbound(_, Kind::IntegerOrField) => {
Type::default_int_or_field_type().into()
TypeBinding::Unbound(_, Kind::Integer) => {
Type::default_unsigned_integer_type().into()
}
TypeBinding::Unbound(_, Kind::SignedIntegerOrField) => {
Type::default_signed_integer_or_field_type().into()
}
TypeBinding::Unbound(_, Kind::Numeric(typ)) => (*typ.clone()).into(),
TypeBinding::Unbound(_, Kind::Any | Kind::Normal) => unreachable!(),
Expand Down Expand Up @@ -2680,7 +2686,7 @@
if let TypeBinding::Unbound(_, type_var_kind) = &*binding.borrow() {
match type_var_kind {
Kind::Any | Kind::Normal => write!(f, "{:?}", var),
Kind::IntegerOrField => write!(f, "IntOrField{:?}", binding),
Kind::SignedIntegerOrField => write!(f, "IntOrField{:?}", binding),
Kind::Integer => write!(f, "Int{:?}", binding),
Kind::Numeric(typ) => write!(f, "Numeric({:?}: {:?})", binding, typ),
}
Expand Down Expand Up @@ -2722,7 +2728,7 @@
Type::Error => write!(f, "error"),
Type::CheckedCast { to, .. } => write!(f, "{:?}", to),
Type::NamedGeneric(NamedGeneric { type_var, name, .. }) => match type_var.kind() {
Kind::Any | Kind::Normal | Kind::Integer | Kind::IntegerOrField => {
Kind::Any | Kind::Normal | Kind::Integer | Kind::SignedIntegerOrField => {
write!(f, "{}{:?}", name, type_var)
}
Kind::Numeric(typ) => {
Expand Down Expand Up @@ -2813,7 +2819,7 @@
len.hash(state);
env.hash(state);
}
Type::Tuple(elems) => elems.hash(state),

Check warning on line 2822 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)

Check warning on line 2822 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)
Type::DataType(def, args) => {
def.hash(state);
args.hash(state);
Expand Down
15 changes: 9 additions & 6 deletions compiler/noirc_frontend/src/hir_def/types/unification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,18 @@ impl Kind {
(Kind::Any, _) | (_, Kind::Any) => true,

// Kind::Normal unifies with Kind::Integer and Kind::IntegerOrField
(Kind::Normal, Kind::Integer | Kind::IntegerOrField)
| (Kind::Integer | Kind::IntegerOrField, Kind::Normal) => true,
(Kind::Normal, Kind::Integer | Kind::SignedIntegerOrField)
| (Kind::Integer | Kind::SignedIntegerOrField, Kind::Normal) => true,

// Kind::Integer unifies with Kind::IntegerOrField
(Kind::Integer | Kind::IntegerOrField, Kind::Integer | Kind::IntegerOrField) => true,
(
Kind::Integer | Kind::SignedIntegerOrField,
Kind::Integer | Kind::SignedIntegerOrField,
) => true,

// Kind::IntegerOrField unifies with Kind::Numeric(_)
(Kind::IntegerOrField, Kind::Numeric(_typ))
| (Kind::Numeric(_typ), Kind::IntegerOrField) => true,
(Kind::SignedIntegerOrField, Kind::Numeric(_typ))
| (Kind::Numeric(_typ), Kind::SignedIntegerOrField) => true,

// Kind::Numeric unifies along its Type argument
(Kind::Numeric(lhs), Kind::Numeric(rhs)) => {
Expand Down Expand Up @@ -140,7 +143,7 @@ impl Type {
})
}
}
TypeBinding::Unbound(_id, Kind::IntegerOrField) => other
TypeBinding::Unbound(_id, Kind::SignedIntegerOrField) => other
.try_unify_to_type_variable(var, flags, bindings, |bindings| {
let only_integer = false;
other.try_bind_to_polymorphic_int(var, bindings, only_integer)
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/monomorphization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ impl<'interner> Monomorphizer<'interner> {
Kind::Any => (),
Kind::Normal => (),
Kind::Integer => (),
Kind::IntegerOrField => (),
Kind::SignedIntegerOrField => (),
Kind::Numeric(typ) => Self::check_type(typ, ident.location)?,
}
Self::check_type(binding, ident.location)?;
Expand Down Expand Up @@ -1317,7 +1317,7 @@ impl<'interner> Monomorphizer<'interner> {
// Default any remaining unbound type variables.
// This should only happen if the variable in question is unused
// and within a larger generic type.
type_var.bind(HirType::default_int_or_field_type());
type_var.bind(HirType::default_signed_integer_or_field_type());
ast::Type::Field
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/ownership/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fn does_not_move_into_loop() {
}
unconstrained fn use_var$f1(_x$l3: [Field; 2]) -> () {
}
unconstrained fn use_var$f2(_x$l4: [Field; 1]) -> () {
unconstrained fn use_var$f2(_x$l4: [i32; 1]) -> () {
}
");
}
Expand Down Expand Up @@ -109,7 +109,7 @@ fn can_move_within_loop() {
use_var$f1(x$l1);
}
}
unconstrained fn use_var$f1(_x$l2: [Field; 2]) -> () {
unconstrained fn use_var$f1(_x$l2: [i32; 2]) -> () {
}
");
}
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ fn emit_compile_test(test_path: &str, src: &str, mut expect: Expect) {
}
}

let error_to_bug_cases = ["cast_negative_one_to_u8_size_checks"];
let error_to_bug_cases: [&'static str; 0] = [];
if let Expect::Success = expect {
if error_to_bug_cases
.iter()
Expand Down
16 changes: 8 additions & 8 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@

let chars = line.chars().collect::<Vec<_>>();
let first_caret = chars.iter().position(|c| *c == char).unwrap();
let last_caret = chars.iter().rposition(|c| *c == char).unwrap();

Check warning on line 287 in compiler/noirc_frontend/src/tests.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (rposition)
let start = byte - last_line_length;
let span = Span::from((start + first_caret - 1) as u32..(start + last_caret) as u32);
let error = line.trim().trim_start_matches(char).trim().to_string();
Expand Down Expand Up @@ -1242,7 +1242,7 @@

let new_val = 10;
println(f"random_string{new_val}{new_val}");
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unused expression result of type fmtstr<31, (Field, Field)>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unused expression result of type fmtstr<31, (i32, i32)>
}
fn println<T>(x : T) -> T {
x
Expand Down Expand Up @@ -2018,7 +2018,7 @@
let src = r#"
fn main() {
assert(256 as u8 == 0);
^^^^^^^^^ Casting value of type Field to a smaller type (u8)
^^^^^^^^^ Casting value of type i32 to a smaller type (u8)
~~~~~~~~~ casting untyped value (256) to a type with a maximum size (255) that's smaller than it
}
"#;
Expand Down Expand Up @@ -2941,24 +2941,24 @@
let src = r#"
global ARRAY_LEN = 3;
^^^^^^^^^ Globals must have a specified type
~ Inferred type is `Field`
~ Inferred type is `i32`
global STR_LEN: _ = 2;
^^^^^^^ Globals must have a specified type
~ Inferred type is `Field`
~ Inferred type is `i32`
global FMT_STR_LEN = 2;
^^^^^^^^^^^ Globals must have a specified type
~ Inferred type is `Field`
~ Inferred type is `i32`

fn main() {
let _a: [u32; ARRAY_LEN] = [1, 2, 3];
^^^^^^^^^^^^^^^^ The numeric generic is not of type `u32`
~~~~~~~~~~~~~~~~ expected `u32`, found `Field`
~~~~~~~~~~~~~~~~ expected `u32`, found `i32`
let _b: str<STR_LEN> = "hi";
^^^^^^^ The numeric generic is not of type `u32`
~~~~~~~ expected `u32`, found `Field`
~~~~~~~ expected `u32`, found `i32`
let _c: fmtstr<FMT_STR_LEN, _> = f"hi";
^^^^^^^^^^^ The numeric generic is not of type `u32`
~~~~~~~~~~~ expected `u32`, found `Field`
~~~~~~~~~~~ expected `u32`, found `i32`
}
"#;
check_errors!(src);
Expand Down Expand Up @@ -3190,7 +3190,7 @@
// wouldn't panic due to infinite recursion, but the errors asserted here
// come from the compilation checks, which does static analysis to catch the
// problem before it even has a chance to cause a panic.
let srcs = vec![

Check warning on line 3193 in compiler/noirc_frontend/src/tests.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (srcs)
r#"
fn main() {
^^^^ function `main` cannot return without recursing
Expand Down
Loading
Loading