mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
SoA Types get variable emplacement (!)
We're now reaching the steady state we want to be closert to - when a type is translated to a variable, emplace the variable we created for it in the type index, so that types are never converted again!
This commit is contained in:
parent
d93147dd25
commit
5564796927
5 changed files with 110 additions and 86 deletions
|
@ -8,11 +8,11 @@ use roc_module::ident::TagName;
|
|||
use roc_module::symbol::{ModuleId, Symbol};
|
||||
use roc_region::all::{Loc, Region};
|
||||
use roc_types::subs::{ExhaustiveMark, IllegalCycleMark, Variable};
|
||||
use roc_types::types::{Category, PatternCategory, TypeTag, Types};
|
||||
use roc_types::types::{Category, PatternCategory, TypeCell, TypeTag, Types};
|
||||
|
||||
pub struct Constraints {
|
||||
pub constraints: Vec<Constraint>,
|
||||
pub types: Vec<Cell<Index<TypeTag>>>,
|
||||
pub types: Vec<Cell<Index<TypeCell>>>,
|
||||
pub type_slices: Vec<TypeOrVar>,
|
||||
pub variables: Vec<Variable>,
|
||||
pub loc_symbols: Vec<(Symbol, Region)>,
|
||||
|
@ -60,7 +60,7 @@ impl Default for Constraints {
|
|||
|
||||
pub type ExpectedTypeIndex = Index<Expected<TypeOrVar>>;
|
||||
pub type PExpectedTypeIndex = Index<PExpected<TypeOrVar>>;
|
||||
pub type TypeOrVar = EitherIndex<Cell<Index<TypeTag>>, Variable>;
|
||||
pub type TypeOrVar = EitherIndex<Cell<Index<TypeCell>>, Variable>;
|
||||
|
||||
impl Constraints {
|
||||
pub fn new() -> Self {
|
||||
|
@ -138,9 +138,9 @@ impl Constraints {
|
|||
}
|
||||
}
|
||||
|
||||
pub const EMPTY_RECORD: Index<Cell<Index<TypeTag>>> = Index::new(0);
|
||||
pub const EMPTY_TAG_UNION: Index<Cell<Index<TypeTag>>> = Index::new(1);
|
||||
pub const STR: Index<Cell<Index<TypeTag>>> = Index::new(2);
|
||||
pub const EMPTY_RECORD: Index<Cell<Index<TypeCell>>> = Index::new(0);
|
||||
pub const EMPTY_TAG_UNION: Index<Cell<Index<TypeCell>>> = Index::new(1);
|
||||
pub const STR: Index<Cell<Index<TypeCell>>> = Index::new(2);
|
||||
|
||||
pub const CATEGORY_RECORD: Index<Category> = Index::new(0);
|
||||
pub const CATEGORY_FOREIGNCALL: Index<Category> = Index::new(1);
|
||||
|
@ -173,9 +173,9 @@ impl Constraints {
|
|||
pub fn push_type(
|
||||
&mut self,
|
||||
types: &Types,
|
||||
typ: Index<TypeTag>,
|
||||
) -> EitherIndex<Cell<Index<TypeTag>>, Variable> {
|
||||
match types[typ] {
|
||||
typ: Index<TypeCell>,
|
||||
) -> EitherIndex<Cell<Index<TypeCell>>, Variable> {
|
||||
match types[typ].get() {
|
||||
TypeTag::EmptyRecord => EitherIndex::from_left(Self::EMPTY_RECORD),
|
||||
TypeTag::EmptyTagUnion => EitherIndex::from_left(Self::EMPTY_TAG_UNION),
|
||||
TypeTag::Apply {
|
||||
|
@ -184,7 +184,7 @@ impl Constraints {
|
|||
} => EitherIndex::from_left(Self::STR),
|
||||
TypeTag::Variable(var) => Self::push_type_variable(var),
|
||||
_ => {
|
||||
let index: Index<Cell<Index<TypeTag>>> =
|
||||
let index: Index<Cell<Index<TypeCell>>> =
|
||||
Index::push_new(&mut self.types, Cell::new(typ));
|
||||
EitherIndex::from_left(index)
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ use roc_region::all::{Loc, Region};
|
|||
use roc_types::subs::{IllegalCycleMark, Variable};
|
||||
use roc_types::types::Type::{self, *};
|
||||
use roc_types::types::{
|
||||
AliasKind, AnnotationSource, Category, OptAbleType, PReason, Reason, RecordField,
|
||||
AliasKind, AnnotationSource, Category, OptAbleType, PReason, Reason, RecordField, TypeCell,
|
||||
TypeExtension, TypeTag, Types,
|
||||
};
|
||||
|
||||
|
@ -1608,7 +1608,7 @@ fn constrain_function_def(
|
|||
|
||||
let signature_index = constraints.push_type(types, signature);
|
||||
|
||||
let (arg_types, signature_closure_type, ret_type) = match types[signature] {
|
||||
let (arg_types, signature_closure_type, ret_type) = match types[signature].get() {
|
||||
TypeTag::Function(signature_closure_type, ret_type) => (
|
||||
types.get_type_arguments(signature),
|
||||
signature_closure_type,
|
||||
|
@ -2503,7 +2503,7 @@ fn constrain_typed_def(
|
|||
//
|
||||
// This means we get errors like "the first argument of `f` is weird"
|
||||
// instead of the more generic "something is wrong with the body of `f`"
|
||||
match (&def.loc_expr.value, types[signature]) {
|
||||
match (&def.loc_expr.value, types[signature].get()) {
|
||||
(
|
||||
Closure(ClosureData {
|
||||
function_type: fn_var,
|
||||
|
@ -2667,7 +2667,7 @@ fn constrain_typed_function_arguments(
|
|||
def_pattern_state: &mut PatternState,
|
||||
argument_pattern_state: &mut PatternState,
|
||||
arguments: &[(Variable, AnnotatedMark, Loc<Pattern>)],
|
||||
arg_types: Slice<TypeTag>,
|
||||
arg_types: Slice<TypeCell>,
|
||||
) {
|
||||
// ensure type matches the one in the annotation
|
||||
let opt_label = if let Pattern::Identifier(label) = def.loc_pattern.value {
|
||||
|
@ -2805,7 +2805,7 @@ fn constrain_typed_function_arguments_simple(
|
|||
def_pattern_state: &mut PatternState,
|
||||
argument_pattern_state: &mut PatternState,
|
||||
arguments: &[(Variable, AnnotatedMark, Loc<Pattern>)],
|
||||
arg_types: Slice<TypeTag>,
|
||||
arg_types: Slice<TypeCell>,
|
||||
) {
|
||||
let it = arguments.iter().zip(arg_types.into_iter()).enumerate();
|
||||
for (index, ((pattern_var, annotated_mark, loc_pattern), ann)) in it {
|
||||
|
@ -3094,7 +3094,7 @@ fn constrain_closure_size(
|
|||
}
|
||||
|
||||
pub struct InstantiateRigids {
|
||||
pub signature: Index<TypeTag>,
|
||||
pub signature: Index<TypeCell>,
|
||||
pub new_rigid_variables: Vec<Variable>,
|
||||
pub new_infer_variables: Vec<Variable>,
|
||||
}
|
||||
|
@ -3321,7 +3321,7 @@ fn constraint_recursive_function(
|
|||
signature_index,
|
||||
));
|
||||
|
||||
let (arg_types, _signature_closure_type, ret_type) = match types[signature] {
|
||||
let (arg_types, _signature_closure_type, ret_type) = match types[signature].get() {
|
||||
TypeTag::Function(signature_closure_type, ret_type) => (
|
||||
types.get_type_arguments(signature),
|
||||
signature_closure_type,
|
||||
|
@ -3764,7 +3764,7 @@ fn rec_defs_help(
|
|||
//
|
||||
// This means we get errors like "the first argument of `f` is weird"
|
||||
// instead of the more generic "something is wrong with the body of `f`"
|
||||
match (&def.loc_expr.value, types[signature]) {
|
||||
match (&def.loc_expr.value, types[signature].get()) {
|
||||
(
|
||||
Closure(ClosureData {
|
||||
function_type: fn_var,
|
||||
|
|
|
@ -771,7 +771,7 @@ fn could_be_a_tag_union(types: &Types, constraints: &mut Constraints, typ: TypeO
|
|||
Ok(typ_index) => {
|
||||
let typ_cell = &mut constraints.types[typ_index.index()];
|
||||
!matches!(
|
||||
types[*typ_cell.get_mut()],
|
||||
types[*typ_cell.get_mut()].get(),
|
||||
TypeTag::Apply { .. } | TypeTag::Function(..) | TypeTag::Record(..)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ use roc_types::subs::{
|
|||
};
|
||||
use roc_types::types::{
|
||||
gather_fields_unsorted_iter, AliasKind, AliasShared, Category, OptAbleVar, Polarity, Reason,
|
||||
RecordField, Type, TypeExtension, TypeTag, Types, Uls,
|
||||
RecordField, Type, TypeCell, TypeExtension, TypeTag, Types, Uls,
|
||||
};
|
||||
use roc_unify::unify::{
|
||||
unify, unify_introduced_ability_specialization, Env as UEnv, Mode, Obligated,
|
||||
|
@ -138,7 +138,7 @@ impl DelayedAliasVariables {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Aliases {
|
||||
aliases: Vec<(Symbol, Index<TypeTag>, DelayedAliasVariables, AliasKind)>,
|
||||
aliases: Vec<(Symbol, Index<TypeCell>, DelayedAliasVariables, AliasKind)>,
|
||||
variables: Vec<OptAbleVar>,
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ impl Aliases {
|
|||
}
|
||||
};
|
||||
|
||||
// TODO: can we construct Aliases from TypeTag directly?
|
||||
// TODO: can we construct Aliases from TypeCell directly?
|
||||
let alias_typ = types.from_old_type(&alias.typ);
|
||||
|
||||
self.aliases
|
||||
|
@ -2263,7 +2263,7 @@ fn type_cell_to_var(
|
|||
pools: &mut Pools,
|
||||
types: &mut Types,
|
||||
aliases: &mut Aliases,
|
||||
typ_cell: &Cell<Index<TypeTag>>,
|
||||
typ_cell: &Cell<Index<TypeCell>>,
|
||||
) -> Variable {
|
||||
let typ = typ_cell.get();
|
||||
let var = type_to_var(
|
||||
|
@ -2278,7 +2278,7 @@ fn type_cell_to_var(
|
|||
typ,
|
||||
);
|
||||
unsafe {
|
||||
types.set_variable(typ, var);
|
||||
types.emplace_variable(typ, var);
|
||||
}
|
||||
|
||||
var
|
||||
|
@ -2293,9 +2293,9 @@ pub(crate) fn type_to_var(
|
|||
pools: &mut Pools,
|
||||
types: &mut Types,
|
||||
aliases: &mut Aliases,
|
||||
typ: Index<TypeTag>,
|
||||
typ: Index<TypeCell>,
|
||||
) -> Variable {
|
||||
if let TypeTag::Variable(var) = types[typ] {
|
||||
if let TypeTag::Variable(var) = types[typ].get() {
|
||||
var
|
||||
} else {
|
||||
let mut arena = take_scratchpad();
|
||||
|
@ -2336,11 +2336,11 @@ impl RegisterVariable {
|
|||
pools: &mut Pools,
|
||||
arena: &'_ bumpalo::Bump,
|
||||
types: &mut Types,
|
||||
typ: Index<TypeTag>,
|
||||
typ: Index<TypeCell>,
|
||||
) -> Self {
|
||||
use RegisterVariable::*;
|
||||
|
||||
match types[typ] {
|
||||
match types[typ].get() {
|
||||
TypeTag::Variable(var) => Direct(var),
|
||||
TypeTag::EmptyRecord => Direct(Variable::EMPTY_RECORD),
|
||||
TypeTag::EmptyTagUnion => Direct(Variable::EMPTY_TAG_UNION),
|
||||
|
@ -2373,7 +2373,7 @@ impl RegisterVariable {
|
|||
pools: &mut Pools,
|
||||
arena: &'_ bumpalo::Bump,
|
||||
types: &mut Types,
|
||||
typ: Index<TypeTag>,
|
||||
typ: Index<TypeCell>,
|
||||
stack: &mut bumpalo::collections::Vec<'_, TypeToVar>,
|
||||
) -> Variable {
|
||||
match Self::from_type(subs, rank, pools, arena, types, typ) {
|
||||
|
@ -2444,7 +2444,7 @@ impl AmbientFunctionPolicy {
|
|||
#[derive(Debug)]
|
||||
enum TypeToVar {
|
||||
Defer {
|
||||
typ: Index<TypeTag>,
|
||||
typ: Index<TypeCell>,
|
||||
destination: Variable,
|
||||
ambient_function: AmbientFunctionPolicy,
|
||||
},
|
||||
|
@ -2461,7 +2461,7 @@ fn type_to_variable<'a>(
|
|||
arena: &'a bumpalo::Bump,
|
||||
aliases: &mut Aliases,
|
||||
types: &mut Types,
|
||||
typ: Index<TypeTag>,
|
||||
typ: Index<TypeCell>,
|
||||
// Helpers for instantiating ambient functions of lambda set variables from type aliases.
|
||||
is_alias_lambda_set_arg: bool,
|
||||
) -> Variable {
|
||||
|
@ -2505,7 +2505,7 @@ fn type_to_variable<'a>(
|
|||
}) = stack.pop()
|
||||
{
|
||||
use TypeTag::*;
|
||||
match types[typ] {
|
||||
match types[typ].get() {
|
||||
Variable(_) | EmptyRecord | EmptyTagUnion => {
|
||||
unreachable!("This variant should never be deferred!")
|
||||
}
|
||||
|
@ -2812,7 +2812,7 @@ fn type_to_variable<'a>(
|
|||
}
|
||||
|
||||
StructuralAlias { shared, actual } | OpaqueAlias { shared, actual } => {
|
||||
let kind = match types[typ] {
|
||||
let kind = match types[typ].get() {
|
||||
StructuralAlias { .. } => AliasKind::Structural,
|
||||
OpaqueAlias { .. } => AliasKind::Opaque,
|
||||
_ => internal_error!(),
|
||||
|
@ -3062,10 +3062,10 @@ fn roc_result_to_var(
|
|||
pools: &mut Pools,
|
||||
arena: &'_ bumpalo::Bump,
|
||||
types: &mut Types,
|
||||
result_type: Index<TypeTag>,
|
||||
result_type: Index<TypeCell>,
|
||||
stack: &mut bumpalo::collections::Vec<'_, TypeToVar>,
|
||||
) -> Variable {
|
||||
match types[result_type] {
|
||||
match types[result_type].get() {
|
||||
TypeTag::TagUnion(tags) => {
|
||||
let ext_slice = types.get_type_arguments(result_type);
|
||||
|
||||
|
@ -3245,7 +3245,7 @@ fn register_tag_arguments(
|
|||
arena: &'_ bumpalo::Bump,
|
||||
types: &mut Types,
|
||||
stack: &mut bumpalo::collections::Vec<'_, TypeToVar>,
|
||||
arguments: Slice<TypeTag>,
|
||||
arguments: Slice<TypeCell>,
|
||||
) -> VariableSubsSlice {
|
||||
if arguments.is_empty() {
|
||||
VariableSubsSlice::default()
|
||||
|
@ -3374,7 +3374,7 @@ fn type_to_union_tags(
|
|||
arena: &'_ bumpalo::Bump,
|
||||
types: &mut Types,
|
||||
union_tags: UnionTags,
|
||||
opt_ext_slice: Slice<TypeTag>,
|
||||
opt_ext_slice: Slice<TypeCell>,
|
||||
stack: &mut bumpalo::collections::Vec<'_, TypeToVar>,
|
||||
) -> (UnionTags, Variable) {
|
||||
use bumpalo::collections::Vec;
|
||||
|
@ -3430,7 +3430,7 @@ fn create_union_lambda(
|
|||
arena: &'_ bumpalo::Bump,
|
||||
types: &mut Types,
|
||||
closure: Symbol,
|
||||
capture_types: Slice<TypeTag>,
|
||||
capture_types: Slice<TypeCell>,
|
||||
stack: &mut bumpalo::collections::Vec<'_, TypeToVar>,
|
||||
) -> UnionLambdas {
|
||||
let variable_slice =
|
||||
|
|
|
@ -12,6 +12,7 @@ use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
|||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
use roc_region::all::{Loc, Region};
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
use std::fmt::Write;
|
||||
|
||||
|
@ -370,8 +371,28 @@ pub struct AliasShared {
|
|||
pub symbol: Symbol,
|
||||
pub type_argument_abilities: Slice<AbilitySet>,
|
||||
pub type_argument_regions: Slice<Region>,
|
||||
pub lambda_set_variables: Slice<TypeTag>,
|
||||
pub infer_ext_in_output_variables: Slice<TypeTag>,
|
||||
pub lambda_set_variables: Slice<TypeCell>,
|
||||
pub infer_ext_in_output_variables: Slice<TypeCell>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct TypeCell(Cell<TypeTag>);
|
||||
|
||||
static_assertions::assert_eq_size!(TypeCell, TypeTag);
|
||||
|
||||
impl TypeCell {
|
||||
const fn new(tag: TypeTag) -> Self {
|
||||
Self(Cell::new(tag))
|
||||
}
|
||||
|
||||
fn set(&self, tag: TypeTag) {
|
||||
self.0.set(tag)
|
||||
}
|
||||
|
||||
pub fn get(&self) -> TypeTag {
|
||||
self.0.get()
|
||||
}
|
||||
}
|
||||
|
||||
/// The tag (head constructor) of a canonical type stored in [Types].
|
||||
|
@ -382,9 +403,9 @@ pub enum TypeTag {
|
|||
/// The arguments are implicit
|
||||
Function(
|
||||
/// lambda set
|
||||
Index<TypeTag>,
|
||||
Index<TypeCell>,
|
||||
/// return type
|
||||
Index<TypeTag>,
|
||||
Index<TypeCell>,
|
||||
),
|
||||
/// Closure arguments are implicit
|
||||
ClosureTag {
|
||||
|
@ -402,21 +423,21 @@ pub enum TypeTag {
|
|||
},
|
||||
StructuralAlias {
|
||||
shared: Index<AliasShared>,
|
||||
actual: Index<TypeTag>,
|
||||
actual: Index<TypeCell>,
|
||||
},
|
||||
OpaqueAlias {
|
||||
shared: Index<AliasShared>,
|
||||
actual: Index<TypeTag>,
|
||||
actual: Index<TypeCell>,
|
||||
},
|
||||
HostExposedAlias {
|
||||
shared: Index<AliasShared>,
|
||||
actual_type: Index<TypeTag>,
|
||||
actual_type: Index<TypeCell>,
|
||||
actual_variable: Variable,
|
||||
},
|
||||
|
||||
Apply {
|
||||
symbol: Symbol,
|
||||
// type_argument_types: Slice<TypeTag>, implicit
|
||||
// type_argument_types: Slice<TypeCell>, implicit
|
||||
type_argument_regions: Slice<Region>,
|
||||
region: Region, // IDEA: make implicit, final element of `type_argument_regions`
|
||||
},
|
||||
|
@ -437,10 +458,10 @@ pub enum TypeTag {
|
|||
/// type arguments of a [TypeTag].
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct AsideTypeSlice(Slice<TypeTag>);
|
||||
pub struct AsideTypeSlice(Slice<TypeCell>);
|
||||
|
||||
impl AsideTypeSlice {
|
||||
pub fn into_iter(&self) -> impl Iterator<Item = Index<TypeTag>> {
|
||||
pub fn into_iter(&self) -> impl Iterator<Item = Index<TypeCell>> {
|
||||
self.0.into_iter()
|
||||
}
|
||||
|
||||
|
@ -463,12 +484,12 @@ pub struct Types {
|
|||
// `tags_slices` is a parallel array (so these two vectors always have the same size), that
|
||||
// allows storing a slice of types. This is used for storing the function argument types, or
|
||||
// the extension parameter of tag unions/records.
|
||||
tags: Vec<TypeTag>,
|
||||
tags_slices: Vec<Slice<TypeTag>>,
|
||||
tags: Vec<TypeCell>,
|
||||
tags_slices: Vec<Slice<TypeCell>>,
|
||||
|
||||
// used to store other slices of types that are not the "main" arguments of a type stored in
|
||||
// `tags_slices`.
|
||||
aside_types_slices: Vec<Slice<TypeTag>>,
|
||||
aside_types_slices: Vec<Slice<TypeCell>>,
|
||||
|
||||
// region info where appropriate (retained for generating error messages)
|
||||
regions: Vec<Region>,
|
||||
|
@ -486,7 +507,7 @@ pub struct Types {
|
|||
|
||||
// these tag types are relatively rare, and so we store them in a way that reduces space, at
|
||||
// the cost of slightly higher lookup time
|
||||
single_tag_union_tag_names: VecMap<Index<TypeTag>, TagName>,
|
||||
single_tag_union_tag_names: VecMap<Index<TypeCell>, TagName>,
|
||||
}
|
||||
|
||||
impl Default for Types {
|
||||
|
@ -496,21 +517,21 @@ impl Default for Types {
|
|||
}
|
||||
|
||||
impl Types {
|
||||
pub const EMPTY_RECORD: Index<TypeTag> = Index::new(0);
|
||||
const EMPTY_RECORD_TAG: TypeTag = TypeTag::EmptyRecord;
|
||||
const EMPTY_RECORD_ARGS: Slice<TypeTag> = Slice::empty();
|
||||
pub const EMPTY_RECORD: Index<TypeCell> = Index::new(0);
|
||||
const EMPTY_RECORD_TAG: TypeCell = TypeCell::new(TypeTag::EmptyRecord);
|
||||
const EMPTY_RECORD_ARGS: Slice<TypeCell> = Slice::empty();
|
||||
|
||||
pub const EMPTY_TAG_UNION: Index<TypeTag> = Index::new(1);
|
||||
const EMPTY_TAG_UNION_TAG: TypeTag = TypeTag::EmptyTagUnion;
|
||||
const EMPTY_TAG_UNION_ARGS: Slice<TypeTag> = Slice::empty();
|
||||
pub const EMPTY_TAG_UNION: Index<TypeCell> = Index::new(1);
|
||||
const EMPTY_TAG_UNION_TAG: TypeCell = TypeCell::new(TypeTag::EmptyTagUnion);
|
||||
const EMPTY_TAG_UNION_ARGS: Slice<TypeCell> = Slice::empty();
|
||||
|
||||
pub const STR: Index<TypeTag> = Index::new(2);
|
||||
const STR_TAG: TypeTag = TypeTag::Apply {
|
||||
pub const STR: Index<TypeCell> = Index::new(2);
|
||||
const STR_TAG: TypeCell = TypeCell::new(TypeTag::Apply {
|
||||
symbol: Symbol::STR_STR,
|
||||
type_argument_regions: Slice::empty(),
|
||||
region: Region::zero(),
|
||||
};
|
||||
const STR_ARGS: Slice<TypeTag> = Slice::empty();
|
||||
});
|
||||
const STR_ARGS: Slice<TypeCell> = Slice::empty();
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
@ -548,7 +569,7 @@ impl Types {
|
|||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn get_tag_name(&self, typ: &Index<TypeTag>) -> &TagName {
|
||||
pub fn get_tag_name(&self, typ: &Index<TypeCell>) -> &TagName {
|
||||
self.single_tag_union_tag_names
|
||||
.get(typ)
|
||||
.expect("typ is not a single tag union")
|
||||
|
@ -557,7 +578,7 @@ impl Types {
|
|||
pub fn record_fields_slices(
|
||||
&self,
|
||||
fields: RecordFields,
|
||||
) -> (Slice<Lowercase>, Slice<RecordField<()>>, Slice<TypeTag>) {
|
||||
) -> (Slice<Lowercase>, Slice<RecordField<()>>, Slice<TypeCell>) {
|
||||
let RecordFields {
|
||||
length,
|
||||
field_names_start,
|
||||
|
@ -589,11 +610,11 @@ impl Types {
|
|||
/// # Safety
|
||||
///
|
||||
/// May only be called if `var` is known to represent the type at `index`.
|
||||
pub unsafe fn set_variable(&mut self, index: Index<TypeTag>, var: Variable) {
|
||||
self.tags[index.index()] = TypeTag::Variable(var);
|
||||
pub unsafe fn emplace_variable(&self, index: Index<TypeCell>, var: Variable) {
|
||||
self.tags[index.index()].0.replace(TypeTag::Variable(var));
|
||||
}
|
||||
|
||||
fn reserve_type_tags(&mut self, length: usize) -> Slice<TypeTag> {
|
||||
fn reserve_type_tags(&mut self, length: usize) -> Slice<TypeCell> {
|
||||
use std::iter::repeat;
|
||||
|
||||
debug_assert_eq!(self.tags.len(), self.tags_slices.len());
|
||||
|
@ -601,21 +622,24 @@ impl Types {
|
|||
self.tags_slices
|
||||
.extend(repeat(Slice::default()).take(length));
|
||||
|
||||
Slice::extend_new(&mut self.tags, repeat(TypeTag::EmptyRecord).take(length))
|
||||
Slice::extend_new(
|
||||
&mut self.tags,
|
||||
repeat(TypeCell::new(TypeTag::EmptyRecord)).take(length),
|
||||
)
|
||||
}
|
||||
|
||||
fn reserve_type_tag(&mut self) -> Index<TypeTag> {
|
||||
fn reserve_type_tag(&mut self) -> Index<TypeCell> {
|
||||
debug_assert_eq!(self.tags.len(), self.tags_slices.len());
|
||||
|
||||
self.tags_slices.push(Slice::default());
|
||||
|
||||
Index::push_new(&mut self.tags, TypeTag::EmptyRecord)
|
||||
Index::push_new(&mut self.tags, TypeCell::new(TypeTag::EmptyRecord))
|
||||
}
|
||||
|
||||
fn set_type_tag(&mut self, index: Index<TypeTag>, tag: TypeTag, type_slice: Slice<TypeTag>) {
|
||||
fn set_type_tag(&mut self, index: Index<TypeCell>, tag: TypeTag, type_slice: Slice<TypeCell>) {
|
||||
debug_assert_eq!(self.tags.len(), self.tags_slices.len());
|
||||
|
||||
self.tags[index.index()] = tag;
|
||||
self.tags[index.index()].set(tag);
|
||||
self.tags_slices[index.index()] = type_slice;
|
||||
}
|
||||
|
||||
|
@ -624,7 +648,7 @@ impl Types {
|
|||
&mut self,
|
||||
// evil, but allows us to emulate reference-polymorphism
|
||||
old: impl ExactSizeIterator<Item = B>,
|
||||
) -> Slice<TypeTag>
|
||||
) -> Slice<TypeCell>
|
||||
where
|
||||
B: std::borrow::Borrow<Type>,
|
||||
{
|
||||
|
@ -641,7 +665,7 @@ impl Types {
|
|||
&mut self,
|
||||
tags: &[(TagName, Vec<Type>)],
|
||||
extension: &TypeExtension,
|
||||
) -> (UnionTags, Slice<TypeTag>) {
|
||||
) -> (UnionTags, Slice<TypeCell>) {
|
||||
let tag_names_slice =
|
||||
Slice::extend_new(&mut self.tag_names, tags.iter().map(|(n, _)| n.clone()));
|
||||
|
||||
|
@ -720,7 +744,7 @@ impl Types {
|
|||
}
|
||||
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn from_old_type(&mut self, old: &Type) -> Index<TypeTag> {
|
||||
pub fn from_old_type(&mut self, old: &Type) -> Index<TypeCell> {
|
||||
let index = self.reserve_type_tag();
|
||||
self.from_old_type_at(index, old);
|
||||
index
|
||||
|
@ -728,10 +752,10 @@ impl Types {
|
|||
|
||||
pub fn function(
|
||||
&mut self,
|
||||
arguments: Slice<TypeTag>,
|
||||
lambda_set: Index<TypeTag>,
|
||||
ret: Index<TypeTag>,
|
||||
) -> Index<TypeTag> {
|
||||
arguments: Slice<TypeCell>,
|
||||
lambda_set: Index<TypeCell>,
|
||||
ret: Index<TypeCell>,
|
||||
) -> Index<TypeCell> {
|
||||
let index = self.reserve_type_tag();
|
||||
|
||||
let tag = TypeTag::Function(lambda_set, ret);
|
||||
|
@ -740,7 +764,7 @@ impl Types {
|
|||
}
|
||||
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn from_old_type_at(&mut self, index: Index<TypeTag>, old: &Type) {
|
||||
fn from_old_type_at(&mut self, index: Index<TypeCell>, old: &Type) {
|
||||
match old {
|
||||
Type::EmptyRec => self.set_type_tag(index, TypeTag::EmptyRecord, Slice::default()),
|
||||
Type::EmptyTagUnion => {
|
||||
|
@ -1003,9 +1027,9 @@ impl Types {
|
|||
/// Creates a deep clone of a type with substituted variables.
|
||||
pub fn clone_with_variable_substitutions(
|
||||
&mut self,
|
||||
typ: Index<TypeTag>,
|
||||
typ: Index<TypeCell>,
|
||||
subs: &MutMap<Variable, Variable>,
|
||||
) -> Index<TypeTag> {
|
||||
) -> Index<TypeCell> {
|
||||
let cloned = self.reserve_type_tag();
|
||||
|
||||
let mut stack = vec![(cloned, typ)];
|
||||
|
@ -1085,7 +1109,7 @@ impl Types {
|
|||
while let Some((dest_index, typ)) = stack.pop() {
|
||||
use TypeTag::*;
|
||||
|
||||
let (tag, args) = match self[typ] {
|
||||
let (tag, args) = match self[typ].get() {
|
||||
Variable(v) => (Variable(subst!(v)), Default::default()),
|
||||
EmptyRecord => (EmptyRecord, Default::default()),
|
||||
EmptyTagUnion => (EmptyTagUnion, Default::default()),
|
||||
|
@ -1599,7 +1623,7 @@ macro_rules! impl_types_index_slice {
|
|||
}
|
||||
|
||||
impl_types_index! {
|
||||
tags, TypeTag
|
||||
tags, TypeCell
|
||||
aliases, AliasShared
|
||||
type_arg_abilities, AbilitySet
|
||||
regions, Region
|
||||
|
@ -1613,7 +1637,7 @@ impl_types_index_slice! {
|
|||
}
|
||||
|
||||
impl std::ops::Index<Index<AsideTypeSlice>> for Types {
|
||||
type Output = Slice<TypeTag>;
|
||||
type Output = Slice<TypeCell>;
|
||||
|
||||
fn index(&self, slice: Index<AsideTypeSlice>) -> &Self::Output {
|
||||
&self.aside_types_slices[slice.index()]
|
||||
|
@ -1621,7 +1645,7 @@ impl std::ops::Index<Index<AsideTypeSlice>> for Types {
|
|||
}
|
||||
|
||||
impl std::ops::Index<Slice<AsideTypeSlice>> for Types {
|
||||
type Output = [Slice<TypeTag>];
|
||||
type Output = [Slice<TypeCell>];
|
||||
|
||||
fn index(&self, slice: Slice<AsideTypeSlice>) -> &Self::Output {
|
||||
&self.aside_types_slices[slice.indices()]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue