Numbers are opaques

This commit is contained in:
Ayaz Hafiz 2022-04-25 10:58:20 -04:00
parent 969d14dfe9
commit b6383f81ee
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
18 changed files with 684 additions and 1089 deletions

View file

@ -1895,17 +1895,7 @@ fn num_float(pool: &mut Pool, range: TypeId) -> Type2 {
fn num_floatingpoint(pool: &mut Pool, range: TypeId) -> Type2 { fn num_floatingpoint(pool: &mut Pool, range: TypeId) -> Type2 {
let range_type = pool.get(range); let range_type = pool.get(range);
let alias_content = Type2::TagUnion( let alias_content = range_type.shallow_clone();
PoolVec::new(
vec![(
TagName::Private(Symbol::NUM_AT_FLOATINGPOINT),
PoolVec::new(vec![range_type.shallow_clone()].into_iter(), pool),
)]
.into_iter(),
pool,
),
pool.add(Type2::EmptyTagUnion),
);
Type2::Alias( Type2::Alias(
Symbol::NUM_FLOATINGPOINT, Symbol::NUM_FLOATINGPOINT,
@ -1931,22 +1921,10 @@ fn num_int(pool: &mut Pool, range: TypeId) -> Type2 {
#[inline(always)] #[inline(always)]
fn _num_signed64(pool: &mut Pool) -> Type2 { fn _num_signed64(pool: &mut Pool) -> Type2 {
let alias_content = Type2::TagUnion(
PoolVec::new(
vec![(
TagName::Private(Symbol::NUM_AT_SIGNED64),
PoolVec::empty(pool),
)]
.into_iter(),
pool,
),
pool.add(Type2::EmptyTagUnion),
);
Type2::Alias( Type2::Alias(
Symbol::NUM_SIGNED64, Symbol::NUM_SIGNED64,
PoolVec::empty(pool), PoolVec::empty(pool),
pool.add(alias_content), pool.add(Type2::EmptyTagUnion),
) )
} }
@ -1974,17 +1952,7 @@ fn num_unsigned32(pool: &mut Pool) -> Type2 {
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);
let alias_content = Type2::TagUnion( let alias_content = range_type.shallow_clone();
PoolVec::new(
vec![(
TagName::Private(Symbol::NUM_AT_INTEGER),
PoolVec::new(vec![range_type.shallow_clone()].into_iter(), pool),
)]
.into_iter(),
pool,
),
pool.add(Type2::EmptyTagUnion),
);
Type2::Alias( Type2::Alias(
Symbol::NUM_INTEGER, Symbol::NUM_INTEGER,
@ -1997,17 +1965,7 @@ fn _num_integer(pool: &mut Pool, range: TypeId) -> Type2 {
fn num_num(pool: &mut Pool, type_id: TypeId) -> Type2 { fn num_num(pool: &mut Pool, type_id: TypeId) -> Type2 {
let range_type = pool.get(type_id); let range_type = pool.get(type_id);
let alias_content = Type2::TagUnion( let alias_content = range_type.shallow_clone();
PoolVec::new(
vec![(
TagName::Private(Symbol::NUM_AT_NUM),
PoolVec::new(vec![range_type.shallow_clone()].into_iter(), pool),
)]
.into_iter(),
pool,
),
pool.add(Type2::EmptyTagUnion),
);
Type2::Alias( Type2::Alias(
Symbol::NUM_NUM, Symbol::NUM_NUM,

View file

@ -189,7 +189,7 @@ interface Num
## ##
## In practice, these are rarely needed. It's most common to write ## In practice, these are rarely needed. It's most common to write
## number literals without any suffix. ## number literals without any suffix.
Num a : [ @Num a ] Num a := a
## A decimal number. ## A decimal number.
## ##
@ -223,7 +223,7 @@ Num a : [ @Num a ]
## [Dec] typically takes slightly less time than [F64] to perform addition and ## [Dec] typically takes slightly less time than [F64] to perform addition and
## subtraction, but 10-20 times longer to perform multiplication and division. ## subtraction, but 10-20 times longer to perform multiplication and division.
## [sqrt] and trigonometry are massively slower with [Dec] than with [F64]. ## [sqrt] and trigonometry are massively slower with [Dec] than with [F64].
Dec : Float [ @Decimal128 ] Dec : Num (FloatingPoint Decimal)
## A fixed-size number with a fractional component. ## A fixed-size number with a fractional component.
## ##
@ -292,7 +292,7 @@ Dec : Float [ @Decimal128 ]
## loops and conditionals. If you need to do performance-critical trigonometry ## loops and conditionals. If you need to do performance-critical trigonometry
## or square roots, either [F64] or [F32] is probably a better choice than the ## or square roots, either [F64] or [F32] is probably a better choice than the
## usual default choice of [Dec], despite the precision problems they bring. ## usual default choice of [Dec], despite the precision problems they bring.
Float a : Num [ @Fraction a ] Float range : Num (FloatingPoint range)
## A fixed-size integer - that is, a number with no fractional component. ## A fixed-size integer - that is, a number with no fractional component.
## ##
@ -343,19 +343,19 @@ Float a : Num [ @Fraction a ]
## * Start by deciding if this integer should allow negative numbers, and choose signed or unsigned accordingly. ## * Start by deciding if this integer should allow negative numbers, and choose signed or unsigned accordingly.
## * Next, think about the range of numbers you expect this number to hold. Choose the smallest size you will never expect to overflow, no matter the inputs your program receives. (Validating inputs for size, and presenting the user with an error if they are too big, can help guard against overflow.) ## * Next, think about the range of numbers you expect this number to hold. Choose the smallest size you will never expect to overflow, no matter the inputs your program receives. (Validating inputs for size, and presenting the user with an error if they are too big, can help guard against overflow.)
## * Finally, if a particular numeric calculation is running too slowly, you can try experimenting with other number sizes. This rarely makes a meaningful difference, but some processors can operate on different number sizes at different speeds. ## * Finally, if a particular numeric calculation is running too slowly, you can try experimenting with other number sizes. This rarely makes a meaningful difference, but some processors can operate on different number sizes at different speeds.
Int size : Num [ @Integer size ] Int range : Num (Integer range)
## A signed 8-bit integer, ranging from -128 to 127 ## A signed 8-bit integer, ranging from -128 to 127
I8 : Int [ @Signed8 ] I8 : Int Signed8
U8 : Int [ @Unsigned8 ] U8 : Int Unsigned8
I16 : Int [ @Signed16 ] I16 : Int Signed16
U16 : Int [ @Unsigned16 ] U16 : Int Unsigned16
I32 : Int [ @Signed32 ] I32 : Int Signed32
U32 : Int [ @Unsigned32 ] U32 : Int Unsigned32
I64 : Int [ @Signed64 ] I64 : Int Signed64
U64 : Int [ @Unsigned64 ] U64 : Int Unsigned64
I128 : Int [ @Signed128 ] I128 : Int Signed128
U128 : Int [ @Unsigned128 ] U128 : Int Unsigned128
## A [natural number](https://en.wikipedia.org/wiki/Natural_number) represented ## A [natural number](https://en.wikipedia.org/wiki/Natural_number) represented
## as a 64-bit unsigned integer on 64-bit systems, a 32-bit unsigned integer ## as a 64-bit unsigned integer on 64-bit systems, a 32-bit unsigned integer
@ -367,7 +367,7 @@ U128 : Int [ @Unsigned128 ]
## a [List] can hold on a 64-bit system fits in a 64-bit unsigned integer, and ## a [List] can hold on a 64-bit system fits in a 64-bit unsigned integer, and
## on a 32-bit system it fits in 32-bit unsigned integer. This makes [Nat] a ## on a 32-bit system it fits in 32-bit unsigned integer. This makes [Nat] a
## good fit for [List.len] regardless of system. ## good fit for [List.len] regardless of system.
Nat : Int [ @Natural ] Nat : Num (Integer Natural)
## A 64-bit signed integer. All number literals without decimal points are compatible with #Int values. ## A 64-bit signed integer. All number literals without decimal points are compatible with #Int values.
## ##
@ -443,7 +443,7 @@ Nat : Int [ @Natural ]
## ##
## As such, it's very important to design your code not to exceed these bounds! ## As such, it's very important to design your code not to exceed these bounds!
## If you need to do math outside these bounds, consider using a larger numeric size. ## If you need to do math outside these bounds, consider using a larger numeric size.
Int size : Num [ @Int size ] Int range : Num (Integer range)
## Convert ## Convert

View file

@ -158,25 +158,25 @@ interface Num
Bool.{ Bool } Bool.{ Bool }
] ]
Num range : [ @Num range ] Num range := range
Int range : Num (Integer range) Int range : Num (Integer range)
Float range : Num (FloatingPoint range) Float range : Num (FloatingPoint range)
Signed128 : [ @Signed128 ] Signed128 := []
Signed64 : [ @Signed64 ] Signed64 := []
Signed32 : [ @Signed32 ] Signed32 := []
Signed16 : [ @Signed16 ] Signed16 := []
Signed8 : [ @Signed8 ] Signed8 := []
Unsigned128 : [ @Unsigned128 ] Unsigned128 := []
Unsigned64 : [ @Unsigned64 ] Unsigned64 := []
Unsigned32 : [ @Unsigned32 ] Unsigned32 := []
Unsigned16 : [ @Unsigned16 ] Unsigned16 := []
Unsigned8 : [ @Unsigned8 ] Unsigned8 := []
Natural : [ @Natural ] Natural := []
Integer range : [ @Integer range ] Integer range := range
I128 : Num (Integer Signed128) I128 : Num (Integer Signed128)
I64 : Num (Integer Signed64) I64 : Num (Integer Signed64)
@ -192,11 +192,11 @@ U8 : Num (Integer Unsigned8)
Nat : Num (Integer Natural) Nat : Num (Integer Natural)
Decimal : [ @Decimal ] Decimal := []
Binary64 : [ @Binary64 ] Binary64 := []
Binary32 : [ @Binary32 ] Binary32 := []
FloatingPoint range : [ @FloatingPoint range ] FloatingPoint range := range
F64 : Num (FloatingPoint Binary64) F64 : Num (FloatingPoint Binary64)
F32 : Num (FloatingPoint Binary32) F32 : Num (FloatingPoint Binary32)

View file

@ -68,13 +68,9 @@ impl FloatWidth {
pub const fn try_from_symbol(symbol: Symbol) -> Option<Self> { pub const fn try_from_symbol(symbol: Symbol) -> Option<Self> {
match symbol { match symbol {
Symbol::NUM_F64 | Symbol::NUM_BINARY64 | Symbol::NUM_AT_BINARY64 => { Symbol::NUM_F64 | Symbol::NUM_BINARY64 => Some(FloatWidth::F64),
Some(FloatWidth::F64)
}
Symbol::NUM_F32 | Symbol::NUM_BINARY32 | Symbol::NUM_AT_BINARY32 => { Symbol::NUM_F32 | Symbol::NUM_BINARY32 => Some(FloatWidth::F32),
Some(FloatWidth::F32)
}
_ => None, _ => None,
} }
@ -136,26 +132,16 @@ impl IntWidth {
pub const fn try_from_symbol(symbol: Symbol) -> Option<Self> { pub const fn try_from_symbol(symbol: Symbol) -> Option<Self> {
match symbol { match symbol {
Symbol::NUM_I128 | Symbol::NUM_SIGNED128 | Symbol::NUM_AT_SIGNED128 => { Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => Some(IntWidth::I128),
Some(IntWidth::I128) Symbol::NUM_I64 | Symbol::NUM_SIGNED64 => Some(IntWidth::I64),
} Symbol::NUM_I32 | Symbol::NUM_SIGNED32 => Some(IntWidth::I32),
Symbol::NUM_I64 | Symbol::NUM_SIGNED64 | Symbol::NUM_AT_SIGNED64 => Some(IntWidth::I64), Symbol::NUM_I16 | Symbol::NUM_SIGNED16 => Some(IntWidth::I16),
Symbol::NUM_I32 | Symbol::NUM_SIGNED32 | Symbol::NUM_AT_SIGNED32 => Some(IntWidth::I32), Symbol::NUM_I8 | Symbol::NUM_SIGNED8 => Some(IntWidth::I8),
Symbol::NUM_I16 | Symbol::NUM_SIGNED16 | Symbol::NUM_AT_SIGNED16 => Some(IntWidth::I16), Symbol::NUM_U128 | Symbol::NUM_UNSIGNED128 => Some(IntWidth::U128),
Symbol::NUM_I8 | Symbol::NUM_SIGNED8 | Symbol::NUM_AT_SIGNED8 => Some(IntWidth::I8), Symbol::NUM_U64 | Symbol::NUM_UNSIGNED64 => Some(IntWidth::U64),
Symbol::NUM_U128 | Symbol::NUM_UNSIGNED128 | Symbol::NUM_AT_UNSIGNED128 => { Symbol::NUM_U32 | Symbol::NUM_UNSIGNED32 => Some(IntWidth::U32),
Some(IntWidth::U128) Symbol::NUM_U16 | Symbol::NUM_UNSIGNED16 => Some(IntWidth::U16),
} Symbol::NUM_U8 | Symbol::NUM_UNSIGNED8 => Some(IntWidth::U8),
Symbol::NUM_U64 | Symbol::NUM_UNSIGNED64 | Symbol::NUM_AT_UNSIGNED64 => {
Some(IntWidth::U64)
}
Symbol::NUM_U32 | Symbol::NUM_UNSIGNED32 | Symbol::NUM_AT_UNSIGNED32 => {
Some(IntWidth::U32)
}
Symbol::NUM_U16 | Symbol::NUM_UNSIGNED16 | Symbol::NUM_AT_UNSIGNED16 => {
Some(IntWidth::U16)
}
Symbol::NUM_U8 | Symbol::NUM_UNSIGNED8 | Symbol::NUM_AT_UNSIGNED8 => Some(IntWidth::U8),
_ => None, _ => None,
} }
} }

View file

@ -36,7 +36,12 @@ fn add_aliases(var_store: &mut VarStore) -> SendMap<Symbol, Alias> {
let mut aliases = SendMap::default(); let mut aliases = SendMap::default();
for (symbol, builtin_alias) in solved_aliases { for (symbol, builtin_alias) in solved_aliases {
let BuiltinAlias { region, vars, typ } = builtin_alias; let BuiltinAlias {
region,
vars,
typ,
kind,
} = builtin_alias;
let mut free_vars = FreeVars::default(); let mut free_vars = FreeVars::default();
let typ = roc_types::solved_types::to_type(&typ, &mut free_vars, var_store); let typ = roc_types::solved_types::to_type(&typ, &mut free_vars, var_store);
@ -55,8 +60,7 @@ fn add_aliases(var_store: &mut VarStore) -> SendMap<Symbol, Alias> {
lambda_set_variables: Vec::new(), lambda_set_variables: Vec::new(),
recursion_variables: MutSet::default(), recursion_variables: MutSet::default(),
type_variables: variables, type_variables: variables,
// TODO(opaques): replace when opaques are included in the stdlib kind,
kind: AliasKind::Structural,
}; };
aliases.insert(symbol, alias); aliases.insert(symbol, alias);

View file

@ -2,13 +2,13 @@ use arrayvec::ArrayVec;
use roc_can::constraint::{Constraint, Constraints}; use roc_can::constraint::{Constraint, Constraints};
use roc_can::expected::Expected::{self, *}; use roc_can::expected::Expected::{self, *};
use roc_can::num::{FloatBound, FloatWidth, IntBound, IntWidth, NumericBound, SignDemand}; use roc_can::num::{FloatBound, FloatWidth, IntBound, IntWidth, NumericBound, SignDemand};
use roc_module::ident::{Lowercase, TagName}; use roc_module::ident::Lowercase;
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_region::all::Region; use roc_region::all::Region;
use roc_types::subs::Variable; use roc_types::subs::Variable;
use roc_types::types::Reason;
use roc_types::types::Type::{self, *}; use roc_types::types::Type::{self, *};
use roc_types::types::{AliasKind, Category}; use roc_types::types::{AliasKind, Category};
use roc_types::types::{Reason, TypeExtension};
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
@ -163,14 +163,14 @@ fn builtin_alias(
symbol: Symbol, symbol: Symbol,
type_arguments: Vec<(Lowercase, Type)>, type_arguments: Vec<(Lowercase, Type)>,
actual: Box<Type>, actual: Box<Type>,
kind: AliasKind,
) -> Type { ) -> Type {
Type::Alias { Type::Alias {
symbol, symbol,
type_arguments, type_arguments,
actual, actual,
lambda_set_variables: vec![], lambda_set_variables: vec![],
// TODO(opaques): revisit later kind,
kind: AliasKind::Structural,
} }
} }
@ -180,49 +180,48 @@ pub fn num_float(range: Type) -> Type {
Symbol::NUM_FLOAT, Symbol::NUM_FLOAT,
vec![("range".into(), range.clone())], vec![("range".into(), range.clone())],
Box::new(num_num(num_floatingpoint(range))), Box::new(num_num(num_floatingpoint(range))),
AliasKind::Structural,
) )
} }
#[inline(always)] #[inline(always)]
pub fn num_floatingpoint(range: Type) -> Type { pub fn num_floatingpoint(range: Type) -> Type {
let alias_content = Type::TagUnion(
vec![(
TagName::Private(Symbol::NUM_AT_FLOATINGPOINT),
vec![range.clone()],
)],
TypeExtension::Closed,
);
builtin_alias( builtin_alias(
Symbol::NUM_FLOATINGPOINT, Symbol::NUM_FLOATINGPOINT,
vec![("range".into(), range)], vec![("range".into(), range.clone())],
Box::new(alias_content), Box::new(range),
AliasKind::Opaque,
) )
} }
#[inline(always)] #[inline(always)]
pub fn num_u32() -> Type { pub fn num_u32() -> Type {
builtin_alias(Symbol::NUM_U32, vec![], Box::new(num_int(num_unsigned32()))) builtin_alias(
Symbol::NUM_U32,
vec![],
Box::new(num_int(num_unsigned32())),
AliasKind::Structural,
)
} }
#[inline(always)] #[inline(always)]
fn num_unsigned32() -> Type { fn num_unsigned32() -> Type {
let alias_content = Type::TagUnion( builtin_alias(
vec![(TagName::Private(Symbol::NUM_AT_UNSIGNED32), vec![])], Symbol::NUM_UNSIGNED32,
TypeExtension::Closed, vec![],
); Box::new(Type::EmptyTagUnion),
AliasKind::Opaque,
builtin_alias(Symbol::NUM_UNSIGNED32, vec![], Box::new(alias_content)) )
} }
#[inline(always)] #[inline(always)]
pub fn num_binary64() -> Type { pub fn num_binary64() -> Type {
let alias_content = Type::TagUnion( builtin_alias(
vec![(TagName::Private(Symbol::NUM_AT_BINARY64), vec![])], Symbol::NUM_BINARY64,
TypeExtension::Closed, vec![],
); Box::new(Type::EmptyTagUnion),
AliasKind::Opaque,
builtin_alias(Symbol::NUM_BINARY64, vec![], Box::new(alias_content)) )
} }
#[inline(always)] #[inline(always)]
@ -231,47 +230,37 @@ pub fn num_int(range: Type) -> Type {
Symbol::NUM_INT, Symbol::NUM_INT,
vec![("range".into(), range.clone())], vec![("range".into(), range.clone())],
Box::new(num_num(num_integer(range))), Box::new(num_num(num_integer(range))),
AliasKind::Structural,
) )
} }
#[inline(always)] #[inline(always)]
pub fn num_signed64() -> Type { pub fn num_signed64() -> Type {
let alias_content = Type::TagUnion( builtin_alias(
vec![(TagName::Private(Symbol::NUM_AT_SIGNED64), vec![])], Symbol::NUM_SIGNED64,
TypeExtension::Closed, vec![],
); Box::new(Type::EmptyTagUnion),
AliasKind::Opaque,
builtin_alias(Symbol::NUM_SIGNED64, 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(
vec![(
TagName::Private(Symbol::NUM_AT_INTEGER),
vec![range.clone()],
)],
TypeExtension::Closed,
);
builtin_alias( builtin_alias(
Symbol::NUM_INTEGER, Symbol::NUM_INTEGER,
vec![("range".into(), range)], vec![("range".into(), range.clone())],
Box::new(alias_content), Box::new(range),
AliasKind::Opaque,
) )
} }
#[inline(always)] #[inline(always)]
pub fn num_num(typ: Type) -> Type { pub fn num_num(typ: Type) -> Type {
let alias_content = Type::TagUnion(
vec![(TagName::Private(Symbol::NUM_AT_NUM), vec![typ.clone()])],
TypeExtension::Closed,
);
builtin_alias( builtin_alias(
Symbol::NUM_NUM, Symbol::NUM_NUM,
vec![("range".into(), typ)], vec![("range".into(), typ.clone())],
Box::new(alias_content), Box::new(typ),
AliasKind::Opaque,
) )
} }

View file

@ -39,7 +39,7 @@ use roc_solve::solve;
use roc_target::TargetInfo; use roc_target::TargetInfo;
use roc_types::solved_types::Solved; use roc_types::solved_types::Solved;
use roc_types::subs::{Subs, VarStore, Variable}; use roc_types::subs::{Subs, VarStore, Variable};
use roc_types::types::{Alias, AliasCommon, TypeExtension}; use roc_types::types::{Alias, AliasCommon, AliasKind, TypeExtension};
use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap; use std::collections::HashMap;
use std::io; use std::io;
@ -4715,50 +4715,35 @@ fn default_aliases() -> roc_solve::solve::Aliases {
let mut var_store = VarStore::default(); let mut var_store = VarStore::default();
// Num range := range
{ {
let symbol = Symbol::NUM_NUM; let symbol = Symbol::NUM_NUM;
let tvar = var_store.fresh(); let tvar = var_store.fresh();
let typ = Type::TagUnion(
vec![(
TagName::Private(Symbol::NUM_AT_NUM),
vec![Type::Variable(tvar)],
)],
TypeExtension::Closed,
);
let alias = Alias { let alias = Alias {
region: Region::zero(), region: Region::zero(),
type_variables: vec![Loc::at_zero(("range".into(), tvar))], type_variables: vec![Loc::at_zero(("range".into(), tvar))],
lambda_set_variables: Default::default(), lambda_set_variables: Default::default(),
recursion_variables: Default::default(), recursion_variables: Default::default(),
typ, typ: Type::Variable(tvar),
kind: roc_types::types::AliasKind::Structural, kind: roc_types::types::AliasKind::Structural,
}; };
solve_aliases.insert(symbol, alias); solve_aliases.insert(symbol, alias);
} }
// FloatingPoint range : [ @FloatingPoint range ] // FloatingPoint range := []
{ {
let symbol = Symbol::NUM_FLOATINGPOINT; let symbol = Symbol::NUM_FLOATINGPOINT;
let tvar = var_store.fresh(); let tvar = var_store.fresh();
let typ = Type::TagUnion(
vec![(
TagName::Private(Symbol::NUM_AT_FLOATINGPOINT),
vec![Type::Variable(tvar)],
)],
TypeExtension::Closed,
);
let alias = Alias { let alias = Alias {
region: Region::zero(), region: Region::zero(),
type_variables: vec![Loc::at_zero(("range".into(), tvar))], type_variables: vec![Loc::at_zero(("range".into(), tvar))],
lambda_set_variables: Default::default(), lambda_set_variables: Default::default(),
recursion_variables: Default::default(), recursion_variables: Default::default(),
typ, typ: Type::Variable(tvar),
kind: roc_types::types::AliasKind::Structural, kind: roc_types::types::AliasKind::Opaque,
}; };
solve_aliases.insert(symbol, alias); solve_aliases.insert(symbol, alias);
@ -4773,11 +4758,13 @@ fn default_aliases() -> roc_solve::solve::Aliases {
symbol: Symbol::NUM_NUM, symbol: Symbol::NUM_NUM,
type_arguments: vec![( type_arguments: vec![(
"range".into(), "range".into(),
Type::DelayedAlias(AliasCommon { Type::Alias {
symbol: Symbol::NUM_INTEGER, symbol: Symbol::NUM_INTEGER,
type_arguments: vec![("range".into(), Type::Variable(tvar))], type_arguments: vec![("range".into(), Type::Variable(tvar))],
lambda_set_variables: vec![], lambda_set_variables: vec![],
}), actual: Box::new(Type::Variable(tvar)),
kind: AliasKind::Opaque,
},
)], )],
lambda_set_variables: vec![], lambda_set_variables: vec![],
}); });
@ -4794,6 +4781,7 @@ fn default_aliases() -> roc_solve::solve::Aliases {
solve_aliases.insert(symbol, alias); solve_aliases.insert(symbol, alias);
} }
// Float range : Num (FloatingPoint range)
{ {
let symbol = Symbol::NUM_FLOAT; let symbol = Symbol::NUM_FLOAT;
let tvar = var_store.fresh(); let tvar = var_store.fresh();
@ -4802,11 +4790,13 @@ fn default_aliases() -> roc_solve::solve::Aliases {
symbol: Symbol::NUM_NUM, symbol: Symbol::NUM_NUM,
type_arguments: vec![( type_arguments: vec![(
"range".into(), "range".into(),
Type::DelayedAlias(AliasCommon { Type::Alias {
symbol: Symbol::NUM_FLOATINGPOINT, symbol: Symbol::NUM_FLOATINGPOINT,
type_arguments: vec![("range".into(), Type::Variable(tvar))], type_arguments: vec![("range".into(), Type::Variable(tvar))],
lambda_set_variables: vec![], lambda_set_variables: vec![],
}), actual: Box::new(Type::Variable(tvar)),
kind: AliasKind::Opaque,
},
)], )],
lambda_set_variables: vec![], lambda_set_variables: vec![],
}); });
@ -4823,24 +4813,17 @@ fn default_aliases() -> roc_solve::solve::Aliases {
solve_aliases.insert(symbol, alias); solve_aliases.insert(symbol, alias);
} }
// Integer range := range
{ {
let symbol = Symbol::NUM_INTEGER; let symbol = Symbol::NUM_INTEGER;
let tvar = var_store.fresh(); let tvar = var_store.fresh();
let typ = Type::TagUnion(
vec![(
TagName::Private(Symbol::NUM_AT_INTEGER),
vec![Type::Variable(tvar)],
)],
TypeExtension::Closed,
);
let alias = Alias { let alias = Alias {
region: Region::zero(), region: Region::zero(),
type_variables: vec![Loc::at_zero(("range".into(), tvar))], type_variables: vec![Loc::at_zero(("range".into(), tvar))],
lambda_set_variables: Default::default(), lambda_set_variables: Default::default(),
recursion_variables: Default::default(), recursion_variables: Default::default(),
typ, typ: Type::Variable(tvar),
kind: roc_types::types::AliasKind::Structural, kind: roc_types::types::AliasKind::Structural,
}; };
@ -4875,38 +4858,33 @@ fn default_aliases() -> roc_solve::solve::Aliases {
solve_aliases.insert(symbol, alias); solve_aliases.insert(symbol, alias);
} }
let mut unit_function = |alias_name: Symbol, at_tag_name: Symbol| { let mut zero_opaque = |alias_name: Symbol| {
let typ = Type::TagUnion(
vec![(TagName::Private(at_tag_name), vec![])],
TypeExtension::Closed,
);
let alias = Alias { let alias = Alias {
region: Region::zero(), region: Region::zero(),
type_variables: vec![], type_variables: vec![],
lambda_set_variables: Default::default(), lambda_set_variables: Default::default(),
recursion_variables: Default::default(), recursion_variables: Default::default(),
typ, typ: Type::EmptyTagUnion,
kind: roc_types::types::AliasKind::Structural, kind: AliasKind::Opaque,
}; };
solve_aliases.insert(alias_name, alias); solve_aliases.insert(alias_name, alias);
}; };
unit_function(Symbol::NUM_SIGNED8, Symbol::NUM_AT_SIGNED8); zero_opaque(Symbol::NUM_SIGNED8);
unit_function(Symbol::NUM_SIGNED16, Symbol::NUM_AT_SIGNED16); zero_opaque(Symbol::NUM_SIGNED16);
unit_function(Symbol::NUM_SIGNED32, Symbol::NUM_AT_SIGNED32); zero_opaque(Symbol::NUM_SIGNED32);
unit_function(Symbol::NUM_SIGNED64, Symbol::NUM_AT_SIGNED64); zero_opaque(Symbol::NUM_SIGNED64);
unit_function(Symbol::NUM_SIGNED128, Symbol::NUM_AT_SIGNED128); zero_opaque(Symbol::NUM_SIGNED128);
unit_function(Symbol::NUM_UNSIGNED8, Symbol::NUM_AT_UNSIGNED8); zero_opaque(Symbol::NUM_UNSIGNED8);
unit_function(Symbol::NUM_UNSIGNED16, Symbol::NUM_AT_UNSIGNED16); zero_opaque(Symbol::NUM_UNSIGNED16);
unit_function(Symbol::NUM_UNSIGNED32, Symbol::NUM_AT_UNSIGNED32); zero_opaque(Symbol::NUM_UNSIGNED32);
unit_function(Symbol::NUM_UNSIGNED64, Symbol::NUM_AT_UNSIGNED64); zero_opaque(Symbol::NUM_UNSIGNED64);
unit_function(Symbol::NUM_UNSIGNED128, Symbol::NUM_AT_UNSIGNED128); zero_opaque(Symbol::NUM_UNSIGNED128);
unit_function(Symbol::NUM_BINARY32, Symbol::NUM_AT_BINARY32); zero_opaque(Symbol::NUM_BINARY32);
unit_function(Symbol::NUM_BINARY64, Symbol::NUM_AT_BINARY64); zero_opaque(Symbol::NUM_BINARY64);
solve_aliases solve_aliases
} }

View file

@ -907,160 +907,143 @@ define_builtins! {
} }
1 NUM: "Num" => { 1 NUM: "Num" => {
0 NUM_NUM: "Num" // the Num.Num type alias 0 NUM_NUM: "Num" // the Num.Num type alias
1 NUM_AT_NUM: "@Num" // the Num.@Num private tag 1 NUM_I128: "I128" // the Num.I128 type alias
2 NUM_I128: "I128" // the Num.I128 type alias 2 NUM_U128: "U128" // the Num.U128 type alias
3 NUM_U128: "U128" // the Num.U128 type alias 3 NUM_I64: "I64" // the Num.I64 type alias
4 NUM_I64: "I64" // the Num.I64 type alias 4 NUM_U64: "U64" // the Num.U64 type alias
5 NUM_U64: "U64" // the Num.U64 type alias 5 NUM_I32: "I32" // the Num.I32 type alias
6 NUM_I32: "I32" // the Num.I32 type alias 6 NUM_U32: "U32" // the Num.U32 type alias
7 NUM_U32: "U32" // the Num.U32 type alias 7 NUM_I16: "I16" // the Num.I16 type alias
8 NUM_I16: "I16" // the Num.I16 type alias 8 NUM_U16: "U16" // the Num.U16 type alias
9 NUM_U16: "U16" // the Num.U16 type alias 9 NUM_I8: "I8" // the Num.I8 type alias
10 NUM_I8: "I8" // the Num.I8 type alias 10 NUM_U8: "U8" // the Num.U8 type alias
11 NUM_U8: "U8" // the Num.U8 type alias 11 NUM_INTEGER: "Integer" // Int : Num Integer
12 NUM_INTEGER: "Integer" // Int : Num Integer 12 NUM_F64: "F64" // the Num.F64 type alias
13 NUM_AT_INTEGER: "@Integer" // the Int.@Integer private tag 13 NUM_F32: "F32" // the Num.F32 type alias
14 NUM_F64: "F64" // the Num.F64 type alias 14 NUM_FLOATINGPOINT: "FloatingPoint" // Float : Num FloatingPoint
15 NUM_F32: "F32" // the Num.F32 type alias 15 NUM_MAX_FLOAT: "maxFloat"
16 NUM_FLOATINGPOINT: "FloatingPoint" // Float : Num FloatingPoint 16 NUM_MIN_FLOAT: "minFloat"
17 NUM_AT_FLOATINGPOINT: "@FloatingPoint" // the Float.@FloatingPoint private tag 17 NUM_ABS: "abs"
18 NUM_MAX_FLOAT: "maxFloat" 18 NUM_NEG: "neg"
19 NUM_MIN_FLOAT: "minFloat" 19 NUM_ADD: "add"
20 NUM_ABS: "abs" 20 NUM_SUB: "sub"
21 NUM_NEG: "neg" 21 NUM_MUL: "mul"
22 NUM_ADD: "add" 22 NUM_LT: "isLt"
23 NUM_SUB: "sub" 23 NUM_LTE: "isLte"
24 NUM_MUL: "mul" 24 NUM_GT: "isGt"
25 NUM_LT: "isLt" 25 NUM_GTE: "isGte"
26 NUM_LTE: "isLte" 26 NUM_TO_FLOAT: "toFloat"
27 NUM_GT: "isGt" 27 NUM_SIN: "sin"
28 NUM_GTE: "isGte" 28 NUM_COS: "cos"
29 NUM_TO_FLOAT: "toFloat" 29 NUM_TAN: "tan"
30 NUM_SIN: "sin" 30 NUM_IS_ZERO: "isZero"
31 NUM_COS: "cos" 31 NUM_IS_EVEN: "isEven"
32 NUM_TAN: "tan" 32 NUM_IS_ODD: "isOdd"
33 NUM_IS_ZERO: "isZero" 33 NUM_IS_POSITIVE: "isPositive"
34 NUM_IS_EVEN: "isEven" 34 NUM_IS_NEGATIVE: "isNegative"
35 NUM_IS_ODD: "isOdd" 35 NUM_REM: "rem"
36 NUM_IS_POSITIVE: "isPositive" 36 NUM_REM_CHECKED: "remChecked"
37 NUM_IS_NEGATIVE: "isNegative" 37 NUM_DIV_FLOAT: "div"
38 NUM_REM: "rem" 38 NUM_DIV_FLOAT_CHECKED: "divChecked"
39 NUM_REM_CHECKED: "remChecked" 39 NUM_DIV_TRUNC: "divTrunc"
40 NUM_DIV_FLOAT: "div" 40 NUM_DIV_TRUNC_CHECKED: "divTruncChecked"
41 NUM_DIV_FLOAT_CHECKED: "divChecked" 41 NUM_SQRT: "sqrt"
42 NUM_DIV_TRUNC: "divTrunc" 42 NUM_SQRT_CHECKED: "sqrtChecked"
43 NUM_DIV_TRUNC_CHECKED: "divTruncChecked" 43 NUM_LOG: "log"
44 NUM_SQRT: "sqrt" 44 NUM_LOG_CHECKED: "logChecked"
45 NUM_SQRT_CHECKED: "sqrtChecked" 45 NUM_ROUND: "round"
46 NUM_LOG: "log" 46 NUM_COMPARE: "compare"
47 NUM_LOG_CHECKED: "logChecked" 47 NUM_POW: "pow"
48 NUM_ROUND: "round" 48 NUM_CEILING: "ceiling"
49 NUM_COMPARE: "compare" 49 NUM_POW_INT: "powInt"
50 NUM_POW: "pow" 50 NUM_FLOOR: "floor"
51 NUM_CEILING: "ceiling" 51 NUM_ADD_WRAP: "addWrap"
52 NUM_POW_INT: "powInt" 52 NUM_ADD_CHECKED: "addChecked"
53 NUM_FLOOR: "floor" 53 NUM_ADD_SATURATED: "addSaturated"
54 NUM_ADD_WRAP: "addWrap" 54 NUM_ATAN: "atan"
55 NUM_ADD_CHECKED: "addChecked" 55 NUM_ACOS: "acos"
56 NUM_ADD_SATURATED: "addSaturated" 56 NUM_ASIN: "asin"
57 NUM_ATAN: "atan" 57 NUM_SIGNED128: "Signed128"
58 NUM_ACOS: "acos" 58 NUM_SIGNED64: "Signed64"
59 NUM_ASIN: "asin" 59 NUM_SIGNED32: "Signed32"
60 NUM_AT_SIGNED128: "@Signed128" 60 NUM_SIGNED16: "Signed16"
61 NUM_SIGNED128: "Signed128" 61 NUM_SIGNED8: "Signed8"
62 NUM_AT_SIGNED64: "@Signed64" 62 NUM_UNSIGNED128: "Unsigned128"
63 NUM_SIGNED64: "Signed64" 63 NUM_UNSIGNED64: "Unsigned64"
64 NUM_AT_SIGNED32: "@Signed32" 64 NUM_UNSIGNED32: "Unsigned32"
65 NUM_SIGNED32: "Signed32" 65 NUM_UNSIGNED16: "Unsigned16"
66 NUM_AT_SIGNED16: "@Signed16" 66 NUM_UNSIGNED8: "Unsigned8"
67 NUM_SIGNED16: "Signed16" 67 NUM_BINARY64: "Binary64"
68 NUM_AT_SIGNED8: "@Signed8" 68 NUM_BINARY32: "Binary32"
69 NUM_SIGNED8: "Signed8" 69 NUM_BITWISE_AND: "bitwiseAnd"
70 NUM_AT_UNSIGNED128: "@Unsigned128" 70 NUM_BITWISE_XOR: "bitwiseXor"
71 NUM_UNSIGNED128: "Unsigned128" 71 NUM_BITWISE_OR: "bitwiseOr"
72 NUM_AT_UNSIGNED64: "@Unsigned64" 72 NUM_SHIFT_LEFT: "shiftLeftBy"
73 NUM_UNSIGNED64: "Unsigned64" 73 NUM_SHIFT_RIGHT: "shiftRightBy"
74 NUM_AT_UNSIGNED32: "@Unsigned32" 74 NUM_SHIFT_RIGHT_ZERO_FILL: "shiftRightZfBy"
75 NUM_UNSIGNED32: "Unsigned32" 75 NUM_SUB_WRAP: "subWrap"
76 NUM_AT_UNSIGNED16: "@Unsigned16" 76 NUM_SUB_CHECKED: "subChecked"
77 NUM_UNSIGNED16: "Unsigned16" 77 NUM_SUB_SATURATED: "subSaturated"
78 NUM_AT_UNSIGNED8: "@Unsigned8" 78 NUM_MUL_WRAP: "mulWrap"
79 NUM_UNSIGNED8: "Unsigned8" 79 NUM_MUL_CHECKED: "mulChecked"
80 NUM_AT_BINARY64: "@Binary64" 80 NUM_INT: "Int"
81 NUM_BINARY64: "Binary64" 81 NUM_FLOAT: "Float"
82 NUM_AT_BINARY32: "@Binary32" 82 NUM_NATURAL: "Natural"
83 NUM_BINARY32: "Binary32" 83 NUM_NAT: "Nat"
84 NUM_BITWISE_AND: "bitwiseAnd" 84 NUM_INT_CAST: "intCast"
85 NUM_BITWISE_XOR: "bitwiseXor" 85 NUM_IS_MULTIPLE_OF: "isMultipleOf"
86 NUM_BITWISE_OR: "bitwiseOr" 86 NUM_DECIMAL: "Decimal"
87 NUM_SHIFT_LEFT: "shiftLeftBy" 87 NUM_DEC: "Dec" // the Num.Dectype alias
88 NUM_SHIFT_RIGHT: "shiftRightBy" 88 NUM_BYTES_TO_U16: "bytesToU16"
89 NUM_SHIFT_RIGHT_ZERO_FILL: "shiftRightZfBy" 89 NUM_BYTES_TO_U32: "bytesToU32"
90 NUM_SUB_WRAP: "subWrap" 90 NUM_CAST_TO_NAT: "#castToNat"
91 NUM_SUB_CHECKED: "subChecked" 91 NUM_DIV_CEIL: "divCeil"
92 NUM_SUB_SATURATED: "subSaturated" 92 NUM_DIV_CEIL_CHECKED: "divCeilChecked"
93 NUM_MUL_WRAP: "mulWrap" 93 NUM_TO_STR: "toStr"
94 NUM_MUL_CHECKED: "mulChecked" 94 NUM_MIN_I8: "minI8"
95 NUM_INT: "Int" 95 NUM_MAX_I8: "maxI8"
96 NUM_FLOAT: "Float" 96 NUM_MIN_U8: "minU8"
97 NUM_AT_NATURAL: "@Natural" 97 NUM_MAX_U8: "maxU8"
98 NUM_NATURAL: "Natural" 98 NUM_MIN_I16: "minI16"
99 NUM_NAT: "Nat" 99 NUM_MAX_I16: "maxI16"
100 NUM_INT_CAST: "intCast" 100 NUM_MIN_U16: "minU16"
101 NUM_IS_MULTIPLE_OF: "isMultipleOf" 101 NUM_MAX_U16: "maxU16"
102 NUM_AT_DECIMAL: "@Decimal" 102 NUM_MIN_I32: "minI32"
103 NUM_DECIMAL: "Decimal" 103 NUM_MAX_I32: "maxI32"
104 NUM_DEC: "Dec" // the Num.Dectype alias 104 NUM_MIN_U32: "minU32"
105 NUM_BYTES_TO_U16: "bytesToU16" 105 NUM_MAX_U32: "maxU32"
106 NUM_BYTES_TO_U32: "bytesToU32" 106 NUM_MIN_I64: "minI64"
107 NUM_CAST_TO_NAT: "#castToNat" 107 NUM_MAX_I64: "maxI64"
108 NUM_DIV_CEIL: "divCeil" 108 NUM_MIN_U64: "minU64"
109 NUM_DIV_CEIL_CHECKED: "divCeilChecked" 109 NUM_MAX_U64: "maxU64"
110 NUM_TO_STR: "toStr" 110 NUM_MIN_I128: "minI128"
111 NUM_MIN_I8: "minI8" 111 NUM_MAX_I128: "maxI128"
112 NUM_MAX_I8: "maxI8" 112 NUM_TO_I8: "toI8"
113 NUM_MIN_U8: "minU8" 113 NUM_TO_I8_CHECKED: "toI8Checked"
114 NUM_MAX_U8: "maxU8" 114 NUM_TO_I16: "toI16"
115 NUM_MIN_I16: "minI16" 115 NUM_TO_I16_CHECKED: "toI16Checked"
116 NUM_MAX_I16: "maxI16" 116 NUM_TO_I32: "toI32"
117 NUM_MIN_U16: "minU16" 117 NUM_TO_I32_CHECKED: "toI32Checked"
118 NUM_MAX_U16: "maxU16" 118 NUM_TO_I64: "toI64"
119 NUM_MIN_I32: "minI32" 119 NUM_TO_I64_CHECKED: "toI64Checked"
120 NUM_MAX_I32: "maxI32" 120 NUM_TO_I128: "toI128"
121 NUM_MIN_U32: "minU32" 121 NUM_TO_I128_CHECKED: "toI128Checked"
122 NUM_MAX_U32: "maxU32" 122 NUM_TO_U8: "toU8"
123 NUM_MIN_I64: "minI64" 123 NUM_TO_U8_CHECKED: "toU8Checked"
124 NUM_MAX_I64: "maxI64" 124 NUM_TO_U16: "toU16"
125 NUM_MIN_U64: "minU64" 125 NUM_TO_U16_CHECKED: "toU16Checked"
126 NUM_MAX_U64: "maxU64" 126 NUM_TO_U32: "toU32"
127 NUM_MIN_I128: "minI128" 127 NUM_TO_U32_CHECKED: "toU32Checked"
128 NUM_MAX_I128: "maxI128" 128 NUM_TO_U64: "toU64"
129 NUM_TO_I8: "toI8" 129 NUM_TO_U64_CHECKED: "toU64Checked"
130 NUM_TO_I8_CHECKED: "toI8Checked" 130 NUM_TO_U128: "toU128"
131 NUM_TO_I16: "toI16" 131 NUM_TO_U128_CHECKED: "toU128Checked"
132 NUM_TO_I16_CHECKED: "toI16Checked" 132 NUM_TO_NAT: "toNat"
133 NUM_TO_I32: "toI32" 133 NUM_TO_NAT_CHECKED: "toNatChecked"
134 NUM_TO_I32_CHECKED: "toI32Checked" 134 NUM_TO_F32: "toF32"
135 NUM_TO_I64: "toI64" 135 NUM_TO_F32_CHECKED: "toF32Checked"
136 NUM_TO_I64_CHECKED: "toI64Checked" 136 NUM_TO_F64: "toF64"
137 NUM_TO_I128: "toI128" 137 NUM_TO_F64_CHECKED: "toF64Checked"
138 NUM_TO_I128_CHECKED: "toI128Checked"
139 NUM_TO_U8: "toU8"
140 NUM_TO_U8_CHECKED: "toU8Checked"
141 NUM_TO_U16: "toU16"
142 NUM_TO_U16_CHECKED: "toU16Checked"
143 NUM_TO_U32: "toU32"
144 NUM_TO_U32_CHECKED: "toU32Checked"
145 NUM_TO_U64: "toU64"
146 NUM_TO_U64_CHECKED: "toU64Checked"
147 NUM_TO_U128: "toU128"
148 NUM_TO_U128_CHECKED: "toU128Checked"
149 NUM_TO_NAT: "toNat"
150 NUM_TO_NAT_CHECKED: "toNatChecked"
151 NUM_TO_F32: "toF32"
152 NUM_TO_F32_CHECKED: "toF32Checked"
153 NUM_TO_F64: "toF64"
154 NUM_TO_F64_CHECKED: "toF64Checked"
} }
2 BOOL: "Bool" => { 2 BOOL: "Bool" => {
0 BOOL_BOOL: "Bool" // the Bool.Bool type alias 0 BOOL_BOOL: "Bool" // the Bool.Bool type alias
@ -1077,101 +1060,99 @@ define_builtins! {
} }
3 STR: "Str" => { 3 STR: "Str" => {
0 STR_STR: "Str" imported // the Str.Str type alias 0 STR_STR: "Str" imported // the Str.Str type alias
1 STR_AT_STR: "@Str" // the Str.@Str private tag 1 STR_IS_EMPTY: "isEmpty"
2 STR_IS_EMPTY: "isEmpty" 2 STR_APPEND: "#append" // unused
3 STR_APPEND: "#append" // unused 3 STR_CONCAT: "concat"
4 STR_CONCAT: "concat" 4 STR_JOIN_WITH: "joinWith"
5 STR_JOIN_WITH: "joinWith" 5 STR_SPLIT: "split"
6 STR_SPLIT: "split" 6 STR_COUNT_GRAPHEMES: "countGraphemes"
7 STR_COUNT_GRAPHEMES: "countGraphemes" 7 STR_STARTS_WITH: "startsWith"
8 STR_STARTS_WITH: "startsWith" 8 STR_ENDS_WITH: "endsWith"
9 STR_ENDS_WITH: "endsWith" 9 STR_FROM_UTF8: "fromUtf8"
10 STR_FROM_UTF8: "fromUtf8" 10 STR_UT8_PROBLEM: "Utf8Problem" // the Utf8Problem type alias
11 STR_UT8_PROBLEM: "Utf8Problem" // the Utf8Problem type alias 11 STR_UT8_BYTE_PROBLEM: "Utf8ByteProblem" // the Utf8ByteProblem type alias
12 STR_UT8_BYTE_PROBLEM: "Utf8ByteProblem" // the Utf8ByteProblem type alias 12 STR_TO_UTF8: "toUtf8"
13 STR_TO_UTF8: "toUtf8" 13 STR_STARTS_WITH_CODE_PT: "startsWithCodePt"
14 STR_STARTS_WITH_CODE_PT: "startsWithCodePt" 14 STR_ALIAS_ANALYSIS_STATIC: "#aliasAnalysisStatic" // string with the static lifetime
15 STR_ALIAS_ANALYSIS_STATIC: "#aliasAnalysisStatic" // string with the static lifetime 15 STR_FROM_UTF8_RANGE: "fromUtf8Range"
16 STR_FROM_UTF8_RANGE: "fromUtf8Range" 16 STR_REPEAT: "repeat"
17 STR_REPEAT: "repeat" 17 STR_TRIM: "trim"
18 STR_TRIM: "trim" 18 STR_TRIM_LEFT: "trimLeft"
19 STR_TRIM_LEFT: "trimLeft" 19 STR_TRIM_RIGHT: "trimRight"
20 STR_TRIM_RIGHT: "trimRight" 20 STR_TO_DEC: "toDec"
21 STR_TO_DEC: "toDec" 21 STR_TO_F64: "toF64"
22 STR_TO_F64: "toF64" 22 STR_TO_F32: "toF32"
23 STR_TO_F32: "toF32" 23 STR_TO_NAT: "toNat"
24 STR_TO_NAT: "toNat" 24 STR_TO_U128: "toU128"
25 STR_TO_U128: "toU128" 25 STR_TO_I128: "toI128"
26 STR_TO_I128: "toI128" 26 STR_TO_U64: "toU64"
27 STR_TO_U64: "toU64" 27 STR_TO_I64: "toI64"
28 STR_TO_I64: "toI64" 28 STR_TO_U32: "toU32"
29 STR_TO_U32: "toU32" 29 STR_TO_I32: "toI32"
30 STR_TO_I32: "toI32" 30 STR_TO_U16: "toU16"
31 STR_TO_U16: "toU16" 31 STR_TO_I16: "toI16"
32 STR_TO_I16: "toI16" 32 STR_TO_U8: "toU8"
33 STR_TO_U8: "toU8" 33 STR_TO_I8: "toI8"
34 STR_TO_I8: "toI8"
} }
4 LIST: "List" => { 4 LIST: "List" => {
0 LIST_LIST: "List" imported // the List.List type alias 0 LIST_LIST: "List" imported // the List.List type alias
1 LIST_AT_LIST: "@List" // the List.@List private tag 1 LIST_IS_EMPTY: "isEmpty"
2 LIST_IS_EMPTY: "isEmpty" 2 LIST_GET: "get"
3 LIST_GET: "get" 3 LIST_SET: "set"
4 LIST_SET: "set" 4 LIST_APPEND: "append"
5 LIST_APPEND: "append" 5 LIST_MAP: "map"
6 LIST_MAP: "map" 6 LIST_LEN: "len"
7 LIST_LEN: "len" 7 LIST_WALK_BACKWARDS: "walkBackwards"
8 LIST_WALK_BACKWARDS: "walkBackwards" 8 LIST_CONCAT: "concat"
9 LIST_CONCAT: "concat" 9 LIST_FIRST: "first"
10 LIST_FIRST: "first" 10 LIST_SINGLE: "single"
11 LIST_SINGLE: "single" 11 LIST_REPEAT: "repeat"
12 LIST_REPEAT: "repeat" 12 LIST_REVERSE: "reverse"
13 LIST_REVERSE: "reverse" 13 LIST_PREPEND: "prepend"
14 LIST_PREPEND: "prepend" 14 LIST_JOIN: "join"
15 LIST_JOIN: "join" 15 LIST_KEEP_IF: "keepIf"
16 LIST_KEEP_IF: "keepIf" 16 LIST_CONTAINS: "contains"
17 LIST_CONTAINS: "contains" 17 LIST_SUM: "sum"
18 LIST_SUM: "sum" 18 LIST_WALK: "walk"
19 LIST_WALK: "walk" 19 LIST_LAST: "last"
20 LIST_LAST: "last" 20 LIST_KEEP_OKS: "keepOks"
21 LIST_KEEP_OKS: "keepOks" 21 LIST_KEEP_ERRS: "keepErrs"
22 LIST_KEEP_ERRS: "keepErrs" 22 LIST_MAP_WITH_INDEX: "mapWithIndex"
23 LIST_MAP_WITH_INDEX: "mapWithIndex" 23 LIST_MAP2: "map2"
24 LIST_MAP2: "map2" 24 LIST_MAP3: "map3"
25 LIST_MAP3: "map3" 25 LIST_PRODUCT: "product"
26 LIST_PRODUCT: "product" 26 LIST_WALK_UNTIL: "walkUntil"
27 LIST_WALK_UNTIL: "walkUntil" 27 LIST_RANGE: "range"
28 LIST_RANGE: "range" 28 LIST_SORT_WITH: "sortWith"
29 LIST_SORT_WITH: "sortWith" 29 LIST_DROP: "drop"
30 LIST_DROP: "drop" 30 LIST_SWAP: "swap"
31 LIST_SWAP: "swap" 31 LIST_DROP_AT: "dropAt"
32 LIST_DROP_AT: "dropAt" 32 LIST_DROP_LAST: "dropLast"
33 LIST_DROP_LAST: "dropLast" 33 LIST_MIN: "min"
34 LIST_MIN: "min" 34 LIST_MIN_LT: "#minlt"
35 LIST_MIN_LT: "#minlt" 35 LIST_MAX: "max"
36 LIST_MAX: "max" 36 LIST_MAX_GT: "#maxGt"
37 LIST_MAX_GT: "#maxGt" 37 LIST_MAP4: "map4"
38 LIST_MAP4: "map4" 38 LIST_DROP_FIRST: "dropFirst"
39 LIST_DROP_FIRST: "dropFirst" 39 LIST_JOIN_MAP: "joinMap"
40 LIST_JOIN_MAP: "joinMap" 40 LIST_JOIN_MAP_CONCAT: "#joinMapConcat"
41 LIST_JOIN_MAP_CONCAT: "#joinMapConcat" 41 LIST_ANY: "any"
42 LIST_ANY: "any" 42 LIST_TAKE_FIRST: "takeFirst"
43 LIST_TAKE_FIRST: "takeFirst" 43 LIST_TAKE_LAST: "takeLast"
44 LIST_TAKE_LAST: "takeLast" 44 LIST_FIND: "find"
45 LIST_FIND: "find" 45 LIST_FIND_RESULT: "#find_result" // symbol used in the definition of List.find
46 LIST_FIND_RESULT: "#find_result" // symbol used in the definition of List.find 46 LIST_SUBLIST: "sublist"
47 LIST_SUBLIST: "sublist" 47 LIST_INTERSPERSE: "intersperse"
48 LIST_INTERSPERSE: "intersperse" 48 LIST_INTERSPERSE_CLOS: "#intersperseClos"
49 LIST_INTERSPERSE_CLOS: "#intersperseClos" 49 LIST_SPLIT: "split"
50 LIST_SPLIT: "split" 50 LIST_SPLIT_CLOS: "#splitClos"
51 LIST_SPLIT_CLOS: "#splitClos" 51 LIST_ALL: "all"
52 LIST_ALL: "all" 52 LIST_DROP_IF: "dropIf"
53 LIST_DROP_IF: "dropIf" 53 LIST_DROP_IF_PREDICATE: "#dropIfPred"
54 LIST_DROP_IF_PREDICATE: "#dropIfPred" 54 LIST_SORT_ASC: "sortAsc"
55 LIST_SORT_ASC: "sortAsc" 55 LIST_SORT_DESC: "sortDesc"
56 LIST_SORT_DESC: "sortDesc" 56 LIST_SORT_DESC_COMPARE: "#sortDescCompare"
57 LIST_SORT_DESC_COMPARE: "#sortDescCompare" 57 LIST_REPLACE: "replace"
58 LIST_REPLACE: "replace"
} }
5 RESULT: "Result" => { 5 RESULT: "Result" => {
0 RESULT_RESULT: "Result" // the Result.Result type alias 0 RESULT_RESULT: "Result" // the Result.Result type alias
@ -1188,41 +1169,39 @@ define_builtins! {
} }
6 DICT: "Dict" => { 6 DICT: "Dict" => {
0 DICT_DICT: "Dict" imported // the Dict.Dict type alias 0 DICT_DICT: "Dict" imported // the Dict.Dict type alias
1 DICT_AT_DICT: "@Dict" // the Dict.@Dict private tag 1 DICT_EMPTY: "empty"
2 DICT_EMPTY: "empty" 2 DICT_SINGLE: "single"
3 DICT_SINGLE: "single" 3 DICT_GET: "get"
4 DICT_GET: "get" 4 DICT_GET_RESULT: "#get_result" // symbol used in the definition of Dict.get
5 DICT_GET_RESULT: "#get_result" // symbol used in the definition of Dict.get 5 DICT_WALK: "walk"
6 DICT_WALK: "walk" 6 DICT_INSERT: "insert"
7 DICT_INSERT: "insert" 7 DICT_LEN: "len"
8 DICT_LEN: "len"
9 DICT_REMOVE: "remove" 8 DICT_REMOVE: "remove"
10 DICT_CONTAINS: "contains" 9 DICT_CONTAINS: "contains"
11 DICT_KEYS: "keys" 10 DICT_KEYS: "keys"
12 DICT_VALUES: "values" 11 DICT_VALUES: "values"
13 DICT_UNION: "union" 12 DICT_UNION: "union"
14 DICT_INTERSECTION: "intersection" 13 DICT_INTERSECTION: "intersection"
15 DICT_DIFFERENCE: "difference" 14 DICT_DIFFERENCE: "difference"
} }
7 SET: "Set" => { 7 SET: "Set" => {
0 SET_SET: "Set" imported // the Set.Set type alias 0 SET_SET: "Set" imported // the Set.Set type alias
1 SET_AT_SET: "@Set" // the Set.@Set private tag 1 SET_EMPTY: "empty"
2 SET_EMPTY: "empty" 2 SET_SINGLE: "single"
3 SET_SINGLE: "single" 3 SET_LEN: "len"
4 SET_LEN: "len" 4 SET_INSERT: "insert"
5 SET_INSERT: "insert" 5 SET_REMOVE: "remove"
6 SET_REMOVE: "remove" 6 SET_UNION: "union"
7 SET_UNION: "union" 7 SET_DIFFERENCE: "difference"
8 SET_DIFFERENCE: "difference" 8 SET_INTERSECTION: "intersection"
9 SET_INTERSECTION: "intersection" 9 SET_TO_LIST: "toList"
10 SET_TO_LIST: "toList" 10 SET_FROM_LIST: "fromList"
11 SET_FROM_LIST: "fromList" 11 SET_WALK: "walk"
12 SET_WALK: "walk" 12 SET_WALK_USER_FUNCTION: "#walk_user_function"
13 SET_WALK_USER_FUNCTION: "#walk_user_function" 13 SET_CONTAINS: "contains"
14 SET_CONTAINS: "contains" 14 SET_TO_DICT: "toDict"
15 SET_TO_DICT: "toDict"
} }
8 BOX: "Box" => { 8 BOX: "Box" => {
0 BOX_BOX_TYPE: "Box" imported // the Box.Box opaque type 0 BOX_BOX_TYPE: "Box" imported // the Box.Box opaque type

View file

@ -8640,9 +8640,9 @@ pub fn num_argument_to_int_or_float(
num_argument_to_int_or_float(subs, target_info, var, true) num_argument_to_int_or_float(subs, target_info, var, true)
} }
Symbol::NUM_DECIMAL | Symbol::NUM_AT_DECIMAL => IntOrFloat::DecimalFloatType, Symbol::NUM_DECIMAL => IntOrFloat::DecimalFloatType,
Symbol::NUM_NAT | Symbol::NUM_NATURAL | Symbol::NUM_AT_NATURAL => { Symbol::NUM_NAT | Symbol::NUM_NATURAL => {
let int_width = match target_info.ptr_width() { let int_width = match target_info.ptr_width() {
roc_target::PtrWidth::Bytes4 => IntWidth::U32, roc_target::PtrWidth::Bytes4 => IntWidth::U32,
roc_target::PtrWidth::Bytes8 => IntWidth::U64, roc_target::PtrWidth::Bytes8 => IntWidth::U64,

View file

@ -983,6 +983,16 @@ pub const fn round_up_to_alignment(width: u32, alignment: u32) -> u32 {
} }
} }
#[inline(always)]
pub fn is_unresolved_var(subs: &Subs, var: Variable) -> bool {
use Content::*;
let content = subs.get_content_without_compacting(var);
matches!(
content,
FlexVar(..) | RigidVar(..) | FlexAbleVar(..) | RigidAbleVar(..),
)
}
impl<'a> Layout<'a> { impl<'a> Layout<'a> {
pub const VOID: Self = Layout::Union(UnionLayout::NonRecursive(&[])); pub const VOID: Self = Layout::Union(UnionLayout::NonRecursive(&[]));
pub const UNIT: Self = Layout::Struct { pub const UNIT: Self = Layout::Struct {
@ -1015,12 +1025,24 @@ impl<'a> Layout<'a> {
} }
match symbol { match symbol {
Symbol::NUM_DECIMAL | Symbol::NUM_AT_DECIMAL => { Symbol::NUM_DECIMAL => return Ok(Layout::Builtin(Builtin::Decimal)),
return Ok(Layout::Builtin(Builtin::Decimal))
Symbol::NUM_NAT | Symbol::NUM_NATURAL => {
return Ok(Layout::usize(env.target_info))
} }
Symbol::NUM_NAT | Symbol::NUM_NATURAL | Symbol::NUM_AT_NATURAL => { Symbol::NUM_NUM | Symbol::NUM_INT | Symbol::NUM_INTEGER
return Ok(Layout::usize(env.target_info)) if is_unresolved_var(env.subs, actual_var) =>
{
// default to i64
return Ok(Layout::i64());
}
Symbol::NUM_FLOAT | Symbol::NUM_FLOATINGPOINT
if is_unresolved_var(env.subs, actual_var) =>
{
// default to f64
return Ok(Layout::f64());
} }
_ => Self::from_var(env, actual_var), _ => Self::from_var(env, actual_var),
@ -1689,7 +1711,7 @@ fn layout_from_flat_type<'a>(
Ok(Layout::f32()) Ok(Layout::f32())
} }
Symbol::NUM_NUM | Symbol::NUM_AT_NUM => { Symbol::NUM_NUM => {
// Num.Num should only ever have 1 argument, e.g. Num.Num Int.Integer // Num.Num should only ever have 1 argument, e.g. Num.Num Int.Integer
debug_assert_eq!(args.len(), 1); debug_assert_eq!(args.len(), 1);
@ -2135,31 +2157,20 @@ fn union_sorted_tags_help_new<'a>(
// just one tag in the union (but with arguments) can be a struct // just one tag in the union (but with arguments) can be a struct
let mut layouts = Vec::with_capacity_in(tags_list.len(), env.arena); let mut layouts = Vec::with_capacity_in(tags_list.len(), env.arena);
// special-case NUM_AT_NUM: if its argument is a FlexVar, make it Int for &var in arguments {
match tag_name { match Layout::from_var(env, var) {
TagName::Private(Symbol::NUM_AT_NUM) => { Ok(layout) => {
let var = arguments[0]; layouts.push(layout);
layouts.push( }
unwrap_num_tag(env.subs, var, env.target_info).expect("invalid num layout"), Err(LayoutProblem::UnresolvedTypeVar(_)) => {
); // If we encounter an unbound type var (e.g. `Ok *`)
} // then it's zero-sized; In the future we may drop this argument
_ => { // completely, but for now we represent it with the empty tag union
for &var in arguments { layouts.push(Layout::VOID)
match Layout::from_var(env, var) { }
Ok(layout) => { Err(LayoutProblem::Erroneous) => {
layouts.push(layout); // An erroneous type var will code gen to a runtime
} // error, so we don't need to store any data for it.
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
// If we encounter an unbound type var (e.g. `Ok *`)
// then it's zero-sized; In the future we may drop this argument
// completely, but for now we represent it with the empty tag union
layouts.push(Layout::VOID)
}
Err(LayoutProblem::Erroneous) => {
// An erroneous type var will code gen to a runtime
// error, so we don't need to store any data for it.
}
}
} }
} }
} }
@ -2341,37 +2352,26 @@ pub fn union_sorted_tags_help<'a>(
let mut layouts = Vec::with_capacity_in(tags_vec.len(), arena); let mut layouts = Vec::with_capacity_in(tags_vec.len(), arena);
let mut contains_zero_sized = false; let mut contains_zero_sized = false;
// special-case NUM_AT_NUM: if its argument is a FlexVar, make it Int for var in arguments {
match tag_name { match Layout::from_var(&mut env, var) {
TagName::Private(Symbol::NUM_AT_NUM) => { Ok(layout) => {
layouts.push( // Drop any zero-sized arguments like {}
unwrap_num_tag(subs, arguments[0], target_info) if !layout.is_dropped_because_empty() {
.expect("invalid num layout"), layouts.push(layout);
); } else {
} contains_zero_sized = true;
_ => {
for var in arguments {
match Layout::from_var(&mut env, var) {
Ok(layout) => {
// Drop any zero-sized arguments like {}
if !layout.is_dropped_because_empty() {
layouts.push(layout);
} else {
contains_zero_sized = true;
}
}
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
// If we encounter an unbound type var (e.g. `Ok *`)
// then it's zero-sized; In the future we may drop this argument
// completely, but for now we represent it with the empty tag union
layouts.push(Layout::VOID)
}
Err(LayoutProblem::Erroneous) => {
// An erroneous type var will code gen to a runtime
// error, so we don't need to store any data for it.
}
} }
} }
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
// If we encounter an unbound type var (e.g. `Ok *`)
// then it's zero-sized; In the future we may drop this argument
// completely, but for now we represent it with the empty tag union
layouts.push(Layout::VOID)
}
Err(LayoutProblem::Erroneous) => {
// An erroneous type var will code gen to a runtime
// error, so we don't need to store any data for it.
}
} }
} }
@ -2529,24 +2529,20 @@ pub fn union_sorted_tags_help<'a>(
fn layout_from_newtype<'a>(env: &mut Env<'a, '_>, tags: &UnsortedUnionTags) -> Layout<'a> { fn layout_from_newtype<'a>(env: &mut Env<'a, '_>, tags: &UnsortedUnionTags) -> Layout<'a> {
debug_assert!(tags.is_newtype_wrapper(env.subs)); debug_assert!(tags.is_newtype_wrapper(env.subs));
let (tag_name, var) = tags.get_newtype(env.subs); let (_tag_name, var) = tags.get_newtype(env.subs);
if tag_name == &TagName::Private(Symbol::NUM_AT_NUM) { match Layout::from_var(env, var) {
unwrap_num_tag(env.subs, var, env.target_info).expect("invalid Num argument") Ok(layout) => layout,
} else { Err(LayoutProblem::UnresolvedTypeVar(_)) => {
match Layout::from_var(env, var) { // If we encounter an unbound type var (e.g. `Ok *`)
Ok(layout) => layout, // then it's zero-sized; In the future we may drop this argument
Err(LayoutProblem::UnresolvedTypeVar(_)) => { // completely, but for now we represent it with the empty tag union
// If we encounter an unbound type var (e.g. `Ok *`) Layout::VOID
// then it's zero-sized; In the future we may drop this argument }
// completely, but for now we represent it with the empty tag union Err(LayoutProblem::Erroneous) => {
Layout::VOID // An erroneous type var will code gen to a runtime
} // error, so we don't need to store any data for it.
Err(LayoutProblem::Erroneous) => { todo!()
// An erroneous type var will code gen to a runtime
// error, so we don't need to store any data for it.
todo!()
}
} }
} }
} }
@ -2560,76 +2556,65 @@ fn layout_from_tag_union<'a>(env: &mut Env<'a, '_>, tags: &UnsortedUnionTags) ->
let tags_vec = &tags.tags; let tags_vec = &tags.tags;
match tags_vec.get(0) { let opt_rec_var = None;
Some((tag_name, arguments)) if *tag_name == &TagName::Private(Symbol::NUM_AT_NUM) => { let variant = union_sorted_tags_help_new(env, tags_vec, opt_rec_var);
debug_assert_eq!(arguments.len(), 1);
let &var = arguments.iter().next().unwrap(); match variant {
Never => Layout::VOID,
Unit | UnitWithArguments => Layout::UNIT,
BoolUnion { .. } => Layout::bool(),
ByteUnion(_) => Layout::u8(),
Newtype {
arguments: field_layouts,
..
} => {
let answer1 = if field_layouts.len() == 1 {
field_layouts[0]
} else {
Layout::struct_no_name_order(field_layouts.into_bump_slice())
};
unwrap_num_tag(env.subs, var, env.target_info).expect("invalid Num argument") answer1
} }
_ => { Wrapped(variant) => {
let opt_rec_var = None; use WrappedVariant::*;
let variant = union_sorted_tags_help_new(env, tags_vec, opt_rec_var);
match variant { match variant {
Never => Layout::VOID, NonRecursive {
Unit | UnitWithArguments => Layout::UNIT, sorted_tag_layouts: tags,
BoolUnion { .. } => Layout::bool(),
ByteUnion(_) => Layout::u8(),
Newtype {
arguments: field_layouts,
..
} => { } => {
let answer1 = if field_layouts.len() == 1 { let mut tag_layouts = Vec::with_capacity_in(tags.len(), env.arena);
field_layouts[0] tag_layouts.extend(tags.iter().map(|r| r.1));
} else {
Layout::struct_no_name_order(field_layouts.into_bump_slice())
};
answer1 Layout::Union(UnionLayout::NonRecursive(tag_layouts.into_bump_slice()))
} }
Wrapped(variant) => {
use WrappedVariant::*;
match variant { Recursive {
NonRecursive { sorted_tag_layouts: tags,
sorted_tag_layouts: tags, } => {
} => { let mut tag_layouts = Vec::with_capacity_in(tags.len(), env.arena);
let mut tag_layouts = Vec::with_capacity_in(tags.len(), env.arena); tag_layouts.extend(tags.iter().map(|r| r.1));
tag_layouts.extend(tags.iter().map(|r| r.1));
Layout::Union(UnionLayout::NonRecursive(tag_layouts.into_bump_slice())) debug_assert!(tag_layouts.len() > 1);
} Layout::Union(UnionLayout::Recursive(tag_layouts.into_bump_slice()))
Recursive {
sorted_tag_layouts: tags,
} => {
let mut tag_layouts = Vec::with_capacity_in(tags.len(), env.arena);
tag_layouts.extend(tags.iter().map(|r| r.1));
debug_assert!(tag_layouts.len() > 1);
Layout::Union(UnionLayout::Recursive(tag_layouts.into_bump_slice()))
}
NullableWrapped {
nullable_id,
nullable_name: _,
sorted_tag_layouts: tags,
} => {
let mut tag_layouts = Vec::with_capacity_in(tags.len(), env.arena);
tag_layouts.extend(tags.iter().map(|r| r.1));
Layout::Union(UnionLayout::NullableWrapped {
nullable_id,
other_tags: tag_layouts.into_bump_slice(),
})
}
NullableUnwrapped { .. } => todo!(),
NonNullableUnwrapped { .. } => todo!(),
}
} }
NullableWrapped {
nullable_id,
nullable_name: _,
sorted_tag_layouts: tags,
} => {
let mut tag_layouts = Vec::with_capacity_in(tags.len(), env.arena);
tag_layouts.extend(tags.iter().map(|r| r.1));
Layout::Union(UnionLayout::NullableWrapped {
nullable_id,
other_tags: tag_layouts.into_bump_slice(),
})
}
NullableUnwrapped { .. } => todo!(),
NonNullableUnwrapped { .. } => todo!(),
} }
} }
} }
@ -2727,6 +2712,8 @@ fn layout_from_num_content<'a>(
} }
} }
// TODO: removable?
#[allow(dead_code)]
fn unwrap_num_tag<'a>( fn unwrap_num_tag<'a>(
subs: &Subs, subs: &Subs,
var: Variable, var: Variable,

View file

@ -678,11 +678,9 @@ impl Layout {
} }
match symbol { match symbol {
Symbol::NUM_DECIMAL | Symbol::NUM_AT_DECIMAL => Ok(Layout::Decimal), Symbol::NUM_DECIMAL => Ok(Layout::Decimal),
Symbol::NUM_NAT | Symbol::NUM_NATURAL | Symbol::NUM_AT_NATURAL => { Symbol::NUM_NAT | Symbol::NUM_NATURAL => Ok(layouts.usize()),
Ok(layouts.usize())
}
_ => { _ => {
// at this point we throw away alias information // at this point we throw away alias information

View file

@ -5,6 +5,7 @@ use roc_can::constraint::Constraint::{self, *};
use roc_can::constraint::{Constraints, LetConstraint}; use roc_can::constraint::{Constraints, LetConstraint};
use roc_can::expected::{Expected, PExpected}; use roc_can::expected::{Expected, PExpected};
use roc_collections::all::MutMap; use roc_collections::all::MutMap;
use roc_error_macros::internal_error;
use roc_module::ident::TagName; use roc_module::ident::TagName;
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_region::all::{Loc, Region}; use roc_region::all::{Loc, Region};
@ -195,20 +196,20 @@ impl Aliases {
register(subs, rank, pools, content) register(subs, rank, pools, content)
} }
/// Instantiate an alias of the form `Foo a : [ @Foo a ]` /// Build an alias of the form `Num range := range`
fn instantiate_num_at_alias( fn build_num_opaque(
subs: &mut Subs, subs: &mut Subs,
rank: Rank, rank: Rank,
pools: &mut Pools, pools: &mut Pools,
tag_name_slice: SubsSlice<TagName>, symbol: Symbol,
range_slice: SubsSlice<Variable>, range_var: Variable,
) -> Variable { ) -> Variable {
let variable_slices = SubsSlice::extend_new(&mut subs.variable_slices, [range_slice]); let content = Content::Alias(
symbol,
let union_tags = UnionTags::from_slices(tag_name_slice, variable_slices); AliasVariables::insert_into_subs(subs, [range_var], []),
let ext_var = Variable::EMPTY_TAG_UNION; range_var,
let flat_type = FlatType::TagUnion(union_tags, ext_var); AliasKind::Opaque,
let content = Content::Structure(flat_type); );
register(subs, rank, pools, content) register(subs, rank, pools, content)
} }
@ -227,126 +228,46 @@ impl Aliases {
Some(var) Some(var)
} }
Symbol::NUM_NUM => { Symbol::NUM_NUM | Symbol::NUM_FLOATINGPOINT | Symbol::NUM_INTEGER => {
let var = Self::instantiate_num_at_alias( // These are opaque types Num range := range (respectively for FloatingPoint and
subs, // Integer). They should not have been built as DelayedAliases!
rank, internal_error!("Attempting to build delayed instantiation of opaque num");
pools,
Subs::NUM_AT_NUM,
SubsSlice::new(alias_variables.variables_start, 1),
);
Some(var)
}
Symbol::NUM_FLOATINGPOINT => {
let var = Self::instantiate_num_at_alias(
subs,
rank,
pools,
Subs::NUM_AT_FLOATINGPOINT,
SubsSlice::new(alias_variables.variables_start, 1),
);
Some(var)
}
Symbol::NUM_INTEGER => {
let var = Self::instantiate_num_at_alias(
subs,
rank,
pools,
Subs::NUM_AT_INTEGER,
SubsSlice::new(alias_variables.variables_start, 1),
);
Some(var)
} }
Symbol::NUM_INT => { Symbol::NUM_INT => {
// [ @Integer range ] // Int range : Num (Integer range)
let integer_content_var = Self::instantiate_builtin_aliases( //
self, // build `Integer range := range`
let integer_content_var = Self::build_num_opaque(
subs, subs,
rank, rank,
pools, pools,
Symbol::NUM_INTEGER, Symbol::NUM_INTEGER,
alias_variables, subs.variables[alias_variables.variables_start as usize],
)
.unwrap();
// Integer range (alias variable is the same as `Int range`)
let integer_alias_variables = alias_variables;
let integer_content = Content::Alias(
Symbol::NUM_INTEGER,
integer_alias_variables,
integer_content_var,
AliasKind::Structural,
);
let integer_alias_var = register(subs, rank, pools, integer_content);
// [ @Num (Integer range) ]
let num_alias_variables =
AliasVariables::insert_into_subs(subs, [integer_alias_var], []);
let num_content_var = Self::instantiate_builtin_aliases(
self,
subs,
rank,
pools,
Symbol::NUM_NUM,
num_alias_variables,
)
.unwrap();
let num_content = Content::Alias(
Symbol::NUM_NUM,
num_alias_variables,
num_content_var,
AliasKind::Structural,
); );
Some(register(subs, rank, pools, num_content)) // build `Num (Integer range) := Integer range`
let num_content_var =
Self::build_num_opaque(subs, rank, pools, Symbol::NUM_NUM, integer_content_var);
Some(num_content_var)
} }
Symbol::NUM_FLOAT => { Symbol::NUM_FLOAT => {
// [ @FloatingPoint range ] // Float range : Num (FloatingPoint range)
let fpoint_content_var = Self::instantiate_builtin_aliases( //
self, // build `FloatingPoint range := range`
let fpoint_content_var = Self::build_num_opaque(
subs, subs,
rank, rank,
pools, pools,
Symbol::NUM_FLOATINGPOINT, Symbol::NUM_FLOATINGPOINT,
alias_variables, subs.variables[alias_variables.variables_start as usize],
)
.unwrap();
// FloatingPoint range (alias variable is the same as `Float range`)
let fpoint_alias_variables = alias_variables;
let fpoint_content = Content::Alias(
Symbol::NUM_FLOATINGPOINT,
fpoint_alias_variables,
fpoint_content_var,
AliasKind::Structural,
);
let fpoint_alias_var = register(subs, rank, pools, fpoint_content);
// [ @Num (FloatingPoint range) ]
let num_alias_variables =
AliasVariables::insert_into_subs(subs, [fpoint_alias_var], []);
let num_content_var = Self::instantiate_builtin_aliases(
self,
subs,
rank,
pools,
Symbol::NUM_NUM,
num_alias_variables,
)
.unwrap();
let num_content = Content::Alias(
Symbol::NUM_NUM,
num_alias_variables,
num_content_var,
AliasKind::Structural,
); );
Some(register(subs, rank, pools, num_content)) // build `Num (FloatingPoint range) := FloatingPoint range`
let num_content_var =
Self::build_num_opaque(subs, rank, pools, Symbol::NUM_NUM, fpoint_content_var);
Some(num_content_var)
} }
_ => None, _ => None,
} }

View file

@ -28,53 +28,58 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
aliases.insert(symbol, alias); aliases.insert(symbol, alias);
}; };
// Int range : [ @Int range ] // Int range : Num (Integer range)
add_alias( add_alias(
Symbol::NUM_INT, Symbol::NUM_INT,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![Loc::at(Region::zero(), "range".into())], vars: vec![Loc::at(Region::zero(), "range".into())],
typ: int_alias_content(flex(TVAR1)), typ: int_alias_content(flex(TVAR1)),
kind: AliasKind::Structural,
}, },
); );
// Float range : [ @Float range ] // Float range : Num (FloatingPoint range)
add_alias( add_alias(
Symbol::NUM_FLOAT, Symbol::NUM_FLOAT,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![Loc::at(Region::zero(), "range".into())], vars: vec![Loc::at(Region::zero(), "range".into())],
typ: float_alias_content(flex(TVAR1)), typ: float_alias_content(flex(TVAR1)),
kind: AliasKind::Structural,
}, },
); );
// Num range : [ @Num range ] // Num range := range
add_alias( add_alias(
Symbol::NUM_NUM, Symbol::NUM_NUM,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![Loc::at(Region::zero(), "range".into())], vars: vec![Loc::at(Region::zero(), "range".into())],
typ: num_alias_content(flex(TVAR1)), typ: num_alias_content(flex(TVAR1)),
kind: AliasKind::Opaque,
}, },
); );
// Integer range : [ @Integer range ] // Integer range := range
add_alias( add_alias(
Symbol::NUM_INTEGER, Symbol::NUM_INTEGER,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![Loc::at(Region::zero(), "range".into())], vars: vec![Loc::at(Region::zero(), "range".into())],
typ: integer_alias_content(flex(TVAR1)), typ: integer_alias_content(flex(TVAR1)),
kind: AliasKind::Opaque,
}, },
); );
// Natural : [ @Natural ] // Natural := []
add_alias( add_alias(
Symbol::NUM_NATURAL, Symbol::NUM_NATURAL,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: natural_alias_content(), typ: natural_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
@ -85,16 +90,18 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: nat_alias_content(), typ: nat_alias_content(),
kind: AliasKind::Structural,
}, },
); );
// Signed128 : [ @Signed128 ] // Signed128 := []
add_alias( add_alias(
Symbol::NUM_SIGNED128, Symbol::NUM_SIGNED128,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: signed128_alias_content(), typ: signed128_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
@ -105,6 +112,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: i128_alias_content(), typ: i128_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -115,16 +123,18 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: u128_alias_content(), typ: u128_alias_content(),
kind: AliasKind::Structural,
}, },
); );
// Signed64 : [ @Signed64 ] // Signed64 := []
add_alias( add_alias(
Symbol::NUM_SIGNED64, Symbol::NUM_SIGNED64,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: signed64_alias_content(), typ: signed64_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
@ -135,6 +145,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: i64_alias_content(), typ: i64_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -145,16 +156,18 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: u64_alias_content(), typ: u64_alias_content(),
kind: AliasKind::Structural,
}, },
); );
// Signed32 : [ @Signed32 ] // Signed32 := []
add_alias( add_alias(
Symbol::NUM_SIGNED32, Symbol::NUM_SIGNED32,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: signed32_alias_content(), typ: signed32_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
@ -165,6 +178,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: i32_alias_content(), typ: i32_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -175,16 +189,18 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: u32_alias_content(), typ: u32_alias_content(),
kind: AliasKind::Structural,
}, },
); );
// Signed16 : [ @Signed16 ] // Signed16 := []
add_alias( add_alias(
Symbol::NUM_SIGNED16, Symbol::NUM_SIGNED16,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: signed16_alias_content(), typ: signed16_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
@ -195,6 +211,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: i16_alias_content(), typ: i16_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -205,16 +222,18 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: u16_alias_content(), typ: u16_alias_content(),
kind: AliasKind::Structural,
}, },
); );
// Signed8 : [ @Signed8 ] // Signed8 := []
add_alias( add_alias(
Symbol::NUM_SIGNED8, Symbol::NUM_SIGNED8,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: signed8_alias_content(), typ: signed8_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
@ -225,6 +244,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: i8_alias_content(), typ: i8_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -235,46 +255,51 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: u8_alias_content(), typ: u8_alias_content(),
kind: AliasKind::Structural,
}, },
); );
// Decimal : [ @Decimal ] // Decimal := []
add_alias( add_alias(
Symbol::NUM_DECIMAL, Symbol::NUM_DECIMAL,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: decimal_alias_content(), typ: decimal_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
// Binary64 : [ @Binary64 ] // Binary64 := []
add_alias( add_alias(
Symbol::NUM_BINARY64, Symbol::NUM_BINARY64,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: binary64_alias_content(), typ: binary64_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
// Binary32 : [ @Binary32 ] // Binary32 := []
add_alias( add_alias(
Symbol::NUM_BINARY32, Symbol::NUM_BINARY32,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![], vars: vec![],
typ: binary32_alias_content(), typ: binary32_alias_content(),
kind: AliasKind::Opaque,
}, },
); );
// FloatingPoint range : [ @FloatingPoint range ] // FloatingPoint range := range
add_alias( add_alias(
Symbol::NUM_FLOATINGPOINT, Symbol::NUM_FLOATINGPOINT,
BuiltinAlias { BuiltinAlias {
region: Region::zero(), region: Region::zero(),
vars: vec![Loc::at(Region::zero(), "range".into())], vars: vec![Loc::at(Region::zero(), "range".into())],
typ: floatingpoint_alias_content(flex(TVAR1)), typ: floatingpoint_alias_content(flex(TVAR1)),
kind: AliasKind::Opaque,
}, },
); );
@ -285,6 +310,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: dec_alias_content(), typ: dec_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -295,6 +321,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: f64_alias_content(), typ: f64_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -305,6 +332,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: f32_alias_content(), typ: f32_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -315,6 +343,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: bool_alias_content(), typ: bool_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -325,6 +354,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: str_utf8_byte_problem_alias_content(), typ: str_utf8_byte_problem_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -335,6 +365,7 @@ pub fn aliases() -> MutMap<Symbol, BuiltinAlias> {
region: Region::zero(), region: Region::zero(),
vars: Vec::new(), vars: Vec::new(),
typ: str_utf8_byte_problem_alias_content(), typ: str_utf8_byte_problem_alias_content(),
kind: AliasKind::Structural,
}, },
); );
@ -353,13 +384,13 @@ pub fn num_type(range: SolvedType) -> SolvedType {
vec![("range".into(), range.clone())], vec![("range".into(), range.clone())],
vec![], vec![],
Box::new(num_alias_content(range)), Box::new(num_alias_content(range)),
AliasKind::Structural, AliasKind::Opaque,
) )
} }
#[inline(always)] #[inline(always)]
fn num_alias_content(range: SolvedType) -> SolvedType { fn num_alias_content(range: SolvedType) -> SolvedType {
single_private_tag(Symbol::NUM_AT_NUM, vec![range]) range
} }
// FLOATING POINT // FLOATING POINT
@ -371,13 +402,13 @@ pub fn floatingpoint_type(range: SolvedType) -> SolvedType {
vec![("range".into(), range.clone())], vec![("range".into(), range.clone())],
vec![], vec![],
Box::new(floatingpoint_alias_content(range)), Box::new(floatingpoint_alias_content(range)),
AliasKind::Structural, AliasKind::Opaque,
) )
} }
#[inline(always)] #[inline(always)]
fn floatingpoint_alias_content(range: SolvedType) -> SolvedType { fn floatingpoint_alias_content(range: SolvedType) -> SolvedType {
single_private_tag(Symbol::NUM_AT_FLOATINGPOINT, vec![range]) range
} }
// FLOAT // FLOAT
@ -659,13 +690,13 @@ pub fn integer_type(range: SolvedType) -> SolvedType {
vec![("range".into(), range.clone())], vec![("range".into(), range.clone())],
vec![], vec![],
Box::new(integer_alias_content(range)), Box::new(integer_alias_content(range)),
AliasKind::Structural, AliasKind::Opaque,
) )
} }
#[inline(always)] #[inline(always)]
fn integer_alias_content(range: SolvedType) -> SolvedType { fn integer_alias_content(range: SolvedType) -> SolvedType {
single_private_tag(Symbol::NUM_AT_INTEGER, vec![range]) range
} }
#[inline(always)] #[inline(always)]
@ -681,7 +712,7 @@ pub fn binary64_type() -> SolvedType {
#[inline(always)] #[inline(always)]
pub fn binary64_alias_content() -> SolvedType { pub fn binary64_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_BINARY64, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -697,7 +728,7 @@ pub fn binary32_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn binary32_alias_content() -> SolvedType { fn binary32_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_BINARY32, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -713,7 +744,7 @@ pub fn natural_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn natural_alias_content() -> SolvedType { fn natural_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_NATURAL, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -729,7 +760,7 @@ pub fn signed128_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn signed128_alias_content() -> SolvedType { fn signed128_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_SIGNED128, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -745,7 +776,7 @@ pub fn signed64_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn signed64_alias_content() -> SolvedType { fn signed64_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_SIGNED64, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -761,7 +792,7 @@ pub fn signed32_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn signed32_alias_content() -> SolvedType { fn signed32_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_SIGNED32, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -777,7 +808,7 @@ pub fn signed16_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn signed16_alias_content() -> SolvedType { fn signed16_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_SIGNED16, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -793,7 +824,7 @@ pub fn signed8_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn signed8_alias_content() -> SolvedType { fn signed8_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_SIGNED8, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -809,7 +840,7 @@ pub fn unsigned128_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn unsigned128_alias_content() -> SolvedType { fn unsigned128_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_UNSIGNED128, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -825,7 +856,7 @@ pub fn unsigned64_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn unsigned64_alias_content() -> SolvedType { fn unsigned64_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_UNSIGNED64, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -841,7 +872,7 @@ pub fn unsigned32_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn unsigned32_alias_content() -> SolvedType { fn unsigned32_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_UNSIGNED32, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -857,7 +888,7 @@ pub fn unsigned16_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn unsigned16_alias_content() -> SolvedType { fn unsigned16_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_UNSIGNED16, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
@ -873,12 +904,12 @@ pub fn unsigned8_type() -> SolvedType {
#[inline(always)] #[inline(always)]
fn unsigned8_alias_content() -> SolvedType { fn unsigned8_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_UNSIGNED8, vec![]) SolvedType::EmptyTagUnion
} }
#[inline(always)] #[inline(always)]
fn decimal_alias_content() -> SolvedType { fn decimal_alias_content() -> SolvedType {
single_private_tag(Symbol::NUM_AT_DECIMAL, vec![]) SolvedType::EmptyTagUnion
} }
// Dec // Dec

View file

@ -78,6 +78,7 @@ pub struct BuiltinAlias {
pub region: Region, pub region: Region,
pub vars: Vec<Loc<Lowercase>>, pub vars: Vec<Loc<Lowercase>>,
pub typ: SolvedType, pub typ: SolvedType,
pub kind: AliasKind,
} }
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]

View file

@ -1009,22 +1009,7 @@ define_const_var! {
ORDER_ENUM, ORDER_ENUM,
:pub ORDER, :pub ORDER,
// [ @Signed8 ] // Signed8 := []
AT_SIGNED8,
AT_SIGNED16,
AT_SIGNED32,
AT_SIGNED64,
AT_SIGNED128,
AT_UNSIGNED8,
AT_UNSIGNED16,
AT_UNSIGNED32,
AT_UNSIGNED64,
AT_UNSIGNED128,
AT_NATURAL,
// Signed8 : [ @Signed8 ]
:pub SIGNED8, :pub SIGNED8,
:pub SIGNED16, :pub SIGNED16,
:pub SIGNED32, :pub SIGNED32,
@ -1039,22 +1024,7 @@ define_const_var! {
:pub NATURAL, :pub NATURAL,
// [ @Integer Signed8 ] // Integer Signed8 := Signed8
AT_INTEGER_SIGNED8,
AT_INTEGER_SIGNED16,
AT_INTEGER_SIGNED32,
AT_INTEGER_SIGNED64,
AT_INTEGER_SIGNED128,
AT_INTEGER_UNSIGNED8,
AT_INTEGER_UNSIGNED16,
AT_INTEGER_UNSIGNED32,
AT_INTEGER_UNSIGNED64,
AT_INTEGER_UNSIGNED128,
AT_INTEGER_NATURAL,
// Integer Signed8 : [ @Integer Signed8 ]
INTEGER_SIGNED8, INTEGER_SIGNED8,
INTEGER_SIGNED16, INTEGER_SIGNED16,
INTEGER_SIGNED32, INTEGER_SIGNED32,
@ -1069,22 +1039,7 @@ define_const_var! {
INTEGER_NATURAL, INTEGER_NATURAL,
// [ @Num (Integer Signed8) ] // Num (Integer Signed8) := Integer Signed8
AT_NUM_INTEGER_SIGNED8,
AT_NUM_INTEGER_SIGNED16,
AT_NUM_INTEGER_SIGNED32,
AT_NUM_INTEGER_SIGNED64,
AT_NUM_INTEGER_SIGNED128,
AT_NUM_INTEGER_UNSIGNED8,
AT_NUM_INTEGER_UNSIGNED16,
AT_NUM_INTEGER_UNSIGNED32,
AT_NUM_INTEGER_UNSIGNED64,
AT_NUM_INTEGER_UNSIGNED128,
AT_NUM_INTEGER_NATURAL,
// Num (Integer Signed8)
NUM_INTEGER_SIGNED8, NUM_INTEGER_SIGNED8,
NUM_INTEGER_SIGNED16, NUM_INTEGER_SIGNED16,
NUM_INTEGER_SIGNED32, NUM_INTEGER_SIGNED32,
@ -1114,32 +1069,17 @@ define_const_var! {
:pub NAT, :pub NAT,
// [ @Binary32 ] // Binary32 : []
AT_BINARY32,
AT_BINARY64,
AT_DECIMAL,
// Binary32 : [ @Binary32 ]
BINARY32, BINARY32,
BINARY64, BINARY64,
DECIMAL, DECIMAL,
// [ @Float Binary32 ] // Float Binary32 := Binary32
AT_FLOAT_BINARY32,
AT_FLOAT_BINARY64,
AT_FLOAT_DECIMAL,
// Float Binary32 : [ @Float Binary32 ]
FLOAT_BINARY32, FLOAT_BINARY32,
FLOAT_BINARY64, FLOAT_BINARY64,
FLOAT_DECIMAL, FLOAT_DECIMAL,
// [ @Num (Float Binary32) ] // Num (Float Binary32) := Float Binary32
AT_NUM_FLOAT_BINARY32,
AT_NUM_FLOAT_BINARY64,
AT_NUM_FLOAT_DECIMAL,
// Num (Float Binary32)
NUM_FLOAT_BINARY32, NUM_FLOAT_BINARY32,
NUM_FLOAT_BINARY64, NUM_FLOAT_BINARY64,
NUM_FLOAT_DECIMAL, NUM_FLOAT_DECIMAL,
@ -1273,80 +1213,47 @@ impl fmt::Debug for VarId {
fn integer_type( fn integer_type(
subs: &mut Subs, subs: &mut Subs,
num_at_signed64: Symbol,
num_signed64: Symbol, num_signed64: Symbol,
num_i64: Symbol, num_i64: Symbol,
at_signed64: Variable,
signed64: Variable, signed64: Variable,
at_integer_signed64: Variable,
integer_signed64: Variable, integer_signed64: Variable,
at_num_integer_signed64: Variable,
num_integer_signed64: Variable, num_integer_signed64: Variable,
var_i64: Variable, var_i64: Variable,
) { ) {
// define the type Signed64 (which is an alias for [ @Signed64 ]) // define the type Signed64 := []
{ {
let tags = UnionTags::insert_into_subs(subs, [(TagName::Private(num_at_signed64), [])]);
subs.set_content(at_signed64, {
Content::Structure(FlatType::TagUnion(tags, Variable::EMPTY_TAG_UNION))
});
subs.set_content(signed64, { subs.set_content(signed64, {
Content::Alias( Content::Alias(
num_signed64, num_signed64,
AliasVariables::default(), AliasVariables::default(),
at_signed64, Variable::EMPTY_TAG_UNION,
AliasKind::Structural, AliasKind::Opaque,
) )
}); });
} }
// define the type `Num.Integer Num.Signed64` // define the type `Num.Integer Num.Signed64 := Num.Signed64`
{ {
let tags = UnionTags::insert_into_subs(
subs,
[(TagName::Private(Symbol::NUM_AT_INTEGER), [signed64])],
);
subs.set_content(at_integer_signed64, {
Content::Structure(FlatType::TagUnion(tags, Variable::EMPTY_TAG_UNION))
});
let vars = AliasVariables::insert_into_subs(subs, [signed64], []); let vars = AliasVariables::insert_into_subs(subs, [signed64], []);
subs.set_content(integer_signed64, { subs.set_content(integer_signed64, {
Content::Alias( Content::Alias(Symbol::NUM_INTEGER, vars, signed64, AliasKind::Opaque)
Symbol::NUM_INTEGER,
vars,
at_signed64,
AliasKind::Structural,
)
}); });
} }
// define the type `Num.Num (Num.Integer Num.Signed64)` // define the type `Num.Num (Num.Integer Num.Signed64) := Num.Integer Num.Signed64`
{ {
let tags = UnionTags::insert_into_subs(
subs,
[(TagName::Private(Symbol::NUM_AT_NUM), [integer_signed64])],
);
subs.set_content(at_num_integer_signed64, {
Content::Structure(FlatType::TagUnion(tags, Variable::EMPTY_TAG_UNION))
});
let vars = AliasVariables::insert_into_subs(subs, [integer_signed64], []); let vars = AliasVariables::insert_into_subs(subs, [integer_signed64], []);
subs.set_content(num_integer_signed64, { subs.set_content(num_integer_signed64, {
Content::Alias( Content::Alias(Symbol::NUM_NUM, vars, integer_signed64, AliasKind::Opaque)
Symbol::NUM_NUM,
vars,
at_num_integer_signed64,
AliasKind::Structural,
)
}); });
}
// define the type `Num.I64 : Num.Num (Num.Integer Num.Signed64)`
{
subs.set_content(var_i64, { subs.set_content(var_i64, {
Content::Alias( Content::Alias(
num_i64, num_i64,
@ -1361,154 +1268,110 @@ fn integer_type(
fn define_integer_types(subs: &mut Subs) { fn define_integer_types(subs: &mut Subs) {
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_SIGNED128,
Symbol::NUM_SIGNED128, Symbol::NUM_SIGNED128,
Symbol::NUM_I128, Symbol::NUM_I128,
Variable::AT_SIGNED128,
Variable::SIGNED128, Variable::SIGNED128,
Variable::AT_INTEGER_SIGNED128,
Variable::INTEGER_SIGNED128, Variable::INTEGER_SIGNED128,
Variable::AT_NUM_INTEGER_SIGNED128,
Variable::NUM_INTEGER_SIGNED128, Variable::NUM_INTEGER_SIGNED128,
Variable::I128, Variable::I128,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_SIGNED64,
Symbol::NUM_SIGNED64, Symbol::NUM_SIGNED64,
Symbol::NUM_I64, Symbol::NUM_I64,
Variable::AT_SIGNED64,
Variable::SIGNED64, Variable::SIGNED64,
Variable::AT_INTEGER_SIGNED64,
Variable::INTEGER_SIGNED64, Variable::INTEGER_SIGNED64,
Variable::AT_NUM_INTEGER_SIGNED64,
Variable::NUM_INTEGER_SIGNED64, Variable::NUM_INTEGER_SIGNED64,
Variable::I64, Variable::I64,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_SIGNED32,
Symbol::NUM_SIGNED32, Symbol::NUM_SIGNED32,
Symbol::NUM_I32, Symbol::NUM_I32,
Variable::AT_SIGNED32,
Variable::SIGNED32, Variable::SIGNED32,
Variable::AT_INTEGER_SIGNED32,
Variable::INTEGER_SIGNED32, Variable::INTEGER_SIGNED32,
Variable::AT_NUM_INTEGER_SIGNED32,
Variable::NUM_INTEGER_SIGNED32, Variable::NUM_INTEGER_SIGNED32,
Variable::I32, Variable::I32,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_SIGNED16,
Symbol::NUM_SIGNED16, Symbol::NUM_SIGNED16,
Symbol::NUM_I16, Symbol::NUM_I16,
Variable::AT_SIGNED16,
Variable::SIGNED16, Variable::SIGNED16,
Variable::AT_INTEGER_SIGNED16,
Variable::INTEGER_SIGNED16, Variable::INTEGER_SIGNED16,
Variable::AT_NUM_INTEGER_SIGNED16,
Variable::NUM_INTEGER_SIGNED16, Variable::NUM_INTEGER_SIGNED16,
Variable::I16, Variable::I16,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_SIGNED8,
Symbol::NUM_SIGNED8, Symbol::NUM_SIGNED8,
Symbol::NUM_I8, Symbol::NUM_I8,
Variable::AT_SIGNED8,
Variable::SIGNED8, Variable::SIGNED8,
Variable::AT_INTEGER_SIGNED8,
Variable::INTEGER_SIGNED8, Variable::INTEGER_SIGNED8,
Variable::AT_NUM_INTEGER_SIGNED8,
Variable::NUM_INTEGER_SIGNED8, Variable::NUM_INTEGER_SIGNED8,
Variable::I8, Variable::I8,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_UNSIGNED128,
Symbol::NUM_UNSIGNED128, Symbol::NUM_UNSIGNED128,
Symbol::NUM_U128, Symbol::NUM_U128,
Variable::AT_UNSIGNED128,
Variable::UNSIGNED128, Variable::UNSIGNED128,
Variable::AT_INTEGER_UNSIGNED128,
Variable::INTEGER_UNSIGNED128, Variable::INTEGER_UNSIGNED128,
Variable::AT_NUM_INTEGER_UNSIGNED128,
Variable::NUM_INTEGER_UNSIGNED128, Variable::NUM_INTEGER_UNSIGNED128,
Variable::U128, Variable::U128,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_UNSIGNED64,
Symbol::NUM_UNSIGNED64, Symbol::NUM_UNSIGNED64,
Symbol::NUM_U64, Symbol::NUM_U64,
Variable::AT_UNSIGNED64,
Variable::UNSIGNED64, Variable::UNSIGNED64,
Variable::AT_INTEGER_UNSIGNED64,
Variable::INTEGER_UNSIGNED64, Variable::INTEGER_UNSIGNED64,
Variable::AT_NUM_INTEGER_UNSIGNED64,
Variable::NUM_INTEGER_UNSIGNED64, Variable::NUM_INTEGER_UNSIGNED64,
Variable::U64, Variable::U64,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_UNSIGNED32,
Symbol::NUM_UNSIGNED32, Symbol::NUM_UNSIGNED32,
Symbol::NUM_U32, Symbol::NUM_U32,
Variable::AT_UNSIGNED32,
Variable::UNSIGNED32, Variable::UNSIGNED32,
Variable::AT_INTEGER_UNSIGNED32,
Variable::INTEGER_UNSIGNED32, Variable::INTEGER_UNSIGNED32,
Variable::AT_NUM_INTEGER_UNSIGNED32,
Variable::NUM_INTEGER_UNSIGNED32, Variable::NUM_INTEGER_UNSIGNED32,
Variable::U32, Variable::U32,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_UNSIGNED16,
Symbol::NUM_UNSIGNED16, Symbol::NUM_UNSIGNED16,
Symbol::NUM_U16, Symbol::NUM_U16,
Variable::AT_UNSIGNED16,
Variable::UNSIGNED16, Variable::UNSIGNED16,
Variable::AT_INTEGER_UNSIGNED16,
Variable::INTEGER_UNSIGNED16, Variable::INTEGER_UNSIGNED16,
Variable::AT_NUM_INTEGER_UNSIGNED16,
Variable::NUM_INTEGER_UNSIGNED16, Variable::NUM_INTEGER_UNSIGNED16,
Variable::U16, Variable::U16,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_UNSIGNED8,
Symbol::NUM_UNSIGNED8, Symbol::NUM_UNSIGNED8,
Symbol::NUM_U8, Symbol::NUM_U8,
Variable::AT_UNSIGNED8,
Variable::UNSIGNED8, Variable::UNSIGNED8,
Variable::AT_INTEGER_UNSIGNED8,
Variable::INTEGER_UNSIGNED8, Variable::INTEGER_UNSIGNED8,
Variable::AT_NUM_INTEGER_UNSIGNED8,
Variable::NUM_INTEGER_UNSIGNED8, Variable::NUM_INTEGER_UNSIGNED8,
Variable::U8, Variable::U8,
); );
integer_type( integer_type(
subs, subs,
Symbol::NUM_AT_NATURAL,
Symbol::NUM_NATURAL, Symbol::NUM_NATURAL,
Symbol::NUM_NAT, Symbol::NUM_NAT,
Variable::AT_NATURAL,
Variable::NATURAL, Variable::NATURAL,
Variable::AT_INTEGER_NATURAL,
Variable::INTEGER_NATURAL, Variable::INTEGER_NATURAL,
Variable::AT_NUM_INTEGER_NATURAL,
Variable::NUM_INTEGER_NATURAL, Variable::NUM_INTEGER_NATURAL,
Variable::NAT, Variable::NAT,
); );
@ -1518,80 +1381,47 @@ fn define_integer_types(subs: &mut Subs) {
fn float_type( fn float_type(
subs: &mut Subs, subs: &mut Subs,
num_at_binary64: Symbol,
num_binary64: Symbol, num_binary64: Symbol,
num_f64: Symbol, num_f64: Symbol,
at_binary64: Variable,
binary64: Variable, binary64: Variable,
at_float_binary64: Variable,
float_binary64: Variable, float_binary64: Variable,
at_num_float_binary64: Variable,
num_float_binary64: Variable, num_float_binary64: Variable,
var_f64: Variable, var_f64: Variable,
) { ) {
// define the type Binary64 (which is an alias for [ @Binary64 ]) // define the type Binary64 := []
{ {
let tags = UnionTags::insert_into_subs(subs, [(TagName::Private(num_at_binary64), [])]);
subs.set_content(at_binary64, {
Content::Structure(FlatType::TagUnion(tags, Variable::EMPTY_TAG_UNION))
});
subs.set_content(binary64, { subs.set_content(binary64, {
Content::Alias( Content::Alias(
num_binary64, num_binary64,
AliasVariables::default(), AliasVariables::default(),
at_binary64, Variable::EMPTY_TAG_UNION,
AliasKind::Structural, AliasKind::Structural,
) )
}); });
} }
// define the type `Num.Float Num.Binary64` // define the type `Num.Float Num.Binary64 := Num.Binary64`
{ {
let tags = UnionTags::insert_into_subs(
subs,
[(TagName::Private(Symbol::NUM_AT_FLOATINGPOINT), [binary64])],
);
subs.set_content(at_float_binary64, {
Content::Structure(FlatType::TagUnion(tags, Variable::EMPTY_TAG_UNION))
});
let vars = AliasVariables::insert_into_subs(subs, [binary64], []); let vars = AliasVariables::insert_into_subs(subs, [binary64], []);
subs.set_content(float_binary64, { subs.set_content(float_binary64, {
Content::Alias( Content::Alias(Symbol::NUM_FLOATINGPOINT, vars, binary64, AliasKind::Opaque)
Symbol::NUM_FLOATINGPOINT, });
vars, }
at_binary64,
AliasKind::Structural, // define the type `Num.Num (Num.Float Num.Binary64) := Num.Float Num.Binary64`
) {
let vars = AliasVariables::insert_into_subs(subs, [float_binary64], []);
subs.set_content(num_float_binary64, {
Content::Alias(Symbol::NUM_NUM, vars, float_binary64, AliasKind::Opaque)
}); });
} }
// define the type `F64: Num.Num (Num.Float Num.Binary64)` // define the type `F64: Num.Num (Num.Float Num.Binary64)`
{ {
let tags = UnionTags::insert_into_subs(
subs,
[(TagName::Private(Symbol::NUM_AT_NUM), [float_binary64])],
);
subs.set_content(at_num_float_binary64, {
Content::Structure(FlatType::TagUnion(tags, Variable::EMPTY_TAG_UNION))
});
let vars = AliasVariables::insert_into_subs(subs, [float_binary64], []);
subs.set_content(num_float_binary64, {
Content::Alias(
Symbol::NUM_NUM,
vars,
at_num_float_binary64,
AliasKind::Structural,
)
});
subs.set_content(var_f64, { subs.set_content(var_f64, {
Content::Alias( Content::Alias(
num_f64, num_f64,
@ -1606,42 +1436,30 @@ fn float_type(
fn define_float_types(subs: &mut Subs) { fn define_float_types(subs: &mut Subs) {
float_type( float_type(
subs, subs,
Symbol::NUM_AT_BINARY32,
Symbol::NUM_BINARY32, Symbol::NUM_BINARY32,
Symbol::NUM_F32, Symbol::NUM_F32,
Variable::AT_BINARY32,
Variable::BINARY32, Variable::BINARY32,
Variable::AT_FLOAT_BINARY32,
Variable::FLOAT_BINARY32, Variable::FLOAT_BINARY32,
Variable::AT_NUM_FLOAT_BINARY32,
Variable::NUM_FLOAT_BINARY32, Variable::NUM_FLOAT_BINARY32,
Variable::F32, Variable::F32,
); );
float_type( float_type(
subs, subs,
Symbol::NUM_AT_BINARY64,
Symbol::NUM_BINARY64, Symbol::NUM_BINARY64,
Symbol::NUM_F64, Symbol::NUM_F64,
Variable::AT_BINARY64,
Variable::BINARY64, Variable::BINARY64,
Variable::AT_FLOAT_BINARY64,
Variable::FLOAT_BINARY64, Variable::FLOAT_BINARY64,
Variable::AT_NUM_FLOAT_BINARY64,
Variable::NUM_FLOAT_BINARY64, Variable::NUM_FLOAT_BINARY64,
Variable::F64, Variable::F64,
); );
float_type( float_type(
subs, subs,
Symbol::NUM_AT_DECIMAL,
Symbol::NUM_DECIMAL, Symbol::NUM_DECIMAL,
Symbol::NUM_DEC, Symbol::NUM_DEC,
Variable::AT_DECIMAL,
Variable::DECIMAL, Variable::DECIMAL,
Variable::AT_FLOAT_DECIMAL,
Variable::FLOAT_DECIMAL, Variable::FLOAT_DECIMAL,
Variable::AT_NUM_FLOAT_DECIMAL,
Variable::NUM_FLOAT_DECIMAL, Variable::NUM_FLOAT_DECIMAL,
Variable::DEC, Variable::DEC,
); );
@ -1651,12 +1469,9 @@ impl Subs {
pub const RESULT_TAG_NAMES: SubsSlice<TagName> = SubsSlice::new(0, 2); pub const RESULT_TAG_NAMES: SubsSlice<TagName> = SubsSlice::new(0, 2);
pub const TAG_NAME_ERR: SubsIndex<TagName> = SubsIndex::new(0); pub const TAG_NAME_ERR: SubsIndex<TagName> = SubsIndex::new(0);
pub const TAG_NAME_OK: SubsIndex<TagName> = SubsIndex::new(1); pub const TAG_NAME_OK: SubsIndex<TagName> = SubsIndex::new(1);
pub const NUM_AT_NUM: SubsSlice<TagName> = SubsSlice::new(2, 1); pub const TAG_NAME_INVALID_NUM_STR: SubsIndex<TagName> = SubsIndex::new(2);
pub const NUM_AT_INTEGER: SubsSlice<TagName> = SubsSlice::new(3, 1); pub const TAG_NAME_BAD_UTF_8: SubsIndex<TagName> = SubsIndex::new(3);
pub const NUM_AT_FLOATINGPOINT: SubsSlice<TagName> = SubsSlice::new(4, 1); pub const TAG_NAME_OUT_OF_BOUNDS: SubsIndex<TagName> = SubsIndex::new(4);
pub const TAG_NAME_INVALID_NUM_STR: SubsIndex<TagName> = SubsIndex::new(5);
pub const TAG_NAME_BAD_UTF_8: SubsIndex<TagName> = SubsIndex::new(6);
pub const TAG_NAME_OUT_OF_BOUNDS: SubsIndex<TagName> = SubsIndex::new(7);
pub fn new() -> Self { pub fn new() -> Self {
Self::with_capacity(0) Self::with_capacity(0)
@ -1670,10 +1485,6 @@ impl Subs {
tag_names.push(TagName::Global("Err".into())); tag_names.push(TagName::Global("Err".into()));
tag_names.push(TagName::Global("Ok".into())); tag_names.push(TagName::Global("Ok".into()));
tag_names.push(TagName::Private(Symbol::NUM_AT_NUM));
tag_names.push(TagName::Private(Symbol::NUM_AT_INTEGER));
tag_names.push(TagName::Private(Symbol::NUM_AT_FLOATINGPOINT));
tag_names.push(TagName::Global("InvalidNumStr".into())); tag_names.push(TagName::Global("InvalidNumStr".into()));
tag_names.push(TagName::Global("BadUtf8".into())); tag_names.push(TagName::Global("BadUtf8".into()));
tag_names.push(TagName::Global("OutOfBounds".into())); tag_names.push(TagName::Global("OutOfBounds".into()));

View file

@ -120,6 +120,21 @@ impl Mode {
fn as_eq(self) -> Self { fn as_eq(self) -> Self {
(self - Mode::PRESENT) | Mode::EQ (self - Mode::PRESENT) | Mode::EQ
} }
#[cfg(debug_assertions)]
fn pretty_print(&self) -> &str {
if self.contains(Mode::EQ | Mode::RIGID_AS_FLEX) {
"~*"
} else if self.contains(Mode::PRESENT | Mode::RIGID_AS_FLEX) {
"+=*"
} else if self.contains(Mode::EQ) {
"~"
} else if self.contains(Mode::PRESENT) {
"+="
} else {
unreachable!("Bad mode!")
}
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -309,7 +324,7 @@ fn debug_print_unified_types(subs: &mut Subs, ctx: &Context, opt_outcome: Option
// println!("\n --------------- \n"); // println!("\n --------------- \n");
let content_1 = subs.get(ctx.first).content; let content_1 = subs.get(ctx.first).content;
let content_2 = subs.get(ctx.second).content; let content_2 = subs.get(ctx.second).content;
let mode = if ctx.mode.is_eq() { "~" } else { "+=" }; let mode = ctx.mode.pretty_print();
eprintln!( eprintln!(
"{}{}({:?}-{:?}): {:?} {:?} {} {:?} {:?}", "{}{}({:?}-{:?}): {:?} {:?} {} {:?} {:?}",
" ".repeat(use_depth), " ".repeat(use_depth),
@ -573,7 +588,7 @@ fn unify_opaque(
// Alias wins // Alias wins
merge(subs, ctx, Alias(symbol, args, real_var, kind)) merge(subs, ctx, Alias(symbol, args, real_var, kind))
} }
RigidVar(_) | RigidAbleVar(..) => unify_pool(subs, pool, real_var, ctx.second, ctx.mode), // RigidVar(_) | RigidAbleVar(..) => unify_pool(subs, pool, real_var, ctx.second, ctx.mode),
FlexAbleVar(_, ability) if args.is_empty() => { FlexAbleVar(_, ability) if args.is_empty() => {
// Opaque type wins // Opaque type wins
let mut outcome = merge(subs, ctx, Alias(symbol, args, real_var, kind)); let mut outcome = merge(subs, ctx, Alias(symbol, args, real_var, kind));
@ -604,6 +619,15 @@ fn unify_opaque(
mismatch!("{:?}", symbol) mismatch!("{:?}", symbol)
} }
} }
RangedNumber(other_real_var, other_range_vars) => {
// This opaque might be a number, check if it unifies with the target ranged number var.
let outcome = unify_pool(subs, pool, ctx.first, *other_real_var, ctx.mode);
if outcome.mismatches.is_empty() {
check_valid_range(subs, pool, ctx.first, *other_range_vars, ctx.mode)
} else {
outcome
}
}
other => { other => {
// The type on the left is an opaque, but the one on the right is not! // The type on the left is an opaque, but the one on the right is not!
mismatch!("Cannot unify opaque {:?} with {:?}", symbol, other) mismatch!("Cannot unify opaque {:?} with {:?}", symbol, other)

View file

@ -283,12 +283,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
macro_rules! num_helper { macro_rules! num_helper {
($ty:ty) => { ($ty:ty) => {
app.call_function(main_fn_name, |_, num: $ty| { app.call_function(main_fn_name, |_, num: $ty| {
num_to_ast( number_literal_to_ast(env.arena, num)
env,
number_literal_to_ast(env.arena, num),
// We determine the number from what the alias looks like.
alias_content.unwrap_or(raw_content),
)
}) })
}; };
} }
@ -299,10 +294,11 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
bool_to_ast(env, mem, num, raw_content) bool_to_ast(env, mem, num, raw_content)
})), })),
Layout::Builtin(Builtin::Int(int_width)) => { Layout::Builtin(Builtin::Int(int_width)) => {
use Content::*;
use IntWidth::*; use IntWidth::*;
let result = match (raw_content, int_width) { let result = match (alias_content, int_width) {
(Content::Structure(FlatType::Apply(Symbol::NUM_NUM, _)), U8) => num_helper!(u8), (Some(Alias(Symbol::NUM_UNSIGNED8, ..)), U8) => num_helper!(u8),
(_, U8) => { (_, U8) => {
// This is not a number, it's a tag union or something else // This is not a number, it's a tag union or something else
app.call_function(main_fn_name, |mem: &A::Memory, num: u8| { app.call_function(main_fn_name, |mem: &A::Memory, num: u8| {
@ -507,7 +503,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
($method: ident, $ty: ty) => {{ ($method: ident, $ty: ty) => {{
let num: $ty = mem.$method(addr); let num: $ty = mem.$method(addr);
num_to_ast(env, number_literal_to_ast(env.arena, num), content) number_literal_to_ast(env.arena, num)
}}; }};
} }
@ -1137,12 +1133,6 @@ fn byte_to_ast<'a, M: ReplAppMemory>(
FlatType::TagUnion(tags, _) if tags.len() == 1 => { FlatType::TagUnion(tags, _) if tags.len() == 1 => {
let (tag_name, payload_vars) = unpack_single_element_tag_union(env.subs, *tags); let (tag_name, payload_vars) = unpack_single_element_tag_union(env.subs, *tags);
// If this tag union represents a number, skip right to
// returning it as an Expr::Num
if let TagName::Private(Symbol::NUM_AT_NUM) = &tag_name {
return Expr::Num(env.arena.alloc_str(&value.to_string()));
}
let loc_tag_expr = { let loc_tag_expr = {
let tag_name = &tag_name.as_ident_str(env.interns, env.home); let tag_name = &tag_name.as_ident_str(env.interns, env.home);
let tag_expr = if tag_name.starts_with('@') { let tag_expr = if tag_name.starts_with('@') {
@ -1203,7 +1193,7 @@ fn byte_to_ast<'a, M: ReplAppMemory>(
} }
} }
other => { other => {
unreachable!("Unexpected FlatType {:?} in bool_to_ast", other); unreachable!("Unexpected FlatType {:?} in byte_to_ast", other);
} }
} }
} }
@ -1213,79 +1203,7 @@ fn byte_to_ast<'a, M: ReplAppMemory>(
byte_to_ast(env, mem, value, content) byte_to_ast(env, mem, value, content)
} }
other => { other => {
unreachable!("Unexpected FlatType {:?} in bool_to_ast", other); unreachable!("Unexpected FlatType {:?} in byte_to_ast", other);
}
}
}
fn num_to_ast<'a>(env: &Env<'a, '_>, num_expr: Expr<'a>, content: &Content) -> Expr<'a> {
use Content::*;
let arena = env.arena;
match content {
Structure(flat_type) => {
match flat_type {
FlatType::Apply(Symbol::NUM_NUM, _) => num_expr,
FlatType::TagUnion(tags, _) => {
// This was a single-tag union that got unwrapped at runtime.
debug_assert_eq!(tags.len(), 1);
let (tag_name, payload_vars) = unpack_single_element_tag_union(env.subs, *tags);
// If this tag union represents a number, skip right to
// returning it as an Expr::Num
if let TagName::Private(Symbol::NUM_AT_NUM) = &tag_name {
return num_expr;
}
let loc_tag_expr = {
let tag_name = &tag_name.as_ident_str(env.interns, env.home);
let tag_expr = if tag_name.starts_with('@') {
Expr::PrivateTag(arena.alloc_str(tag_name))
} else {
Expr::GlobalTag(arena.alloc_str(tag_name))
};
&*arena.alloc(Loc {
value: tag_expr,
region: Region::zero(),
})
};
let payload = {
// Since this has the layout of a number, there should be
// exactly one payload in this tag.
debug_assert_eq!(payload_vars.len(), 1);
let var = *payload_vars.iter().next().unwrap();
let content = env.subs.get_content_without_compacting(var);
let loc_payload = &*arena.alloc(Loc {
value: num_to_ast(env, num_expr, content),
region: Region::zero(),
});
arena.alloc([loc_payload])
};
Expr::Apply(loc_tag_expr, payload, CalledVia::Space)
}
other => {
panic!("Unexpected FlatType {:?} in num_to_ast", other);
}
}
}
Alias(_, _, var, _) => {
let content = env.subs.get_content_without_compacting(*var);
num_to_ast(env, num_expr, content)
}
RangedNumber(typ, _) => {
num_to_ast(env, num_expr, env.subs.get_content_without_compacting(*typ))
}
other => {
panic!("Unexpected FlatType {:?} in num_to_ast", other);
} }
} }
} }

View file

@ -16,6 +16,12 @@ use ven_pretty::DocAllocator;
const DUPLICATE_NAME: &str = "DUPLICATE NAME"; const DUPLICATE_NAME: &str = "DUPLICATE NAME";
const ADD_ANNOTATIONS: &str = r#"Can more type annotations be added? Type annotations always help me give more specific messages, and I think they could help a lot in this case"#; const ADD_ANNOTATIONS: &str = r#"Can more type annotations be added? Type annotations always help me give more specific messages, and I think they could help a lot in this case"#;
const OPAQUE_NUM_SYMBOLS: &[Symbol] = &[
Symbol::NUM_NUM,
Symbol::NUM_INTEGER,
Symbol::NUM_FLOATINGPOINT,
];
pub fn type_problem<'b>( pub fn type_problem<'b>(
alloc: &'b RocDocAllocator<'b>, alloc: &'b RocDocAllocator<'b>,
lines: &LineInfo, lines: &LineInfo,
@ -2318,7 +2324,11 @@ fn to_diff<'b>(
} }
} }
(Alias(_, _, _, AliasKind::Opaque), _) | (_, Alias(_, _, _, AliasKind::Opaque)) => { (Alias(sym, _, _, AliasKind::Opaque), _) | (_, Alias(sym, _, _, AliasKind::Opaque))
// Skip the hint for numbers; it's not as useful as saying "this type is not a number"
if !OPAQUE_NUM_SYMBOLS.contains(&sym) =>
{
dbg!(&type1, &type2);
let (left, left_able) = to_doc(alloc, Parens::InFn, type1); let (left, left_able) = to_doc(alloc, Parens::InFn, type1);
let (right, right_able) = to_doc(alloc, Parens::InFn, type2); let (right, right_able) = to_doc(alloc, Parens::InFn, type2);