introduce namespace enum to distinguish module select from type constructor select in patterns.

Signed-off-by: KtorZ <matthias.benkort@gmail.com>
This commit is contained in:
KtorZ 2025-03-15 15:49:22 +01:00
parent f786e80924
commit c556ada7d5
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
8 changed files with 70 additions and 43 deletions

View File

@ -1535,8 +1535,8 @@ impl BinOp {
}
}
pub type UntypedPattern = Pattern<(), ()>;
pub type TypedPattern = Pattern<PatternConstructor, Rc<Type>>;
pub type UntypedPattern = Pattern<(), (), Namespace>;
pub type TypedPattern = Pattern<PatternConstructor, Rc<Type>, String>;
impl TypedPattern {
pub fn var(name: &str) -> Self {
@ -1654,7 +1654,13 @@ impl TypedPattern {
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum Pattern<Constructor, Type> {
pub enum Namespace {
Module(String),
Type(String),
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum Pattern<Constructor, Type, NamespaceKind> {
Int {
location: Span,
value: String,
@ -1707,7 +1713,7 @@ pub enum Pattern<Constructor, Type> {
location: Span,
name: String,
arguments: Vec<CallArg<Self>>,
module: Option<String>,
module: Option<NamespaceKind>,
constructor: Constructor,
spread_location: Option<Span>,
tipo: Type,
@ -1725,7 +1731,7 @@ pub enum Pattern<Constructor, Type> {
},
}
impl<A, B> Pattern<A, B> {
impl<A, B, C> Pattern<A, B, C> {
pub fn location(&self) -> Span {
match self {
Pattern::Assign { pattern, .. } => pattern.location(),
@ -2201,22 +2207,23 @@ impl<T: Default> AssignmentKind<T> {
}
}
pub type MultiPattern<PatternConstructor, Type> = Vec<Pattern<PatternConstructor, Type>>;
pub type MultiPattern<PatternConstructor, Type, NamespaceKind> =
Vec<Pattern<PatternConstructor, Type, NamespaceKind>>;
pub type UntypedMultiPattern = MultiPattern<(), ()>;
pub type TypedMultiPattern = MultiPattern<PatternConstructor, Rc<Type>>;
pub type UntypedMultiPattern = MultiPattern<(), (), Namespace>;
pub type TypedMultiPattern = MultiPattern<PatternConstructor, Rc<Type>, String>;
#[derive(Debug, Clone, PartialEq)]
pub struct UntypedClause {
pub location: Span,
pub patterns: Vec1<Pattern<(), ()>>,
pub patterns: Vec1<UntypedPattern>,
pub then: UntypedExpr,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct TypedClause {
pub location: Span,
pub pattern: Pattern<PatternConstructor, Rc<Type>>,
pub pattern: TypedPattern,
pub then: TypedExpr,
}

View File

@ -2,16 +2,15 @@ pub(crate) use crate::{
ast::{
self, Annotation, ArgBy, ArgName, AssignmentKind, AssignmentPattern, BinOp, Bls12_381Point,
ByteArrayFormatPreference, CallArg, Curve, DataType, DataTypeKey, DefinitionLocation,
Located, LogicalOpChainKind, ParsedCallArg, Pattern, RecordConstructorArg,
RecordUpdateSpread, Span, TraceKind, TypedArg, TypedAssignmentKind, TypedClause,
TypedDataType, TypedIfBranch, TypedPattern, TypedRecordUpdateArg, UnOp, UntypedArg,
UntypedAssignmentKind, UntypedClause, UntypedIfBranch, UntypedRecordUpdateArg,
Located, LogicalOpChainKind, ParsedCallArg, RecordConstructorArg, RecordUpdateSpread, Span,
TraceKind, TypedArg, TypedAssignmentKind, TypedClause, TypedDataType, TypedIfBranch,
TypedPattern, TypedRecordUpdateArg, UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause,
UntypedIfBranch, UntypedRecordUpdateArg,
},
parser::token::Base,
tipo::{
check_replaceable_opaque_type, convert_opaque_type, lookup_data_type_by_tipo,
ModuleValueConstructor, PatternConstructor, Type, TypeVar, ValueConstructor,
ValueConstructorVariant,
ModuleValueConstructor, Type, TypeVar, ValueConstructor, ValueConstructorVariant,
},
};
use indexmap::IndexMap;
@ -109,7 +108,7 @@ pub enum TypedExpr {
location: Span,
tipo: Rc<Type>,
value: Box<Self>,
pattern: Pattern<PatternConstructor, Rc<Type>>,
pattern: TypedPattern,
kind: TypedAssignmentKind,
},

View File

@ -2,7 +2,7 @@ use crate::{
ast::{
Annotation, ArgBy, ArgName, ArgVia, AssignmentKind, AssignmentPattern, BinOp,
ByteArrayFormatPreference, CallArg, CurveType, DataType, Definition, Function,
LogicalOpChainKind, ModuleConstant, OnTestFailure, Pattern, RecordConstructor,
LogicalOpChainKind, ModuleConstant, Namespace, OnTestFailure, Pattern, RecordConstructor,
RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg,
TypedValidator, UnOp, UnqualifiedImport, UntypedArg, UntypedArgVia, UntypedAssignmentKind,
UntypedClause, UntypedDefinition, UntypedFunction, UntypedIfBranch, UntypedModule,
@ -1202,7 +1202,7 @@ impl<'comments> Formatter<'comments> {
&mut self,
name: &'a str,
args: &'a [CallArg<UntypedPattern>],
module: &'a Option<String>,
module: &'a Option<Namespace>,
spread_location: Option<Span>,
is_record: bool,
) -> Document<'a> {
@ -1217,7 +1217,9 @@ impl<'comments> Formatter<'comments> {
}
let name = match module {
Some(m) => m.to_doc().append(".").append(name),
Some(Namespace::Module(m)) | Some(Namespace::Type(m)) => {
m.to_doc().append(".").append(name)
}
None => name.to_doc(),
};

View File

@ -8,7 +8,9 @@ Constructor {
name: "Foo",
arguments: [],
module: Some(
"module",
Module(
"module",
),
),
constructor: (),
spread_location: None,

View File

@ -8,9 +8,9 @@ use super::{
use crate::{
ast::{
self, Annotation, CallArg, DataType, Definition, Function, ModuleConstant, ModuleKind,
RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition, TypedFunction,
TypedPattern, TypedValidator, UnqualifiedImport, UntypedArg, UntypedDefinition,
UntypedFunction, Use, Validator, PIPE_VARIABLE,
Namespace, RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition,
TypedFunction, TypedPattern, TypedValidator, UnqualifiedImport, UntypedArg,
UntypedDefinition, UntypedFunction, Use, Validator, PIPE_VARIABLE,
},
tipo::{fields::FieldMap, TypeAliasAnnotation},
IdGenerator,
@ -443,7 +443,7 @@ impl<'a> Environment<'a> {
#[allow(clippy::result_large_err)]
pub fn get_value_constructor(
&mut self,
module: Option<&String>,
module: Option<&Namespace>,
name: &str,
location: Span,
) -> Result<&ValueConstructor, Error> {
@ -457,7 +457,11 @@ impl<'a> Environment<'a> {
constructors: self.local_constructor_names(),
}),
Some(m) => {
Some(Namespace::Type(..)) => {
todo!()
}
Some(Namespace::Module(m)) => {
let (_, module) =
self.imported_modules
.get(m)

View File

@ -1,6 +1,9 @@
use super::Type;
use crate::{
ast::{Annotation, BinOp, CallArg, LogicalOpChainKind, Span, UntypedFunction, UntypedPattern},
ast::{
Annotation, BinOp, CallArg, LogicalOpChainKind, Namespace, Span, UntypedFunction,
UntypedPattern,
},
error::ExtraData,
expr::{self, AssignmentPattern, UntypedAssignmentKind, UntypedExpr},
format::Formatter,
@ -395,7 +398,7 @@ From there, you can define 'increment', a function that takes a single argument
expected: usize,
given: Vec<CallArg<UntypedPattern>>,
name: String,
module: Option<String>,
module: Option<Namespace>,
is_record: bool,
},
@ -718,7 +721,7 @@ Perhaps, try the following:
label: String,
name: String,
args: Vec<CallArg<UntypedPattern>>,
module: Option<String>,
module: Option<Namespace>,
spread_location: Option<Span>,
},
@ -1274,7 +1277,7 @@ fn suggest_pattern(
expected: usize,
name: &str,
given: &[CallArg<UntypedPattern>],
module: &Option<String>,
module: &Option<Namespace>,
is_record: bool,
) -> Option<String> {
if expected > given.len() {
@ -1309,7 +1312,7 @@ fn suggest_generic(name: &str, expected: usize) -> String {
fn suggest_constructor_pattern(
name: &str,
args: &[CallArg<UntypedPattern>],
module: &Option<String>,
module: &Option<Namespace>,
spread_location: Option<Span>,
) -> String {
let fixed_args = args

View File

@ -11,11 +11,11 @@ use super::{
use crate::{
ast::{
self, Annotation, ArgName, AssignmentKind, AssignmentPattern, BinOp, Bls12_381Point,
ByteArrayFormatPreference, CallArg, Curve, Function, IfBranch, LogicalOpChainKind, Pattern,
RecordUpdateSpread, Span, TraceKind, TraceLevel, Tracing, TypedArg, TypedCallArg,
TypedClause, TypedIfBranch, TypedPattern, TypedRecordUpdateArg, TypedValidator, UnOp,
UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedFunction, UntypedIfBranch,
UntypedPattern, UntypedRecordUpdateArg,
ByteArrayFormatPreference, CallArg, Curve, Function, IfBranch, LogicalOpChainKind,
Namespace, Pattern, RecordUpdateSpread, Span, TraceKind, TraceLevel, Tracing, TypedArg,
TypedCallArg, TypedClause, TypedIfBranch, TypedPattern, TypedRecordUpdateArg,
TypedValidator, UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedFunction,
UntypedIfBranch, UntypedPattern, UntypedRecordUpdateArg,
},
builtins::{from_default_function, BUILTIN},
expr::{FnStyle, TypedExpr, UntypedExpr},
@ -404,7 +404,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
module_alias,
label,
..
} => (Some(module_alias), label),
} => (Some(Namespace::Module(module_alias.to_string())), label),
TypedExpr::Var { name, .. } => (None, name),
@ -413,7 +413,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
Ok(self
.environment
.get_value_constructor(module, name, location)?
.get_value_constructor(module.as_ref(), name, location)?
.field_map())
}
@ -792,12 +792,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
args: Vec<UntypedRecordUpdateArg>,
location: Span,
) -> Result<TypedExpr, Error> {
let (module, name): (Option<String>, String) = match self.infer(constructor.clone())? {
let (module, name): (Option<Namespace>, String) = match self.infer(constructor.clone())? {
TypedExpr::ModuleSelect {
module_alias,
label,
..
} => (Some(module_alias), label),
} => (Some(Namespace::Module(module_alias)), label),
TypedExpr::Var { name, .. } => (None, name),

View File

@ -6,7 +6,7 @@ use super::{
hydrator::Hydrator,
PatternConstructor, Type, ValueConstructorVariant,
};
use crate::ast::{CallArg, Pattern, Span, TypedPattern, UntypedPattern};
use crate::ast::{CallArg, Namespace, Pattern, Span, TypedPattern, UntypedPattern};
use itertools::Itertools;
use std::{
collections::{HashMap, HashSet},
@ -570,7 +570,12 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
Ok(Pattern::Constructor {
location,
module,
// NOTE:
// Type namespaces are completely erased during type-check.
module: match module {
None | Some(Namespace::Type(_)) => None,
Some(Namespace::Module(m)) => Some(m),
},
name,
arguments: pattern_args,
constructor,
@ -601,7 +606,12 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
Ok(Pattern::Constructor {
location,
module,
// NOTE:
// Type namespaces are completely erased during type-check.
module: match module {
None | Some(Namespace::Type(_)) => None,
Some(Namespace::Module(m)) => Some(m),
},
name,
arguments: vec![],
constructor,