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
6 changes: 4 additions & 2 deletions compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ impl<'a> FunctionContext<'a> {
ast::Type::Tuple(fields) => {
Tree::Branch(vecmap(fields, |field| Self::map_type_helper(field, f)))
}
ast::Type::Unit => Tree::empty(),
// TODO: WIP
// ast::Type::Unit => Tree::empty(),
// A mutable reference wraps each element into a reference.
// This can be multiple values if the element type is a tuple.
ast::Type::Reference(element, _) => {
Expand Down Expand Up @@ -259,7 +260,8 @@ impl<'a> FunctionContext<'a> {
ast::Type::FmtString(_, _) => {
panic!("convert_non_tuple_type called on a fmt string: {typ}")
}
ast::Type::Unit => panic!("convert_non_tuple_type called on a unit type"),
// TODO: WIP
// ast::Type::Unit => panic!("convert_non_tuple_type called on a unit type"),
ast::Type::Tuple(_) => panic!("convert_non_tuple_type called on a tuple: {typ}"),
ast::Type::Function(_, _, _, _) => Type::Function,
ast::Type::Slice(_) => panic!("convert_non_tuple_type called on a slice: {typ}"),
Expand Down
20 changes: 16 additions & 4 deletions compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,8 @@ impl FunctionContext<'_> {

Ok(Tree::Branch(vec![string, field_count.into(), fields]))
}
ast::Literal::Unit => Ok(Self::unit_value()),
// TODO: WIP
// ast::Literal::Unit => Ok(Self::unit_value()),
}
}

Expand Down Expand Up @@ -410,8 +411,13 @@ impl FunctionContext<'_> {
match expr {
Expression::Ident(ident) => Ok(self.codegen_ident_reference(ident)),
Expression::ExtractTupleField(tuple, index) => {
// TODO: WIP
let tuple = self.codegen_reference(tuple)?;
Ok(Self::get_field(tuple, *index))
if tuple.is_leaf() {
Ok(tuple)
} else {
Ok(Self::get_field(tuple, *index))
}
}
other => self.codegen_expression(other),
}
Expand Down Expand Up @@ -1035,8 +1041,14 @@ impl FunctionContext<'_> {
tuple: &Expression,
field_index: usize,
) -> Result<Values, RuntimeError> {
let tuple = self.codegen_expression(tuple)?;
Ok(Self::get_field(tuple, field_index))
// TODO: WIP
let tuple = self.codegen_reference(tuple)?;
if tuple.is_leaf() {
Ok(tuple)
} else {
// TODO: NOTE: there's another Self::get_field case in codegen_reference
Ok(Self::get_field(tuple, field_index))
}
}

/// Generate SSA for a function call. Note that calls to built-in functions
Expand Down
8 changes: 8 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ssa_gen/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ impl<T> Tree<T> {
Tree::Leaf(value) => value,
}
}

// TODO: WIP
pub(super) fn is_leaf(&self) -> bool {
match self {
Tree::Leaf(_) => true,
_ => false,
}
}
}

