Skip to content

Commit 65bd95c

Browse files
committed
Added named implementation parameters for functions
1 parent 10c37c2 commit 65bd95c

File tree

7 files changed

+63
-47
lines changed

7 files changed

+63
-47
lines changed

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,11 @@ pub struct Call {
1010
pub args: Vec<Expr>,
1111
pub expected_to_return: Option<Type>,
1212
pub generics: Vec<TypeArg>,
13-
pub using: Vec<Type>,
13+
pub using: Vec<Using>,
14+
}
15+
16+
#[derive(Clone, Debug)]
17+
pub struct Using {
18+
pub name: String,
19+
pub ty: Type,
1420
}

Diff for: src/interpreter/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ impl<'a, S: SyscallHandler> Interpreter<'a, S> {
9494
break value;
9595
}
9696
ir::Instr::Call(call) => {
97-
let mut arguments = Vec::with_capacity(call.arguments.len());
97+
let mut arguments = Vec::with_capacity(call.args.len());
9898

99-
for argument in call.arguments.iter() {
99+
for argument in call.args.iter() {
100100
arguments.push(self.eval(&registers, argument));
101101
}
102102

Diff for: src/ir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl BinaryOperands {
204204
#[derive(Clone, Debug)]
205205
pub struct Call {
206206
pub func: FuncRef,
207-
pub arguments: Box<[Value]>,
207+
pub args: Box<[Value]>,
208208
pub unpromoted_variadic_arg_types: Box<[Type]>,
209209
}
210210

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

+7-10
Original file line numberDiff line numberDiff line change
@@ -795,8 +795,8 @@ unsafe fn emit_call(
795795

796796
let function_value = skeleton.function;
797797

798-
let mut arguments = call
799-
.arguments
798+
let mut args = call
799+
.args
800800
.iter()
801801
.enumerate()
802802
.map(|(i, argument)| {
@@ -830,7 +830,7 @@ unsafe fn emit_call(
830830

831831
// If we're using variadic arguments, then we have to re-generate the ABI
832832
// function signature for the way we're calling it
833-
let abi_function_approximation = (abi_function.parameter_types.len() < arguments.len())
833+
let abi_function_approximation = (abi_function.parameter_types.len() < args.len())
834834
.then(|| {
835835
ABIFunction::new(
836836
ctx,
@@ -845,10 +845,7 @@ unsafe fn emit_call(
845845
.unwrap_or(Cow::Borrowed(abi_function));
846846

847847
// After generating the function signature, we should have ABI parameter information for each argument
848-
assert_eq!(
849-
abi_function_approximation.parameter_types.len(),
850-
arguments.len()
851-
);
848+
assert_eq!(abi_function_approximation.parameter_types.len(), args.len());
852849

853850
// NOTE: We shouldn't need inalloca, since we intend to target
854851
// only x86_64 Windows GNU on Windows, as opposed to older MSVC ABIs.
@@ -914,7 +911,7 @@ unsafe fn emit_call(
914911
let saved_stack_pointer = builder.save_stack_pointer(ctx);
915912

916913
for (argument, argument_type, abi_param, param_mapping) in zip4(
917-
arguments.iter().copied(),
914+
args.iter().copied(),
918915
argument_types_iter,
919916
abi_function_approximation.parameter_types.iter(),
920917
params_mapping.params().iter(),
@@ -1140,8 +1137,8 @@ unsafe fn emit_call(
11401137
builder.get(),
11411138
function_type,
11421139
function_value,
1143-
arguments.as_mut_ptr(),
1144-
arguments.len().try_into().unwrap(),
1140+
args.as_mut_ptr(),
1141+
args.len().try_into().unwrap(),
11451142
cstr!("").as_ptr(),
11461143
))
11471144
}

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ pub fn lower_expr(
183183

184184
Ok(builder.push(ir::Instr::Call(ir::Call {
185185
func: function,
186-
arguments: args,
186+
args,
187187
unpromoted_variadic_arg_types: variadic_arg_types,
188188
})))
189189
}
@@ -554,7 +554,7 @@ pub fn lower_expr(
554554
let func_ref = imp
555555
.body
556556
.get(&poly_call.callee.member)
557-
.expect("expected impl body function refereneced by poly call to exist");
557+
.expect("expected impl body function referenced by poly call to exist");
558558

559559
let callee = asg
560560
.funcs
@@ -602,7 +602,7 @@ pub fn lower_expr(
602602

603603
Ok(builder.push(ir::Instr::Call(ir::Call {
604604
func: function,
605-
arguments: args,
605+
args,
606606
unpromoted_variadic_arg_types: variadic_arg_types,
607607
})))
608608
}

Diff for: src/parser/parse_expr/primary/call.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::Parser;
22
use crate::{
3-
ast::{Call, Expr, ExprKind, TypeArg},
3+
ast::{Call, Expr, ExprKind, TypeArg, Using},
44
inflow::Inflow,
55
name::Name,
66
parser::error::ParseError,
@@ -82,7 +82,12 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
8282
self.ignore_newlines();
8383
}
8484

85-
using.push(self.parse_type(Some("implementation"), Some("for implementation"))?);
85+
let name = self.parse_identifier(Some("for implementation parameter name"))?;
86+
87+
using.push(Using {
88+
name,
89+
ty: self.parse_type(Some("implementation"), Some("for implementation"))?,
90+
});
8691
self.ignore_newlines();
8792
}
8893

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

+36-28
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ pub fn call_callee(
6969
mut args: Vec<TypedExpr>,
7070
source: Source,
7171
) -> Result<TypedExpr, ResolveError> {
72-
for impl_arg in call.using.iter() {
72+
for impl_using in call.using.iter() {
73+
let impl_arg = &impl_using.ty;
7374
let (impl_ref, impl_poly_catalog) = resolve_impl_mention_from_type(ctx, impl_arg)?;
7475

7576
let imp = ctx
@@ -81,34 +82,41 @@ pub fn call_callee(
8182
let arg_concrete_trait = impl_poly_catalog.bake().resolve_trait(&imp.target)?;
8283

8384
let function = ctx.asg.funcs.get(callee.function).unwrap();
84-
for (poly_impl_name, param_generic_trait) in function.impl_params.params.iter() {
85-
let param_concrete_trait = callee.recipe.resolve_trait(param_generic_trait)?;
86-
87-
if arg_concrete_trait != param_concrete_trait {
88-
return Err(ResolveError::other(
89-
format!(
90-
"Implementation of {} cannot be used for {}",
91-
arg_concrete_trait.display(ctx.asg),
92-
param_concrete_trait.display(ctx.asg)
93-
),
94-
impl_arg.source,
95-
));
96-
}
9785

98-
if callee
99-
.recipe
100-
.polymorphs
101-
.insert(poly_impl_name.into(), PolyValue::Impl(impl_ref))
102-
.is_some()
103-
{
104-
return Err(ResolveError::other(
105-
format!(
106-
"Multiple implementations were specified for implementation parameter '${}'",
107-
poly_impl_name
108-
),
109-
impl_arg.source,
110-
));
111-
}
86+
let poly_impl_name = &impl_using.name;
87+
88+
let Some(param_generic_trait) = function.impl_params.params.get(&impl_using.name) else {
89+
return Err(ResolveError::other(
90+
format!("Unknown implementation argument '${}'", poly_impl_name),
91+
source,
92+
));
93+
};
94+
95+
let param_concrete_trait = callee.recipe.resolve_trait(param_generic_trait)?;
96+
97+
if arg_concrete_trait != param_concrete_trait {
98+
return Err(ResolveError::other(
99+
format!(
100+
"Implementation of {} cannot be used for {}",
101+
arg_concrete_trait.display(ctx.asg),
102+
param_concrete_trait.display(ctx.asg)
103+
),
104+
impl_arg.source,
105+
));
106+
}
107+
if callee
108+
.recipe
109+
.polymorphs
110+
.insert(poly_impl_name.into(), PolyValue::Impl(impl_ref))
111+
.is_some()
112+
{
113+
return Err(ResolveError::other(
114+
format!(
115+
"Multiple implementations were specified for implementation parameter '${}'",
116+
poly_impl_name
117+
),
118+
impl_arg.source,
119+
));
112120
}
113121

114122
// NOTE: We will need to populate the callee's poly recipe with `callee.recipe.polymorphs.insert()`

0 commit comments

Comments
 (0)