diff --git a/src/asg/expr/conditional.rs b/src/asg/expr/conditional.rs index bf736df..f6b0f0a 100644 --- a/src/asg/expr/conditional.rs +++ b/src/asg/expr/conditional.rs @@ -3,7 +3,7 @@ use crate::asg::{Block, Type}; #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct Conditional { - pub result_type: Type, + pub result_type: Option, pub branches: Vec, pub otherwise: Option, } diff --git a/src/lower/expr/mod.rs b/src/lower/expr/mod.rs index e168300..10ef44e 100644 --- a/src/lower/expr/mod.rs +++ b/src/lower/expr/mod.rs @@ -421,9 +421,12 @@ pub fn lower_expr( builder.use_block(resume_basicblock_id); if conditional.otherwise.is_some() { - let ir_type = - lower_type(ir_module, &builder.unpoly(&conditional.result_type)?, asg)?; - Ok(builder.push(ir::Instr::Phi(ir::Phi { ir_type, incoming }))) + if let Some(result_type) = &conditional.result_type { + let ir_type = lower_type(ir_module, &builder.unpoly(result_type)?, asg)?; + Ok(builder.push(ir::Instr::Phi(ir::Phi { ir_type, incoming }))) + } else { + Ok(Value::Literal(Literal::Void)) + } } else { Ok(Value::Literal(Literal::Void)) } diff --git a/src/resolve/expr/array_access.rs b/src/resolve/expr/array_access.rs index d1b854b..d1972dc 100644 --- a/src/resolve/expr/array_access.rs +++ b/src/resolve/expr/array_access.rs @@ -1,4 +1,4 @@ -use super::{resolve_expr, PreferredType, ResolveExprCtx}; +use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode}; use crate::{ asg::{self, TypedExpr}, ast, @@ -23,7 +23,8 @@ pub fn resolve_array_access_expr( ctx, &array_access.subject, None, - crate::resolve::Initialized::Require, + Initialized::Require, + ResolveExprMode::RequireValue, )?, c_integer_assumptions, )?; @@ -36,6 +37,7 @@ pub fn resolve_array_access_expr( &asg::TypeKind::Integer(IntegerBits::Bits64, IntegerSign::Unsigned).at(source), )), Initialized::Require, + ResolveExprMode::RequireValue, )?, c_integer_assumptions, )?; diff --git a/src/resolve/expr/basic_binary_operation.rs b/src/resolve/expr/basic_binary_operation.rs index d8bff33..066f0ce 100644 --- a/src/resolve/expr/basic_binary_operation.rs +++ b/src/resolve/expr/basic_binary_operation.rs @@ -1,15 +1,15 @@ -use super::{resolve_expr, PreferredType, ResolveExprCtx}; +use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode}; use crate::{ + asg::{ + self, Constraint, FloatOrInteger, FloatOrSignLax, NumericMode, SignOrIndeterminate, + TypedExpr, + }, ast, resolve::{ error::{ResolveError, ResolveErrorKind}, unify_types::unify_types, Initialized, }, - asg::{ - self, Constraint, FloatOrInteger, FloatOrSignLax, NumericMode, SignOrIndeterminate, - TypedExpr, - }, source_files::Source, }; use ast::IntegerSign; @@ -27,6 +27,7 @@ pub fn resolve_basic_binary_operation_expr( &binary_operation.left, preferred_type, Initialized::Require, + ResolveExprMode::RequireValue, )?; let mut right = resolve_expr( @@ -34,6 +35,7 @@ pub fn resolve_basic_binary_operation_expr( &binary_operation.right, preferred_type, Initialized::Require, + ResolveExprMode::RequireValue, )?; if let asg::TypeKind::IntegerLiteral(left) = &left.ty.kind { @@ -105,51 +107,54 @@ pub fn resolve_basic_binary_operator( ast::BasicBinaryOperator::Multiply => { NumericMode::try_new(ty).map(asg::BasicBinaryOperator::Multiply) } - ast::BasicBinaryOperator::Divide => float_or_sign_lax_from_type(ty, false) - .map(asg::BasicBinaryOperator::Divide), - ast::BasicBinaryOperator::Modulus => float_or_sign_lax_from_type(ty, false) - .map(asg::BasicBinaryOperator::Modulus), - ast::BasicBinaryOperator::Equals => float_or_integer_from_type(ty, true) - .map(asg::BasicBinaryOperator::Equals), - ast::BasicBinaryOperator::NotEquals => float_or_integer_from_type(ty, true) - .map(asg::BasicBinaryOperator::NotEquals), - ast::BasicBinaryOperator::LessThan => float_or_sign_lax_from_type(ty, false) - .map(asg::BasicBinaryOperator::LessThan), - ast::BasicBinaryOperator::LessThanEq => float_or_sign_lax_from_type(ty, false) - .map(asg::BasicBinaryOperator::LessThanEq), - ast::BasicBinaryOperator::GreaterThan => float_or_sign_lax_from_type(ty, false) - .map(asg::BasicBinaryOperator::GreaterThan), + ast::BasicBinaryOperator::Divide => { + float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::Divide) + } + ast::BasicBinaryOperator::Modulus => { + float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::Modulus) + } + ast::BasicBinaryOperator::Equals => { + float_or_integer_from_type(ty, true).map(asg::BasicBinaryOperator::Equals) + } + ast::BasicBinaryOperator::NotEquals => { + float_or_integer_from_type(ty, true).map(asg::BasicBinaryOperator::NotEquals) + } + ast::BasicBinaryOperator::LessThan => { + float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::LessThan) + } + ast::BasicBinaryOperator::LessThanEq => { + float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::LessThanEq) + } + ast::BasicBinaryOperator::GreaterThan => { + float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::GreaterThan) + } ast::BasicBinaryOperator::GreaterThanEq => { - float_or_sign_lax_from_type(ty, false) - .map(asg::BasicBinaryOperator::GreaterThanEq) + float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::GreaterThanEq) } - ast::BasicBinaryOperator::BitwiseAnd => (ty.kind.is_integer() - || ty.kind.is_c_integer() - || ty.kind.is_boolean()) - .then_some(asg::BasicBinaryOperator::BitwiseAnd), - ast::BasicBinaryOperator::BitwiseOr => (ty.kind.is_integer() - || ty.kind.is_c_integer() - || ty.kind.is_boolean()) - .then_some(asg::BasicBinaryOperator::BitwiseOr), - ast::BasicBinaryOperator::BitwiseXor => (ty.kind.is_integer() - || ty.kind.is_c_integer()) - .then_some(asg::BasicBinaryOperator::BitwiseXor), + ast::BasicBinaryOperator::BitwiseAnd => { + (ty.kind.is_integer() || ty.kind.is_c_integer() || ty.kind.is_boolean()) + .then_some(asg::BasicBinaryOperator::BitwiseAnd) + } + ast::BasicBinaryOperator::BitwiseOr => { + (ty.kind.is_integer() || ty.kind.is_c_integer() || ty.kind.is_boolean()) + .then_some(asg::BasicBinaryOperator::BitwiseOr) + } + ast::BasicBinaryOperator::BitwiseXor => (ty.kind.is_integer() || ty.kind.is_c_integer()) + .then_some(asg::BasicBinaryOperator::BitwiseXor), ast::BasicBinaryOperator::LeftShift | ast::BasicBinaryOperator::LogicalLeftShift => { (ty.kind.is_integer() || ty.kind.is_c_integer()) .then_some(asg::BasicBinaryOperator::LogicalLeftShift) } ast::BasicBinaryOperator::RightShift => match ty.kind { - asg::TypeKind::Integer(_, sign) => { - Some(asg::BasicBinaryOperator::ArithmeticRightShift( - SignOrIndeterminate::Sign(sign), - )) - } + asg::TypeKind::Integer(_, sign) => Some( + asg::BasicBinaryOperator::ArithmeticRightShift(SignOrIndeterminate::Sign(sign)), + ), asg::TypeKind::CInteger(c_integer, sign) => Some(if let Some(sign) = sign { asg::BasicBinaryOperator::ArithmeticRightShift(SignOrIndeterminate::Sign(sign)) } else { - asg::BasicBinaryOperator::ArithmeticRightShift( - SignOrIndeterminate::Indeterminate(c_integer), - ) + asg::BasicBinaryOperator::ArithmeticRightShift(SignOrIndeterminate::Indeterminate( + c_integer, + )) }), _ => None, }, @@ -173,9 +178,7 @@ fn float_or_integer_from_type( ) -> Option { match &unified_type.kind { asg::TypeKind::Boolean if allow_on_bools => Some(FloatOrInteger::Integer), - asg::TypeKind::Integer(..) | asg::TypeKind::CInteger(..) => { - Some(FloatOrInteger::Integer) - } + asg::TypeKind::Integer(..) | asg::TypeKind::CInteger(..) => Some(FloatOrInteger::Integer), asg::TypeKind::Floating(_) => Some(FloatOrInteger::Float), _ => None, } diff --git a/src/resolve/expr/call.rs b/src/resolve/expr/call.rs index 88c36bb..8521e1d 100644 --- a/src/resolve/expr/call.rs +++ b/src/resolve/expr/call.rs @@ -1,4 +1,4 @@ -use super::{resolve_expr, PreferredType, ResolveExprCtx}; +use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode}; use crate::{ asg::{self, Callee, Cast, CastFrom, TypedExpr}, ast::{self, CInteger, FloatSize}, @@ -28,7 +28,13 @@ pub fn resolve_call_expr( let mut args = Vec::with_capacity(call.args.len()); for arg in call.args.iter() { - args.push(resolve_expr(ctx, arg, None, Initialized::Require)?); + args.push(resolve_expr( + ctx, + arg, + None, + Initialized::Require, + ResolveExprMode::RequireValue, + )?); } let args = match cast(ctx, call, args, source)? { diff --git a/src/resolve/expr/conditional.rs b/src/resolve/expr/conditional.rs index 817ec5c..9d86a61 100644 --- a/src/resolve/expr/conditional.rs +++ b/src/resolve/expr/conditional.rs @@ -1,5 +1,6 @@ -use super::{resolve_expr, PreferredType, ResolveExprCtx}; +use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode}; use crate::{ + asg::{self, Branch, TypedExpr}, ast, resolve::{ conform::{conform_expr_or_error, ConformMode}, @@ -8,7 +9,6 @@ use crate::{ unify_types::unify_types, Initialized, }, - asg::{self, Branch, TypedExpr}, source_files::Source, }; use itertools::Itertools; @@ -17,6 +17,7 @@ pub fn resolve_conditional_expr( ctx: &mut ResolveExprCtx<'_, '_>, conditional: &ast::Conditional, preferred_type: Option, + mode: ResolveExprMode, source: Source, ) -> Result { let ast::Conditional { @@ -28,9 +29,15 @@ pub fn resolve_conditional_expr( for (expr, block) in conditions.iter() { ctx.variable_haystack.begin_scope(); - let condition = resolve_expr(ctx, expr, preferred_type, Initialized::Require)?; + let condition = resolve_expr( + ctx, + expr, + preferred_type, + Initialized::Require, + ResolveExprMode::RequireValue, + )?; - let stmts = resolve_stmts(ctx, &block.stmts)?; + let stmts = resolve_stmts(ctx, &block.stmts, mode)?; let condition = conform_expr_or_error( ctx, @@ -53,7 +60,7 @@ pub fn resolve_conditional_expr( .as_ref() .map(|otherwise| { ctx.variable_haystack.begin_scope(); - let maybe_block = resolve_stmts(ctx, &otherwise.stmts).map(asg::Block::new); + let maybe_block = resolve_stmts(ctx, &otherwise.stmts, mode).map(asg::Block::new); ctx.variable_haystack.end_scope(); maybe_block }) @@ -66,23 +73,27 @@ pub fn resolve_conditional_expr( .map(|block| block.get_result_type(source)) .collect_vec(); - let result_type = if block_results + let result_type: Option = if mode == ResolveExprMode::NeglectValue { + None + } else if block_results .iter() .any(|result| result.kind == asg::TypeKind::Void) { - block_results - .iter() - .all_equal() - .then_some(asg::TypeKind::Void.at(source)) - .ok_or_else(|| { - ResolveErrorKind::MismatchingYieldedTypes { - got: block_results - .iter() - .map(|ty| ty.kind.to_string()) - .collect_vec(), - } - .at(source) - }) + Some( + block_results + .iter() + .all_equal() + .then_some(asg::TypeKind::Void.at(source)) + .ok_or_else(|| { + ResolveErrorKind::MismatchingYieldedTypes { + got: block_results + .iter() + .map(|ty| ty.kind.to_string()) + .collect_vec(), + } + .at(source) + })?, + ) } else { let mut last_exprs = branches_without_else .chunks_exact_mut(1) @@ -110,6 +121,7 @@ pub fn resolve_conditional_expr( ctx.adept_conform_behavior(), source, ) + .map(Some) .ok_or_else(|| { ResolveErrorKind::MismatchingYieldedTypes { got: block_results @@ -118,8 +130,8 @@ pub fn resolve_conditional_expr( .collect_vec(), } .at(source) - }) - }?; + })? + }; let expr = asg::Expr::new( asg::ExprKind::Conditional(Box::new(asg::Conditional { @@ -130,5 +142,8 @@ pub fn resolve_conditional_expr( source, ); - Ok(TypedExpr::new(result_type, expr)) + Ok(TypedExpr::new( + result_type.unwrap_or_else(|| asg::TypeKind::Void.at(source)), + expr, + )) } diff --git a/src/resolve/expr/declare_assign.rs b/src/resolve/expr/declare_assign.rs index ff5f400..1f5533e 100644 --- a/src/resolve/expr/declare_assign.rs +++ b/src/resolve/expr/declare_assign.rs @@ -1,4 +1,4 @@ -use super::{resolve_expr, ResolveExprCtx}; +use super::{resolve_expr, ResolveExprCtx, ResolveExprMode}; use crate::{ asg::{self, TypedExpr}, ast::{self}, @@ -18,7 +18,13 @@ pub fn resolve_declare_assign_expr( let c_integer_assumptions = ctx.c_integer_assumptions(); let value = conform_expr_to_default_or_error( - resolve_expr(ctx, &declare_assign.value, None, Initialized::Require)?, + resolve_expr( + ctx, + &declare_assign.value, + None, + Initialized::Require, + ResolveExprMode::RequireValue, + )?, c_integer_assumptions, )?; diff --git a/src/resolve/expr/member_expr.rs b/src/resolve/expr/member_expr.rs index d61003a..3f8b8c1 100644 --- a/src/resolve/expr/member_expr.rs +++ b/src/resolve/expr/member_expr.rs @@ -6,6 +6,7 @@ use crate::{ core_struct_info::{get_core_struct_info, CoreStructInfo}, destination::resolve_expr_to_destination, error::{ResolveError, ResolveErrorKind}, + expr::ResolveExprMode, Initialized, PolyCatalog, }, source_files::Source, @@ -18,7 +19,13 @@ pub fn resolve_member_expr( min_privacy: Privacy, source: Source, ) -> Result { - let resolved_subject = resolve_expr(ctx, subject, None, Initialized::Require)?; + let resolved_subject = resolve_expr( + ctx, + subject, + None, + Initialized::Require, + ResolveExprMode::RequireValue, + )?; let CoreStructInfo { struct_ref, diff --git a/src/resolve/expr/mod.rs b/src/resolve/expr/mod.rs index 1a32d56..84ab977 100644 --- a/src/resolve/expr/mod.rs +++ b/src/resolve/expr/mod.rs @@ -84,6 +84,12 @@ impl<'a, 'b> ResolveExprCtx<'a, 'b> { } } +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ResolveExprMode { + RequireValue, + NeglectValue, +} + #[derive(Copy, Clone, Debug)] pub enum PreferredType<'a> { Reference(&'a asg::Type), @@ -135,6 +141,7 @@ pub fn resolve_expr( ast_expr: &ast::Expr, preferred_type: Option, initialized: Initialized, + mode: ResolveExprMode, ) -> Result { let source = ast_expr.source; @@ -276,6 +283,7 @@ pub fn resolve_expr( &unary_operation.inner, preferred_type, Initialized::Require, + ResolveExprMode::RequireValue, )?; let result_type = resolved_expr.ty.clone().pointer(source); let destination = resolve_expr_to_destination(resolved_expr)?; @@ -288,6 +296,7 @@ pub fn resolve_expr( &unary_operation.inner, preferred_type, Initialized::Require, + ResolveExprMode::RequireValue, )?; let result_type = match &resolved_expr.ty.kind { @@ -310,7 +319,7 @@ pub fn resolve_expr( } }, ast::ExprKind::Conditional(conditional) => { - resolve_conditional_expr(ctx, conditional, preferred_type, source) + resolve_conditional_expr(ctx, conditional, preferred_type, mode, source) } ast::ExprKind::While(while_loop) => { ctx.variable_haystack.begin_scope(); @@ -320,6 +329,7 @@ pub fn resolve_expr( &while_loop.condition, Some(PreferredType::of(&asg::TypeKind::Boolean.at(source))), Initialized::Require, + ResolveExprMode::RequireValue, )?; let condition = conform_expr_or_error( @@ -332,7 +342,11 @@ pub fn resolve_expr( )? .expr; - let block = asg::Block::new(resolve_stmts(ctx, &while_loop.block.stmts)?); + let block = asg::Block::new(resolve_stmts( + ctx, + &while_loop.block.stmts, + ResolveExprMode::NeglectValue, + )?); ctx.variable_haystack.end_scope(); Ok(TypedExpr::new( @@ -369,6 +383,7 @@ pub fn resolve_expr( arg, Some(PreferredType::Reference(&preferred_type)), Initialized::Require, + ResolveExprMode::RequireValue, )? .expr, ); diff --git a/src/resolve/expr/short_circuiting_binary_operation.rs b/src/resolve/expr/short_circuiting_binary_operation.rs index 0b0d4ef..d8fa1b5 100644 --- a/src/resolve/expr/short_circuiting_binary_operation.rs +++ b/src/resolve/expr/short_circuiting_binary_operation.rs @@ -1,12 +1,12 @@ -use super::{resolve_expr, PreferredType, ResolveExprCtx}; +use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode}; use crate::{ + asg::{self, TypedExpr}, ast, resolve::{ conform::{conform_expr, ConformMode, Perform}, error::{ResolveError, ResolveErrorKind}, Initialized, }, - asg::{self, TypedExpr}, source_files::Source, }; @@ -23,6 +23,7 @@ pub fn resolve_short_circuiting_binary_operation_expr( &binary_operation.left, preferred_type, Initialized::Require, + ResolveExprMode::RequireValue, )?; let left = conform_expr::( @@ -50,6 +51,7 @@ pub fn resolve_short_circuiting_binary_operation_expr( &binary_operation.right, preferred_type, Initialized::Require, + ResolveExprMode::RequireValue, )?; let right = conform_expr::( diff --git a/src/resolve/expr/static_member.rs b/src/resolve/expr/static_member.rs index 25907fc..8dca601 100644 --- a/src/resolve/expr/static_member.rs +++ b/src/resolve/expr/static_member.rs @@ -1,4 +1,4 @@ -use super::{call::call_callee, resolve_expr, ResolveExprCtx}; +use super::{call::call_callee, resolve_expr, ResolveExprCtx, ResolveExprMode}; use crate::{ asg::{self, TypeKind, TypedExpr}, ast::{self, StaticMember, StaticMemberActionKind}, @@ -79,7 +79,13 @@ pub fn resolve_static_member_call( let mut args = Vec::with_capacity(call.args.len()); for arg in call.args.iter() { - args.push(resolve_expr(ctx, arg, None, Initialized::Require)?); + args.push(resolve_expr( + ctx, + arg, + None, + Initialized::Require, + ResolveExprMode::RequireValue, + )?); } let Some(imp) = impl_ref.and_then(|found| ctx.asg.impls.get(*found)) else { diff --git a/src/resolve/expr/struct_literal.rs b/src/resolve/expr/struct_literal.rs index 90c161e..fcac670 100644 --- a/src/resolve/expr/struct_literal.rs +++ b/src/resolve/expr/struct_literal.rs @@ -1,4 +1,4 @@ -use super::{resolve_expr, PreferredType, ResolveExprCtx}; +use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode}; use crate::{ asg::{self, StructLiteral, StructRef, TypedExpr}, ast::{self, ConformBehavior, FieldInitializer, FillBehavior}, @@ -119,6 +119,7 @@ pub fn resolve_struct_literal_expr( &field_initializer.value, Some(PreferredType::FieldType(struct_ref, &field_name)), Initialized::Require, + ResolveExprMode::RequireValue, )?; // Lookup additional details required for resolution diff --git a/src/resolve/expr/unary_operation.rs b/src/resolve/expr/unary_operation.rs index 320c9b1..dd5beab 100644 --- a/src/resolve/expr/unary_operation.rs +++ b/src/resolve/expr/unary_operation.rs @@ -1,12 +1,12 @@ -use super::{resolve_expr, PreferredType, ResolveExprCtx}; +use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode}; use crate::{ + asg::{Expr, ExprKind, TypeKind, TypedExpr, UnaryMathOperation}, ast::{self, UnaryMathOperator}, resolve::{ conform::to_default::conform_expr_to_default_or_error, error::{ResolveError, ResolveErrorKind}, Initialized, }, - asg::{Expr, ExprKind, TypeKind, TypedExpr, UnaryMathOperation}, source_files::Source, }; @@ -17,8 +17,14 @@ pub fn resolve_unary_math_operation_expr( preferred_type: Option, source: Source, ) -> Result { - let resolved_expr = resolve_expr(ctx, inner, preferred_type, Initialized::Require) - .and_then(|expr| conform_expr_to_default_or_error(expr, ctx.c_integer_assumptions()))?; + let resolved_expr = resolve_expr( + ctx, + inner, + preferred_type, + Initialized::Require, + ResolveExprMode::RequireValue, + ) + .and_then(|expr| conform_expr_to_default_or_error(expr, ctx.c_integer_assumptions()))?; let from_type = &resolved_expr.ty; diff --git a/src/resolve/expr/variable.rs b/src/resolve/expr/variable.rs index e33e711..67120d2 100644 --- a/src/resolve/expr/variable.rs +++ b/src/resolve/expr/variable.rs @@ -1,4 +1,4 @@ -use super::{PreferredType, ResolveExprCtx}; +use super::{PreferredType, ResolveExprCtx, ResolveExprMode}; use crate::{ asg::{self, GlobalVarDecl, Type, TypedExpr}, ast::HelperExpr, @@ -174,13 +174,14 @@ fn resolve_helper_expr( helper_expr: &HelperExpr, preferred_type: Option, initialized: Initialized, + mode: ResolveExprMode, source: Source, ) -> Result { let TypedExpr { ty, expr, is_initialized, - } = resolve_expr(ctx, &helper_expr.value, preferred_type, initialized)?; + } = resolve_expr(ctx, &helper_expr.value, preferred_type, initialized, mode)?; return Ok(TypedExpr::new_maybe_initialized( ty, diff --git a/src/resolve/func_body.rs b/src/resolve/func_body.rs index 432c46f..5d4c76b 100644 --- a/src/resolve/func_body.rs +++ b/src/resolve/func_body.rs @@ -1,6 +1,11 @@ use super::{ - ctx::ResolveCtx, error::ResolveError, expr::ResolveExprCtx, job::FuncJob, stmt::resolve_stmts, - type_ctx::ResolveTypeCtx, variable_haystack::VariableHaystack, + ctx::ResolveCtx, + error::ResolveError, + expr::{ResolveExprCtx, ResolveExprMode}, + job::FuncJob, + stmt::resolve_stmts, + type_ctx::ResolveTypeCtx, + variable_haystack::VariableHaystack, }; use crate::{ asg::{Asg, FuncRef}, @@ -129,6 +134,7 @@ fn resolve_func_body( current_constraints: constraints, }, &ast_function.stmts, + ResolveExprMode::NeglectValue, )?; asg.funcs diff --git a/src/resolve/helper_expr.rs b/src/resolve/helper_expr.rs index 927f948..f33cebb 100644 --- a/src/resolve/helper_expr.rs +++ b/src/resolve/helper_expr.rs @@ -1,7 +1,7 @@ use super::{ ctx::ResolveCtx, error::ResolveError, - expr::{resolve_expr, ResolveExprCtx}, + expr::{resolve_expr, ResolveExprCtx, ResolveExprMode}, initialized::Initialized, variable_haystack::VariableHaystack, }; @@ -44,7 +44,13 @@ pub fn resolve_helper_expressions( current_constraints: CurrentConstraints::new_empty(), }; - resolve_expr(&mut ctx, &helper_expr.value, None, Initialized::Require)? + resolve_expr( + &mut ctx, + &helper_expr.value, + None, + Initialized::Require, + ResolveExprMode::RequireValue, + )? }; let helper_exprs = ctx diff --git a/src/resolve/stmt.rs b/src/resolve/stmt.rs index f8fec57..73569c8 100644 --- a/src/resolve/stmt.rs +++ b/src/resolve/stmt.rs @@ -2,7 +2,9 @@ use super::{ conform::{conform_expr, ConformMode, Perform}, destination::resolve_expr_to_destination, error::{ResolveError, ResolveErrorKind}, - expr::{resolve_basic_binary_operator, resolve_expr, PreferredType, ResolveExprCtx}, + expr::{ + resolve_basic_binary_operator, resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode, + }, Initialized, }; use crate::{asg, ast}; @@ -11,11 +13,12 @@ use std::borrow::Cow; pub fn resolve_stmts( ctx: &mut ResolveExprCtx, stmts: &[ast::Stmt], + mode: ResolveExprMode, ) -> Result, ResolveError> { let mut resolved_stmts = Vec::with_capacity(stmts.len()); for stmt in stmts.iter() { - resolved_stmts.push(resolve_stmt(ctx, stmt)?); + resolved_stmts.push(resolve_stmt(ctx, stmt, mode)?); } Ok(resolved_stmts) @@ -24,6 +27,7 @@ pub fn resolve_stmts( pub fn resolve_stmt( ctx: &mut ResolveExprCtx, ast_stmt: &ast::Stmt, + mode: ResolveExprMode, ) -> Result { let source = ast_stmt.source; @@ -39,6 +43,7 @@ pub fn resolve_stmt( value, Some(PreferredType::ReturnType(func_ref)), Initialized::Require, + ResolveExprMode::RequireValue, )?; let mut return_type = @@ -82,7 +87,7 @@ pub fn resolve_stmt( Ok(asg::Stmt::new(asg::StmtKind::Return(return_value), source)) } ast::StmtKind::Expr(value) => Ok(asg::Stmt::new( - asg::StmtKind::Expr(resolve_expr(ctx, value, None, Initialized::Require)?), + asg::StmtKind::Expr(resolve_expr(ctx, value, None, Initialized::Require, mode)?), source, )), ast::StmtKind::Declaration(declaration) => { @@ -97,6 +102,7 @@ pub fn resolve_stmt( value, Some(PreferredType::of(&ty)), Initialized::Require, + ResolveExprMode::RequireValue, ) }) .transpose()? @@ -156,6 +162,7 @@ pub fn resolve_stmt( &assignment.destination, None, Initialized::AllowUninitialized, + ResolveExprMode::RequireValue, )?; let value = resolve_expr( @@ -163,6 +170,7 @@ pub fn resolve_stmt( &assignment.value, Some(PreferredType::of(&destination_expr.ty)), Initialized::Require, + ResolveExprMode::RequireValue, )?; let value = conform_expr::( diff --git a/tests/success/if_neglect_result/main.adept b/tests/success/if_neglect_result/main.adept new file mode 100644 index 0000000..3fd690e --- /dev/null +++ b/tests/success/if_neglect_result/main.adept @@ -0,0 +1,13 @@ + +pragma => adept("3.0") + +#[foreign] +func printf(format ptr, ...) int + +func main { + if true { + printf(c"Hello\n") + } else { + // Do nothing + } +} diff --git a/tests/success/impl_generic_simple/main.adept b/tests/success/impl_generic_simple/main.adept index 4fcfdfe..c501ab1 100644 --- a/tests/success/impl_generic_simple/main.adept +++ b/tests/success/impl_generic_simple/main.adept @@ -13,7 +13,6 @@ func main { if c == c'\0' { running = false - 0 } else { printf(c"%c\n", c) }