Skip to content

Commit d0a21ba

Browse files
sor4chikaleidawave
andauthored
fix: synthesize shape in sub-environment scope (#216)
Fixes #196 --------- Co-authored-by: Ben <[email protected]>
1 parent ae5de5d commit d0a21ba

File tree

2 files changed

+98
-75
lines changed

2 files changed

+98
-75
lines changed

checker/specification/specification.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,8 +3363,13 @@ type X = string;
33633363
type X = number;
33643364
const a: X = "hello world";
33653365
}
3366+
3367+
function func<YEA>() {}
3368+
3369+
type B = YEA;
33663370
```
33673371

3372+
- Could not find type 'YEA'
33683373
- Type "hello world" is not assignable to type X
33693374

33703375
#### Type has no generics

checker/src/synthesis/functions.rs

Lines changed: 93 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -636,86 +636,104 @@ pub(super) fn synthesise_shape<T: crate::ReadFromFS, B: parser::FunctionBased>(
636636
environment: &mut Environment,
637637
checking_data: &mut CheckingData<T, super::EznoParser>,
638638
) -> crate::features::functions::PartialFunction {
639-
let type_parameters = function.type_parameters.as_ref().map(|type_parameters| {
640-
super::functions::synthesise_type_parameters(type_parameters, environment, checking_data)
641-
});
642-
643-
let parameters = function
644-
.parameters
645-
.parameters
646-
.iter()
647-
.map(|parameter| {
648-
let parameter_constraint =
649-
parameter.type_annotation.as_ref().map_or(TypeId::ANY_TYPE, |ta| {
650-
synthesise_type_annotation(ta, environment, checking_data)
639+
environment
640+
.new_lexical_environment_fold_into_parent(
641+
Scope::FunctionAnnotation {},
642+
checking_data,
643+
|environment, checking_data| {
644+
let type_parameters = function.type_parameters.as_ref().map(|type_parameters| {
645+
super::functions::synthesise_type_parameters(
646+
type_parameters,
647+
environment,
648+
checking_data,
649+
)
651650
});
652651

653-
// TODO I think this is correct
654-
let is_optional = parameter.additionally.is_some();
655-
let ty = if is_optional {
656-
checking_data.types.new_or_type(parameter_constraint, TypeId::UNDEFINED_TYPE)
657-
} else {
658-
parameter_constraint
659-
};
660-
661-
SynthesisedParameter {
662-
name: variable_field_to_string(parameter.name.get_ast_ref()),
663-
is_optional,
664-
ty,
665-
position: parameter.position.with_source(environment.get_source()),
666-
}
667-
})
668-
.collect();
669-
670-
let rest_parameter = function.parameters.rest_parameter.as_ref().map(|rest_parameter| {
671-
let parameter_constraint =
672-
rest_parameter.type_annotation.as_ref().map_or(TypeId::ANY_TYPE, |annotation| {
673-
synthesise_type_annotation(annotation, environment, checking_data)
674-
});
675-
676-
let item_type = if let TypeId::ERROR_TYPE = parameter_constraint {
677-
TypeId::ERROR_TYPE
678-
} else if let Type::PartiallyAppliedGenerics(PartiallyAppliedGenerics {
679-
on: TypeId::ARRAY_TYPE,
680-
arguments,
681-
}) = checking_data.types.get_type_by_id(parameter_constraint)
682-
{
683-
if let Some(item) = arguments.get_structure_restriction(TypeId::T_TYPE) {
684-
item
685-
} else {
686-
unreachable!()
687-
}
688-
} else {
689-
crate::utilities::notify!("rest parameter should be array error");
690-
// checking_data.diagnostics_container.add_error(
691-
// TypeCheckError::RestParameterAnnotationShouldBeArrayType(rest_parameter.get),
692-
// );
693-
TypeId::ERROR_TYPE
694-
};
695-
696-
let name = variable_field_to_string(&rest_parameter.name);
652+
let parameters = function
653+
.parameters
654+
.parameters
655+
.iter()
656+
.map(|parameter| {
657+
let parameter_constraint =
658+
parameter.type_annotation.as_ref().map_or(TypeId::ANY_TYPE, |ta| {
659+
synthesise_type_annotation(ta, environment, checking_data)
660+
});
661+
662+
// TODO I think this is correct
663+
let is_optional = parameter.additionally.is_some();
664+
let ty = if is_optional {
665+
checking_data
666+
.types
667+
.new_or_type(parameter_constraint, TypeId::UNDEFINED_TYPE)
668+
} else {
669+
parameter_constraint
670+
};
671+
672+
SynthesisedParameter {
673+
name: variable_field_to_string(parameter.name.get_ast_ref()),
674+
is_optional,
675+
ty,
676+
position: parameter.position.with_source(environment.get_source()),
677+
}
678+
})
679+
.collect();
680+
681+
let rest_parameter =
682+
function.parameters.rest_parameter.as_ref().map(|rest_parameter| {
683+
let parameter_constraint = rest_parameter.type_annotation.as_ref().map_or(
684+
TypeId::ANY_TYPE,
685+
|annotation| {
686+
synthesise_type_annotation(annotation, environment, checking_data)
687+
},
688+
);
689+
690+
let item_type = if let TypeId::ERROR_TYPE = parameter_constraint {
691+
TypeId::ERROR_TYPE
692+
} else if let Type::PartiallyAppliedGenerics(PartiallyAppliedGenerics {
693+
on: TypeId::ARRAY_TYPE,
694+
arguments,
695+
}) = checking_data.types.get_type_by_id(parameter_constraint)
696+
{
697+
if let Some(item) = arguments.get_structure_restriction(TypeId::T_TYPE)
698+
{
699+
item
700+
} else {
701+
unreachable!()
702+
}
703+
} else {
704+
crate::utilities::notify!("rest parameter should be array error");
705+
// checking_data.diagnostics_container.add_error(
706+
// TypeCheckError::RestParameterAnnotationShouldBeArrayType(rest_parameter.get),
707+
// );
708+
TypeId::ERROR_TYPE
709+
};
710+
711+
let name = variable_field_to_string(&rest_parameter.name);
712+
713+
SynthesisedRestParameter {
714+
item_type,
715+
// This will be overridden when actual synthesis
716+
ty: parameter_constraint,
717+
name,
718+
position: rest_parameter.position.with_source(environment.get_source()),
719+
}
720+
});
697721

698-
SynthesisedRestParameter {
699-
item_type,
700-
// This will be overridden when actual synthesis
701-
ty: parameter_constraint,
702-
name,
703-
position: rest_parameter.position.with_source(environment.get_source()),
704-
}
705-
});
722+
let return_type = function.return_type.as_ref().map(|annotation| {
723+
ReturnType(
724+
synthesise_type_annotation(annotation, environment, checking_data),
725+
annotation.get_position().with_source(environment.get_source()),
726+
)
727+
});
706728

707-
let return_type = function.return_type.as_ref().map(|annotation| {
708-
ReturnType(
709-
synthesise_type_annotation(annotation, environment, checking_data),
710-
annotation.get_position().with_source(environment.get_source()),
729+
crate::features::functions::PartialFunction(
730+
type_parameters,
731+
SynthesisedParameters { parameters, rest_parameter },
732+
return_type,
733+
)
734+
},
711735
)
712-
});
713-
714-
crate::features::functions::PartialFunction(
715-
type_parameters,
716-
SynthesisedParameters { parameters, rest_parameter },
717-
return_type,
718-
)
736+
.0
719737
}
720738

721739
/// TODO WIP

0 commit comments

Comments
 (0)