From d598de4ac50e1e5a807d03899c52edf045f97748 Mon Sep 17 00:00:00 2001 From: IsaacShelton Date: Thu, 12 Dec 2024 20:51:09 -0600 Subject: [PATCH] Started implementing structure polymorph constraint enforcement --- src/resolve/type_ctx/mod.rs | 31 ++++++++++++++++++++++++-- src/resolve/type_ctx/resolve_type.rs | 30 +++++-------------------- src/resolve/type_definition/prepare.rs | 13 +++++------ 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/resolve/type_ctx/mod.rs b/src/resolve/type_ctx/mod.rs index 52b7f45e..5717a62c 100644 --- a/src/resolve/type_ctx/mod.rs +++ b/src/resolve/type_ctx/mod.rs @@ -2,8 +2,16 @@ mod find; mod find_error; mod resolve_type; -use super::expr::ResolveExprCtx; -use crate::{name::ResolvedName, resolved, workspace::fs::FsNodeId}; +use super::{ + error::{ResolveError, ResolveErrorKind}, + expr::ResolveExprCtx, +}; +use crate::{ + ast, + name::ResolvedName, + resolved::{self, Constraint}, + workspace::fs::FsNodeId, +}; use std::collections::{HashMap, HashSet}; #[derive(Debug)] @@ -42,3 +50,22 @@ impl<'a, 'b, 'c> From<&'c ResolveExprCtx<'a, 'b>> for ResolveTypeCtx<'c> { ) } } + +pub fn resolve_constraints(constraints: &[ast::Type]) -> Result, ResolveError> { + let mut resolved_constraints = vec![]; + + for constraint in constraints { + if let ast::TypeKind::Named(name, arguments) = &constraint.kind { + resolved_constraints.push(match name.as_plain_str() { + Some("PrimitiveAdd") if arguments.is_empty() => Constraint::PrimitiveAdd, + _ => { + return Err( + ResolveErrorKind::UndeclaredTrait(name.to_string()).at(constraint.source) + ) + } + }); + } + } + + Ok(resolved_constraints) +} diff --git a/src/resolve/type_ctx/resolve_type.rs b/src/resolve/type_ctx/resolve_type.rs index 51decd9f..2d92d854 100644 --- a/src/resolve/type_ctx/resolve_type.rs +++ b/src/resolve/type_ctx/resolve_type.rs @@ -1,9 +1,9 @@ -use super::ResolveTypeCtx; +use super::{resolve_constraints, ResolveTypeCtx}; use crate::{ ast::{self, IntegerBits}, ir::IntegerSign, resolve::error::{ResolveError, ResolveErrorKind}, - resolved::{self, Constraint}, + resolved, source_files::Source, }; use std::borrow::Borrow; @@ -81,28 +81,10 @@ impl<'a> ResolveTypeCtx<'a> { }, )) } - ast::TypeKind::Polymorph(polymorph, constraints) => { - let mut resolved_constraints = vec![]; - - for constraint in constraints { - if let ast::TypeKind::Named(name, arguments) = &constraint.kind { - resolved_constraints.push(match name.as_plain_str() { - Some("PrimitiveAdd") if arguments.is_empty() => { - Constraint::PrimitiveAdd - } - _ => { - return Err(ResolveErrorKind::UndeclaredTrait(name.to_string()) - .at(constraint.source)) - } - }); - } - } - - Ok(resolved::TypeKind::Polymorph( - polymorph.clone(), - resolved_constraints, - )) - } + ast::TypeKind::Polymorph(polymorph, constraints) => Ok(resolved::TypeKind::Polymorph( + polymorph.clone(), + resolve_constraints(constraints)?, + )), } .map(|kind| kind.at(ast_type.source)) } diff --git a/src/resolve/type_definition/prepare.rs b/src/resolve/type_definition/prepare.rs index 0d9a954a..4af19159 100644 --- a/src/resolve/type_definition/prepare.rs +++ b/src/resolve/type_definition/prepare.rs @@ -5,6 +5,7 @@ use crate::{ ctx::ResolveCtx, error::{ResolveError, ResolveErrorKind}, job::TypeJob, + type_ctx::resolve_constraints, }, resolved::{self, EnumRef, HumanName, StructureRef, TypeAliasRef, TypeDecl, TypeParameters}, workspace::fs::FsNodeId, @@ -37,7 +38,7 @@ pub fn prepare_type_jobs( resolved_ast, module_fs_node_id, structure, - )); + )?); } for definition in file.enums.iter() { @@ -69,17 +70,13 @@ fn prepare_structure( resolved_ast: &mut resolved::Ast, module_fs_node_id: FsNodeId, structure: &ast::Structure, -) -> StructureRef { +) -> Result { let source = structure.source; let mut parameters = TypeParameters::default(); for (name, parameter) in structure.parameters.iter() { - let constraints = vec![]; - - if !parameter.constraints.is_empty() { - todo!("type parameters with constraints are not supported yet"); - } + let constraints = resolve_constraints(¶meter.constraints)?; if parameters .parameters @@ -123,7 +120,7 @@ fn prepare_structure( }, ); - structure_ref + Ok(structure_ref) } fn prepare_enum(