1use super::helpers::{is_type_param, ty_to_type_expr};
2use super::prelude::*;
3
4impl Elaborator {
5 pub(super) fn elaborate_function_body(
6 &mut self,
7 function: &mut FunctionDecl,
8 ) -> Result<(), ElabError> {
9 let signature = self
10 .signatures
11 .get(&function.name)
12 .cloned()
13 .ok_or_else(|| ElabError::UnknownFunction {
14 name: function.name.clone(),
15 })?;
16 let mut locals = Vec::new();
17 for (param, (_, param_ty)) in function.params.iter().zip(signature.params.iter()) {
18 locals.push((param.name.clone(), param_ty.clone()));
19 }
20 let _ =
21 self.elaborate_block(&mut function.body, Some(&signature.return_ty), &mut locals)?;
22 Ok(())
23 }
24
25 pub(super) fn bind_meta_arg(
26 &self,
27 callee_name: &str,
28 param: &Param,
29 expr: &Expr,
30 ) -> Result<TemplateMetaBinding, ElabError> {
31 match (¶m.ty.ty, expr) {
32 (TypeExpr::Named(name), Expr::String(value)) if name == "String" => {
33 Ok(TemplateMetaBinding::String(value.clone()))
34 }
35 (TypeExpr::Named(name), Expr::Int(value)) if name == "i64" => {
36 Ok(TemplateMetaBinding::Int(*value))
37 }
38 (TypeExpr::Named(name), Expr::Number(value)) if name == "i64" => {
39 let parsed = value
40 .raw
41 .parse::<i64>()
42 .map_err(|_| ElabError::UnsupportedTypeExpr)?;
43 Ok(TemplateMetaBinding::Int(parsed))
44 }
45 (TypeExpr::Named(name), _) if name == "String" || name == "i64" => {
46 Err(ElabError::UnsupportedMetaArg {
47 name: callee_name.to_owned(),
48 param: param.name.clone(),
49 })
50 }
51 _ => Err(ElabError::UnsupportedMetaParamType {
52 name: callee_name.to_owned(),
53 param: param.name.clone(),
54 }),
55 }
56 }
57
58 pub(super) fn next_instance_name(&mut self, callee_name: &str) -> String {
59 let instance = self.next_function_instance_id;
60 self.next_function_instance_id += 1;
61 format!("{callee_name}[__inst_{instance}]")
62 }
63
64 pub(super) fn elaborate_call_runtime_args(
65 &mut self,
66 args: &mut Vec<CallArg>,
67 params: &[(OwnershipMode, Ty)],
68 locals: &mut Vec<(String, Ty)>,
69 callee_name: &str,
70 ) -> Result<(), ElabError> {
71 self.validate_runtime_call_args(args, params, locals, callee_name)
72 }
73
74 pub(super) fn resolve_function_signature(
75 &mut self,
76 function: &FunctionDecl,
77 type_params: &[String],
78 bindings: &BTreeMap<String, Ty>,
79 ) -> Result<FunctionSig, ElabError> {
80 let type_params = type_params.iter().cloned().collect::<BTreeSet<_>>();
81 let mut params = Vec::with_capacity(function.params.len());
82 for param in &function.params {
83 let ty = self.resolve_type_expr(¶m.ty.ty, bindings, &type_params, None)?;
84 self.ensure_ty_instantiated(&ty)?;
85 params.push((param.ty.mode, ty));
86 }
87 let return_ty =
88 self.resolve_type_expr(&function.return_type.ty, bindings, &type_params, None)?;
89 self.ensure_ty_instantiated(&return_ty)?;
90 Ok(FunctionSig { params, return_ty })
91 }
92
93 pub(super) fn apply_type_bindings_to_function(
94 &mut self,
95 function: &mut FunctionDecl,
96 bindings: &BTreeMap<String, Ty>,
97 type_params: &[String],
98 ) -> Result<(), ElabError> {
99 let type_params = type_params.iter().cloned().collect::<BTreeSet<_>>();
100 for param in &mut function.params {
101 self.apply_type_bindings_to_type_ref(&mut param.ty, bindings, &type_params)?;
102 }
103 self.apply_type_bindings_to_type_ref(&mut function.return_type, bindings, &type_params)?;
104 self.apply_type_bindings_to_block(&mut function.body, bindings, &type_params)?;
105 Ok(())
106 }
107
108 pub(super) fn specialize_function_params(
109 &mut self,
110 function: &mut FunctionDecl,
111 variadic_pack_tys: &[Ty],
112 ) -> Result<(), ElabError> {
113 let original_params = function.params.clone();
114 let mut params = Vec::new();
115 for param in &original_params {
116 if is_type_param(param) || param.is_meta {
117 continue;
118 }
119 if param.is_variadic {
120 for (index, item_ty) in variadic_pack_tys.iter().enumerate() {
121 let mut specialized = param.clone();
122 specialized.name = format!("{}__{index}", param.name);
123 specialized.is_meta = false;
124 specialized.is_variadic = false;
125 specialized.ty.ty = ty_to_type_expr(item_ty);
126 params.push(specialized);
127 }
128 } else {
129 let mut specialized = param.clone();
130 specialized.is_meta = false;
131 specialized.is_variadic = false;
132 params.push(specialized);
133 }
134 }
135 function.params = params;
136 self.apply_variadic_param_substitutions(function, &original_params, variadic_pack_tys)?;
137 Ok(())
138 }
139
140 pub(super) fn apply_variadic_param_substitutions(
141 &mut self,
142 function: &mut FunctionDecl,
143 original_params: &[Param],
144 variadic_pack_tys: &[Ty],
145 ) -> Result<(), ElabError> {
146 let mut replacements = BTreeMap::new();
147 for original in original_params {
148 if !original.is_variadic {
149 continue;
150 }
151 let items = variadic_pack_tys
152 .iter()
153 .enumerate()
154 .map(|(index, _)| Expr::Ident {
155 name: format!("{}__{index}", original.name),
156 span: original.name_span,
157 })
158 .collect();
159 replacements.insert(
160 original.name.clone(),
161 Expr::Tuple {
162 items,
163 span: original.name_span,
164 },
165 );
166 }
167 self.apply_expr_replacements_to_block(&mut function.body, &replacements)
168 }
169
170 pub(super) fn apply_meta_bindings_to_function(
171 &mut self,
172 function: &mut FunctionDecl,
173 bindings: &BTreeMap<String, TemplateMetaBinding>,
174 ) -> Result<(), ElabError> {
175 self.apply_meta_bindings_to_block(&mut function.body, bindings)
176 }
177
178 pub(super) fn apply_expr_replacements_to_block(
179 &mut self,
180 block: &mut Block,
181 replacements: &BTreeMap<String, Expr>,
182 ) -> Result<(), ElabError> {
183 for stmt in &mut block.statements {
184 self.apply_expr_replacements_to_stmt(stmt, replacements)?;
185 }
186 Ok(())
187 }
188
189 pub(super) fn apply_expr_replacements_to_stmt(
190 &mut self,
191 stmt: &mut Stmt,
192 replacements: &BTreeMap<String, Expr>,
193 ) -> Result<(), ElabError> {
194 match stmt {
195 Stmt::Let { value, .. } | Stmt::Expr { expr: value, .. } => {
196 self.apply_expr_replacements_to_expr(value, replacements)
197 }
198 Stmt::Assign { value, .. } => self.apply_expr_replacements_to_expr(value, replacements),
199 Stmt::If {
200 condition,
201 then_block,
202 else_block,
203 ..
204 } => {
205 self.apply_expr_replacements_to_expr(condition, replacements)?;
206 self.apply_expr_replacements_to_block(then_block, replacements)?;
207 if let Some(else_block) = else_block {
208 self.apply_expr_replacements_to_block(else_block, replacements)?;
209 }
210 Ok(())
211 }
212 Stmt::For { iterable, body, .. } => {
213 self.apply_expr_replacements_to_expr(iterable, replacements)?;
214 self.apply_expr_replacements_to_block(body, replacements)
215 }
216 Stmt::While { condition, body } => {
217 self.apply_expr_replacements_to_expr(condition, replacements)?;
218 self.apply_expr_replacements_to_block(body, replacements)
219 }
220 Stmt::Match { value, arms } => {
221 self.apply_expr_replacements_to_expr(value, replacements)?;
222 for arm in arms {
223 self.apply_expr_replacements_to_block(&mut arm.body, replacements)?;
224 }
225 Ok(())
226 }
227 Stmt::Meta { body } => self.apply_expr_replacements_to_meta_block(body, replacements),
228 }
229 }
230
231 pub(super) fn apply_expr_replacements_to_meta_block(
232 &mut self,
233 block: &mut crate::syntax::ast::MetaBlock,
234 replacements: &BTreeMap<String, Expr>,
235 ) -> Result<(), ElabError> {
236 for stmt in &mut block.statements {
237 match stmt {
238 crate::syntax::ast::MetaStmt::Let { value, .. }
239 | crate::syntax::ast::MetaStmt::Expr { expr: value } => {
240 self.apply_expr_replacements_to_meta_expr(value, replacements)?;
241 }
242 crate::syntax::ast::MetaStmt::Match { value, arms } => {
243 self.apply_expr_replacements_to_meta_expr(value, replacements)?;
244 for arm in arms {
245 if let crate::syntax::ast::MetaMatchPattern::Quote(quoted) =
246 &mut arm.pattern
247 {
248 self.apply_expr_replacements_to_quoted_code(quoted, replacements)?;
249 }
250 self.apply_expr_replacements_to_meta_expr(&mut arm.result, replacements)?;
251 }
252 }
253 crate::syntax::ast::MetaStmt::Meta { body } => {
254 self.apply_expr_replacements_to_meta_block(body, replacements)?;
255 }
256 }
257 }
258 Ok(())
259 }
260
261 pub(super) fn apply_expr_replacements_to_meta_expr(
262 &mut self,
263 expr: &mut crate::syntax::ast::MetaExpr,
264 replacements: &BTreeMap<String, Expr>,
265 ) -> Result<(), ElabError> {
266 match expr {
267 crate::syntax::ast::MetaExpr::Call { args, .. } => {
268 for arg in args {
269 self.apply_expr_replacements_to_meta_expr(arg, replacements)?;
270 }
271 Ok(())
272 }
273 crate::syntax::ast::MetaExpr::BuildExpr(expr) => {
274 self.apply_expr_replacements_to_expr(expr, replacements)
275 }
276 crate::syntax::ast::MetaExpr::Quote(quoted) => {
277 self.apply_expr_replacements_to_quoted_code(quoted, replacements)
278 }
279 crate::syntax::ast::MetaExpr::Splice(value) => {
280 self.apply_expr_replacements_to_meta_expr(value, replacements)
281 }
282 crate::syntax::ast::MetaExpr::Ident(_)
283 | crate::syntax::ast::MetaExpr::Int(_)
284 | crate::syntax::ast::MetaExpr::Bool(_)
285 | crate::syntax::ast::MetaExpr::String(_)
286 | crate::syntax::ast::MetaExpr::Type(_) => Ok(()),
287 }
288 }
289
290 pub(super) fn apply_expr_replacements_to_quoted_code(
291 &mut self,
292 quoted: &mut crate::syntax::ast::QuotedCode,
293 replacements: &BTreeMap<String, Expr>,
294 ) -> Result<(), ElabError> {
295 match quoted {
296 crate::syntax::ast::QuotedCode::Expr(expr) => {
297 self.apply_expr_replacements_to_expr(expr, replacements)
298 }
299 crate::syntax::ast::QuotedCode::Type(_) => Ok(()),
300 }
301 }
302
303 pub(super) fn apply_expr_replacements_to_expr(
304 &mut self,
305 expr: &mut Expr,
306 replacements: &BTreeMap<String, Expr>,
307 ) -> Result<(), ElabError> {
308 match expr {
309 Expr::Ident { name, .. } => {
310 if let Some(replacement) = replacements.get(name) {
311 *expr = replacement.clone();
312 }
313 Ok(())
314 }
315 Expr::Call { callee, args, .. } => {
316 self.apply_expr_replacements_to_expr(callee, replacements)?;
317 for arg in args {
318 if let CallArg::Expr(expr) | CallArg::Spread(expr) = arg {
319 self.apply_expr_replacements_to_expr(expr, replacements)?;
320 }
321 }
322 Ok(())
323 }
324 Expr::IntrinsicCall { args, .. } => {
325 for arg in args {
326 if let CallArg::Expr(expr) | CallArg::Spread(expr) = arg {
327 self.apply_expr_replacements_to_expr(expr, replacements)?;
328 }
329 }
330 Ok(())
331 }
332 Expr::Field { base, .. } | Expr::Prefix { value: base, .. } => {
333 self.apply_expr_replacements_to_expr(base, replacements)
334 }
335 Expr::Index { base, index } => {
336 self.apply_expr_replacements_to_expr(base, replacements)?;
337 self.apply_expr_replacements_to_expr(index, replacements)
338 }
339 Expr::SliceRange { base, start, end } => {
340 self.apply_expr_replacements_to_expr(base, replacements)?;
341 if let Some(start) = start {
342 self.apply_expr_replacements_to_expr(start, replacements)?;
343 }
344 if let Some(end) = end {
345 self.apply_expr_replacements_to_expr(end, replacements)?;
346 }
347 Ok(())
348 }
349 Expr::Binary { lhs, rhs, .. } => {
350 self.apply_expr_replacements_to_expr(lhs, replacements)?;
351 self.apply_expr_replacements_to_expr(rhs, replacements)
352 }
353 Expr::Relational { lhs, rhs, .. } => {
354 self.apply_expr_replacements_to_expr(lhs, replacements)?;
355 self.apply_expr_replacements_to_expr(rhs, replacements)
356 }
357 Expr::Array { items, .. } | Expr::Tuple { items, .. } => {
358 for item in items {
359 self.apply_expr_replacements_to_expr(item, replacements)?;
360 }
361 Ok(())
362 }
363 Expr::StructLit { fields, .. } => {
364 for field in fields {
365 self.apply_expr_replacements_to_expr(&mut field.value, replacements)?;
366 }
367 Ok(())
368 }
369 Expr::Block(block) => self.apply_expr_replacements_to_block(block, replacements),
370 Expr::Splice(meta) => self.apply_expr_replacements_to_meta_expr(meta, replacements),
371 Expr::Int(_) | Expr::Number(_) | Expr::String(_) | Expr::Bool(_) => Ok(()),
372 }
373 }
374
375 pub(super) fn apply_meta_bindings_to_block(
376 &mut self,
377 block: &mut Block,
378 bindings: &BTreeMap<String, TemplateMetaBinding>,
379 ) -> Result<(), ElabError> {
380 for stmt in &mut block.statements {
381 self.apply_meta_bindings_to_stmt(stmt, bindings)?;
382 }
383 Ok(())
384 }
385
386 pub(super) fn apply_meta_bindings_to_stmt(
387 &mut self,
388 stmt: &mut Stmt,
389 bindings: &BTreeMap<String, TemplateMetaBinding>,
390 ) -> Result<(), ElabError> {
391 match stmt {
392 Stmt::Let { value, .. } | Stmt::Expr { expr: value, .. } => {
393 self.apply_meta_bindings_to_expr(value, bindings)
394 }
395 Stmt::Assign { value, .. } => self.apply_meta_bindings_to_expr(value, bindings),
396 Stmt::If {
397 condition,
398 then_block,
399 else_block,
400 ..
401 } => {
402 self.apply_meta_bindings_to_expr(condition, bindings)?;
403 self.apply_meta_bindings_to_block(then_block, bindings)?;
404 if let Some(else_block) = else_block {
405 self.apply_meta_bindings_to_block(else_block, bindings)?;
406 }
407 Ok(())
408 }
409 Stmt::For { iterable, body, .. } => {
410 self.apply_meta_bindings_to_expr(iterable, bindings)?;
411 self.apply_meta_bindings_to_block(body, bindings)
412 }
413 Stmt::While { condition, body } => {
414 self.apply_meta_bindings_to_expr(condition, bindings)?;
415 self.apply_meta_bindings_to_block(body, bindings)
416 }
417 Stmt::Match { value, arms } => {
418 self.apply_meta_bindings_to_expr(value, bindings)?;
419 for arm in arms {
420 self.apply_meta_bindings_to_block(&mut arm.body, bindings)?;
421 }
422 Ok(())
423 }
424 Stmt::Meta { .. } => Ok(()),
425 }
426 }
427
428 pub(super) fn apply_meta_bindings_to_expr(
429 &mut self,
430 expr: &mut Expr,
431 bindings: &BTreeMap<String, TemplateMetaBinding>,
432 ) -> Result<(), ElabError> {
433 match expr {
434 Expr::Ident { name, .. } => {
435 if let Some(replacement) = bindings.get(name) {
436 *expr = match replacement {
437 TemplateMetaBinding::Int(value) => {
438 Expr::Number(crate::syntax::ast::NumberLiteral {
439 raw: value.to_string(),
440 })
441 }
442 TemplateMetaBinding::String(value) => Expr::String(value.clone()),
443 TemplateMetaBinding::Type(_) => return Ok(()),
444 };
445 }
446 Ok(())
447 }
448 Expr::Call { callee, args, .. } => {
449 self.apply_meta_bindings_to_expr(callee, bindings)?;
450 for arg in args {
451 if let CallArg::Expr(expr) | CallArg::Spread(expr) = arg {
452 self.apply_meta_bindings_to_expr(expr, bindings)?;
453 }
454 }
455 Ok(())
456 }
457 Expr::IntrinsicCall { args, .. } => {
458 for arg in args {
459 if let CallArg::Expr(expr) | CallArg::Spread(expr) = arg {
460 self.apply_meta_bindings_to_expr(expr, bindings)?;
461 }
462 }
463 Ok(())
464 }
465 Expr::Field { base, .. } | Expr::Prefix { value: base, .. } => {
466 self.apply_meta_bindings_to_expr(base, bindings)
467 }
468 Expr::Index { base, index } => {
469 self.apply_meta_bindings_to_expr(base, bindings)?;
470 self.apply_meta_bindings_to_expr(index, bindings)
471 }
472 Expr::SliceRange { base, start, end } => {
473 self.apply_meta_bindings_to_expr(base, bindings)?;
474 if let Some(start) = start {
475 self.apply_meta_bindings_to_expr(start, bindings)?;
476 }
477 if let Some(end) = end {
478 self.apply_meta_bindings_to_expr(end, bindings)?;
479 }
480 Ok(())
481 }
482 Expr::Binary { lhs, rhs, .. } => {
483 self.apply_meta_bindings_to_expr(lhs, bindings)?;
484 self.apply_meta_bindings_to_expr(rhs, bindings)
485 }
486 Expr::Relational { lhs, rhs, .. } => {
487 self.apply_meta_bindings_to_expr(lhs, bindings)?;
488 self.apply_meta_bindings_to_expr(rhs, bindings)
489 }
490 Expr::Array { items, .. } | Expr::Tuple { items, .. } => {
491 for item in items {
492 self.apply_meta_bindings_to_expr(item, bindings)?;
493 }
494 Ok(())
495 }
496 Expr::StructLit { fields, .. } => {
497 for field in fields {
498 self.apply_meta_bindings_to_expr(&mut field.value, bindings)?;
499 }
500 Ok(())
501 }
502 Expr::Block(block) => self.apply_meta_bindings_to_block(block, bindings),
503 Expr::Int(_) | Expr::Number(_) | Expr::String(_) | Expr::Bool(_) | Expr::Splice(_) => {
504 Ok(())
505 }
506 }
507 }
508
509 pub(super) fn apply_type_bindings_to_block(
510 &mut self,
511 block: &mut Block,
512 bindings: &BTreeMap<String, Ty>,
513 type_params: &BTreeSet<String>,
514 ) -> Result<(), ElabError> {
515 for stmt in &mut block.statements {
516 self.apply_type_bindings_to_stmt(stmt, bindings, type_params)?;
517 }
518 Ok(())
519 }
520
521 pub(super) fn apply_type_bindings_to_stmt(
522 &mut self,
523 stmt: &mut Stmt,
524 bindings: &BTreeMap<String, Ty>,
525 type_params: &BTreeSet<String>,
526 ) -> Result<(), ElabError> {
527 match stmt {
528 Stmt::Let { value, .. } | Stmt::Expr { expr: value, .. } => {
529 self.apply_type_bindings_to_expr(value, bindings, type_params)
530 }
531 Stmt::Assign { value, .. } => {
532 self.apply_type_bindings_to_expr(value, bindings, type_params)
533 }
534 Stmt::If {
535 condition,
536 then_block,
537 else_block,
538 ..
539 } => {
540 self.apply_type_bindings_to_expr(condition, bindings, type_params)?;
541 self.apply_type_bindings_to_block(then_block, bindings, type_params)?;
542 if let Some(else_block) = else_block {
543 self.apply_type_bindings_to_block(else_block, bindings, type_params)?;
544 }
545 Ok(())
546 }
547 Stmt::For { iterable, body, .. } => {
548 self.apply_type_bindings_to_expr(iterable, bindings, type_params)?;
549 self.apply_type_bindings_to_block(body, bindings, type_params)
550 }
551 Stmt::While { condition, body } => {
552 self.apply_type_bindings_to_expr(condition, bindings, type_params)?;
553 self.apply_type_bindings_to_block(body, bindings, type_params)
554 }
555 Stmt::Match { value, arms } => {
556 self.apply_type_bindings_to_expr(value, bindings, type_params)?;
557 for arm in arms {
558 self.apply_type_bindings_to_block(&mut arm.body, bindings, type_params)?;
559 }
560 Ok(())
561 }
562 Stmt::Meta { .. } => Ok(()),
563 }
564 }
565
566 pub(super) fn apply_type_bindings_to_expr(
567 &mut self,
568 expr: &mut Expr,
569 bindings: &BTreeMap<String, Ty>,
570 type_params: &BTreeSet<String>,
571 ) -> Result<(), ElabError> {
572 match expr {
573 Expr::Call { callee, args, .. } => {
574 self.apply_type_bindings_to_expr(callee, bindings, type_params)?;
575 for arg in args {
576 self.apply_type_bindings_to_call_arg(arg, bindings, type_params)?;
577 }
578 Ok(())
579 }
580 Expr::IntrinsicCall { args, .. } => {
581 for arg in args {
582 self.apply_type_bindings_to_call_arg(arg, bindings, type_params)?;
583 }
584 Ok(())
585 }
586 Expr::Field { base, .. } | Expr::Prefix { value: base, .. } => {
587 self.apply_type_bindings_to_expr(base, bindings, type_params)
588 }
589 Expr::Index { base, index } => {
590 self.apply_type_bindings_to_expr(base, bindings, type_params)?;
591 self.apply_type_bindings_to_expr(index, bindings, type_params)
592 }
593 Expr::SliceRange { base, start, end } => {
594 self.apply_type_bindings_to_expr(base, bindings, type_params)?;
595 if let Some(start) = start {
596 self.apply_type_bindings_to_expr(start, bindings, type_params)?;
597 }
598 if let Some(end) = end {
599 self.apply_type_bindings_to_expr(end, bindings, type_params)?;
600 }
601 Ok(())
602 }
603 Expr::Binary { lhs, rhs, .. } => {
604 self.apply_type_bindings_to_expr(lhs, bindings, type_params)?;
605 self.apply_type_bindings_to_expr(rhs, bindings, type_params)
606 }
607 Expr::Relational { lhs, rhs, .. } => {
608 self.apply_type_bindings_to_expr(lhs, bindings, type_params)?;
609 self.apply_type_bindings_to_expr(rhs, bindings, type_params)
610 }
611 Expr::Array { items, .. } => {
612 for item in items {
613 self.apply_type_bindings_to_expr(item, bindings, type_params)?;
614 }
615 Ok(())
616 }
617 Expr::Tuple { items, .. } => {
618 for item in items {
619 self.apply_type_bindings_to_expr(item, bindings, type_params)?;
620 }
621 Ok(())
622 }
623 Expr::StructLit { fields, .. } => {
624 for field in fields {
625 self.apply_type_bindings_to_expr(&mut field.value, bindings, type_params)?;
626 }
627 Ok(())
628 }
629 Expr::Block(block) => self.apply_type_bindings_to_block(block, bindings, type_params),
630 Expr::Ident { .. }
631 | Expr::Int(_)
632 | Expr::Number(_)
633 | Expr::String(_)
634 | Expr::Bool(_)
635 | Expr::Splice(_) => Ok(()),
636 }
637 }
638
639 pub(super) fn apply_type_bindings_to_call_arg(
640 &mut self,
641 arg: &mut CallArg,
642 bindings: &BTreeMap<String, Ty>,
643 type_params: &BTreeSet<String>,
644 ) -> Result<(), ElabError> {
645 match arg {
646 CallArg::Expr(expr) | CallArg::Spread(expr) => {
647 self.apply_type_bindings_to_expr(expr, bindings, type_params)
648 }
649 CallArg::Type(ty) => {
650 let resolved = self.resolve_type_expr(ty, bindings, type_params, None)?;
651 self.ensure_ty_instantiated(&resolved)?;
652 *ty = ty_to_type_expr(&resolved);
653 Ok(())
654 }
655 }
656 }
657
658 pub(super) fn apply_type_bindings_to_type_ref(
659 &mut self,
660 ty: &mut TypeRef,
661 bindings: &BTreeMap<String, Ty>,
662 type_params: &BTreeSet<String>,
663 ) -> Result<(), ElabError> {
664 let resolved = self.resolve_type_expr(&ty.ty, bindings, type_params, None)?;
665 self.ensure_ty_instantiated(&resolved)?;
666 ty.ty = ty_to_type_expr(&resolved);
667 Ok(())
668 }
669}