Merge remote-tracking branch 'origin/main' into abilities-syntax

This commit is contained in:
Richard Feldman 2023-08-10 20:29:27 -04:00
commit 2da41be29f
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
524 changed files with 47536 additions and 15089 deletions

View file

@ -38,7 +38,7 @@ impl NumericRange {
width.signedness_and_width().1 >= at_least_width.signedness_and_width().1
}
pub(crate) fn width(&self) -> IntLitWidth {
pub fn min_width(&self) -> IntLitWidth {
use NumericRange::*;
match self {
IntAtLeastSigned(w)
@ -52,7 +52,7 @@ impl NumericRange {
/// `None` if there is no common lower bound.
pub fn intersection(&self, other: &Self) -> Option<Self> {
use NumericRange::*;
let (left, right) = (self.width(), other.width());
let (left, right) = (self.min_width(), other.min_width());
let (constructor, is_negative): (fn(IntLitWidth) -> NumericRange, _) = match (self, other) {
// Matching against a signed int, the intersection must also be a signed int
(IntAtLeastSigned(_), _) | (_, IntAtLeastSigned(_)) => (IntAtLeastSigned, true),
@ -154,11 +154,17 @@ impl NumericRange {
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum IntSignedness {
pub enum IntSignedness {
Unsigned,
Signed,
}
impl IntSignedness {
pub fn is_signed(&self) -> bool {
matches!(self, IntSignedness::Signed)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum IntLitWidth {
U8,
@ -184,7 +190,7 @@ pub enum IntLitWidth {
impl IntLitWidth {
/// Returns the `IntSignedness` and bit width of a variant.
fn signedness_and_width(&self) -> (IntSignedness, u32) {
pub fn signedness_and_width(&self) -> (IntSignedness, u32) {
use IntLitWidth::*;
use IntSignedness::*;
match self {
@ -207,7 +213,7 @@ impl IntLitWidth {
}
fn is_signed(&self) -> bool {
self.signedness_and_width().0 == IntSignedness::Signed
self.signedness_and_width().0.is_signed()
}
pub fn type_str(&self) -> &'static str {

View file

@ -402,7 +402,11 @@ fn find_names_needed(
find_under_alias,
);
}
Error | Structure(EmptyRecord) | Structure(EmptyTuple) | Structure(EmptyTagUnion) => {
Error
| Structure(EmptyRecord)
| Structure(EmptyTuple)
| Structure(EmptyTagUnion)
| ErasedLambda => {
// Errors and empty records don't need names.
}
}
@ -827,7 +831,7 @@ fn write_content<'a>(
"".to_string()
};
if env.home == symbol.module_id() {
format!("{}{}", ident_str, disambiguation,)
format!("{ident_str}{disambiguation}",)
} else {
format!(
"{}.{}{}",
@ -866,6 +870,12 @@ fn write_content<'a>(
buf.push(']');
}
ErasedLambda => {
debug_assert!(env.debug.print_lambda_sets);
// Easy mode 🤠
buf.push('?');
}
RangedNumber(range) => {
buf.push_str("Range(");
for (i, &var) in range.variable_slice().iter().enumerate() {

View file

@ -587,15 +587,19 @@ impl<T> Clone for SubsSlice<T> {
impl<T> Default for SubsSlice<T> {
fn default() -> Self {
Self {
start: Default::default(),
length: Default::default(),
_marker: Default::default(),
}
Self::empty()
}
}
impl<T> SubsSlice<T> {
pub fn empty() -> Self {
Self {
start: 0,
length: 0,
_marker: Default::default(),
}
}
pub fn get_slice<'a>(&self, slice: &'a [T]) -> &'a [T] {
&slice[self.indices()]
}
@ -774,11 +778,11 @@ impl fmt::Debug for Subs {
let root = self.get_root_key_without_compacting(var);
if var == root {
write!(f, "{} => ", i)?;
write!(f, "{i} => ")?;
subs_fmt_desc(&desc, self, f)?;
} else {
write!(f, "{} => <{:?}>", i, root)?;
write!(f, "{i} => <{root:?}>")?;
}
writeln!(f)?;
@ -811,7 +815,7 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
Some(index) => subs[*index].as_str(),
None => "_",
};
write!(f, "Flex({})", name)
write!(f, "Flex({name})")
}
Content::FlexAbleVar(name, symbols) => {
let name = match name {
@ -827,7 +831,7 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
Content::RecursionVar {
structure,
opt_name,
} => write!(f, "Recursion({:?}, {:?})", structure, opt_name),
} => write!(f, "Recursion({structure:?}, {opt_name:?})"),
Content::Structure(flat_type) => subs_fmt_flat_type(flat_type, subs, f),
Content::Alias(name, arguments, actual, kind) => {
let slice = subs.get_subs_slice(arguments.all_variables());
@ -855,7 +859,7 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
write!(f, "LambdaSet([")?;
for (name, slice) in solved.iter_from_subs(subs) {
write!(f, "{:?} ", name)?;
write!(f, "{name:?} ")?;
for var in slice {
write!(
f,
@ -869,7 +873,7 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
write!(f, "]")?;
if let Some(rec_var) = recursion_var.into_variable() {
write!(f, " as <{:?}>", rec_var)?;
write!(f, " as <{rec_var:?}>")?;
}
for Uls(var, member, region) in subs.get_subs_slice(*unspecialized) {
write!(
@ -881,10 +885,11 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
region
)?;
}
write!(f, ", ^<{:?}>)", ambient_function_var)
write!(f, ", ^<{ambient_function_var:?}>)")
}
Content::ErasedLambda => write!(f, "ErasedLambda"),
Content::RangedNumber(range) => {
write!(f, "RangedNumber( {:?})", range)
write!(f, "RangedNumber( {range:?})")
}
Content::Error => write!(f, "Error"),
}
@ -903,7 +908,7 @@ fn subs_fmt_flat_type(this: &FlatType, subs: &Subs, f: &mut fmt::Formatter) -> f
FlatType::Apply(name, arguments) => {
let slice = subs.get_subs_slice(*arguments);
write!(f, "Apply({:?}, {:?})", name, slice)
write!(f, "Apply({name:?}, {slice:?})")
}
FlatType::Func(arguments, lambda_set, result) => {
let slice = subs.get_subs_slice(*arguments);
@ -948,7 +953,7 @@ fn subs_fmt_flat_type(this: &FlatType, subs: &Subs, f: &mut fmt::Formatter) -> f
)?;
}
write!(f, "}}<{:?}>", new_ext)
write!(f, "}}<{new_ext:?}>")
}
FlatType::Tuple(elems, ext) => {
write!(f, "( ")?;
@ -962,14 +967,14 @@ fn subs_fmt_flat_type(this: &FlatType, subs: &Subs, f: &mut fmt::Formatter) -> f
)?;
}
write!(f, ")<{:?}>", new_ext)
write!(f, ")<{new_ext:?}>")
}
FlatType::TagUnion(tags, ext) => {
write!(f, "[")?;
let (it, new_ext) = tags.sorted_iterator_and_ext(subs, *ext);
for (name, slice) in it {
write!(f, "{:?} ", name)?;
write!(f, "{name:?} ")?;
for var in slice {
write!(
f,
@ -981,26 +986,22 @@ fn subs_fmt_flat_type(this: &FlatType, subs: &Subs, f: &mut fmt::Formatter) -> f
write!(f, ", ")?;
}
write!(f, "]<{:?}>", new_ext)
write!(f, "]<{new_ext:?}>")
}
FlatType::FunctionOrTagUnion(tagnames, symbol, ext) => {
let tagnames: &[TagName] = subs.get_subs_slice(*tagnames);
write!(
f,
"FunctionOrTagUnion({:?}, {:?}, {:?})",
tagnames, symbol, ext
)
write!(f, "FunctionOrTagUnion({tagnames:?}, {symbol:?}, {ext:?})")
}
FlatType::RecursiveTagUnion(rec, tags, ext) => {
write!(f, "[")?;
let (it, new_ext) = tags.sorted_iterator_and_ext(subs, *ext);
for (name, slice) in it {
write!(f, "{:?} {:?}, ", name, slice)?;
write!(f, "{name:?} {slice:?}, ")?;
}
write!(f, "]<{:?}> as <{:?}>", new_ext, rec)
write!(f, "]<{new_ext:?}> as <{rec:?}>")
}
FlatType::EmptyRecord => write!(f, "EmptyRecord"),
FlatType::EmptyTuple => write!(f, "EmptyTuple"),
@ -1016,7 +1017,7 @@ impl std::fmt::Debug for DebugUtable<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("UnificationTable {\n")?;
for v in 0..self.0.utable.len() {
f.write_fmt(format_args!(" {} => ", v))?;
f.write_fmt(format_args!(" {v} => "))?;
let var = unsafe { Variable::from_index(v as u32) };
let root = self.0.utable.root_key_without_compacting(var);
if root == var {
@ -1234,7 +1235,7 @@ impl IllegalCycleMark {
pub struct Variable(u32);
macro_rules! define_const_var {
($($(:pub)? $name:ident),* $(,)?) => {
($($(#[$meta:meta])* $(:pub)? $name:ident),* $(,)?) => {
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
enum ConstVariables {
$( $name, )*
@ -1242,7 +1243,7 @@ macro_rules! define_const_var {
}
impl Variable {
$( pub const $name: Variable = Variable(ConstVariables::$name as u32); )*
$( $(#[$meta])* pub const $name: Variable = Variable(ConstVariables::$name as u32); )*
pub const NUM_RESERVED_VARS: usize = ConstVariables::FINAL_CONST_VAR as usize;
}
@ -1353,6 +1354,9 @@ define_const_var! {
// The following are abound in derived abilities, so we cache them.
:pub STR,
:pub LIST_U8,
/// The erased lambda type.
:pub ERASED_LAMBDA,
}
impl Variable {
@ -1698,25 +1702,31 @@ pub struct SubsSnapshot {
}
impl Subs {
// IFTTT INIT-TagNames
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_OK: SubsIndex<TagName> = SubsIndex::new(1);
pub const TAG_NAME_INVALID_NUM_STR: SubsIndex<TagName> = SubsIndex::new(2);
pub const TAG_NAME_BAD_UTF_8: SubsIndex<TagName> = SubsIndex::new(3);
pub const TAG_NAME_OUT_OF_BOUNDS: SubsIndex<TagName> = SubsIndex::new(4);
// END INIT-TagNames
// IFTTT INIT-VariableSubsSlice
pub const STR_SLICE: VariableSubsSlice = SubsSlice::new(0, 1);
// END INIT-VariableSubsSlice
// IFTTT INIT-SymbolSubsSlice
#[rustfmt::skip]
pub const AB_ENCODING: SubsSlice<Symbol> = SubsSlice::new(0, 1);
pub const AB_ENCODING: SubsSlice<Symbol> = SubsSlice::new(0, 1);
#[rustfmt::skip]
pub const AB_DECODING: SubsSlice<Symbol> = SubsSlice::new(1, 1);
pub const AB_DECODING: SubsSlice<Symbol> = SubsSlice::new(1, 1);
#[rustfmt::skip]
pub const AB_HASHER: SubsSlice<Symbol> = SubsSlice::new(2, 1);
pub const AB_HASHER: SubsSlice<Symbol> = SubsSlice::new(2, 1);
#[rustfmt::skip]
pub const AB_HASH: SubsSlice<Symbol> = SubsSlice::new(3, 1);
pub const AB_HASH: SubsSlice<Symbol> = SubsSlice::new(3, 1);
#[rustfmt::skip]
pub const AB_EQ: SubsSlice<Symbol> = SubsSlice::new(4, 1);
pub const AB_EQ: SubsSlice<Symbol> = SubsSlice::new(4, 1);
// END INIT-SymbolSubsSlice
pub fn new() -> Self {
Self::with_capacity(0)
@ -1727,13 +1737,16 @@ impl Subs {
let mut tag_names = Vec::with_capacity(32);
// IFTTT INIT-TagNames
tag_names.push(TagName("Err".into()));
tag_names.push(TagName("Ok".into()));
tag_names.push(TagName("InvalidNumStr".into()));
tag_names.push(TagName("BadUtf8".into()));
tag_names.push(TagName("OutOfBounds".into()));
// END INIT-TagNames
// IFTTT INIT-SymbolNames
let mut symbol_names = Vec::with_capacity(32);
symbol_names.push(Symbol::ENCODE_ENCODING);
@ -1741,13 +1754,15 @@ impl Subs {
symbol_names.push(Symbol::HASH_HASHER);
symbol_names.push(Symbol::HASH_HASH_ABILITY);
symbol_names.push(Symbol::BOOL_EQ);
// END INIT-SymbolNames
// IFTTT INIT-VariableSubsSlice
let variables = vec![Variable::STR];
// END INIT-VariableSubsSlice
let mut subs = Subs {
utable: UnificationTable::default(),
variables: vec![
// Used for STR_SLICE
Variable::STR,
],
variables,
tag_names,
symbol_names,
field_names: Vec::new(),
@ -1811,6 +1826,8 @@ impl Subs {
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, u8_slice)),
);
subs.set_content(Variable::ERASED_LAMBDA, Content::ErasedLambda);
subs
}
@ -2163,10 +2180,15 @@ impl Subs {
self.utable.vars_since_snapshot(&snapshot.utable_snapshot)
}
pub fn get_lambda_set(&self, lambda_set: Variable) -> LambdaSet {
match self.get_content_without_compacting(lambda_set) {
Content::LambdaSet(lambda_set) => *lambda_set,
_ => internal_error!("not a lambda set"),
pub fn get_lambda_set(&self, mut lambda_set: Variable) -> LambdaSet {
loop {
match self.get_content_without_compacting(lambda_set) {
Content::LambdaSet(lambda_set) => return *lambda_set,
Content::RecursionVar { structure, .. } => {
lambda_set = *structure;
}
_ => internal_error!("not a lambda set"),
}
}
}
@ -2202,7 +2224,7 @@ impl Subs {
| Content::RecursionVar { .. }
| Content::RangedNumber(_)
| Content::Error => return false,
Content::LambdaSet(_) => return true,
Content::LambdaSet(_) | Content::ErasedLambda => return false,
Content::Structure(FlatType::Func(..)) => return true,
Content::Structure(_) => return false,
Content::Alias(_, _, real_var, _) => {
@ -2366,7 +2388,10 @@ pub enum Content {
structure: Variable,
opt_name: Option<SubsIndex<Lowercase>>,
},
/// A resolved set of lambdas. Compatible when functions are kinded as lambda set.
LambdaSet(LambdaSet),
/// A type-erased lambda. Compatible when functions are not kinded.
ErasedLambda,
Structure(FlatType),
Alias(Symbol, AliasVariables, Variable, AliasKind),
RangedNumber(crate::num::NumericRange),
@ -2815,9 +2840,7 @@ where
debug_assert_eq!(
labels.len(),
variables.len(),
"tag name len != variables len: {:?} {:?}",
labels,
variables,
"tag name len != variables len: {labels:?} {variables:?}",
);
Self {
@ -3596,6 +3619,7 @@ fn occurs(
occurs_union(subs, root_var, ctx, safe!(UnionLabels<Symbol>, solved))
}
ErasedLambda => Ok(()),
RangedNumber(_range_vars) => Ok(()),
})();
@ -3681,7 +3705,8 @@ fn explicit_substitute(
| FlexAbleVar(_, _)
| RigidAbleVar(_, _)
| RecursionVar { .. }
| Error => in_var,
| Error
| ErasedLambda => in_var,
Structure(flat_type) => {
match flat_type {
@ -3862,7 +3887,7 @@ fn get_var_names(
subs.set_mark(var, Mark::GET_VAR_NAMES);
match desc.content {
Error | FlexVar(None) | FlexAbleVar(None, _) => taken_names,
Error | FlexVar(None) | FlexAbleVar(None, _) | ErasedLambda => taken_names,
FlexVar(Some(name_index)) | FlexAbleVar(Some(name_index), _) => add_name(
subs,
@ -4020,7 +4045,7 @@ where
} else {
// TODO is this the proper use of index here, or should we be
// doing something else like turning it into an ASCII letter?
Lowercase::from(format!("{}{}", given_name, index))
Lowercase::from(format!("{given_name}{index}"))
};
match taken_names.get(&indexed_name) {
@ -4179,7 +4204,7 @@ fn content_to_err_type(
ErrorType::Alias(symbol, err_args, Box::new(err_type), kind)
}
LambdaSet(self::LambdaSet { .. }) => {
LambdaSet(..) | ErasedLambda => {
// Don't print lambda sets since we don't expect them to be exposed to the user
ErrorType::Error
}
@ -4330,7 +4355,7 @@ fn flat_type_to_err_type(
ErrorType::Error => ErrorType::Record(err_fields, TypeExt::Closed),
other =>
panic!("Tried to convert a record extension to an error, but the record extension had the ErrorType of {:?}", other)
panic!("Tried to convert a record extension to an error, but the record extension had the ErrorType of {other:?}")
}
}
@ -4362,7 +4387,7 @@ fn flat_type_to_err_type(
ErrorType::Error => ErrorType::Tuple(err_elems, TypeExt::Closed),
other =>
panic!("Tried to convert a record extension to an error, but the record extension had the ErrorType of {:?}", other)
panic!("Tried to convert a record extension to an error, but the record extension had the ErrorType of {other:?}")
}
}
@ -4388,7 +4413,7 @@ fn flat_type_to_err_type(
ErrorType::Error => ErrorType::TagUnion(err_tags, TypeExt::Closed, pol),
other =>
panic!("Tried to convert a tag union extension to an error, but the tag union extension had the ErrorType of {:?}", other)
panic!("Tried to convert a tag union extension to an error, but the tag union extension had the ErrorType of {other:?}")
}
}
@ -4418,7 +4443,7 @@ fn flat_type_to_err_type(
ErrorType::Error => ErrorType::TagUnion(err_tags, TypeExt::Closed, pol),
other =>
panic!("Tried to convert a tag union extension to an error, but the tag union extension had the ErrorType of {:?}", other)
panic!("Tried to convert a tag union extension to an error, but the tag union extension had the ErrorType of {other:?}")
}
}
@ -4450,7 +4475,7 @@ fn flat_type_to_err_type(
ErrorType::Error => ErrorType::RecursiveTagUnion(rec_error_type, err_tags, TypeExt::Closed, pol),
other =>
panic!("Tried to convert a recursive tag union extension to an error, but the tag union extension had the ErrorType of {:?}", other)
panic!("Tried to convert a recursive tag union extension to an error, but the tag union extension had the ErrorType of {other:?}")
}
}
}
@ -4789,6 +4814,7 @@ impl StorageSubs {
unspecialized: Self::offset_uls_slice(offsets, *unspecialized),
ambient_function: Self::offset_variable(offsets, *ambient_function_var),
}),
ErasedLambda => ErasedLambda,
RangedNumber(range) => RangedNumber(*range),
Error => Content::Error,
}
@ -5156,7 +5182,7 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
copy
}
FlexVar(None) | Error => copy,
FlexVar(None) | ErasedLambda | Error => copy,
RecursionVar {
opt_name,
@ -5391,6 +5417,7 @@ fn is_registered(content: &Content) -> bool {
| Content::FlexAbleVar(..)
| Content::RigidAbleVar(..) => false,
Content::Structure(FlatType::EmptyRecord | FlatType::EmptyTagUnion) => false,
Content::ErasedLambda => false,
Content::Structure(_)
| Content::RecursionVar { .. }
@ -5788,6 +5815,12 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
copy
}
ErasedLambda => {
env.target.set(copy, make_descriptor(ErasedLambda));
copy
}
RangedNumber(range) => {
let new_content = RangedNumber(range);
@ -5862,7 +5895,7 @@ fn instantiate_rigids_help(subs: &mut Subs, max_rank: Rank, initial: Variable) {
}
})
}
FlexVar(_) | FlexAbleVar(_, _) | Error => (),
FlexVar(_) | FlexAbleVar(_, _) | ErasedLambda | Error => (),
RecursionVar { structure, .. } => {
stack.push(*structure);
@ -6049,7 +6082,8 @@ pub fn get_member_lambda_sets_at_region(subs: &Subs, var: Variable, target_regio
| Content::RecursionVar {
structure: _,
opt_name: _,
} => {}
}
| Content::ErasedLambda => {}
}
}
@ -6074,7 +6108,7 @@ fn is_inhabited(subs: &Subs, var: Variable) -> bool {
// are determined as illegal and reported during canonicalization, because you
// cannot have a tag union without a non-recursive variant.
| Content::RecursionVar { .. } => {}
Content::LambdaSet(_) => {}
Content::LambdaSet(_) | Content::ErasedLambda => {}
Content::Structure(structure) => match structure {
FlatType::Apply(_, args) => stack.extend(subs.get_subs_slice(*args)),
FlatType::Func(args, _, ret) => {

View file

@ -55,11 +55,11 @@ impl<T: fmt::Debug> fmt::Debug for RecordField<T> {
use RecordField::*;
match self {
Optional(typ) => write!(f, "Optional({:?})", typ),
Required(typ) => write!(f, "Required({:?})", typ),
Demanded(typ) => write!(f, "Demanded({:?})", typ),
RigidRequired(typ) => write!(f, "RigidRequired({:?})", typ),
RigidOptional(typ) => write!(f, "RigidOptional({:?})", typ),
Optional(typ) => write!(f, "Optional({typ:?})"),
Required(typ) => write!(f, "Required({typ:?})"),
Demanded(typ) => write!(f, "Demanded({typ:?})"),
RigidRequired(typ) => write!(f, "RigidRequired({typ:?})"),
RigidOptional(typ) => write!(f, "RigidOptional({typ:?})"),
}
}
}
@ -398,11 +398,6 @@ pub enum TypeTag {
shared: Index<AliasShared>,
actual: Index<TypeTag>,
},
HostExposedAlias {
shared: Index<AliasShared>,
actual_type: Index<TypeTag>,
actual_variable: Variable,
},
Apply {
symbol: Symbol,
@ -998,41 +993,6 @@ impl Types {
self.set_type_tag(index, tag, type_arguments_slice)
}
Type::HostExposedAlias {
name,
type_arguments,
lambda_set_variables,
actual_var,
actual,
} => {
let type_arguments_slice = self.from_old_type_slice(type_arguments.iter());
let lambda_set_slice = {
let slice = self.reserve_type_tags(lambda_set_variables.len());
for (index, argument) in slice.into_iter().zip(lambda_set_variables) {
self.from_old_type_at(index, &argument.0);
}
Slice::new(slice.start() as _, slice.len() as _)
};
let alias_shared = AliasShared {
symbol: *name,
type_argument_abilities: Slice::default(),
type_argument_regions: Slice::default(),
lambda_set_variables: lambda_set_slice,
infer_ext_in_output_variables: Slice::default(),
};
let tag = TypeTag::HostExposedAlias {
shared: Index::push_new(&mut self.aliases, alias_shared),
actual_type: self.from_old_type(actual),
actual_variable: *actual_var,
};
self.set_type_tag(index, tag, type_arguments_slice)
}
Type::Variable(var) => {
self.set_type_tag(index, TypeTag::Variable(*var), Slice::default())
}
@ -1217,27 +1177,6 @@ impl Types {
new_type_arguments,
)
}
HostExposedAlias {
shared,
actual_type,
actual_variable,
} => {
let type_arguments = self.get_type_arguments(typ);
let new_type_arguments = defer_slice!(type_arguments);
let new_shared = do_shared!(shared);
let new_actual_type = defer!(actual_type);
let new_actual_variable = subst!(actual_variable);
(
HostExposedAlias {
shared: new_shared,
actual_type: new_actual_type,
actual_variable: new_actual_variable,
},
new_type_arguments,
)
}
Apply {
symbol,
type_argument_regions,
@ -1432,12 +1371,7 @@ mod debug_types {
maybe_paren!(Free, p, alias(types, f, tag, shared))
}
TypeTag::StructuralAlias { shared, actual }
| TypeTag::OpaqueAlias { shared, actual }
| TypeTag::HostExposedAlias {
shared,
actual_type: actual,
actual_variable: _,
} => maybe_paren!(
| TypeTag::OpaqueAlias { shared, actual } => maybe_paren!(
Free,
p,
alias(types, f, tag, shared)
@ -1609,7 +1543,7 @@ mod debug_types {
use crate::num::IntLitWidth::*;
use crate::num::NumericRange::*;
let fmt_width = f.text(match range.width() {
let fmt_width = f.text(match range.min_width() {
U8 | I8 => "8",
U16 | I16 => "16",
U32 | I32 => "32",
@ -1743,13 +1677,6 @@ pub enum Type {
actual: Box<Type>,
kind: AliasKind,
},
HostExposedAlias {
name: Symbol,
type_arguments: Vec<Type>,
lambda_set_variables: Vec<LambdaSet>,
actual_var: Variable,
actual: Box<Type>,
},
RecursiveTagUnion(Variable, Vec<(TagName, Vec<Type>)>, TypeExtension),
/// Applying a type to some arguments (e.g. Dict.Dict String Int)
Apply(Symbol, Vec<Loc<Type>>, Region),
@ -1836,19 +1763,6 @@ impl Clone for Type {
actual: actual.clone(),
kind: *kind,
},
Self::HostExposedAlias {
name,
type_arguments,
lambda_set_variables,
actual_var,
actual,
} => Self::HostExposedAlias {
name: *name,
type_arguments: type_arguments.clone(),
lambda_set_variables: lambda_set_variables.clone(),
actual_var: *actual_var,
actual: actual.clone(),
},
Self::RecursiveTagUnion(arg0, arg1, arg2) => {
Self::RecursiveTagUnion(*arg0, arg1.clone(), arg2.clone())
}
@ -1949,10 +1863,10 @@ fn write_tags<'a>(
let mut it = tags.peekable();
while let Some((label, arguments)) = it.next() {
write!(f, "{:?}", label)?;
write!(f, "{label:?}")?;
for argument in arguments {
write!(f, " {:?}", argument)?;
write!(f, " {argument:?}")?;
}
if it.peek().is_some() {
@ -1976,23 +1890,23 @@ impl fmt::Debug for Type {
write!(f, ", ")?;
}
write!(f, "{:?}", arg)?;
write!(f, "{arg:?}")?;
}
write!(f, " |{:?}|", closure)?;
write!(f, " |{closure:?}|")?;
write!(f, " -> ")?;
ret.fmt(f)?;
write!(f, ")")
}
Type::Variable(var) => write!(f, "<{:?}>", var),
Type::Variable(var) => write!(f, "<{var:?}>"),
Type::Apply(symbol, args, _) => {
write!(f, "({:?}", symbol)?;
write!(f, "({symbol:?}")?;
for arg in args {
write!(f, " {:?}", arg)?;
write!(f, " {arg:?}")?;
}
write!(f, ")")
@ -2004,10 +1918,10 @@ impl fmt::Debug for Type {
lambda_set_variables,
infer_ext_in_output_types,
}) => {
write!(f, "(DelayedAlias {:?}", symbol)?;
write!(f, "(DelayedAlias {symbol:?}")?;
for arg in type_arguments {
write!(f, " {:?}", arg)?;
write!(f, " {arg:?}")?;
}
for (lambda_set, greek_letter) in
@ -2017,7 +1931,7 @@ impl fmt::Debug for Type {
}
for (i, infer_ext) in infer_ext_in_output_types.iter().enumerate() {
write!(f, " `{}@{:?}", i, infer_ext)?;
write!(f, " `{i}@{infer_ext:?}")?;
}
write!(f, ")")?;
@ -2032,12 +1946,12 @@ impl fmt::Debug for Type {
actual: _actual,
..
} => {
write!(f, "(Alias {:?}", symbol)?;
write!(f, "(Alias {symbol:?}")?;
for arg in type_arguments {
write!(f, " {:?}", &arg.typ)?;
if let Some(abs) = &arg.opt_abilities {
write!(f, ":{:?}", abs)?;
write!(f, ":{abs:?}")?;
}
}
@ -2048,28 +1962,12 @@ impl fmt::Debug for Type {
}
// Sometimes it's useful to see the expansion of the alias
write!(f, "[ but actually {:?} ]", _actual)?;
write!(f, "[ but actually {_actual:?} ]")?;
write!(f, ")")?;
Ok(())
}
Type::HostExposedAlias {
name,
type_arguments: arguments,
..
} => {
write!(f, "HostExposedAlias {:?}", name)?;
for arg in arguments {
write!(f, " {:?}", arg)?;
}
// Sometimes it's useful to see the expansion of the alias
// write!(f, "[ but actually {:?} ]", _actual)?;
Ok(())
}
Type::Record(fields, ext) => {
write!(f, "{{")?;
@ -2082,13 +1980,11 @@ impl fmt::Debug for Type {
for (label, field_type) in fields {
match field_type {
RecordField::Optional(_) | RecordField::RigidOptional(_) => {
write!(f, "{:?} ? {:?}", label, field_type)?
write!(f, "{label:?} ? {field_type:?}")?
}
RecordField::Required(_)
| RecordField::Demanded(_)
| RecordField::RigidRequired(_) => {
write!(f, "{:?} : {:?}", label, field_type)?
}
| RecordField::RigidRequired(_) => write!(f, "{label:?} : {field_type:?}")?,
}
if any_written_yet {
@ -2129,7 +2025,7 @@ impl fmt::Debug for Type {
let mut any_written_yet = false;
for (_, field_type) in elems.iter() {
write!(f, "{:?}", field_type)?;
write!(f, "{field_type:?}")?;
if any_written_yet {
write!(f, ", ")?;
@ -2179,7 +2075,7 @@ impl fmt::Debug for Type {
}
Type::FunctionOrTagUnion(tag_name, _, ext) => {
write!(f, "[")?;
write!(f, "{:?}", tag_name)?;
write!(f, "{tag_name:?}")?;
write!(f, "]")?;
match ext {
@ -2204,9 +2100,9 @@ impl fmt::Debug for Type {
} => {
write!(f, "ClosureTag(")?;
write!(f, "{:?}, ", name)?;
write!(f, "{name:?}, ")?;
for capture in captures {
write!(f, "{:?}, ", capture)?;
write!(f, "{capture:?}, ")?;
}
write!(f, ")")
@ -2229,13 +2125,13 @@ impl fmt::Debug for Type {
}
}?;
write!(f, " as <{:?}>", rec)
write!(f, " as <{rec:?}>")
}
Type::RangedNumber(range_vars) => {
write!(f, "Ranged({:?})", range_vars)
write!(f, "Ranged({range_vars:?})")
}
Type::UnspecializedLambdaSet { unspecialized } => {
write!(f, "{:?}", unspecialized)
write!(f, "{unspecialized:?}")
}
}
}
@ -2386,22 +2282,6 @@ impl Type {
stack.push(actual);
}
HostExposedAlias {
type_arguments,
lambda_set_variables,
actual: actual_type,
..
} => {
for value in type_arguments.iter_mut() {
stack.push(value);
}
for lambda_set in lambda_set_variables.iter_mut() {
stack.push(lambda_set.as_inner_mut());
}
stack.push(actual_type);
}
Apply(_, args, _) => {
stack.extend(args.iter_mut().map(|t| &mut t.value));
}
@ -2524,22 +2404,6 @@ impl Type {
stack.push(actual);
}
HostExposedAlias {
type_arguments,
lambda_set_variables,
actual: actual_type,
..
} => {
for value in type_arguments.iter_mut() {
stack.push(value);
}
for lambda_set in lambda_set_variables.iter_mut() {
stack.push(lambda_set.as_inner_mut());
}
stack.push(actual_type);
}
Apply(_, args, _) => {
stack.extend(args.iter_mut().map(|t| &mut t.value));
}
@ -2642,10 +2506,6 @@ impl Type {
}
alias_actual.substitute_alias(rep_symbol, rep_args, actual)
}
HostExposedAlias {
actual: actual_type,
..
} => actual_type.substitute_alias(rep_symbol, rep_args, actual),
Apply(symbol, args, region) if *symbol == rep_symbol => {
if args.len() == rep_args.len()
&& args
@ -2729,9 +2589,6 @@ impl Type {
actual: actual_type,
..
} => alias_symbol == &rep_symbol || actual_type.contains_symbol(rep_symbol),
HostExposedAlias { name, actual, .. } => {
name == &rep_symbol || actual.contains_symbol(rep_symbol)
}
Apply(symbol, _, _) if *symbol == rep_symbol => true,
Apply(_, args, _) => args.iter().any(|arg| arg.value.contains_symbol(rep_symbol)),
RangedNumber(_) => false,
@ -2795,7 +2652,6 @@ impl Type {
actual: actual_type,
..
} => actual_type.contains_variable(rep_variable),
HostExposedAlias { actual, .. } => actual.contains_variable(rep_variable),
Apply(_, args, _) => args
.iter()
.any(|arg| arg.value.contains_variable(rep_variable)),
@ -2998,22 +2854,6 @@ fn instantiate_aliases<'a, F>(
.iter_mut()
.for_each(|t| instantiate_aliases(&mut t.value.typ, region, aliases, ctx));
}
HostExposedAlias {
type_arguments: type_args,
lambda_set_variables,
actual: actual_type,
..
} => {
for arg in type_args {
instantiate_aliases(arg, region, aliases, ctx);
}
for arg in lambda_set_variables {
arg.instantiate_aliases(region, aliases, ctx);
}
instantiate_aliases(&mut *actual_type, region, aliases, ctx);
}
Alias {
type_arguments: type_args,
lambda_set_variables,
@ -3172,12 +3012,6 @@ fn symbols_help(initial: &Type) -> Vec<Symbol> {
output.push(*alias_symbol);
stack.push(actual_type);
}
HostExposedAlias { name, actual, .. } => {
// because the type parameters are inlined in the actual type, we don't need to look
// at the type parameters here
output.push(*name);
stack.push(actual);
}
Apply(symbol, args, _) => {
output.push(*symbol);
stack.extend(args.iter().map(|t| &t.value));
@ -3303,16 +3137,6 @@ fn variables_help(tipe: &Type, accum: &mut ImSet<Variable>) {
}
variables_help(actual, accum);
}
HostExposedAlias {
type_arguments: arguments,
actual,
..
} => {
for arg in arguments {
variables_help(arg, accum);
}
variables_help(actual, accum);
}
RangedNumber(_) => {}
Apply(_, args, _) => {
for x in args {
@ -3455,16 +3279,6 @@ fn variables_help_detailed(tipe: &Type, accum: &mut VariableDetail) {
}
variables_help_detailed(actual, accum);
}
HostExposedAlias {
type_arguments: arguments,
actual,
..
} => {
for arg in arguments {
variables_help_detailed(arg, accum);
}
variables_help_detailed(actual, accum);
}
RangedNumber(_) => {}
Apply(_, args, _) => {
for x in args {
@ -4016,7 +3830,7 @@ fn write_debug_error_type_help(error_type: ErrorType, buf: &mut String, parens:
if write_parens {
buf.push('(');
}
write!(buf, "{:?}", symbol).unwrap();
write!(buf, "{symbol:?}").unwrap();
for arg in arguments {
buf.push(' ');
@ -4061,7 +3875,7 @@ fn write_debug_error_type_help(error_type: ErrorType, buf: &mut String, parens:
if write_parens {
buf.push('(');
}
write!(buf, "{:?}", symbol).unwrap();
write!(buf, "{symbol:?}").unwrap();
for arg in arguments {
buf.push(' ');
@ -4146,7 +3960,7 @@ fn write_debug_error_type_help(error_type: ErrorType, buf: &mut String, parens:
let mut it = tags.into_iter().peekable();
while let Some((tag, args)) = it.next() {
write!(buf, "{:?}", tag).unwrap();
write!(buf, "{tag:?}").unwrap();
for arg in args {
buf.push(' ');
write_debug_error_type_help(arg, buf, Parens::InTypeParam);
@ -4165,7 +3979,7 @@ fn write_debug_error_type_help(error_type: ErrorType, buf: &mut String, parens:
let mut it = tags.into_iter().peekable();
while let Some((tag, args)) = it.next() {
write!(buf, "{:?}", tag).unwrap();
write!(buf, "{tag:?}").unwrap();
for arg in args {
buf.push(' ');
write_debug_error_type_help(arg, buf, Parens::Unnecessary);
@ -4655,20 +4469,6 @@ fn instantiate_lambda_sets_as_unspecialized(
stack.push(actual);
stack.extend(type_arguments.iter_mut().rev().map(|t| &mut t.typ));
}
Type::HostExposedAlias {
name: _,
type_arguments,
lambda_set_variables,
actual_var: _,
actual,
} => {
for lambda_set in lambda_set_variables.iter_mut() {
debug_assert!(matches!(lambda_set.0, Type::Variable(_)));
lambda_set.0 = new_uls();
}
stack.push(actual);
stack.extend(type_arguments.iter_mut().rev());
}
Type::Apply(_sym, args, _region) => {
stack.extend(args.iter_mut().rev().map(|t| &mut t.value));
}