mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
optimize restore
This commit is contained in:
parent
65e0866d0a
commit
e030cd3da5
1 changed files with 84 additions and 82 deletions
|
@ -317,7 +317,8 @@ fn subs_fmt_desc(this: &Descriptor, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
|
||||||
subs_fmt_content(&this.content, subs, f)?;
|
subs_fmt_content(&this.content, subs, f)?;
|
||||||
|
|
||||||
write!(f, " r: {:?}", &this.rank)?;
|
write!(f, " r: {:?}", &this.rank)?;
|
||||||
write!(f, " m: {:?}", &this.mark)
|
write!(f, " m: {:?}", &this.mark)?;
|
||||||
|
write!(f, " c: {:?}", &this.copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SubsFmtContent<'a>(pub &'a Content, pub &'a Subs);
|
pub struct SubsFmtContent<'a>(pub &'a Content, pub &'a Subs);
|
||||||
|
@ -1089,6 +1090,10 @@ impl Subs {
|
||||||
&self.utable.probe_value_ref(key).value
|
&self.utable.probe_value_ref(key).value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_ref_mut(&mut self, key: Variable) -> &mut Descriptor {
|
||||||
|
&mut self.utable.probe_value_ref_mut(key).value
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_rank(&self, key: Variable) -> Rank {
|
pub fn get_rank(&self, key: Variable) -> Rank {
|
||||||
self.utable.probe_value_ref(key).value.rank
|
self.utable.probe_value_ref(key).value.rank
|
||||||
}
|
}
|
||||||
|
@ -1201,22 +1206,7 @@ impl Subs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restore(&mut self, var: Variable) {
|
pub fn restore(&mut self, var: Variable) {
|
||||||
let desc = self.get(var);
|
restore_help(self, var)
|
||||||
|
|
||||||
if desc.copy.is_some() {
|
|
||||||
let content = desc.content;
|
|
||||||
|
|
||||||
let desc = Descriptor {
|
|
||||||
content: content.clone(),
|
|
||||||
rank: Rank::NONE,
|
|
||||||
mark: Mark::NONE,
|
|
||||||
copy: OptVariable::NONE,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.set(var, desc);
|
|
||||||
|
|
||||||
restore_content(self, &content);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
@ -1227,6 +1217,10 @@ impl Subs {
|
||||||
self.utable.is_empty()
|
self.utable.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, var: Variable) -> bool {
|
||||||
|
(var.index() as usize) < self.len()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn snapshot(&mut self) -> Snapshot<InPlace<Variable>> {
|
pub fn snapshot(&mut self) -> Snapshot<InPlace<Variable>> {
|
||||||
self.utable.snapshot()
|
self.utable.snapshot()
|
||||||
}
|
}
|
||||||
|
@ -1830,6 +1824,12 @@ impl RecordFields {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn variables(&self) -> VariableSubsSlice {
|
||||||
|
let slice = SubsSlice::new(self.variables_start, self.length);
|
||||||
|
|
||||||
|
VariableSubsSlice { slice }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn iter_variables(&self) -> impl Iterator<Item = SubsIndex<Variable>> {
|
pub fn iter_variables(&self) -> impl Iterator<Item = SubsIndex<Variable>> {
|
||||||
let slice = SubsSlice::new(self.variables_start, self.length);
|
let slice = SubsSlice::new(self.variables_start, self.length);
|
||||||
slice.into_iter()
|
slice.into_iter()
|
||||||
|
@ -2718,83 +2718,85 @@ fn get_fresh_var_name(state: &mut ErrorTypeState) -> Lowercase {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore_content(subs: &mut Subs, content: &Content) {
|
fn restore_help(subs: &mut Subs, initial: Variable) {
|
||||||
use Content::*;
|
let mut stack = vec![initial];
|
||||||
use FlatType::*;
|
|
||||||
|
|
||||||
match content {
|
let variable_slices = &subs.variable_slices;
|
||||||
FlexVar(_) | RigidVar(_) | Error => (),
|
|
||||||
|
|
||||||
RecursionVar { structure, .. } => {
|
let variables = &subs.variables;
|
||||||
subs.restore(*structure);
|
let var_slice = |variable_subs_slice: VariableSubsSlice| {
|
||||||
}
|
&variables[variable_subs_slice.slice.start as usize..]
|
||||||
|
[..variable_subs_slice.slice.length as usize]
|
||||||
|
};
|
||||||
|
|
||||||
Structure(flat_type) => match flat_type {
|
while let Some(var) = stack.pop() {
|
||||||
Apply(_, args) => {
|
let desc = &mut subs.utable.probe_value_ref_mut(var).value;
|
||||||
for index in args.into_iter() {
|
|
||||||
let var = subs[index];
|
|
||||||
subs.restore(var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Func(arg_vars, closure_var, ret_var) => {
|
if desc.copy.is_some() {
|
||||||
for index in arg_vars.into_iter() {
|
desc.rank = Rank::NONE;
|
||||||
let var = subs[index];
|
desc.mark = Mark::NONE;
|
||||||
subs.restore(var);
|
desc.copy = OptVariable::NONE;
|
||||||
|
|
||||||
|
use Content::*;
|
||||||
|
use FlatType::*;
|
||||||
|
|
||||||
|
match &desc.content {
|
||||||
|
FlexVar(_) | RigidVar(_) | Error => (),
|
||||||
|
|
||||||
|
RecursionVar { structure, .. } => {
|
||||||
|
stack.push(*structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
subs.restore(*ret_var);
|
Structure(flat_type) => match flat_type {
|
||||||
subs.restore(*closure_var);
|
Apply(_, args) => {
|
||||||
}
|
stack.extend(var_slice(*args));
|
||||||
|
|
||||||
EmptyRecord => (),
|
|
||||||
EmptyTagUnion => (),
|
|
||||||
|
|
||||||
Record(fields, ext_var) => {
|
|
||||||
for index in fields.iter_variables() {
|
|
||||||
let var = subs[index];
|
|
||||||
subs.restore(var);
|
|
||||||
}
|
|
||||||
|
|
||||||
subs.restore(*ext_var);
|
|
||||||
}
|
|
||||||
TagUnion(tags, ext_var) => {
|
|
||||||
for slice_index in tags.variables() {
|
|
||||||
let slice = subs[slice_index];
|
|
||||||
for var_index in slice {
|
|
||||||
let var = subs[var_index];
|
|
||||||
subs.restore(var);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
subs.restore(*ext_var);
|
Func(arg_vars, closure_var, ret_var) => {
|
||||||
}
|
stack.extend(var_slice(*arg_vars));
|
||||||
FunctionOrTagUnion(_, _, ext_var) => {
|
|
||||||
subs.restore(*ext_var);
|
|
||||||
}
|
|
||||||
|
|
||||||
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
stack.push(*ret_var);
|
||||||
for slice_index in tags.variables() {
|
stack.push(*closure_var);
|
||||||
let slice = subs[slice_index];
|
|
||||||
for var_index in slice {
|
|
||||||
let var = subs[var_index];
|
|
||||||
subs.restore(var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmptyRecord => (),
|
||||||
|
EmptyTagUnion => (),
|
||||||
|
|
||||||
|
Record(fields, ext_var) => {
|
||||||
|
stack.extend(var_slice(fields.variables()));
|
||||||
|
|
||||||
|
stack.push(*ext_var);
|
||||||
|
}
|
||||||
|
TagUnion(tags, ext_var) => {
|
||||||
|
for slice_index in tags.variables() {
|
||||||
|
let slice = variable_slices[slice_index.start as usize];
|
||||||
|
stack.extend(var_slice(slice));
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.push(*ext_var);
|
||||||
|
}
|
||||||
|
FunctionOrTagUnion(_, _, ext_var) => {
|
||||||
|
stack.push(*ext_var);
|
||||||
|
}
|
||||||
|
|
||||||
|
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
||||||
|
for slice_index in tags.variables() {
|
||||||
|
let slice = variable_slices[slice_index.start as usize];
|
||||||
|
stack.extend(var_slice(slice));
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.push(*ext_var);
|
||||||
|
stack.push(*rec_var);
|
||||||
|
}
|
||||||
|
|
||||||
|
Erroneous(_) => (),
|
||||||
|
},
|
||||||
|
Alias(_, args, var) => {
|
||||||
|
stack.extend(var_slice(args.variables()));
|
||||||
|
|
||||||
|
stack.push(*var);
|
||||||
}
|
}
|
||||||
|
|
||||||
subs.restore(*ext_var);
|
|
||||||
subs.restore(*rec_var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Erroneous(_) => (),
|
|
||||||
},
|
|
||||||
Alias(_, args, var) => {
|
|
||||||
for var_index in args.variables().into_iter() {
|
|
||||||
let var = subs[var_index];
|
|
||||||
subs.restore(var);
|
|
||||||
}
|
|
||||||
|
|
||||||
subs.restore(*var);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue