diff --git a/stage0/src/ast/func.rs b/stage0/src/ast/func.rs index 4f4670a..3422ca2 100644 --- a/stage0/src/ast/func.rs +++ b/stage0/src/ast/func.rs @@ -53,21 +53,14 @@ impl Function { let mut params = Vec::with_capacity(self.params.len()); for p in &self.params { - let t = match p.ty.to_external(cx, uses.clone()) { - Some(v) => v, - None => return Err(SyntaxError::new(p.ty.name().span(), "undefined type")), - }; - + let t = p.ty.to_external(cx, uses.clone())?; params.push(crate::pkg::FunctionParam::new(p.name.value().to_owned(), t)); } params }, match &self.ret { - Some(v) => match v.to_external(cx, uses.clone()) { - Some(v) => v, - None => return Err(SyntaxError::new(v.name().span(), "undefined type")), - }, + Some(v) => v.to_external(cx, uses.clone())?, None => crate::pkg::Type::Unit { ptr: 0 }, }, ); diff --git a/stage0/src/ast/ty.rs b/stage0/src/ast/ty.rs index d27d77d..f389625 100644 --- a/stage0/src/ast/ty.rs +++ b/stage0/src/ast/ty.rs @@ -32,13 +32,14 @@ impl Type { let mut ty = match &self.name { TypeName::Unit(_, _) => LlvmType::Void(LlvmVoid::new(cx)), TypeName::Never(_) => return Ok(None), - TypeName::Ident(n) => match Self::resolve(cx, uses, n) { - Some((n, t)) => match t { + TypeName::Ident(n) => { + let (n, t) = Self::resolve(cx, uses, n)?; + + match t { ResolvedType::Internal(v) => Self::build_internal_type(cx, &n, v), ResolvedType::External((_, t)) => Self::build_external_type(cx, &n, t), - }, - None => return Err(SyntaxError::new(n.span(), "type is undefined")), - }, + } + } }; // Resolve pointers. @@ -53,7 +54,7 @@ impl Type { &self, cx: &Codegen<'b>, uses: U, - ) -> Option { + ) -> Result { use crate::pkg::Type; let ptr = self.prefixes.len(); @@ -97,7 +98,7 @@ impl Type { } }; - Some(ty) + Ok(ty) } fn build_internal_type<'a, 'b: 'a>( @@ -176,9 +177,9 @@ impl Type { cg: &Codegen<'b>, uses: U, name: &Path, - ) -> Option<(String, &'b ResolvedType<'b>)> { + ) -> Result<(String, &'b ResolvedType<'b>), SyntaxError> { // Resolve full name. - let name = match name.as_local() { + let (name, span) = match name.as_local() { Some(name) => { // Search from use declarations first to allow overrides. let mut found = None; @@ -199,23 +200,26 @@ impl Type { } match found { - Some(v) => v.name().to_string(), + Some(v) => (v.name().to_string(), v.name().span()), None => { - if cg.namespace().is_empty() { + let fqtn = if cg.namespace().is_empty() { format!("self.{}", name) } else { format!("self.{}.{}", cg.namespace(), name) - } + }; + + (fqtn, name.span().clone()) } } } - None => name.to_string(), + None => (name.to_string(), name.span()), }; // Resolve type. - let ty = cg.resolver().resolve(&name)?; - - Some((name, ty)) + match cg.resolver().resolve(&name) { + Some(ty) => Ok((name, ty)), + None => Err(SyntaxError::new(span, "undefined type")), + } } }