Extract register_types
@@ -6,7 +6,7 @@ use crate::ast::{
self, Arg, ArgNames, BinOp, CallArg, Clause, ClauseGuard, Expr, Meta, Pattern, Statement,
TypeAst, TypedClause, TypedClauseGuard, TypedExpr, TypedModule, TypedMultiPattern,
TypedPattern, UnqualifiedImport, UntypedClause, UntypedClauseGuard, UntypedExpr, UntypedModule,
- UntypedMultiPattern, UntypedPattern,
+ UntypedMultiPattern, UntypedPattern, UntypedStatement,
};
use crate::error::GleamExpect;
use std::cell::RefCell;
@@ -1268,20 +1268,13 @@ fn make_type_vars(
.collect::<Result<_, _>>()
}
-/// Crawl the AST, annotating each node with the inferred type or
-/// returning an error.
-///
-pub fn infer_module(
- module: UntypedModule,
- modules: &HashMap<String, Module>,
-) -> Result<TypedModule, Error> {
- let mut env = Env::new(modules);
- let module_name = &module.name;
-
- // Register types so they can be used in constructors and functions
- // earlier in the file
- for s in module.statements.iter() {
- match s {
+/// Iterate over a module, registering any new types created by the module into the env
+fn register_types(
+ statement: &UntypedStatement,
+ module: &Vec<String>,
+ env: &mut Env,
+) -> Result<(), Error> {
+ match statement {
Statement::ExternalType {
name,
public,
@@ -1297,10 +1290,10 @@ pub fn infer_module(
..
} => {
let mut type_vars = hashmap![];
- let parameters = make_type_vars(args, &mut type_vars, meta, &mut env)?;
+ let parameters = make_type_vars(args, &mut type_vars, meta, env)?;
let typ = Type::App {
public: *public,
- module: module_name.clone(),
+ module: module.clone(),
name: name.clone(),
args: parameters.clone(),
};
@@ -1308,7 +1301,7 @@ pub fn infer_module(
name.clone(),
TypeConstructor {
origin: meta.clone(),
- module: module_name.clone(),
+ module: module.clone(),
public: *public,
parameters,
typ,
@@ -1324,14 +1317,13 @@ pub fn infer_module(
resolved_type,
} => {
let mut type_vars = hashmap![];
- let parameters = make_type_vars(args, &mut type_vars, meta, &mut env)?;
- let typ =
- env.type_from_ast(&resolved_type, &mut type_vars, NewTypeAction::Disallow)?;
+ let parameters = make_type_vars(args, &mut type_vars, meta, env)?;
+ let typ = env.type_from_ast(&resolved_type, &mut type_vars, NewTypeAction::Disallow)?;
env.insert_type_constructor(
name.clone(),
TypeConstructor {
origin: meta.clone(),
- module: module_name.clone(),
+ module: module.clone(),
public: *public,
parameters,
typ,
@@ -1341,6 +1333,23 @@ pub fn infer_module(
_ => {}
}
+ Ok(())
+}
+
+/// Crawl the AST, annotating each node with the inferred type or
+/// returning an error.
+///
+pub fn infer_module(
+ module: UntypedModule,
+ modules: &HashMap<String, Module>,
+) -> Result<TypedModule, Error> {
+ let mut env = Env::new(modules);
+ let module_name = &module.name;
+
+ // Register types so they can be used in constructors and functions
+ // earlier in the file
+ for s in module.statements.iter() {
+ register_types(s, module_name, &mut env)?;
}
let statements: Vec<Statement<_, _, _, Type>> = module
