Skip to content

Commit f6be88b

Browse files
committed
Finished adding initial support for associated types not implied by function signature
1 parent d5be8ea commit f6be88b

File tree

4 files changed

+62
-12
lines changed

4 files changed

+62
-12
lines changed

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

+48-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
resolve::{
55
error::ResolveError,
66
expr::{static_member::resolve_impl_mention_from_type, ResolveExprCtx},
7-
PolyValue,
7+
PolyCatalog, PolyValue,
88
},
99
source_files::{source::Sourced, Source},
1010
};
@@ -15,13 +15,22 @@ pub fn resolve_impl_arg(
1515
callee: &mut Callee,
1616
using: &Using,
1717
used_names: &mut HashSet<String>,
18+
catalog: &mut PolyCatalog,
1819
) -> Result<(), ResolveError> {
1920
let impl_arg = &using.ty;
2021

2122
if let ast::TypeKind::Polymorph(polymorph, args_to_polymorph) = &impl_arg.kind {
22-
resolve_polymorph_impl_arg(ctx, callee, using, polymorph, args_to_polymorph, used_names)
23+
resolve_polymorph_impl_arg(
24+
ctx,
25+
callee,
26+
using,
27+
polymorph,
28+
args_to_polymorph,
29+
used_names,
30+
catalog,
31+
)
2332
} else {
24-
resolve_concrete_impl_arg(ctx, callee, using, impl_arg, used_names)
33+
resolve_concrete_impl_arg(ctx, callee, using, impl_arg, used_names, catalog)
2534
}
2635
}
2736

@@ -31,6 +40,7 @@ fn resolve_concrete_impl_arg(
3140
using: &Using,
3241
impl_arg: &ast::Type,
3342
used_names: &mut HashSet<String>,
43+
catalog: &mut PolyCatalog,
3444
) -> Result<(), ResolveError> {
3545
let impl_arg_source = using.ty.source;
3646
let (impl_ref, impl_poly_catalog) = resolve_impl_mention_from_type(ctx, impl_arg)?;
@@ -46,14 +56,14 @@ fn resolve_concrete_impl_arg(
4656

4757
try_register_specified_impl(
4858
ctx,
49-
callee,
5059
callee_func,
5160
using,
5261
impl_arg_source,
5362
used_names,
5463
PolyValue::Impl(impl_ref),
5564
&arg_concrete_trait,
5665
&callee_func.impl_params,
66+
catalog,
5767
)
5868
}
5969

@@ -64,6 +74,7 @@ fn resolve_polymorph_impl_arg(
6474
polymorph: &str,
6575
args_to_polymorph: &[ast::Type],
6676
used_names: &mut HashSet<String>,
77+
catalog: &mut PolyCatalog,
6778
) -> Result<(), ResolveError> {
6879
let impl_arg_source = using.ty.source;
6980
let callee_func = ctx.asg.funcs.get(callee.func_ref).unwrap();
@@ -97,27 +108,27 @@ fn resolve_polymorph_impl_arg(
97108

98109
try_register_specified_impl(
99110
ctx,
100-
callee,
101111
callee_func,
102112
using,
103113
impl_arg_source,
104114
used_names,
105115
PolyValue::PolyImpl(polymorph.into()),
106116
arg_concrete_trait,
107117
&callee_func.impl_params,
118+
catalog,
108119
)
109120
}
110121

111122
fn try_register_specified_impl(
112123
ctx: &ResolveExprCtx,
113-
callee: &mut Callee,
114124
callee_func: &asg::Func,
115125
using: &Using,
116126
impl_arg_source: Source,
117127
used_names: &mut HashSet<String>,
118128
poly_value: PolyValue,
119129
arg_concrete_trait: &GenericTraitRef,
120130
impl_params: &ImplParams,
131+
catalog: &mut PolyCatalog,
121132
) -> Result<(), ResolveError> {
122133
let target_param = match &using.name {
123134
Some(name_and_source) => name_and_source.as_ref(),
@@ -166,7 +177,36 @@ fn try_register_specified_impl(
166177
));
167178
}
168179

169-
let param_concrete_trait = callee.recipe.resolve_trait(param_generic_trait)?;
180+
if param_generic_trait.args.len() != arg_concrete_trait.args.len() {
181+
return Err(ResolveError::other(
182+
"Mismatching number of arguments expected for trait implementation",
183+
target_param.source,
184+
));
185+
}
186+
187+
for (pattern, concrete) in param_generic_trait
188+
.args
189+
.iter()
190+
.zip(arg_concrete_trait.args.iter())
191+
{
192+
match catalog.match_type(ctx, pattern, concrete) {
193+
Ok(()) => {}
194+
Err(_) => {
195+
return Err(ResolveError::other(
196+
format!(
197+
"Implementation of '{}' cannot be used for '{}'",
198+
arg_concrete_trait.display(ctx.asg),
199+
param_generic_trait.display(ctx.asg)
200+
),
201+
impl_arg_source,
202+
));
203+
}
204+
}
205+
}
206+
207+
// TODO: PERFORMANCE: We shouldn't need to clone this
208+
let recipe = catalog.clone().bake();
209+
let param_concrete_trait = recipe.resolve_trait(param_generic_trait)?;
170210

171211
if *arg_concrete_trait != param_concrete_trait {
172212
return Err(ResolveError::other(
@@ -179,8 +219,7 @@ fn try_register_specified_impl(
179219
));
180220
}
181221

182-
callee
183-
.recipe
222+
catalog
184223
.polymorphs
185224
.insert(target_param.inner().to_string(), poly_value)
186225
.is_some()

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
resolve::{
99
conform::{conform_expr, to_default::conform_expr_to_default, ConformMode, Perform},
1010
error::{ResolveError, ResolveErrorKind},
11-
Initialized, PolyValue,
11+
Initialized, PolyCatalog, PolyValue,
1212
},
1313
source_files::Source,
1414
};
@@ -72,10 +72,14 @@ pub fn call_callee(
7272
source: Source,
7373
) -> Result<TypedExpr, ResolveError> {
7474
let mut used_names = HashSet::new();
75+
let mut catalog = PolyCatalog {
76+
polymorphs: callee.recipe.polymorphs.clone(),
77+
};
7578

7679
for using in call.using.iter() {
77-
resolve_impl_arg(ctx, &mut callee, using, &mut used_names)?;
80+
resolve_impl_arg(ctx, &mut callee, using, &mut used_names, &mut catalog)?;
7881
}
82+
callee.recipe = catalog.bake();
7983

8084
let function = ctx.asg.funcs.get(callee.func_ref).unwrap();
8185
let num_required = function.params.required.len();

Diff for: src/resolve/impl_head.rs

+7
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,13 @@ pub fn create_impl_head<'a>(
421421
body: HashMap::default(),
422422
});
423423

424+
if imp.name.is_none() {
425+
return Err(ResolveError::other(
426+
"Unnamed trait implementations are not supported yet",
427+
imp.source,
428+
));
429+
}
430+
424431
let name = imp
425432
.name
426433
.as_ref()

Diff for: src/resolve/polymorph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ pub enum PolyValue {
202202

203203
#[derive(Clone, Debug, Default)]
204204
pub struct PolyCatalog {
205-
polymorphs: IndexMap<String, PolyValue>,
205+
pub polymorphs: IndexMap<String, PolyValue>,
206206
}
207207

208208
#[derive(Clone, Debug)]

0 commit comments

Comments
 (0)