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 UntypedPattern = Pattern<(), (), Namespace>;
pub type TypedPattern = Pattern<PatternConstructor, Rc<Type>>; pub type TypedPattern = Pattern<PatternConstructor, Rc<Type>, String>;
impl TypedPattern { impl TypedPattern {
pub fn var(name: &str) -> Self { pub fn var(name: &str) -> Self {
@ -1654,7 +1654,13 @@ impl TypedPattern {
} }
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] #[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 { Int {
location: Span, location: Span,
value: String, value: String,
@ -1707,7 +1713,7 @@ pub enum Pattern<Constructor, Type> {
location: Span, location: Span,
name: String, name: String,
arguments: Vec<CallArg<Self>>, arguments: Vec<CallArg<Self>>,
module: Option<String>, module: Option<NamespaceKind>,
constructor: Constructor, constructor: Constructor,
spread_location: Option<Span>, spread_location: Option<Span>,
tipo: Type, 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 { pub fn location(&self) -> Span {
match self { match self {
Pattern::Assign { pattern, .. } => pattern.location(), 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 UntypedMultiPattern = MultiPattern<(), (), Namespace>;
pub type TypedMultiPattern = MultiPattern<PatternConstructor, Rc<Type>>; pub type TypedMultiPattern = MultiPattern<PatternConstructor, Rc<Type>, String>;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct UntypedClause { pub struct UntypedClause {
pub location: Span, pub location: Span,
pub patterns: Vec1<Pattern<(), ()>>, pub patterns: Vec1<UntypedPattern>,
pub then: UntypedExpr, pub then: UntypedExpr,
} }
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct TypedClause { pub struct TypedClause {
pub location: Span, pub location: Span,
pub pattern: Pattern<PatternConstructor, Rc<Type>>, pub pattern: TypedPattern,
pub then: TypedExpr, pub then: TypedExpr,
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ use super::{
hydrator::Hydrator, hydrator::Hydrator,
PatternConstructor, Type, ValueConstructorVariant, PatternConstructor, Type, ValueConstructorVariant,
}; };
use crate::ast::{CallArg, Pattern, Span, TypedPattern, UntypedPattern}; use crate::ast::{CallArg, Namespace, Pattern, Span, TypedPattern, UntypedPattern};
use itertools::Itertools; use itertools::Itertools;
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
@ -570,7 +570,12 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
Ok(Pattern::Constructor { Ok(Pattern::Constructor {
location, 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, name,
arguments: pattern_args, arguments: pattern_args,
constructor, constructor,
@ -601,7 +606,12 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
Ok(Pattern::Constructor { Ok(Pattern::Constructor {
location, 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, name,
arguments: vec![], arguments: vec![],
constructor, constructor,