Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

remove akward wrapping of constant record in function expression

author
Giacomo Cavalieri
committer
Louis Pilfold
date (May 21, 2026, 12:59 PM +0100) commit 43465204 parent 255845a5 change-id rysqpqyr
+31 -78
+10
compiler-core/src/type_.rs
··· 884 884 ValueConstructorVariant::Record { field_map, .. } => field_map.as_ref(), 885 885 } 886 886 } 887 + 888 + fn is_record_constructor_function(&self) -> bool { 889 + match self { 890 + ValueConstructorVariant::LocalVariable { .. } 891 + | ValueConstructorVariant::ModuleFn { .. } 892 + | ValueConstructorVariant::ModuleConstant { .. } => false, 893 + // If it has an arity of zero then it can't be used as a function! 894 + ValueConstructorVariant::Record { arity, .. } => *arity > 0, 895 + } 896 + } 887 897 } 888 898 889 899 #[derive(Debug, Clone, PartialEq, Eq)]
+21 -78
compiler-core/src/type_/expression.rs
··· 4383 4383 } 4384 4384 }; 4385 4385 4386 - let (tag, field_map, variant_index) = match &constructor.variant { 4386 + let (tag, field_map) = match &constructor.variant { 4387 4387 ValueConstructorVariant::Record { 4388 - name, 4389 - field_map, 4390 - variant_index, 4391 - .. 4392 - } => ( 4393 - name.clone(), 4394 - match field_map { 4395 - Some(field_map) => Inferred::Known(field_map.clone()), 4396 - None => Inferred::Unknown, 4397 - }, 4398 - *variant_index, 4399 - ), 4388 + name, field_map, .. 4389 + } => (name.clone(), field_map.clone()), 4400 4390 4401 4391 ValueConstructorVariant::ModuleFn { .. } 4402 4392 | ValueConstructorVariant::LocalVariable { .. } => { ··· 4411 4401 } 4412 4402 }; 4413 4403 4414 - // Pretty much all the other infer functions operate on UntypedExpr 4415 - // or TypedExpr rather than ClauseGuard. To make things easier we 4416 - // build the TypedExpr equivalent of the constructor and use that 4417 - // TODO: resvisit this. It is rather awkward at present how we 4418 - // have to convert to this other data structure. 4419 - let fun = match &module { 4420 - Some((module_alias, module_location)) => { 4421 - let type_ = Arc::clone(&constructor.type_); 4422 - let module_name = self 4423 - .environment 4424 - .imported_modules 4425 - // TODO: remove 4426 - .get(module_alias) 4427 - .expect("Failed to find previously located module import") 4428 - .1 4429 - .name 4430 - .clone(); 4431 - let module_value_constructor = ModuleValueConstructor::Record { 4432 - name: name.clone(), 4433 - variant_index, 4434 - field_map: match &field_map { 4435 - Inferred::Known(fm) => Some(fm.clone()), 4436 - Inferred::Unknown => None, 4437 - }, 4438 - arity: arguments.len() as u16, 4439 - type_: Arc::clone(&type_), 4440 - location: constructor.variant.definition_location(), 4441 - documentation: None, 4442 - }; 4443 - 4444 - TypedExpr::ModuleSelect { 4445 - location: module_location.merge(&location), 4446 - field_start: location.start, 4447 - label: name.clone(), 4448 - module_alias: module_alias.clone(), 4449 - module_name, 4450 - type_, 4451 - constructor: module_value_constructor, 4452 - } 4453 - } 4454 - 4455 - None => TypedExpr::Var { 4456 - constructor: constructor.clone(), 4457 - location, 4458 - name: name.clone(), 4459 - }, 4460 - }; 4461 - 4462 4404 // This is basically the same code as do_infer_call_with_known_fun() 4463 4405 // except the args are typed with infer_clause_guard() here. 4464 4406 // This duplication is a bit awkward but it works! 4465 4407 // Potentially this could be improved later 4466 - let result = match self.get_field_map(&fun) { 4467 - // There's an error retrieving the field map, in that case we 4468 - // return an invalid constant. 4469 - Err(error) => { 4470 - self.problems 4471 - .error(convert_get_value_constructor_error(error, location, None)); 4472 - return self.new_invalid_constant(location); 4473 - } 4408 + let result = match &field_map { 4474 4409 // The fun has a field map so labelled arguments may be present 4475 4410 // and need to be reordered. 4476 - Ok(Some(field_map)) => { 4411 + Some(field_map) => { 4477 4412 field_map.reorder(&mut arguments, location, IncorrectArityContext::Function) 4478 4413 } 4479 4414 // The fun or constructor has no field map and so we error 4480 4415 // if arguments have been labelled. 4481 - Ok(None) if fun.is_record_constructor_function() => assert_no_labelled_arguments( 4482 - &arguments, 4483 - UnexpectedLabelledArgKind::RecordConstructorArgument, 4484 - ), 4485 - Ok(None) => assert_no_labelled_arguments( 4416 + None if constructor.variant.is_record_constructor_function() => { 4417 + assert_no_labelled_arguments( 4418 + &arguments, 4419 + UnexpectedLabelledArgKind::RecordConstructorArgument, 4420 + ) 4421 + } 4422 + 4423 + None => assert_no_labelled_arguments( 4486 4424 &arguments, 4487 4425 UnexpectedLabelledArgKind::FunctionParameter, 4488 4426 ), ··· 4496 4434 } 4497 4435 4498 4436 let (mut arguments_types, return_type) = 4499 - match match_fun_type(fun.type_(), arguments.len(), self.environment) { 4437 + match match_fun_type(constructor.type_.clone(), arguments.len(), self.environment) { 4500 4438 Ok((arguments_types, return_type)) => (arguments_types, return_type), 4501 4439 Err(error) => { 4502 4440 self.problems.error(convert_not_fun_error( 4503 4441 error, 4504 - fun.location(), 4442 + module.map_or(location, |(_, module_location)| { 4443 + module_location.merge(&location) 4444 + }), 4505 4445 location, 4506 4446 CallKind::Function, 4507 4447 )); ··· 4543 4483 arguments, 4544 4484 type_: return_type, 4545 4485 tag, 4546 - field_map, 4486 + field_map: match field_map { 4487 + Some(field_map) => Inferred::Known(field_map), 4488 + None => Inferred::Unknown, 4489 + }, 4547 4490 record_constructor: Some(Box::new(constructor)), 4548 4491 } 4549 4492 }