feat: add module constants
This commit is contained in:
parent
34c8a58391
commit
fedafed845
|
@ -185,6 +185,11 @@ pub enum Constant<T, RecordTag> {
|
|||
value: String,
|
||||
},
|
||||
|
||||
Tuple {
|
||||
location: Span,
|
||||
elements: Vec<Self>,
|
||||
},
|
||||
|
||||
List {
|
||||
location: Span,
|
||||
elements: Vec<Self>,
|
||||
|
@ -221,6 +226,9 @@ impl TypedConstant {
|
|||
Constant::Int { .. } => builtins::int(),
|
||||
Constant::String { .. } => builtins::string(),
|
||||
Constant::ByteArray { .. } => builtins::byte_array(),
|
||||
Constant::Tuple { elements, .. } => {
|
||||
builtins::tuple(elements.iter().map(|e| e.tipo()).collect())
|
||||
}
|
||||
Constant::List { tipo, .. }
|
||||
| Constant::Record { tipo, .. }
|
||||
| Constant::Var { tipo, .. } => tipo.clone(),
|
||||
|
@ -232,6 +240,7 @@ impl<A, B> Constant<A, B> {
|
|||
pub fn location(&self) -> Span {
|
||||
match self {
|
||||
Constant::Int { location, .. }
|
||||
| Constant::Tuple { location, .. }
|
||||
| Constant::List { location, .. }
|
||||
| Constant::String { location, .. }
|
||||
| Constant::Record { location, .. }
|
||||
|
|
|
@ -351,6 +351,13 @@ impl<'comments> Formatter<'comments> {
|
|||
module: Some(module),
|
||||
..
|
||||
} => docvec![module, ".", name],
|
||||
|
||||
Constant::Tuple { elements, .. } => "#"
|
||||
.to_doc()
|
||||
.append(wrap_args(
|
||||
elements.iter().map(|e| (self.const_expr(e), false)),
|
||||
))
|
||||
.group(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ fn module_parser() -> impl Parser<Token, Vec<UntypedDefinition>, Error = ParseEr
|
|||
data_parser(),
|
||||
type_alias_parser(),
|
||||
fn_parser(),
|
||||
constant_parser(),
|
||||
))
|
||||
.repeated()
|
||||
.then_ignore(end())
|
||||
|
@ -265,6 +266,202 @@ pub fn fn_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseEr
|
|||
)
|
||||
}
|
||||
|
||||
fn constant_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError> {
|
||||
pub_parser()
|
||||
.or_not()
|
||||
.then_ignore(just(Token::Const))
|
||||
.then(select! {Token::Name{name} => name})
|
||||
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
|
||||
.then_ignore(just(Token::Equal))
|
||||
.then(constant_value_parser())
|
||||
.map_with_span(|(((public, name), annotation), value), span| {
|
||||
ast::UntypedDefinition::ModuleConstant(ast::ModuleConstant {
|
||||
doc: None,
|
||||
location: span,
|
||||
public: public.is_some(),
|
||||
name,
|
||||
annotation,
|
||||
value: Box::new(value),
|
||||
tipo: (),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn constant_value_parser() -> impl Parser<Token, ast::UntypedConstant, Error = ParseError> {
|
||||
recursive(|r| {
|
||||
let constant_string_parser =
|
||||
select! {Token::String {value} => value}.map_with_span(|value, span| {
|
||||
ast::UntypedConstant::String {
|
||||
location: span,
|
||||
value,
|
||||
}
|
||||
});
|
||||
|
||||
let constant_int_parser =
|
||||
select! {Token::Int {value} => value}.map_with_span(|value, span| {
|
||||
ast::UntypedConstant::Int {
|
||||
location: span,
|
||||
value,
|
||||
}
|
||||
});
|
||||
|
||||
let constant_tuple_parser = just(Token::Hash)
|
||||
.ignore_then(r.clone())
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
|
||||
.map_with_span(|elements, span| ast::UntypedConstant::Tuple {
|
||||
location: span,
|
||||
elements,
|
||||
});
|
||||
|
||||
let constant_bytearray_parser = just(Token::Hash)
|
||||
.ignore_then(
|
||||
select! {Token::Int {value} => value}.validate(|value, span, emit| {
|
||||
let byte: u8 = match value.parse() {
|
||||
Ok(b) => b,
|
||||
Err(_) => {
|
||||
emit(ParseError::expected_input_found(
|
||||
span,
|
||||
None,
|
||||
Some(error::Pattern::Byte),
|
||||
));
|
||||
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
byte
|
||||
}),
|
||||
)
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare))
|
||||
.map_with_span(|bytes, span| ast::UntypedConstant::ByteArray {
|
||||
location: span,
|
||||
bytes,
|
||||
});
|
||||
|
||||
let constant_list_parser = r
|
||||
.clone()
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare))
|
||||
.map_with_span(|elements, span| ast::UntypedConstant::List {
|
||||
location: span,
|
||||
elements,
|
||||
tipo: (),
|
||||
});
|
||||
|
||||
let constant_record_parser = choice((
|
||||
choice((
|
||||
select! {Token::Name { name } => name}
|
||||
.then_ignore(just(Token::Dot))
|
||||
.or_not()
|
||||
.then(select! {Token::UpName { name } => name})
|
||||
.then(
|
||||
select! {Token::Name {name} => name}
|
||||
.then_ignore(just(Token::Colon))
|
||||
.or_not()
|
||||
.then(r.clone())
|
||||
.validate(|(label_opt, value), span, emit| {
|
||||
let label = if label_opt.is_some() {
|
||||
label_opt
|
||||
} else if let ast::UntypedConstant::Var { name, .. } = &value {
|
||||
Some(name.clone())
|
||||
} else {
|
||||
emit(ParseError::expected_input_found(
|
||||
value.location(),
|
||||
None,
|
||||
Some(error::Pattern::RecordPunning),
|
||||
));
|
||||
|
||||
None
|
||||
};
|
||||
|
||||
ast::CallArg {
|
||||
location: span,
|
||||
value,
|
||||
label,
|
||||
}
|
||||
})
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||
)
|
||||
.map_with_span(
|
||||
|((module, name), args), span| ast::UntypedConstant::Record {
|
||||
location: span,
|
||||
module,
|
||||
name,
|
||||
args,
|
||||
tag: (),
|
||||
tipo: (),
|
||||
field_map: None,
|
||||
},
|
||||
),
|
||||
select! {Token::Name { name } => name}
|
||||
.then_ignore(just(Token::Dot))
|
||||
.or_not()
|
||||
.then(select! {Token::UpName { name } => name})
|
||||
.then(
|
||||
r.clone()
|
||||
.map_with_span(|value, span| ast::CallArg {
|
||||
location: span,
|
||||
value,
|
||||
label: None,
|
||||
})
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||
)
|
||||
.map_with_span(
|
||||
|((module, name), args), span| ast::UntypedConstant::Record {
|
||||
location: span,
|
||||
module,
|
||||
name,
|
||||
args,
|
||||
tag: (),
|
||||
tipo: (),
|
||||
field_map: None,
|
||||
},
|
||||
),
|
||||
)),
|
||||
select! {Token::Name { name } => name}
|
||||
.then_ignore(just(Token::Dot))
|
||||
.then(select! {Token::Name{name} => name})
|
||||
.map_with_span(|(module, name), span: Span| ast::UntypedConstant::Var {
|
||||
location: span.union(span),
|
||||
module: Some(module),
|
||||
name,
|
||||
constructor: None,
|
||||
tipo: (),
|
||||
}),
|
||||
));
|
||||
|
||||
let constant_var_parser =
|
||||
select! {Token::Name {name} => name}.map_with_span(|name, span| {
|
||||
ast::UntypedConstant::Var {
|
||||
location: span,
|
||||
module: None,
|
||||
name,
|
||||
constructor: None,
|
||||
tipo: (),
|
||||
}
|
||||
});
|
||||
|
||||
choice((
|
||||
constant_string_parser,
|
||||
constant_int_parser,
|
||||
constant_tuple_parser,
|
||||
constant_bytearray_parser,
|
||||
constant_list_parser,
|
||||
constant_record_parser,
|
||||
constant_var_parser,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fn_param_parser() -> impl Parser<Token, ast::UntypedArg, Error = ParseError> {
|
||||
choice((
|
||||
select! {Token::Name {name} => name}
|
||||
|
@ -445,6 +642,10 @@ pub fn expr_parser(
|
|||
tail,
|
||||
});
|
||||
|
||||
let block_parser = seq_r
|
||||
.clone()
|
||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
||||
|
||||
let anon_fn_parser = just(Token::Fn)
|
||||
.ignore_then(
|
||||
anon_fn_param_parser()
|
||||
|
@ -453,11 +654,7 @@ pub fn expr_parser(
|
|||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||
)
|
||||
.then(just(Token::RArrow).ignore_then(type_parser()).or_not())
|
||||
.then(
|
||||
seq_r
|
||||
.clone()
|
||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||
)
|
||||
.then(seq_r.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)))
|
||||
.map_with_span(
|
||||
|((arguments, return_annotation), body), span| expr::UntypedExpr::Fn {
|
||||
arguments,
|
||||
|
@ -468,8 +665,6 @@ pub fn expr_parser(
|
|||
},
|
||||
);
|
||||
|
||||
let block_parser = seq_r.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
||||
|
||||
// TODO: do guards later
|
||||
// let when_clause_guard_parser = just(Token::If);
|
||||
|
||||
|
@ -999,10 +1194,16 @@ pub fn pattern_parser() -> impl Parser<Token, ast::UntypedPattern, Error = Parse
|
|||
label: Some(name),
|
||||
value: pattern,
|
||||
}),
|
||||
r.clone().map_with_span(|pattern, span| {
|
||||
r.clone().validate(|pattern, span, emit| {
|
||||
let label = if let ast::UntypedPattern::Var { name, .. } = &pattern {
|
||||
Some(name.clone())
|
||||
} else {
|
||||
emit(ParseError::expected_input_found(
|
||||
pattern.location(),
|
||||
None,
|
||||
Some(error::Pattern::RecordPunning),
|
||||
));
|
||||
|
||||
None
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use miette::Diagnostic;
|
|||
use crate::{ast::Span, parser::token::Token};
|
||||
|
||||
#[derive(Debug, Diagnostic, thiserror::Error)]
|
||||
#[error("{kind}")]
|
||||
#[error("{kind}\n")]
|
||||
pub struct ParseError {
|
||||
pub kind: ErrorKind,
|
||||
#[label]
|
||||
|
@ -104,12 +104,17 @@ pub enum Pattern {
|
|||
TermIdent,
|
||||
#[error("Unexpected end of input")]
|
||||
End,
|
||||
#[error("Bad list spread pattern")]
|
||||
#[error("Malformed list spread pattern")]
|
||||
#[diagnostic(help("List spread in matches can\nuse have a discard or var"))]
|
||||
Match,
|
||||
#[error("Bad byte literal")]
|
||||
#[error("Malformed byte literal")]
|
||||
#[diagnostic(help("Bytes must be between 0-255"))]
|
||||
Byte,
|
||||
#[error("Unexpected pattern")]
|
||||
#[diagnostic(help(
|
||||
"If no label is provided then only variables\nmatching a field name are allowed"
|
||||
))]
|
||||
RecordPunning,
|
||||
}
|
||||
|
||||
impl From<char> for Pattern {
|
||||
|
|
|
@ -8,7 +8,7 @@ use super::Type;
|
|||
|
||||
#[derive(Debug, thiserror::Error, Diagnostic)]
|
||||
pub enum Error {
|
||||
#[error("Duplicate argument\n\n{label}")]
|
||||
#[error("Duplicate argument\n\n{label}\n")]
|
||||
#[diagnostic(help("Try renaming it"))]
|
||||
DuplicateArgument {
|
||||
#[label]
|
||||
|
@ -16,7 +16,7 @@ pub enum Error {
|
|||
label: String,
|
||||
},
|
||||
|
||||
#[error("Duplicate const\n\n{name}")]
|
||||
#[error("Duplicate const\n\n{name}\n")]
|
||||
#[diagnostic(help("Try renaming it"))]
|
||||
DuplicateConstName {
|
||||
#[label]
|
||||
|
@ -26,7 +26,7 @@ pub enum Error {
|
|||
name: String,
|
||||
},
|
||||
|
||||
#[error("Duplicate import\n\n{name}")]
|
||||
#[error("Duplicate import\n\n{name}\n")]
|
||||
#[diagnostic(help("Try renaming it"))]
|
||||
DuplicateImport {
|
||||
#[label]
|
||||
|
@ -36,7 +36,7 @@ pub enum Error {
|
|||
name: String,
|
||||
},
|
||||
|
||||
#[error("Duplicate field\n\n{label}")]
|
||||
#[error("Duplicate field\n\n{label}\n")]
|
||||
#[diagnostic(help("Try renaming it"))]
|
||||
DuplicateField {
|
||||
#[label]
|
||||
|
@ -44,7 +44,7 @@ pub enum Error {
|
|||
label: String,
|
||||
},
|
||||
|
||||
#[error("Duplicate name\n\n{name}")]
|
||||
#[error("Duplicate name\n\n{name}\n")]
|
||||
#[diagnostic(help("Try renaming it"))]
|
||||
DuplicateName {
|
||||
#[label]
|
||||
|
@ -54,7 +54,7 @@ pub enum Error {
|
|||
name: String,
|
||||
},
|
||||
|
||||
#[error("Duplicate type name\n\n{name}")]
|
||||
#[error("Duplicate type name\n\n{name}\n")]
|
||||
#[diagnostic(help("Try renaming it"))]
|
||||
DuplicateTypeName {
|
||||
#[label]
|
||||
|
@ -64,7 +64,7 @@ pub enum Error {
|
|||
name: String,
|
||||
},
|
||||
|
||||
#[error("Incorrect arity\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
|
||||
#[error("Incorrect arity\n\nExpected\n\n{expected}\n\nGiven\n\n{given}\n")]
|
||||
IncorrectArity {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -73,7 +73,7 @@ pub enum Error {
|
|||
labels: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("Incorrect number of clause patterns\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
|
||||
#[error("Incorrect number of clause patterns\n\nExpected\n\n{expected}\n\nGiven\n\n{given}\n")]
|
||||
IncorrectNumClausePatterns {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -81,7 +81,7 @@ pub enum Error {
|
|||
given: usize,
|
||||
},
|
||||
|
||||
#[error("Incorrect type arity for `{name}`\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
|
||||
#[error("Incorrect type arity for `{name}`\n\nExpected\n\n{expected}\n\nGiven\n\n{given}\n")]
|
||||
IncorrectTypeArity {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -90,7 +90,7 @@ pub enum Error {
|
|||
given: usize,
|
||||
},
|
||||
|
||||
#[error("Non-exhaustive pattern match")]
|
||||
#[error("Non-exhaustive pattern match\n")]
|
||||
NotExhaustivePatternMatch {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -104,65 +104,65 @@ pub enum Error {
|
|||
tipo: Arc<Type>,
|
||||
},
|
||||
|
||||
#[error("Module\n\n{name}\n\ncontains keyword\n\n{keyword}")]
|
||||
#[error("Module\n\n{name}\n\ncontains keyword\n\n{keyword}\n")]
|
||||
KeywordInModuleName { name: String, keyword: String },
|
||||
|
||||
#[error("Clause guard {name} is not local")]
|
||||
#[error("Clause guard {name} is not local\n")]
|
||||
NonLocalClauseGuardVariable {
|
||||
#[label]
|
||||
location: Span,
|
||||
name: String,
|
||||
},
|
||||
|
||||
#[error("Positional argument after labeled")]
|
||||
#[error("Positional argument after labeled\n")]
|
||||
PositionalArgumentAfterLabeled {
|
||||
#[label]
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("Private type leaked")]
|
||||
#[error("Private type leaked\n")]
|
||||
PrivateTypeLeak {
|
||||
#[label]
|
||||
location: Span,
|
||||
leaked: Type,
|
||||
},
|
||||
|
||||
#[error("Record access unknown type")]
|
||||
#[error("Record access unknown type\n")]
|
||||
RecordAccessUnknownType {
|
||||
#[label]
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("Record update invalid constructor")]
|
||||
#[error("Record update invalid constructor\n")]
|
||||
RecordUpdateInvalidConstructor {
|
||||
#[label]
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("{name} is a reserved module name")]
|
||||
#[error("{name} is a reserved module name\n")]
|
||||
ReservedModuleName { name: String },
|
||||
|
||||
#[error("Unexpected labeled argument\n\n{label}")]
|
||||
#[error("Unexpected labeled argument\n\n{label}\n")]
|
||||
UnexpectedLabeledArg {
|
||||
#[label]
|
||||
location: Span,
|
||||
label: String,
|
||||
},
|
||||
|
||||
#[error("Unexpected type hole")]
|
||||
#[error("Unexpected type hole\n")]
|
||||
UnexpectedTypeHole {
|
||||
#[label]
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("Unknown labels")]
|
||||
#[error("Unknown labels\n")]
|
||||
UnknownLabels {
|
||||
unknown: Vec<(String, Span)>,
|
||||
valid: Vec<String>,
|
||||
supplied: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("Unknown module\n\n{name}")]
|
||||
#[error("Unknown module\n\n{name}\n")]
|
||||
UnknownModule {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -170,7 +170,7 @@ pub enum Error {
|
|||
imported_modules: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("Unknown module field\n\n{name}\n\nin module\n\n{module_name}")]
|
||||
#[error("Unknown module field\n\n{name}\n\nin module\n\n{module_name}\n")]
|
||||
UnknownModuleField {
|
||||
location: Span,
|
||||
name: String,
|
||||
|
@ -179,7 +179,7 @@ pub enum Error {
|
|||
type_constructors: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("Unknown module value\n\n{name}")]
|
||||
#[error("Unknown module value\n\n{name}\n")]
|
||||
UnknownModuleValue {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -188,7 +188,7 @@ pub enum Error {
|
|||
value_constructors: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("Unknown type\n\n{name}\n\nin module\n\n{module_name}")]
|
||||
#[error("Unknown type\n\n{name}\n\nin module\n\n{module_name}\n")]
|
||||
UnknownModuleType {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -197,7 +197,7 @@ pub enum Error {
|
|||
type_constructors: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("Unknown record field\n\n{label}")]
|
||||
#[error("Unknown record field\n\n{label}\n")]
|
||||
UnknownRecordField {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -207,7 +207,7 @@ pub enum Error {
|
|||
situation: Option<UnknownRecordFieldSituation>,
|
||||
},
|
||||
|
||||
#[error("Unknown type\n\n{name}")]
|
||||
#[error("Unknown type\n\n{name}\n")]
|
||||
UnknownType {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -215,7 +215,7 @@ pub enum Error {
|
|||
types: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("Unknown variable\n\n{name}")]
|
||||
#[error("Unknown variable\n\n{name}\n")]
|
||||
UnknownVariable {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -223,14 +223,14 @@ pub enum Error {
|
|||
variables: Vec<String>,
|
||||
},
|
||||
|
||||
#[error("Unnecessary spread operator")]
|
||||
#[error("Unnecessary spread operator\n")]
|
||||
UnnecessarySpreadOperator {
|
||||
#[label]
|
||||
location: Span,
|
||||
arity: usize,
|
||||
},
|
||||
|
||||
#[error("Cannot update a type with multiple constructors")]
|
||||
#[error("Cannot update a type with multiple constructors\n")]
|
||||
UpdateMultiConstructorType {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -271,7 +271,7 @@ pub enum Error {
|
|||
name: String,
|
||||
},
|
||||
|
||||
#[error("")]
|
||||
#[error("Recursive type detected\n")]
|
||||
RecursiveType {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -363,7 +363,7 @@ impl Error {
|
|||
|
||||
#[derive(Debug, PartialEq, Clone, thiserror::Error, Diagnostic)]
|
||||
pub enum Warning {
|
||||
#[error("todo")]
|
||||
#[error("Todo\n")]
|
||||
Todo {
|
||||
kind: TodoKind,
|
||||
#[label]
|
||||
|
@ -371,31 +371,31 @@ pub enum Warning {
|
|||
tipo: Arc<Type>,
|
||||
},
|
||||
|
||||
#[error("implicitly discarded result")]
|
||||
#[error("Implicitly discarded result\n")]
|
||||
ImplicitlyDiscardedResult {
|
||||
#[label]
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("unused literal")]
|
||||
#[error("Unused literal\n")]
|
||||
UnusedLiteral {
|
||||
#[label]
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("record update with no fields")]
|
||||
#[error("Record update with no fields\n")]
|
||||
NoFieldsRecordUpdate {
|
||||
#[label]
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("record update using all fields")]
|
||||
#[error("Record update using all fields\n")]
|
||||
AllFieldsRecordUpdate {
|
||||
#[label]
|
||||
location: Span,
|
||||
},
|
||||
|
||||
#[error("unused type {name}")]
|
||||
#[error("Unused type {name}\n")]
|
||||
UnusedType {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -403,7 +403,7 @@ pub enum Warning {
|
|||
name: String,
|
||||
},
|
||||
|
||||
#[error("unused constructor {name}")]
|
||||
#[error("Unused constructor {name}\n")]
|
||||
UnusedConstructor {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
@ -411,35 +411,35 @@ pub enum Warning {
|
|||
name: String,
|
||||
},
|
||||
|
||||
#[error("unused imported value {name}")]
|
||||
#[error("Unused imported value {name}\n")]
|
||||
UnusedImportedValue {
|
||||
#[label]
|
||||
location: Span,
|
||||
name: String,
|
||||
},
|
||||
|
||||
#[error("unused imported module {name}")]
|
||||
#[error("Unused imported module {name}\n")]
|
||||
UnusedImportedModule {
|
||||
#[label]
|
||||
location: Span,
|
||||
name: String,
|
||||
},
|
||||
|
||||
#[error("unused private module constant {name}")]
|
||||
#[error("Unused private module constant {name}\n")]
|
||||
UnusedPrivateModuleConstant {
|
||||
#[label]
|
||||
location: Span,
|
||||
name: String,
|
||||
},
|
||||
|
||||
#[error("unused private function {name}")]
|
||||
#[error("Unused private function {name}\n")]
|
||||
UnusedPrivateFunction {
|
||||
#[label]
|
||||
location: Span,
|
||||
name: String,
|
||||
},
|
||||
|
||||
#[error("unused variable {name}")]
|
||||
#[error("Unused variable {name}\n")]
|
||||
UnusedVariable {
|
||||
#[label]
|
||||
location: Span,
|
||||
|
|
|
@ -1177,6 +1177,22 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
Ok((typed_pattern, typed_alternatives))
|
||||
}
|
||||
|
||||
fn infer_const_tuple(
|
||||
&mut self,
|
||||
untyped_elements: Vec<UntypedConstant>,
|
||||
location: Span,
|
||||
) -> Result<TypedConstant, Error> {
|
||||
let mut elements = Vec::with_capacity(untyped_elements.len());
|
||||
|
||||
for element in untyped_elements {
|
||||
let element = self.infer_const(&None, element)?;
|
||||
|
||||
elements.push(element);
|
||||
}
|
||||
|
||||
Ok(Constant::Tuple { elements, location })
|
||||
}
|
||||
|
||||
// TODO: extract the type annotation checking into a infer_module_const
|
||||
// function that uses this function internally
|
||||
pub fn infer_const(
|
||||
|
@ -1193,6 +1209,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
location, value, ..
|
||||
} => Ok(Constant::String { location, value }),
|
||||
|
||||
Constant::Tuple {
|
||||
elements, location, ..
|
||||
} => self.infer_const_tuple(elements, location),
|
||||
|
||||
Constant::List {
|
||||
elements, location, ..
|
||||
} => self.infer_const_list(elements, location),
|
||||
|
|
|
@ -265,7 +265,7 @@ impl Diagnostic for Error {
|
|||
|
||||
#[derive(thiserror::Error)]
|
||||
pub enum Warning {
|
||||
#[error("type checking")]
|
||||
#[error("Checking")]
|
||||
Type {
|
||||
path: PathBuf,
|
||||
src: String,
|
||||
|
|
|
@ -3,6 +3,8 @@ use sample/mint
|
|||
use sample/spend
|
||||
use aiken/builtin
|
||||
|
||||
const something = 5
|
||||
|
||||
pub type Redeemer {
|
||||
signer: ByteArray,
|
||||
amount: Int,
|
||||
|
|
Loading…
Reference in New Issue