Get it all to compile!

This commit is contained in:
Eric Correia 2021-10-02 13:48:07 -04:00
parent 555478cdf0
commit 8272ea876f
21 changed files with 217 additions and 21 deletions

View file

@ -746,6 +746,7 @@ fn pattern_to_vars_by_symbol(
| IntLiteral(_, _, _) | IntLiteral(_, _, _)
| FloatLiteral(_, _, _) | FloatLiteral(_, _, _)
| StrLiteral(_) | StrLiteral(_)
| SingleQuote(_)
| Underscore | Underscore
| MalformedPattern(_, _) | MalformedPattern(_, _)
| UnsupportedPattern(_) => {} | UnsupportedPattern(_) => {}

View file

@ -58,6 +58,7 @@ pub enum Expr {
Int(Variable, Variable, Box<str>, i128), Int(Variable, Variable, Box<str>, i128),
Float(Variable, Variable, Box<str>, f64), Float(Variable, Variable, Box<str>, f64),
Str(Box<str>), Str(Box<str>),
SingleQuote(char),
List { List {
elem_var: Variable, elem_var: Variable,
loc_elems: Vec<Located<Expr>>, loc_elems: Vec<Located<Expr>>,
@ -305,6 +306,26 @@ pub fn canonicalize_expr<'a>(
} }
} }
ast::Expr::Str(literal) => flatten_str_literal(env, var_store, scope, literal), ast::Expr::Str(literal) => flatten_str_literal(env, var_store, scope, literal),
ast::Expr::SingleQuote(string) => {
let mut it = string.chars().peekable();
if let Some(char) = it.next() {
if it.peek().is_none() {
(Expr::SingleQuote(char), Output::default())
} else {
// multiple chars is found
let error = roc_problem::can::RuntimeError::MulitpleCharsInSingleQuote(region);
let answer = Expr::RuntimeError(error.clone());
(answer, Output::default())
}
} else {
// no characters found
let error = roc_problem::can::RuntimeError::EmptySingleQuote(region);
let answer = Expr::RuntimeError(error.clone());
(answer, Output::default())
}
}
ast::Expr::List { ast::Expr::List {
items: loc_elems, .. items: loc_elems, ..
} => { } => {
@ -1238,6 +1259,7 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
| other @ Int(_, _, _, _) | other @ Int(_, _, _, _)
| other @ Float(_, _, _, _) | other @ Float(_, _, _, _)
| other @ Str { .. } | other @ Str { .. }
| other @ SingleQuote(_)
| other @ RuntimeError(_) | other @ RuntimeError(_)
| other @ EmptyRecord | other @ EmptyRecord
| other @ Accessor { .. } | other @ Accessor { .. }

View file

@ -386,6 +386,7 @@ fn fix_values_captured_in_closure_pattern(
| IntLiteral(_, _, _) | IntLiteral(_, _, _)
| FloatLiteral(_, _, _) | FloatLiteral(_, _, _)
| StrLiteral(_) | StrLiteral(_)
| SingleQuote(_)
| Underscore | Underscore
| Shadowed(_, _) | Shadowed(_, _)
| MalformedPattern(_, _) | MalformedPattern(_, _)
@ -442,6 +443,7 @@ fn fix_values_captured_in_closure_expr(
| Int(_, _, _, _) | Int(_, _, _, _)
| Float(_, _, _, _) | Float(_, _, _, _)
| Str(_) | Str(_)
| SingleQuote(_)
| Var(_) | Var(_)
| EmptyRecord | EmptyRecord
| RuntimeError(_) | RuntimeError(_)

View file

@ -125,6 +125,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
| Num(_) | Num(_)
| NonBase10Int { .. } | NonBase10Int { .. }
| Str(_) | Str(_)
| SingleQuote(_)
| AccessorFunction(_) | AccessorFunction(_)
| Var { .. } | Var { .. }
| Underscore { .. } | Underscore { .. }

View file

@ -29,6 +29,7 @@ pub enum Pattern {
NumLiteral(Variable, Box<str>, i64), NumLiteral(Variable, Box<str>, i64),
FloatLiteral(Variable, Box<str>, f64), FloatLiteral(Variable, Box<str>, f64),
StrLiteral(Box<str>), StrLiteral(Box<str>),
SingleQuote(char),
Underscore, Underscore,
// Runtime Exceptions // Runtime Exceptions
@ -89,6 +90,7 @@ pub fn symbols_from_pattern_help(pattern: &Pattern, symbols: &mut Vec<Symbol>) {
| IntLiteral(_, _, _) | IntLiteral(_, _, _)
| FloatLiteral(_, _, _) | FloatLiteral(_, _, _)
| StrLiteral(_) | StrLiteral(_)
| SingleQuote(_)
| Underscore | Underscore
| MalformedPattern(_, _) | MalformedPattern(_, _)
| UnsupportedPattern(_) => {} | UnsupportedPattern(_) => {}
@ -237,6 +239,23 @@ pub fn canonicalize_pattern<'a>(
ptype => unsupported_pattern(env, ptype, region), ptype => unsupported_pattern(env, ptype, region),
}, },
SingleQuote(string) => {
let mut it = string.chars().peekable();
if let Some(char) = it.next() {
if it.peek().is_none() {
Pattern::SingleQuote(char)
} else {
// multiple chars is found
let problem = MalformedPatternProblem::MulitpleCharsInSingleQuote;
malformed_pattern(env, problem, region)
}
} else {
// no characters found
let problem = MalformedPatternProblem::EmptySingleQuote;
malformed_pattern(env, problem, region)
}
}
SpaceBefore(sub_pattern, _) | SpaceAfter(sub_pattern, _) => { SpaceBefore(sub_pattern, _) | SpaceAfter(sub_pattern, _) => {
return canonicalize_pattern(env, var_store, scope, pattern_type, sub_pattern, region) return canonicalize_pattern(env, var_store, scope, pattern_type, sub_pattern, region)
} }
@ -476,6 +495,7 @@ fn add_bindings_from_patterns(
| IntLiteral(_, _, _) | IntLiteral(_, _, _)
| FloatLiteral(_, _, _) | FloatLiteral(_, _, _)
| StrLiteral(_) | StrLiteral(_)
| SingleQuote(_)
| Underscore | Underscore
| Shadowed(_, _) | Shadowed(_, _)
| MalformedPattern(_, _) | MalformedPattern(_, _)

View file

@ -158,6 +158,16 @@ pub fn num_signed64() -> Type {
builtin_alias(Symbol::NUM_SIGNED64, vec![], Box::new(alias_content)) builtin_alias(Symbol::NUM_SIGNED64, vec![], Box::new(alias_content))
} }
#[inline(always)]
pub fn num_unsigned32() -> Type {
let alias_content = Type::TagUnion(
vec![(TagName::Private(Symbol::NUM_AT_UNSIGNED32), vec![])],
Box::new(Type::EmptyTagUnion),
);
builtin_alias(Symbol::NUM_UNSIGNED32, vec![], Box::new(alias_content))
}
#[inline(always)] #[inline(always)]
pub fn num_integer(range: Type) -> Type { pub fn num_integer(range: Type) -> Type {
let alias_content = Type::TagUnion( let alias_content = Type::TagUnion(

View file

@ -1,4 +1,6 @@
use crate::builtins::{empty_list_type, float_literal, int_literal, list_type, str_type}; use crate::builtins::{
empty_list_type, float_literal, int_literal, list_type, num_unsigned32, str_type,
};
use crate::pattern::{constrain_pattern, PatternState}; use crate::pattern::{constrain_pattern, PatternState};
use roc_can::annotation::IntroducedVariables; use roc_can::annotation::IntroducedVariables;
use roc_can::constraint::Constraint::{self, *}; use roc_can::constraint::Constraint::{self, *};
@ -217,6 +219,7 @@ pub fn constrain_expr(
exists(vars, And(cons)) exists(vars, And(cons))
} }
Str(_) => Eq(str_type(), expected, Category::Str, region), Str(_) => Eq(str_type(), expected, Category::Str, region),
SingleQuote(_) => Eq(num_unsigned32(), expected, Category::Character, region),
List { List {
elem_var, elem_var,
loc_elems, loc_elems,

View file

@ -59,6 +59,7 @@ fn headers_from_annotation_help(
| NumLiteral(_, _, _) | NumLiteral(_, _, _)
| IntLiteral(_, _, _) | IntLiteral(_, _, _)
| FloatLiteral(_, _, _) | FloatLiteral(_, _, _)
| SingleQuote(_)
| StrLiteral(_) => true, | StrLiteral(_) => true,
RecordDestructure { destructs, .. } => match annotation.value.shallow_dealias() { RecordDestructure { destructs, .. } => match annotation.value.shallow_dealias() {
@ -181,6 +182,15 @@ pub fn constrain_pattern(
)); ));
} }
SingleQuote(_) => {
state.constraints.push(Constraint::Pattern(
region,
PatternCategory::Character,
builtins::num_unsigned32(),
expected,
));
}
RecordDestructure { RecordDestructure {
whole_var, whole_var,
ext_var, ext_var,

View file

@ -27,6 +27,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
Float(_) Float(_)
| Num(_) | Num(_)
| NonBase10Int { .. } | NonBase10Int { .. }
| SingleQuote(_)
| Access(_, _) | Access(_, _)
| AccessorFunction(_) | AccessorFunction(_)
| Var { .. } | Var { .. }
@ -228,6 +229,11 @@ impl<'a> Formattable<'a> for Expr<'a> {
Num(string) | Float(string) | GlobalTag(string) | PrivateTag(string) => { Num(string) | Float(string) | GlobalTag(string) | PrivateTag(string) => {
buf.push_str(string) buf.push_str(string)
} }
SingleQuote(string) => {
buf.push('\'');
buf.push_str(string);
buf.push('\'');
}
NonBase10Int { NonBase10Int {
base, base,
string, string,

View file

@ -35,6 +35,7 @@ impl<'a> Formattable<'a> for Pattern<'a> {
| Pattern::NonBase10Literal { .. } | Pattern::NonBase10Literal { .. }
| Pattern::FloatLiteral(_) | Pattern::FloatLiteral(_)
| Pattern::StrLiteral(_) | Pattern::StrLiteral(_)
| Pattern::SingleQuote(_)
| Pattern::Underscore(_) | Pattern::Underscore(_)
| Pattern::Malformed(_) | Pattern::Malformed(_)
| Pattern::MalformedIdent(_, _) | Pattern::MalformedIdent(_, _)
@ -127,6 +128,11 @@ impl<'a> Formattable<'a> for Pattern<'a> {
StrLiteral(literal) => { StrLiteral(literal) => {
todo!("Format string literal: {:?}", literal); todo!("Format string literal: {:?}", literal);
} }
SingleQuote(string) => {
buf.push('\'');
buf.push_str(string);
buf.push('\'');
}
Underscore(name) => { Underscore(name) => {
buf.push('_'); buf.push('_');
buf.push_str(name); buf.push_str(name);

View file

@ -1676,7 +1676,11 @@ fn pattern_to_when<'a>(
(symbol, Located::at_zero(wrapped_body)) (symbol, Located::at_zero(wrapped_body))
} }
IntLiteral(_, _, _) | NumLiteral(_, _, _) | FloatLiteral(_, _, _) | StrLiteral(_) => { IntLiteral(_, _, _)
| NumLiteral(_, _, _)
| FloatLiteral(_, _, _)
| StrLiteral(_)
| roc_can::pattern::Pattern::SingleQuote(_) => {
// These patters are refutable, and thus should never occur outside a `when` expression // These patters are refutable, and thus should never occur outside a `when` expression
// They should have been replaced with `UnsupportedPattern` during canonicalization // They should have been replaced with `UnsupportedPattern` during canonicalization
unreachable!("refutable pattern {:?} where irrefutable pattern is expected. This should never happen!", pattern.value) unreachable!("refutable pattern {:?} where irrefutable pattern is expected. This should never happen!", pattern.value)
@ -2837,6 +2841,13 @@ pub fn with_hole<'a>(
hole, hole,
), ),
SingleQuote(character) => Stmt::Let(
assigned,
Expr::Literal(Literal::Int(character as _)),
Layout::Builtin(Builtin::Int32),
hole,
),
Num(var, num_str, num) => { Num(var, num_str, num) => {
// first figure out what kind of number this is // first figure out what kind of number this is
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, var, false) { match num_argument_to_int_or_float(env.subs, env.ptr_bytes, var, false) {
@ -7025,6 +7036,7 @@ fn from_can_pattern_help<'a>(
} }
} }
StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())), StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())),
SingleQuote(c) => Ok(Pattern::IntLiteral(*c as _, IntPrecision::I32)),
Shadowed(region, ident) => Err(RuntimeError::Shadowing { Shadowed(region, ident) => Err(RuntimeError::Shadowing {
original_region: *region, original_region: *region,
shadow: ident.clone(), shadow: ident.clone(),

View file

@ -92,7 +92,7 @@ pub enum Expr<'a> {
/// e.g. `.foo` /// e.g. `.foo`
AccessorFunction(&'a str), AccessorFunction(&'a str),
/// eg 'b' /// eg 'b'
SingleQuote(char), SingleQuote(&'a str),
// Collection Literals // Collection Literals
List { List {
@ -360,7 +360,7 @@ pub enum Pattern<'a> {
FloatLiteral(&'a str), FloatLiteral(&'a str),
StrLiteral(StrLiteral<'a>), StrLiteral(StrLiteral<'a>),
Underscore(&'a str), Underscore(&'a str),
SingleQuote(char), SingleQuote(&'a str),
// Space // Space
SpaceBefore(&'a Pattern<'a>, &'a [CommentOrNewline<'a>]), SpaceBefore(&'a Pattern<'a>, &'a [CommentOrNewline<'a>]),

View file

@ -1492,6 +1492,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
| Expr::UnaryOp(_, _) => Err(()), | Expr::UnaryOp(_, _) => Err(()),
Expr::Str(string) => Ok(Pattern::StrLiteral(*string)), Expr::Str(string) => Ok(Pattern::StrLiteral(*string)),
Expr::SingleQuote(string) => Ok(Pattern::SingleQuote(*string)),
Expr::MalformedIdent(string, _problem) => Ok(Pattern::Malformed(string)), Expr::MalformedIdent(string, _problem) => Ok(Pattern::Malformed(string)),
} }
} }

View file

@ -1,5 +1,3 @@
use std::convert::TryInto;
use crate::ast::{EscapedChar, StrLiteral, StrSegment}; use crate::ast::{EscapedChar, StrLiteral, StrSegment};
use crate::expr; use crate::expr;
use crate::parser::Progress::*; use crate::parser::Progress::*;
@ -48,8 +46,8 @@ macro_rules! advance_state {
}; };
} }
pub fn parse_single_quote<'a>() -> impl Parser<'a, char, EString<'a>> { pub fn parse_single_quote<'a>() -> impl Parser<'a, &'a str, EString<'a>> {
move |_arena: &'a Bump, mut state: State<'a>| { move |arena: &'a Bump, mut state: State<'a>| {
if state.bytes.starts_with(b"\'") { if state.bytes.starts_with(b"\'") {
// we will be parsing a single-quote-string // we will be parsing a single-quote-string
} else { } else {
@ -73,9 +71,11 @@ pub fn parse_single_quote<'a>() -> impl Parser<'a, char, EString<'a>> {
state = advance_state!(state, 1)?; state = advance_state!(state, 1)?;
// since we checked the current char between the single quotes we // since we checked the current char between the single quotes we
// know they are valid UTF-8, allowing us to use 'from_u32_unchecked' // know they are valid UTF-8, allowing us to use 'from_u32_unchecked'
let test = unsafe { char::from_u32_unchecked(ch as u32) };
return Ok(( return Ok((
MadeProgress, MadeProgress,
unsafe { char::from_u32_unchecked(ch as u32) }, &*arena.alloc_str(&test.to_string()),
state, state,
)); ));
} }
@ -112,6 +112,8 @@ pub fn parse_single_quote<'a>() -> impl Parser<'a, char, EString<'a>> {
let mut bytes = state.bytes.iter(); let mut bytes = state.bytes.iter();
let mut end_index = 1; let mut end_index = 1;
// Copy paste problem in mono
loop { loop {
match bytes.next() { match bytes.next() {
Some(b'\'') => { Some(b'\'') => {
@ -138,19 +140,14 @@ pub fn parse_single_quote<'a>() -> impl Parser<'a, char, EString<'a>> {
// happy case -> we have some bytes that will fit into a u32 // happy case -> we have some bytes that will fit into a u32
// ending up w/ a slice of bytes that we want to convert into an integer // ending up w/ a slice of bytes that we want to convert into an integer
let bytes_array: [u8; 4] = match state.bytes[1..end_index].try_into() { let raw_bytes = &state.bytes[0..end_index - 1];
Ok(bytes) => bytes,
Err(_) => {
return Err((NoProgress, EString::Open(state.line, state.column), state));
}
};
state = advance_state!(state, end_index)?; state = advance_state!(state, end_index)?;
match char::from_u32(u32::from_ne_bytes(bytes_array)) { match std::str::from_utf8(raw_bytes) {
Some(ch) => { Ok(string) => {
return Ok((MadeProgress, ch, state)); return Ok((MadeProgress, string, state));
} }
None => { Err(_) => {
// invalid UTF-8 // invalid UTF-8
return Err(( return Err((
NoProgress, NoProgress,

View file

@ -421,6 +421,12 @@ mod test_parse {
assert_parses_to(num.to_string().as_str(), Float(num.to_string().as_str())); assert_parses_to(num.to_string().as_str(), Float(num.to_string().as_str()));
} }
// SINGLE QUOTE LITERAL
#[test]
fn single_quote() {
assert_parses_to("'b'", Expr::SingleQuote("b"));
}
// RECORD LITERALS // RECORD LITERALS
#[test] #[test]

View file

@ -172,6 +172,11 @@ pub enum RuntimeError {
VoidValue, VoidValue,
ExposedButNotDefined(Symbol), ExposedButNotDefined(Symbol),
/// where ''
EmptySingleQuote(Region),
/// where 'aa'
MulitpleCharsInSingleQuote(Region),
} }
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
@ -182,4 +187,6 @@ pub enum MalformedPatternProblem {
Unknown, Unknown,
QualifiedIdentifier, QualifiedIdentifier,
BadIdent(roc_parse::ident::BadIdent), BadIdent(roc_parse::ident::BadIdent),
EmptySingleQuote,
MulitpleCharsInSingleQuote,
} }

View file

@ -843,13 +843,17 @@ fn pretty_runtime_error<'b>(
} }
Unknown => " ", Unknown => " ",
QualifiedIdentifier => " qualified ", QualifiedIdentifier => " qualified ",
EmptySingleQuote => " empty character literal ",
MulitpleCharsInSingleQuote => " overfull literal ",
}; };
let tip = match problem { let tip = match problem {
MalformedInt | MalformedFloat | MalformedBase(_) => alloc MalformedInt | MalformedFloat | MalformedBase(_) => alloc
.tip() .tip()
.append(alloc.reflow("Learn more about number literals at TODO")), .append(alloc.reflow("Learn more about number literals at TODO")),
Unknown | BadIdent(_) => alloc.nil(), EmptySingleQuote | MulitpleCharsInSingleQuote | Unknown | BadIdent(_) => {
alloc.nil()
}
QualifiedIdentifier => alloc.tip().append( QualifiedIdentifier => alloc.tip().append(
alloc.reflow("In patterns, only private and global tags can be qualified"), alloc.reflow("In patterns, only private and global tags can be qualified"),
), ),
@ -1122,6 +1126,37 @@ fn pretty_runtime_error<'b>(
title = MISSING_DEFINITION; title = MISSING_DEFINITION;
} }
RuntimeError::EmptySingleQuote(region) => {
let tip = alloc
.tip()
.append(alloc.reflow("Learn more about character literals at TODO"));
doc = alloc.stack(vec![
alloc.concat(vec![alloc.reflow("This character literal is empty.")]),
alloc.region(region),
tip,
]);
title = SYNTAX_PROBLEM;
}
RuntimeError::MulitpleCharsInSingleQuote(region) => {
let tip = alloc
.tip()
.append(alloc.reflow("Learn more about character literals at TODO"));
doc = alloc.stack(vec![
alloc.concat(vec![
alloc.reflow("This character literal contains more than one code point.")
]),
alloc.region(region),
alloc.concat(vec![
alloc.reflow("Character literals can only contain one code point.")
]),
tip,
]);
title = SYNTAX_PROBLEM;
}
} }
(doc, title) (doc, title)

View file

@ -981,6 +981,7 @@ fn add_category<'b>(
this_is, this_is,
alloc.text(" a value in a string interpolation, which was of type:"), alloc.text(" a value in a string interpolation, which was of type:"),
]), ]),
Character => alloc.concat(vec![this_is, alloc.text(" a character of type:")]),
Lambda => alloc.concat(vec![this_is, alloc.text(" an anonymous function of type:")]), Lambda => alloc.concat(vec![this_is, alloc.text(" an anonymous function of type:")]),
@ -1262,7 +1263,8 @@ fn add_pattern_category<'b>(
Str => alloc.reflow(" strings:"), Str => alloc.reflow(" strings:"),
Num => alloc.reflow(" numbers:"), Num => alloc.reflow(" numbers:"),
Int => alloc.reflow(" integers:"), Int => alloc.reflow(" integers:"),
Float => alloc.reflow(" floats"), Float => alloc.reflow(" floats:"),
Character => alloc.reflow(" characters:"),
}; };
alloc.concat(vec![i_am_trying_to_match, rest]) alloc.concat(vec![i_am_trying_to_match, rest])

View file

@ -1159,6 +1159,7 @@ pub enum Category {
Num, Num,
List, List,
Str, Str,
Character,
// records // records
Record, Record,
@ -1180,6 +1181,7 @@ pub enum PatternCategory {
Num, Num,
Int, Int,
Float, Float,
Character,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]

View file

@ -1285,6 +1285,15 @@ pub fn constrain_pattern<'a>(
)); ));
} }
CharacterLiteral(_) => {
state.constraints.push(Constraint::Pattern(
region,
PatternCategory::Character,
num_unsigned32(env.pool),
expected,
));
}
RecordDestructure { RecordDestructure {
whole_var, whole_var,
ext_var, ext_var,
@ -1696,6 +1705,27 @@ fn _num_signed64(pool: &mut Pool) -> Type2 {
) )
} }
#[inline(always)]
fn num_unsigned32(pool: &mut Pool) -> Type2 {
let alias_content = Type2::TagUnion(
PoolVec::new(
vec![(
TagName::Private(Symbol::NUM_UNSIGNED32),
PoolVec::empty(pool),
)]
.into_iter(),
pool,
),
pool.add(Type2::EmptyTagUnion),
);
Type2::Alias(
Symbol::NUM_UNSIGNED32,
PoolVec::empty(pool),
pool.add(alias_content),
)
}
#[inline(always)] #[inline(always)]
fn _num_integer(pool: &mut Pool, range: TypeId) -> Type2 { fn _num_integer(pool: &mut Pool, range: TypeId) -> Type2 {
let range_type = pool.get(range); let range_type = pool.get(range);

View file

@ -28,6 +28,7 @@ pub enum Pattern2 {
IntLiteral(IntVal), // 16B IntLiteral(IntVal), // 16B
FloatLiteral(FloatVal), // 16B FloatLiteral(FloatVal), // 16B
StrLiteral(PoolStr), // 8B StrLiteral(PoolStr), // 8B
CharacterLiteral(char), // 4B
Underscore, // 0B Underscore, // 0B
GlobalTag { GlobalTag {
whole_var: Variable, // 4B whole_var: Variable, // 4B
@ -217,6 +218,26 @@ pub fn to_pattern2<'a>(
ptype => unsupported_pattern(env, ptype, region), ptype => unsupported_pattern(env, ptype, region),
}, },
SingleQuote(string) => match pattern_type {
WhenBranch => {
let mut it = string.chars().peekable();
if let Some(char) = it.next() {
if it.peek().is_none() {
Pattern2::CharacterLiteral(char)
} else {
// multiple chars is found
let problem = MalformedPatternProblem::MulitpleCharsInSingleQuote;
malformed_pattern(env, problem, region)
}
} else {
// no characters found
let problem = MalformedPatternProblem::EmptySingleQuote;
malformed_pattern(env, problem, region)
}
}
ptype => unsupported_pattern(env, ptype, region),
},
GlobalTag(name) => { GlobalTag(name) => {
// Canonicalize the tag's name. // Canonicalize the tag's name.
Pattern2::GlobalTag { Pattern2::GlobalTag {
@ -472,6 +493,7 @@ pub fn symbols_from_pattern(pool: &Pool, initial: &Pattern2) -> Vec<Symbol> {
| IntLiteral(_) | IntLiteral(_)
| FloatLiteral(_) | FloatLiteral(_)
| StrLiteral(_) | StrLiteral(_)
| CharacterLiteral(_)
| Underscore | Underscore
| MalformedPattern(_, _) | MalformedPattern(_, _)
| Shadowed { .. } | Shadowed { .. }
@ -521,6 +543,7 @@ pub fn symbols_and_variables_from_pattern(
| IntLiteral(_) | IntLiteral(_)
| FloatLiteral(_) | FloatLiteral(_)
| StrLiteral(_) | StrLiteral(_)
| CharacterLiteral(_)
| Underscore | Underscore
| MalformedPattern(_, _) | MalformedPattern(_, _)
| Shadowed { .. } | Shadowed { .. }