diff --git a/fine/build.rs b/fine/build.rs index 5994df62..2c73bc92 100644 --- a/fine/build.rs +++ b/fine/build.rs @@ -87,11 +87,6 @@ fn generate_test_for_file(path: PathBuf) -> String { assertions.push(quote! { crate::assert_eval_ok(&_tree, &_lines, #expected); }); - } else if let Some(line) = line.strip_prefix("@check-error:") { - let expected = line.trim(); - assertions.push(quote! { - crate::assert_check_error(&_tree, &_lines, #expected); - }); } else if line.starts_with("@") { panic!("Test file {display_path} has unknown directive: {line}"); } diff --git a/fine/src/semantics.rs b/fine/src/semantics.rs index cde5954c..a3c893ef 100644 --- a/fine/src/semantics.rs +++ b/fine/src/semantics.rs @@ -657,13 +657,17 @@ impl<'a> Semantics<'a> { TreeKind::Identifier => self.type_of_identifier(t, tree), TreeKind::FunctionDecl => self.type_of_function_decl(tree), - TreeKind::ReturnType => self.type_of_return_type(tree), _ => self.internal_compiler_error(Some(t), "asking for a nonsense type"), }; // NOTE: These return `None` if they encounter some problem. let result = result.unwrap_or(Type::Error); + + if result.is_error() { + eprintln!("OH NO AN ERROR AT {}: {:?}", t.index(), tree); + } + self.types.borrow_mut()[t.index()] = Incremental::Complete(result.clone()); result } @@ -1017,11 +1021,6 @@ impl<'a> Semantics<'a> { Some(Type::Function(parameter_types, return_type)) } - fn type_of_return_type(&self, tree: &Tree) -> Option { - assert_eq!(tree.kind, TreeKind::ReturnType); - Some(self.type_of(tree.nth_tree(1)?)) // type expression - } - fn type_of_if_statement(&self, tree: &Tree) -> Option { Some(self.type_of(tree.nth_tree(0)?)) } @@ -1102,7 +1101,9 @@ pub fn check(s: &Semantics) { match tree.kind { TreeKind::Error => {} // already reported TreeKind::File => {} - TreeKind::FunctionDecl => check_function_decl(s, t, tree), + TreeKind::FunctionDecl => { + let _ = s.environment_of(t); + } TreeKind::ParamList => {} TreeKind::Parameter => {} TreeKind::TypeExpression => { @@ -1137,38 +1138,6 @@ pub fn check(s: &Semantics) { } } -fn check_function_decl(s: &Semantics, t: TreeRef, tree: &Tree) { - assert_eq!(tree.kind, TreeKind::FunctionDecl); - let _ = s.environment_of(t); - - let return_type_tree = tree.child_of_kind(s.syntax_tree, TreeKind::ReturnType); - let return_type = return_type_tree - .map(|t| s.type_of(t)) - .unwrap_or(Type::Nothing); - - if let Some(body) = tree.child_of_kind(s.syntax_tree, TreeKind::Block) { - let body_type = s.type_of(body); - if !body_type.compatible_with(&return_type) { - // Just work very hard to get an appropriate error span. - let (start, end) = return_type_tree - .map(|t| { - let rtt = &s.syntax_tree[t]; - (rtt.start_pos, rtt.end_pos) - }) - .unwrap_or_else(|| { - let start = tree.start_pos; - let end_tok = tree - .nth_token(1) - .unwrap_or_else(|| tree.nth_token(0).unwrap()); - let end_pos = end_tok.start + end_tok.as_str().len(); - (start, end_pos) - }); - - s.report_error_span(start, end, format!("the body of this function yields a value of type `{body_type}`, but callers expect this function to produce a `{return_type}`")); - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/fine/tests/example_tests.rs b/fine/tests/example_tests.rs index 5c5230a2..c544f262 100644 --- a/fine/tests/example_tests.rs +++ b/fine/tests/example_tests.rs @@ -259,6 +259,7 @@ fn assert_no_errors(tree: &SyntaxTree, lines: &Lines) { ); } +#[allow(dead_code)] fn assert_eval_ok(tree: &SyntaxTree, lines: &Lines, expected: &str) { let semantics = Semantics::new(tree, lines); @@ -283,17 +284,4 @@ fn assert_eval_ok(tree: &SyntaxTree, lines: &Lines, expected: &str) { } } -fn assert_check_error(tree: &SyntaxTree, lines: &Lines, expected: &str) { - let semantics = Semantics::new(tree, lines); - check(&semantics); - - let errors = semantics.snapshot_errors(); - semantic_assert!( - &semantics, - None, - errors.iter().any(|e| e.message == expected), - "Unable to find the expected error message '{expected}'" - ); -} - include!(concat!(env!("OUT_DIR"), "/generated_tests.rs")); diff --git a/fine/tests/expression/argument.fine b/fine/tests/expression/argument.fine index 78f9d5c7..2b6d9fd2 100644 --- a/fine/tests/expression/argument.fine +++ b/fine/tests/expression/argument.fine @@ -1,8 +1,8 @@ -fun foo(x: f64) -> f64 { +fun foo(x: f64) { x + 7 } -fun test() -> f64 { +fun test() { foo(1) } @@ -22,10 +22,6 @@ fun test() -> f64 { // | TypeExpression // | Identifier:'"f64"' // | RightParen:'")"' -// | ReturnType -// | Arrow:'"->"' -// | TypeExpression -// | Identifier:'"f64"' // | Block // | LeftBrace:'"{"' // | ExpressionStatement @@ -42,10 +38,6 @@ fun test() -> f64 { // | ParamList // | LeftParen:'"("' // | RightParen:'")"' -// | ReturnType -// | Arrow:'"->"' -// | TypeExpression -// | Identifier:'"f64"' // | Block // | LeftBrace:'"{"' // | ExpressionStatement diff --git a/fine/tests/expression/arithmetic.fine b/fine/tests/expression/arithmetic.fine index 700ac5e8..bbe46cbf 100644 --- a/fine/tests/expression/arithmetic.fine +++ b/fine/tests/expression/arithmetic.fine @@ -1,4 +1,4 @@ -fun test() -> f64 { +fun test() { 1 * 2 + -3 * 4 } @@ -13,10 +13,6 @@ fun test() -> f64 { // | ParamList // | LeftParen:'"("' // | RightParen:'")"' -// | ReturnType -// | Arrow:'"->"' -// | TypeExpression -// | Identifier:'"f64"' // | Block // | LeftBrace:'"{"' // | ExpressionStatement diff --git a/fine/tests/expression/boolean.fine b/fine/tests/expression/boolean.fine index 3c95008f..60280dbf 100644 --- a/fine/tests/expression/boolean.fine +++ b/fine/tests/expression/boolean.fine @@ -1,4 +1,4 @@ -fun test() -> bool { +fun test() { true and false or false and !true } @@ -38,10 +38,6 @@ fun test() -> bool { // | ParamList // | LeftParen:'"("' // | RightParen:'")"' -// | ReturnType -// | Arrow:'"->"' -// | TypeExpression -// | Identifier:'"bool"' // | Block // | LeftBrace:'"{"' // | ExpressionStatement diff --git a/fine/tests/expression/conditional.fine b/fine/tests/expression/conditional.fine index 128f0fb3..a7ed78fc 100644 --- a/fine/tests/expression/conditional.fine +++ b/fine/tests/expression/conditional.fine @@ -1,22 +1,22 @@ -fun test() -> f64 { +fun test() { if true { "discarded"; 23 } else { 45 } } // @no-errors // Here come some type probes! // (type of the condition) -// @type: 27 bool +// @type: 20 bool // // (the discarded expression) -// @type: 34 string +// @type: 27 string // // (the "then" clause) -// @type: 47 f64 -// @type: 50 f64 +// @type: 40 f64 +// @type: 43 f64 // // (the "else" clause) -// @type: 59 f64 -// @type: 62 f64 +// @type: 52 f64 +// @type: 55 f64 // // @concrete: // | File @@ -26,10 +26,6 @@ fun test() -> f64 { // | ParamList // | LeftParen:'"("' // | RightParen:'")"' -// | ReturnType -// | Arrow:'"->"' -// | TypeExpression -// | Identifier:'"f64"' // | Block // | LeftBrace:'"{"' // | IfStatement diff --git a/fine/tests/expression/errors/return_type_mismatch.fine b/fine/tests/expression/errors/return_type_mismatch.fine deleted file mode 100644 index 26dfdca7..00000000 --- a/fine/tests/expression/errors/return_type_mismatch.fine +++ /dev/null @@ -1,5 +0,0 @@ -fun test() -> bool { - 32 -} - -// @check-error: the body of this function yields a value of type `f64`, but callers expect this function to produce a `bool` \ No newline at end of file