impl From<IrValueId> for Values {
Expand Down
7 changes: 7 additions & 0 deletions compiler/noirc_evaluator/src/ssa/validation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,13 @@
let called_function = &self.ssa.functions[func_id];

let parameter_types = called_function.view().parameter_types();

// TODO: WIP
let argument_types = arguments.iter().map(|arg| {
dfg.type_of_value(*arg)
}).collect::<Vec<_>>();
dbg!(&called_function, &arguments, &parameter_types, argument_types);

assert_eq!(
arguments.len(),
parameter_types.len(),
Expand Down Expand Up @@ -673,19 +680,19 @@
// message_hash: [u8; N],
// predicate: bool,
// ) -> bool
assert_arguments_length(arguments, 5, "ecdsa_secp_256");

Check warning on line 683 in compiler/noirc_evaluator/src/ssa/validation/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (secp)

let public_key_x = arguments[0];
let public_key_x_type = dfg.type_of_value(public_key_x);
let public_key_x_length =
assert_u8_array(&public_key_x_type, "ecdsa_secp256 public_key_x");

Check warning on line 688 in compiler/noirc_evaluator/src/ssa/validation/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (secp)
assert_array_length(public_key_x_length, 32, "ecdsa_secp256 public_key_x");

Check warning on line 689 in compiler/noirc_evaluator/src/ssa/validation/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (secp)

let public_key_y = arguments[1];
let public_key_y_type = dfg.type_of_value(public_key_y);
let public_key_y_length =
assert_u8_array(&public_key_y_type, "ecdsa_secp256 public_key_y");

Check warning on line 694 in compiler/noirc_evaluator/src/ssa/validation/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (secp)
assert_array_length(public_key_y_length, 32, "ecdsa_secp256 public_key_y");

Check warning on line 695 in compiler/noirc_evaluator/src/ssa/validation/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (secp)

let signature = arguments[2];
let signature_type = dfg.type_of_value(signature);
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/elaborator/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ impl Elaborator<'_> {
Pattern::Tuple(fields, location) => {
let field_types = match expected_type.follow_bindings() {
Type::Tuple(fields) => fields,
Type::Unit => vec![],
Type::Error => Vec::new(),
expected_type => {
let tuple =
Expand Down
9 changes: 9 additions & 0 deletions compiler/noirc_frontend/src/hir_def/types/unification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ impl Type {
}
}

// TODO: WIP
(Tuple(elements), Unit) | (Unit, Tuple(elements)) => {
if elements.len() == 0 {
Ok(())
} else {
Err(UnificationError)
}
}

// No recursive try_unify call for struct fields. Don't want
// to mutate shared type variables within struct definitions.
// This isn't possible currently but will be once noir gets generic types
Expand Down
32 changes: 26 additions & 6 deletions compiler/noirc_frontend/src/monomorphization/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ impl Expression {
Literal::Array(literal) | Literal::Slice(literal) => borrowed(&literal.typ),
Literal::Integer(_, typ, _) => borrowed(typ),
Literal::Bool(_) => borrowed(&Type::Bool),
Literal::Unit => borrowed(&Type::Unit),
// TODO: WIP
// Literal::Unit => borrowed(&Type::Unit),
Literal::Str(s) => owned(Type::String(s.len() as u32)),
Literal::FmtStr(_, size, expr) => expr.return_type().and_then(|typ| {
owned(Type::FmtString(*size as u32, Box::new(typ.into_owned())))
Expand Down Expand Up @@ -196,6 +197,14 @@ impl Expression {
| Expression::Continue => false,
}
}

// TODO: WIP
pub fn is_unit(&self) -> bool {
match self {
Expression::Tuple(fields) => fields.len() == 0,
_ => false,
}
}
}

/// A definition is either a local (variable), function, or is a built-in
Expand Down Expand Up @@ -272,7 +281,8 @@ pub enum Literal {
Slice(ArrayLiteral),
Integer(SignedField, Type, Location),
Bool(bool),
Unit,
// TODO: WIP
// Unit,
Str(String),
FmtStr(Vec<FmtStrFragment>, u64, Box<Expression>),
}
Expand Down Expand Up @@ -503,7 +513,8 @@ pub enum Type {
Bool,
String(/*len:*/ u32), // String(4) = str[4]
FmtString(/*len:*/ u32, Box<Type>),
Unit,
// TODO: WIP
// Unit,
Tuple(Vec<Type>),
Slice(Box<Type>),
Reference(Box<Type>, /*mutable:*/ bool),
Expand Down Expand Up @@ -650,7 +661,8 @@ impl Display for Type {
Type::FmtString(len, elements) => {
write!(f, "fmtstr<{len}, {elements}>")
}
Type::Unit => write!(f, "()"),
// TODO: WIP
// Type::Unit => write!(f, "()"),
Type::Tuple(elements) => {
let elements = vecmap(elements, ToString::to_string);
if elements.len() == 1 {
Expand All @@ -665,8 +677,16 @@ impl Display for Type {
}

let args = vecmap(args, ToString::to_string);
let closure_env_text = match **env {
Type::Unit => "".to_string(),
let closure_env_text = match *(env.clone()) {
// TODO: WIP
// Type::Unit => "".to_string(),
Type::Tuple(elements) => {
if elements.len() == 0 {
"".to_string()
} else {
format!(" with closure environment {env}")
}
}
_ => format!(" with closure environment {env}"),
};
write!(f, "fn({}) -> {}{}", args.join(", "), ret, closure_env_text)
Expand Down
20 changes: 14 additions & 6 deletions compiler/noirc_frontend/src/monomorphization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,9 @@ impl<'interner> Monomorphizer<'interner> {
self.repeated_array(expr, repeated_element, length, true)?
}
},
HirExpression::Literal(HirLiteral::Unit) => ast::Expression::Block(vec![]),
// TODO: WIP
// ast::Expression::Block(vec![]),
HirExpression::Literal(HirLiteral::Unit) => ast::Expression::Tuple(vec![]),
HirExpression::Block(block) => self.block(block.statements)?,
HirExpression::Unsafe(block) => self.block(block.statements)?,

Expand Down Expand Up @@ -1327,7 +1329,9 @@ impl<'interner> Monomorphizer<'interner> {
Box::new(Self::convert_type_helper(fields.as_ref(), location, seen_types)?);
ast::Type::FmtString(size, fields)
}
HirType::Unit => ast::Type::Unit,
// TODO: WIP
// ast::Type::Unit,
HirType::Unit => ast::Type::Tuple(vec![]),
HirType::Array(length, element) => {
let element =
Box::new(Self::convert_type_helper(element.as_ref(), location, seen_types)?);
Expand Down Expand Up @@ -1463,7 +1467,8 @@ impl<'interner> Monomorphizer<'interner> {
let make_function = |is_unconstrained, args, ret, env| {
use ast::Type::*;
match &env {
Unit => Function(args, ret, Box::new(env), is_unconstrained),
// TODO: WIP
// Unit => Function(args, ret, Box::new(env), is_unconstrained),
Tuple(_) => Tuple(vec![
env.clone(),
Function(args, ret, Box::new(env), is_unconstrained),
Expand Down Expand Up @@ -2096,7 +2101,7 @@ impl<'interner> Monomorphizer<'interner> {
let typ = ast::Type::Function(
parameter_types,
Box::new(ret_type),
Box::new(ast::Type::Unit),
Box::new(ast::Type::Tuple(vec![])),
false,
);

Expand Down Expand Up @@ -2336,7 +2341,8 @@ impl<'interner> Monomorphizer<'interner> {
ast::Expression::Literal(ast::Literal::Integer(zero, typ, location))
}
ast::Type::Bool => ast::Expression::Literal(ast::Literal::Bool(false)),
ast::Type::Unit => ast::Expression::Literal(ast::Literal::Unit),
// TODO: WIP
// ast::Type::Unit => ast::Expression::Literal(ast::Expression::Tuple(vec![])),
ast::Type::Array(length, element_type) => {
let element = self.zeroed_value_of_type(element_type.as_ref(), location);
ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral {
Expand Down Expand Up @@ -2559,10 +2565,12 @@ impl<'interner> Monomorphizer<'interner> {
}
}

// TODO: WIP
fn unwrap_tuple_type(typ: &HirType) -> Vec<HirType> {
match typ.follow_bindings() {
HirType::Tuple(fields) => fields.clone(),
other => unreachable!("unwrap_tuple_type: expected tuple, found {:?}", other),
HirType::Unit => vec![],
other => unreachable!("unwrap_tuple_type: expected tuple or unit, found {:?}", other),
}
}

Expand Down
7 changes: 4 additions & 3 deletions compiler/noirc_frontend/src/monomorphization/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,10 @@ impl AstPrinter {
}
write!(f, "\"")
}
Literal::Unit => {
write!(f, "()")
}
// TODO: WIP
// Literal::Unit => {
// write!(f, "()")
// }
}
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/noirc_frontend/src/ownership/last_uses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,9 @@ impl LastUseContext {

fn track_variables_in_literal(&mut self, literal: &Literal) {
match literal {
Literal::Integer(..) | Literal::Bool(_) | Literal::Unit | Literal::Str(_) => (),
// TODO: WIP
// Literal::Integer(..) | Literal::Bool(_) | Literal::Unit | Literal::Str(_) => (),
Literal::Integer(..) | Literal::Bool(_) | Literal::Str(_) => (),

Literal::FmtStr(_, _, captures) => self.track_variables_in_expression(captures),

Expand Down
15 changes: 11 additions & 4 deletions compiler/noirc_frontend/src/ownership/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,9 @@ impl Context {

fn handle_literal(&mut self, literal: &mut Literal) {
match literal {
Literal::Integer(..) | Literal::Bool(_) | Literal::Unit | Literal::Str(_) => (),
// TODO: WIP
// Literal::Integer(..) | Literal::Bool(_) | Literal::Unit | Literal::Str(_) => (),
Literal::Integer(..) | Literal::Bool(_) | Literal::Str(_) => (),

Literal::FmtStr(_, _, captures) => self.handle_expression(captures),

Expand Down Expand Up @@ -347,7 +349,9 @@ impl Context {
if name == "array_len" {
if let Some(Expression::Clone(array)) = call.arguments.get_mut(0) {
let array =
std::mem::replace(array.as_mut(), Expression::Literal(Literal::Unit));
// TODO: WIP
// std::mem::replace(array.as_mut(), Expression::Literal(Literal::Unit));
std::mem::replace(array.as_mut(), Expression::Tuple(vec![]));
call.arguments[0] = array;
}
}
Expand Down Expand Up @@ -417,7 +421,9 @@ fn contains_index(lvalue: &LValue) -> bool {
/// Note that this method should be careful not to actually duplicate the given expression
/// so that we do not duplicate any side-effects.
fn clone_expr(expr: &mut Expression) {
let unit = Expression::Literal(Literal::Unit);
// TODO: WIP
// let unit = Expression::Literal(Literal::Unit);
let unit = Expression::Tuple(vec![]);
let old_expr = std::mem::replace(expr, unit);
*expr = Expression::Clone(Box::new(old_expr));
}
Expand All @@ -427,7 +433,8 @@ fn contains_array_or_str_type(typ: &Type) -> bool {
Type::Field
| Type::Integer(..)
| Type::Bool
| Type::Unit
// TODO: WIP
// | Type::Unit
| Type::Function(..)
| Type::Reference(..) => false,

Expand Down
24 changes: 24 additions & 0 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4535,3 +4535,27 @@ fn disallows_references_in_globals() {
"#;
check_errors!(src);
}

#[test]
fn TODO_rename_unit_match() {
let src = r#"
fn foo(x: ()) {
let (): () = x;
}

fn main() {
foo(())
}
"#;
assert_no_errors!(src);
}

#[test]
fn regression_9729() {
let src = r#"
fn main() {
let _: fmtstr<5, ()> = f"Hello";
}
"#;
assert_no_errors!(src);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "regression_9729"
type = "bin"
authors = [""]

[dependencies]
13 changes: 13 additions & 0 deletions test_programs/compile_success_no_bug/regression_9729/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fn foo(x: ()) {
let (): () = x;
}

unconstrained fn bar(x: ()) {
let (): () = x;
}

fn main() {
foo(());
unsafe { bar(()) };
let _: fmtstr<5, ()> = f"Hello";
}
9 changes: 6 additions & 3 deletions tooling/ast_fuzzer/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ pub fn program_abi(program: &Program) -> Abi {
.collect();

let return_type = match &main.return_type {
Type::Unit => None,
// TODO: WIP
// Type::Unit => None,
typ => Some(AbiReturnType {
abi_type: to_abi_type(typ),
visibility: to_abi_visibility(&program.return_visibility()),
Expand All @@ -34,8 +35,10 @@ pub fn program_abi(program: &Program) -> Abi {
/// Check if a type is valid as an ABI parameter for the `main` function.
fn is_valid_in_abi(typ: &Type) -> bool {
match typ {
Type::Unit
| Type::FmtString(_, _)
// TODO: WIP
// Type::Unit
// | Type::FmtString(_, _)
Type::FmtString(_, _)
| Type::Slice(_)
| Type::Reference(_, _)
| Type::Function(_, _, _, _) => false,
Expand Down
Loading
Loading