mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Infer ranged number for chars in patterns
This commit is contained in:
parent
811c8554ac
commit
619cd2f629
8 changed files with 48 additions and 17 deletions
|
@ -725,7 +725,7 @@ fn deep_copy_pattern_help<C: CopyEnv>(
|
|||
FloatLiteral(sub!(*v1), sub!(*v2), s.clone(), *n, *bound)
|
||||
}
|
||||
StrLiteral(s) => StrLiteral(s.clone()),
|
||||
SingleQuote(c) => SingleQuote(*c),
|
||||
SingleQuote(v1, v2, c, bound) => SingleQuote(sub!(*v1), sub!(*v2), *c, *bound),
|
||||
Underscore => Underscore,
|
||||
AbilityMemberSpecialization { ident, specializes } => AbilityMemberSpecialization {
|
||||
ident: *ident,
|
||||
|
|
|
@ -1884,7 +1884,7 @@ fn pattern_to_vars_by_symbol(
|
|||
| IntLiteral(..)
|
||||
| FloatLiteral(..)
|
||||
| StrLiteral(_)
|
||||
| SingleQuote(_)
|
||||
| SingleQuote(..)
|
||||
| Underscore
|
||||
| MalformedPattern(_, _)
|
||||
| UnsupportedPattern(_)
|
||||
|
|
|
@ -253,7 +253,7 @@ fn sketch_pattern(pattern: &crate::pattern::Pattern) -> SketchedPattern {
|
|||
}
|
||||
&FloatLiteral(_, _, _, f, _) => SP::Literal(Literal::Float(f64::to_bits(f))),
|
||||
StrLiteral(v) => SP::Literal(Literal::Str(v.clone())),
|
||||
&SingleQuote(c) => SP::Literal(Literal::Byte(c as u8)),
|
||||
&SingleQuote(_, _, c, _) => SP::Literal(Literal::Byte(c as u8)),
|
||||
RecordDestructure { destructs, .. } => {
|
||||
let tag_id = TagId(0);
|
||||
let mut patterns = std::vec::Vec::with_capacity(destructs.len());
|
||||
|
|
|
@ -899,7 +899,7 @@ fn fix_values_captured_in_closure_pattern(
|
|||
| IntLiteral(..)
|
||||
| FloatLiteral(..)
|
||||
| StrLiteral(_)
|
||||
| SingleQuote(_)
|
||||
| SingleQuote(..)
|
||||
| Underscore
|
||||
| Shadowed(..)
|
||||
| MalformedPattern(_, _)
|
||||
|
|
|
@ -12,6 +12,7 @@ use roc_parse::ast::{self, StrLiteral, StrSegment};
|
|||
use roc_parse::pattern::PatternType;
|
||||
use roc_problem::can::{MalformedPatternProblem, Problem, RuntimeError, ShadowKind};
|
||||
use roc_region::all::{Loc, Region};
|
||||
use roc_types::num::SingleQuoteBound;
|
||||
use roc_types::subs::{VarStore, Variable};
|
||||
use roc_types::types::{LambdaSet, OptAbleVar, PatternCategory, Type};
|
||||
|
||||
|
@ -59,7 +60,7 @@ pub enum Pattern {
|
|||
IntLiteral(Variable, Variable, Box<str>, IntValue, IntBound),
|
||||
FloatLiteral(Variable, Variable, Box<str>, f64, FloatBound),
|
||||
StrLiteral(Box<str>),
|
||||
SingleQuote(char),
|
||||
SingleQuote(Variable, Variable, char, SingleQuoteBound),
|
||||
Underscore,
|
||||
|
||||
/// An identifier that marks a specialization of an ability member.
|
||||
|
@ -95,7 +96,7 @@ impl Pattern {
|
|||
IntLiteral(var, ..) => Some(*var),
|
||||
FloatLiteral(var, ..) => Some(*var),
|
||||
StrLiteral(_) => None,
|
||||
SingleQuote(_) => None,
|
||||
SingleQuote(..) => None,
|
||||
Underscore => None,
|
||||
|
||||
AbilityMemberSpecialization { .. } => None,
|
||||
|
@ -148,7 +149,7 @@ impl Pattern {
|
|||
IntLiteral(..) => C::Int,
|
||||
FloatLiteral(..) => C::Float,
|
||||
StrLiteral(_) => C::Str,
|
||||
SingleQuote(_) => C::Character,
|
||||
SingleQuote(..) => C::Character,
|
||||
Underscore => C::PatternDefault,
|
||||
|
||||
AbilityMemberSpecialization { .. } => C::PatternDefault,
|
||||
|
@ -456,7 +457,12 @@ pub fn canonicalize_pattern<'a>(
|
|||
let mut it = string.chars().peekable();
|
||||
if let Some(char) = it.next() {
|
||||
if it.peek().is_none() {
|
||||
Pattern::SingleQuote(char)
|
||||
Pattern::SingleQuote(
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
char,
|
||||
SingleQuoteBound::from_char(char),
|
||||
)
|
||||
} else {
|
||||
// multiple chars is found
|
||||
let problem = MalformedPatternProblem::MultipleCharsInSingleQuote;
|
||||
|
@ -724,7 +730,7 @@ impl<'a> BindingsFromPattern<'a> {
|
|||
| IntLiteral(..)
|
||||
| FloatLiteral(..)
|
||||
| StrLiteral(_)
|
||||
| SingleQuote(_)
|
||||
| SingleQuote(..)
|
||||
| Underscore
|
||||
| Shadowed(_, _, _)
|
||||
| MalformedPattern(_, _)
|
||||
|
|
|
@ -71,7 +71,7 @@ fn headers_from_annotation_help(
|
|||
| NumLiteral(..)
|
||||
| IntLiteral(..)
|
||||
| FloatLiteral(..)
|
||||
| SingleQuote(_)
|
||||
| SingleQuote(..)
|
||||
| StrLiteral(_) => true,
|
||||
|
||||
RecordDestructure { destructs, .. } => match annotation.value.shallow_dealias() {
|
||||
|
@ -320,9 +320,32 @@ pub fn constrain_pattern(
|
|||
));
|
||||
}
|
||||
|
||||
SingleQuote(_) => {
|
||||
&SingleQuote(num_var, precision_var, _, bound) => {
|
||||
// First constraint on the free num var; this improves the resolved type quality in
|
||||
// case the bound is an alias.
|
||||
let num_type = builtins::add_numeric_bound_constr(
|
||||
constraints,
|
||||
&mut state.constraints,
|
||||
num_var,
|
||||
num_var,
|
||||
bound,
|
||||
region,
|
||||
Category::Int,
|
||||
);
|
||||
|
||||
// Link the free num var with the int var and our expectation.
|
||||
let int_type = builtins::num_int(Type::Variable(precision_var));
|
||||
|
||||
state.constraints.push(constraints.equal_types(
|
||||
num_type.clone(), // TODO check me if something breaks!
|
||||
Expected::NoExpectation(int_type),
|
||||
Category::Int,
|
||||
region,
|
||||
));
|
||||
|
||||
// Also constrain the pattern against the num var, again to reuse aliases if they're present.
|
||||
state.constraints.push(constraints.equal_pattern_types(
|
||||
builtins::num_u32(),
|
||||
num_type,
|
||||
expected,
|
||||
PatternCategory::Character,
|
||||
region,
|
||||
|
|
|
@ -8889,10 +8889,12 @@ fn from_can_pattern_help<'a>(
|
|||
IntOrFloatValue::Float(*float),
|
||||
)),
|
||||
StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())),
|
||||
SingleQuote(c) => Ok(Pattern::IntLiteral(
|
||||
(*c as i128).to_ne_bytes(),
|
||||
IntWidth::I32,
|
||||
)),
|
||||
SingleQuote(var, _, c, _) => match layout_cache.from_var(env.arena, *var, env.subs) {
|
||||
Ok(Layout::Builtin(Builtin::Int(width))) => {
|
||||
Ok(Pattern::IntLiteral((*c as i128).to_ne_bytes(), width))
|
||||
}
|
||||
o => internal_error!("an integer width was expected, but we found {:?}", o),
|
||||
},
|
||||
Shadowed(region, ident, _new_symbol) => Err(RuntimeError::Shadowing {
|
||||
original_region: *region,
|
||||
shadow: ident.clone(),
|
||||
|
|
|
@ -366,7 +366,7 @@ fn pattern<'a>(
|
|||
f.text(&**n)
|
||||
}
|
||||
StrLiteral(s) => f.text(format!(r#""{}""#, s)),
|
||||
SingleQuote(c) => f.text(format!("'{}'", c)),
|
||||
SingleQuote(_, _, c, _) => f.text(format!("'{}'", c)),
|
||||
Underscore => f.text("_"),
|
||||
|
||||
Shadowed(_, _, _) => todo!(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue