Fix checking that parameters and return-type is known
This commit is contained in:
parent
0a90ac4497
commit
ef427f5e58
@ -542,7 +542,7 @@ pub fn pick_return<T>(lhs: (ReturnKind, T), rhs: (ReturnKind, T)) -> (ReturnKind
|
||||
impl TypeKind {
|
||||
/// Assert that a type is already known and not vague. Return said type or
|
||||
/// error.
|
||||
pub fn assert_known(&self) -> Result<TypeKind, ErrorKind> {
|
||||
pub fn assert_unvague(&self) -> Result<TypeKind, ErrorKind> {
|
||||
self.known().map_err(ErrorKind::TypeIsVague)
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ impl<'t> Pass for TypeCheck<'t> {
|
||||
name,
|
||||
kind,
|
||||
meta,
|
||||
source_module,
|
||||
source_module: _,
|
||||
} = &typedef;
|
||||
|
||||
match kind {
|
||||
@ -162,12 +162,12 @@ fn check_typedefs_for_recursion<'a, 'b>(
|
||||
impl FunctionDefinition {
|
||||
fn typecheck(
|
||||
&mut self,
|
||||
hints: &TypeRefs,
|
||||
typerefs: &TypeRefs,
|
||||
state: &mut TypecheckPassState,
|
||||
) -> Result<TypeKind, ErrorKind> {
|
||||
for param in &self.parameters {
|
||||
let param_t = state.or_else(
|
||||
param.1.assert_known(),
|
||||
param.1.assert_known(typerefs, state),
|
||||
TypeKind::Vague(Vague::Unknown),
|
||||
self.signature(),
|
||||
);
|
||||
@ -185,11 +185,11 @@ impl FunctionDefinition {
|
||||
state.ok(res, self.signature());
|
||||
}
|
||||
|
||||
let return_type = self.return_type.clone();
|
||||
let return_type = self.return_type.clone().assert_known(typerefs, state)?;
|
||||
let inferred = match &mut self.kind {
|
||||
FunctionDefinitionKind::Local(block, _) => {
|
||||
state.scope.return_type_hint = Some(self.return_type.clone());
|
||||
block.typecheck(&mut state.inner(), &hints, Some(&return_type))
|
||||
block.typecheck(&mut state.inner(), &typerefs, Some(&return_type))
|
||||
}
|
||||
FunctionDefinitionKind::Extern(_) => {
|
||||
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
||||
@ -755,3 +755,29 @@ impl Literal {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeKind {
|
||||
fn assert_known(
|
||||
&self,
|
||||
refs: &TypeRefs,
|
||||
state: &TypecheckPassState,
|
||||
) -> Result<TypeKind, ErrorKind> {
|
||||
match &self {
|
||||
TypeKind::Array(type_kind, _) => type_kind.as_ref().assert_known(refs, state),
|
||||
TypeKind::CustomType(custom_type_key) => state
|
||||
.scope
|
||||
.types
|
||||
.get(custom_type_key)
|
||||
.map(|_| self.clone())
|
||||
.ok_or(ErrorKind::NoSuchType(
|
||||
custom_type_key.0.clone(),
|
||||
state.module_id.unwrap(),
|
||||
)),
|
||||
TypeKind::Borrow(type_kind, _) => type_kind.assert_known(refs, state),
|
||||
TypeKind::UserPtr(type_kind) => type_kind.assert_known(refs, state),
|
||||
TypeKind::CodegenPtr(type_kind) => type_kind.assert_known(refs, state),
|
||||
TypeKind::Vague(vague_type) => Err(ErrorKind::TypeIsVague(*vague_type)),
|
||||
_ => Ok(self.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ impl FunctionDefinition {
|
||||
) -> Result<(), ErrorKind> {
|
||||
let scope_hints = ScopeTypeRefs::from(type_refs);
|
||||
for param in &self.parameters {
|
||||
let param_t = state.or_else(param.1.assert_known(), Vague(Unknown), self.signature());
|
||||
let param_t = state.or_else(param.1.assert_unvague(), Vague(Unknown), self.signature());
|
||||
let res = scope_hints
|
||||
.new_var(param.0.clone(), false, ¶m_t)
|
||||
.or(Err(ErrorKind::VariableAlreadyDefined(param.0.clone())));
|
||||
|
5
reid_src/test.reid
Normal file
5
reid_src/test.reid
Normal file
@ -0,0 +1,5 @@
|
||||
extern fn SDL_malloc(size: u64) -> *SDL_Thing;
|
||||
|
||||
fn main() {
|
||||
let pixels = SDL_malloc(4 * 320 * 240);
|
||||
}
|
Loading…
Reference in New Issue
Block a user