Skip to content

Commit

Permalink
Merge pull request #122 from lambdaclass/add_fncall_checks
Browse files Browse the repository at this point in the history
add function call type checks
  • Loading branch information
edg-l authored May 10, 2024
2 parents dc95fdd + e5692d0 commit 56a8221
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 14 deletions.
44 changes: 32 additions & 12 deletions crates/concrete_check/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub fn lowering_error_to_report(
program_id,
} => {
let offset = span.from;
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("ModuleNotFound")
.with_label(
Expand All @@ -33,7 +33,7 @@ pub fn lowering_error_to_report(
function,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("FunctionNotFound")
.with_label(
Expand All @@ -48,7 +48,7 @@ pub fn lowering_error_to_report(
name,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("StructFieldNotFound")
.with_label(
Expand All @@ -64,7 +64,7 @@ pub fn lowering_error_to_report(
symbol,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
let offset = symbol.span.from;
Report::build(ReportKind::Error, path.clone(), offset)
.with_code("ImportNotFound")
Expand All @@ -90,7 +90,7 @@ pub fn lowering_error_to_report(
type_span,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
let mut labels = vec![Label::new((path.clone(), span.into()))
.with_message(format!(
"Can't mutate {name:?} because it's behind a immutable borrow"
Expand All @@ -115,7 +115,7 @@ pub fn lowering_error_to_report(
name,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("UnrecognizedType")
.with_label(
Expand All @@ -131,7 +131,7 @@ pub fn lowering_error_to_report(
id,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("E_ID")
.with_label(
Expand All @@ -147,7 +147,7 @@ pub fn lowering_error_to_report(
message,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("NotYetImplemented")
.with_label(
Expand All @@ -163,7 +163,7 @@ pub fn lowering_error_to_report(
expected,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
let mut labels = vec![Label::new((path.clone(), span.into()))
.with_message(format!(
"Unexpected type '{}', expected '{}'",
Expand All @@ -190,7 +190,7 @@ pub fn lowering_error_to_report(
name,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("UseOfUndeclaredVariable")
.with_label(
Expand All @@ -205,7 +205,7 @@ pub fn lowering_error_to_report(
name,
program_id,
} => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("ExternFnWithBody")
.with_label(
Expand All @@ -216,12 +216,32 @@ pub fn lowering_error_to_report(
.finish()
}
LoweringError::InternalError(msg, program_id) => {
let path = file_paths[program_id].to_str().unwrap().to_string();
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), 0)
.with_code("InternalError")
.with_message(msg)
.finish()
}
LoweringError::CallParamCountMismatch {
span,
found,
needs,
program_id,
} => {
let path = file_paths[program_id].display().to_string();
Report::build(ReportKind::Error, path.clone(), span.from)
.with_code("CallParamCountMismatch")
.with_label(
Label::new((path, span.into()))
.with_message(format!(
"function call parameter count mismatch: found {}, needs {}.",
found, needs
))
.with_color(colors.next()),
)
.finish()
}

LoweringError::NotMutable {
span,
declare_span,
Expand Down
33 changes: 33 additions & 0 deletions crates/concrete_driver/tests/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,39 @@ fn undeclared_var() {
);
}

#[test]
fn call_param_count_mismatch() {
let (source, name) = (
include_str!("invalid_programs/call_param_count_mismatch.con"),
"call_param_count_mismatch",
);
let error = check_invalid_program(source, name);

assert!(
matches!(
&error,
LoweringError::CallParamCountMismatch { found, needs, .. } if *found == 2 && *needs == 1
),
"{:#?}",
error
);
}

#[test]
fn call_param_type_mismatch() {
let (source, name) = (
include_str!("invalid_programs/call_param_type_mismatch.con"),
"call_param_type_mismatch",
);
let error = check_invalid_program(source, name);

assert!(
matches!(&error, LoweringError::UnexpectedType { .. }),
"{:#?}",
error
);
}

#[test]
fn invalid_assign() {
let (source, name) = (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod Test {
fn main() -> i32 {
return hello(1, 2);
}

fn hello(a: i32) -> i32 {
return a * 2;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
mod Test {
fn main() -> i32 {
let x: u32 = 1;
return hello(x);
}

fn hello(a: i32) -> i32 {
return a * 2;
}
}
23 changes: 21 additions & 2 deletions crates/concrete_ir/src/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,11 +1223,30 @@ fn lower_fn_call(
}
};

if args_ty.len() != info.args.len() {
return Err(LoweringError::CallParamCountMismatch {
span: info.span,
found: info.args.len(),
needs: args_ty.len(),
program_id: builder.get_module_body().id.program_id,
});
}

let mut args = Vec::new();

for (arg, arg_ty) in info.args.iter().zip(args_ty) {
let rvalue = lower_expression(builder, arg, Some(arg_ty.clone()))?;
args.push(rvalue.0);
let (rvalue, rvalue_ty, arg_span) = lower_expression(builder, arg, Some(arg_ty.clone()))?;

if rvalue_ty.kind != arg_ty.kind {
return Err(LoweringError::UnexpectedType {
span: arg_span,
found: rvalue_ty,
expected: arg_ty,
program_id: builder.get_module_body().id.program_id,
});
}

args.push(rvalue);
}

let dest_local = builder.add_local(Local::temp(ret_ty.clone()));
Expand Down
7 changes: 7 additions & 0 deletions crates/concrete_ir/src/lowering/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,11 @@ pub enum LoweringError {
},
#[error("internal error: {0}")]
InternalError(String, usize),
#[error("function call parameter count mismatch, found {found}, needs {needs}")]
CallParamCountMismatch {
span: Span,
found: usize,
needs: usize,
program_id: usize,
},
}

0 comments on commit 56a8221

Please sign in to comment.