From 9ca2e336eb7cb18600e18473fa5a9feb27d7a289 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Tue, 12 Mar 2024 13:03:35 +0100 Subject: [PATCH] improv cast --- lib/edlang_ast/src/lib.rs | 2 +- lib/edlang_codegen_llvm/src/codegen.rs | 4 ++-- lib/edlang_ir/src/lib.rs | 2 +- lib/edlang_lowering/src/lib.rs | 29 +++++++++++++++++++++++--- lib/edlang_parser/src/grammar.lalrpop | 2 +- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/edlang_ast/src/lib.rs b/lib/edlang_ast/src/lib.rs index ef92d59e3..f28de1556 100644 --- a/lib/edlang_ast/src/lib.rs +++ b/lib/edlang_ast/src/lib.rs @@ -176,7 +176,7 @@ pub enum Expression { Binary(Box, BinaryOp, Box), Deref(Box, Span), AsRef(Box, bool, Span), - Cast(PathExpr, Type, Span), + Cast(Box, Type, Span), } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/lib/edlang_codegen_llvm/src/codegen.rs b/lib/edlang_codegen_llvm/src/codegen.rs index 9b2839c96..900297461 100644 --- a/lib/edlang_codegen_llvm/src/codegen.rs +++ b/lib/edlang_codegen_llvm/src/codegen.rs @@ -1033,7 +1033,7 @@ fn compile_rvalue<'ctx>( ); compile_unary_op(ctx, fn_id, locals, *op, value)? } - ir::RValue::Cast(place, target_ty, span) => { + ir::RValue::Cast(op, target_ty, span) => { ctx.set_debug_loc( ctx.builder .get_current_debug_location() @@ -1044,7 +1044,7 @@ fn compile_rvalue<'ctx>( let target_ty = target_ty.clone(); let target_llvm_ty = compile_basic_type(ctx, &target_ty); - let (value, ty) = compile_load_place(ctx, fn_id, locals, place, false)?; + let (value, ty) = compile_load_operand(ctx, fn_id, locals, op)?; let current_ty = compile_basic_type(ctx, &ty); if target_llvm_ty.is_pointer_type() { diff --git a/lib/edlang_ir/src/lib.rs b/lib/edlang_ir/src/lib.rs index 1a92c3fc7..54f81eb1d 100644 --- a/lib/edlang_ir/src/lib.rs +++ b/lib/edlang_ir/src/lib.rs @@ -419,7 +419,7 @@ pub enum RValue { BinOp(BinOp, Operand, Operand, Span), LogicOp(LogicalOp, Operand, Operand, Span), UnOp(UnOp, Operand, Span), - Cast(Place, TypeInfo, Span), + Cast(Operand, TypeInfo, Span), } #[derive(Debug, Clone)] diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index 115cef43d..31a9ddcc1 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -735,14 +735,37 @@ fn lower_expr( (RValue::Use(Operand::Move(place), info.span), ty, info.span) } - ast::Expression::Cast(path, cast_ty, span) => { - let (place, _ty, _path_span) = lower_path(builder, path)?; + ast::Expression::Cast(exp, cast_ty, span) => { + let (value, ty, _exp_span) = lower_expr(builder, exp, None)?; let new_ty = lower_type(&builder.ctx, cast_ty, builder.local_module)?; let kind = new_ty.kind.clone(); // todo: some checks? - (RValue::Cast(place, new_ty, *span), kind, *span) + // check if its a use directly, to avoid a temporary. + let rvalue = match value { + RValue::Use(op, _) => RValue::Cast(op, new_ty.clone(), *span), + value => { + let inner_local = builder.add_local(Local::temp(ty.clone())); + let inner_place = Place { + local: inner_local, + projection: Default::default(), + }; + + builder.statements.push(Statement { + span: None, + kind: StatementKind::StorageLive(inner_local), + }); + + builder.statements.push(Statement { + span: None, + kind: StatementKind::Assign(inner_place.clone(), value), + }); + RValue::Cast(Operand::Move(inner_place), new_ty.clone(), *span) + } + }; + + (rvalue, kind, *span) } }) } diff --git a/lib/edlang_parser/src/grammar.lalrpop b/lib/edlang_parser/src/grammar.lalrpop index 46656462c..d564dd150 100644 --- a/lib/edlang_parser/src/grammar.lalrpop +++ b/lib/edlang_parser/src/grammar.lalrpop @@ -343,7 +343,7 @@ pub(crate) Expression: ast::Expression = { Box::new(rhs) ), #[precedence(level="5")] #[assoc(side="left")] - "as" => ast::Expression::Cast(a, b, ast::Span::new(lo, hi)), + "as" => ast::Expression::Cast(Box::new(a), b, ast::Span::new(lo, hi)), "(" ")" => ast::Expression::StructInit(<>), }