Skip to content

Commit 10c37c2

Browse files
committed
Finished adding basic support for calling functions with polymorphic trait implementations
1 parent 818d600 commit 10c37c2

File tree

7 files changed

+69
-25
lines changed

7 files changed

+69
-25
lines changed

Diff for: src/asg/expr/call.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{asg::FuncRef, resolve::PolyRecipe};
44
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
55
pub struct Call {
66
pub callee: Callee,
7-
pub arguments: Vec<TypedExpr>,
7+
pub args: Vec<TypedExpr>,
88
}
99

1010
#[derive(Clone, Debug, Hash, PartialEq, Eq)]

Diff for: src/asg/expr/poly_call.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::TypedExpr;
2+
use crate::resolve::PolyRecipe;
23

34
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
45
pub struct PolyCall {
@@ -10,4 +11,5 @@ pub struct PolyCall {
1011
pub struct PolyCallee {
1112
pub polymorph: String,
1213
pub member: String,
14+
pub recipe: PolyRecipe,
1315
}

Diff for: src/ir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ impl BinaryOperands {
205205
pub struct Call {
206206
pub func: FuncRef,
207207
pub arguments: Box<[Value]>,
208-
pub unpromoted_variadic_argument_types: Box<[Type]>,
208+
pub unpromoted_variadic_arg_types: Box<[Type]>,
209209
}
210210

211211
#[derive(Clone, Debug)]

Diff for: src/llvm_backend/functions/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ unsafe fn emit_call(
814814
let abi_function = skeleton.abi_function.as_ref().expect("abi function");
815815

816816
let variadic_argument_types = call
817-
.unpromoted_variadic_argument_types
817+
.unpromoted_variadic_arg_types
818818
.iter()
819819
.map(|argument_type| {
820820
promote_variadic_argument_type(builder, &ctx.ir_module.target, argument_type)

Diff for: src/lower/expr/mod.rs

+61-10
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,15 @@ pub fn lower_expr(
140140
.get(call.callee.function)
141141
.expect("referenced function to exist");
142142

143-
let arguments = call
144-
.arguments
143+
let args = call
144+
.args
145145
.iter()
146-
.map(|argument| lower_expr(builder, ir_module, &argument.expr, function, asg))
146+
.map(|arg| lower_expr(builder, ir_module, &arg.expr, function, asg))
147147
.collect::<Result<Box<[_]>, _>>()?;
148148

149-
let variadic_argument_types = call.arguments[callee.params.required.len()..]
149+
let variadic_arg_types = call.args[callee.params.required.len()..]
150150
.iter()
151-
.map(|argument| lower_type(ir_module, &builder.unpoly(&argument.ty)?, asg))
151+
.map(|arg| lower_type(ir_module, &builder.unpoly(&arg.ty)?, asg))
152152
.collect::<Result<Box<[_]>, _>>()?;
153153

154154
// NOTE: We have to resolve our own polymorphs in the mapping
@@ -183,8 +183,8 @@ pub fn lower_expr(
183183

184184
Ok(builder.push(ir::Instr::Call(ir::Call {
185185
func: function,
186-
arguments,
187-
unpromoted_variadic_argument_types: variadic_argument_types,
186+
arguments: args,
187+
unpromoted_variadic_arg_types: variadic_arg_types,
188188
})))
189189
}
190190
ExprKind::Variable(variable) => {
@@ -551,9 +551,60 @@ pub fn lower_expr(
551551

552552
let imp = asg.impls.get(impl_ref).expect("referenced impl to exist");
553553

554-
dbg!(poly_call);
555-
dbg!(imp);
556-
todo!("lowering poly calls is not implemented yet!");
554+
let func_ref = imp
555+
.body
556+
.get(&poly_call.callee.member)
557+
.expect("expected impl body function refereneced by poly call to exist");
558+
559+
let callee = asg
560+
.funcs
561+
.get(*func_ref)
562+
.expect("referenced function to exist");
563+
564+
let args = poly_call
565+
.args
566+
.iter()
567+
.map(|arg| lower_expr(builder, ir_module, &arg.expr, function, asg))
568+
.collect::<Result<Box<[_]>, _>>()?;
569+
570+
let variadic_arg_types = poly_call.args[callee.params.required.len()..]
571+
.iter()
572+
.map(|arg| lower_type(ir_module, &builder.unpoly(&arg.ty)?, asg))
573+
.collect::<Result<Box<[_]>, _>>()?;
574+
575+
// NOTE: We have to resolve our own polymorphs in the mapping
576+
let mut polymorphs = IndexMap::<String, PolyValue>::new();
577+
578+
for (name, value) in poly_call.callee.recipe.polymorphs.iter() {
579+
match value {
580+
PolyValue::Type(ty) => {
581+
polymorphs.insert(
582+
name.clone(),
583+
PolyValue::Type(
584+
Borrow::<asg::Type>::borrow(&builder.unpoly(&ty)?.0).clone(),
585+
),
586+
);
587+
}
588+
PolyValue::Expr(_) => {
589+
todo!("compile-time expression parameters are not supported when calling generic functions yet")
590+
}
591+
PolyValue::Impl(impl_ref) => {
592+
polymorphs.insert(name.clone(), PolyValue::Impl(*impl_ref));
593+
}
594+
}
595+
}
596+
597+
let recipe = PolyRecipe { polymorphs };
598+
599+
let function = ir_module.funcs.translate(*func_ref, &recipe, || {
600+
lower_func_head(ir_module, *func_ref, &recipe, asg)
601+
})?;
602+
603+
Ok(builder.push(ir::Instr::Call(ir::Call {
604+
func: function,
605+
arguments: args,
606+
unpromoted_variadic_arg_types: variadic_arg_types,
607+
})))
557608
}
558609
}
559610
}

Diff for: src/resolve/expr/call.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ pub fn call_callee(
7878
.get(impl_ref)
7979
.expect("referenced impl to exist");
8080

81-
dbg!(&callee.recipe);
82-
dbg!(&imp.target);
83-
8481
let arg_concrete_trait = impl_poly_catalog.bake().resolve_trait(&imp.target)?;
8582

8683
let function = ctx.asg.funcs.get(callee.function).unwrap();
@@ -98,9 +95,6 @@ pub fn call_callee(
9895
));
9996
}
10097

101-
dbg!(&arg_concrete_trait);
102-
dbg!(&param_concrete_trait);
103-
10498
if callee
10599
.recipe
106100
.polymorphs
@@ -125,8 +119,7 @@ pub fn call_callee(
125119
let num_required = function.params.required.len();
126120

127121
if !function.impl_params.params.is_empty() {
128-
dbg!(&function.impl_params);
129-
eprintln!("warning: calling functions with implementation parameters is not fully implemented yet!");
122+
eprintln!("warning: calling functions with implementation parameters is not fully implemented yet! (more that one implementation parameter is not supported yet)");
130123
}
131124

132125
for (i, arg) in args.iter_mut().enumerate() {
@@ -188,10 +181,7 @@ pub fn call_callee(
188181
Ok(TypedExpr::new(
189182
return_type,
190183
asg::Expr::new(
191-
asg::ExprKind::Call(Box::new(asg::Call {
192-
callee,
193-
arguments: args,
194-
})),
184+
asg::ExprKind::Call(Box::new(asg::Call { callee, args })),
195185
source,
196186
),
197187
))

Diff for: src/resolve/expr/static_member.rs

+1
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ pub fn resolve_static_member_call_polymorph(
343343
callee: PolyCallee {
344344
polymorph: polymorph.into(),
345345
member,
346+
recipe: catalog.bake(),
346347
},
347348
args,
348349
}))

0 commit comments

Comments
 (0)