shallow clone

This commit is contained in:
Folkert 2020-12-21 15:34:11 +01:00
parent 4c15267be3
commit 7e494ad428
5 changed files with 96 additions and 34 deletions

View File

@ -1,5 +1,5 @@
use crate::pattern::{Pattern2, PatternId};
use crate::pool::{NodeId, PoolStr, PoolVec};
use crate::pool::{NodeId, PoolStr, PoolVec, ShallowClone};
use crate::types::{Type2, TypeId};
use arraystring::{typenum::U30, ArrayString};
use roc_can::expr::Recursive;
@ -204,9 +204,22 @@ pub enum Expr2 {
#[derive(Debug)]
pub struct ValueDef {
pattern: PatternId, // 4B
expr_type: Option<(Type2, Rigids)>, // ?
expr_var: Variable, // 4B
pattern: PatternId, // 4B
expr_type: Option<(TypeId, Rigids)>, // ?
expr_var: Variable, // 4B
}
impl ShallowClone for ValueDef {
fn shallow_clone(&self) -> Self {
Self {
pattern: self.pattern,
expr_type: match &self.expr_type {
Some((id, rigids)) => Some((*id, rigids.shallow_clone())),
None => None,
},
expr_var: self.expr_var,
}
}
}
#[derive(Debug)]
@ -224,6 +237,34 @@ pub enum FunctionDef {
},
}
impl ShallowClone for FunctionDef {
fn shallow_clone(&self) -> Self {
match self {
Self::WithAnnotation {
name,
arguments,
rigids,
return_type,
} => Self::WithAnnotation {
name: *name,
arguments: arguments.shallow_clone(),
rigids: *rigids,
return_type: *return_type,
},
Self::NoAnnotation {
name,
arguments,
return_var,
} => Self::NoAnnotation {
name: *name,
arguments: arguments.shallow_clone(),
return_var: *return_var,
},
}
}
}
#[derive(Debug)]
pub struct Rigids {
pub named: PoolVec<(PoolStr, Variable)>, // 8B
@ -254,7 +295,11 @@ fn size_of_expr() {
assert_eq!(std::mem::size_of::<Expr2>(), crate::pool::NODE_BYTES);
}
/// Clones the outer node, but does not clone any nodeids
pub trait ShallowClone {
fn shallow_clone(&self) -> Self;
impl ShallowClone for Rigids {
fn shallow_clone(&self) -> Self {
Self {
named: self.named.shallow_clone(),
unnamed: self.unnamed.shallow_clone(),
}
}
}

View File

@ -8,14 +8,14 @@
// };
// use crate::pattern::{bindings_from_patterns, canonicalize_pattern, Pattern};
// use crate::procedure::References;
use crate::ast::{FunctionDef, Rigids, ShallowClone, ValueDef};
use crate::ast::{FunctionDef, Rigids, ValueDef};
use crate::expr::Env;
use crate::pattern::{
symbols_and_variables_from_pattern, symbols_from_pattern, to_pattern_id, Pattern2, PatternId,
};
use crate::pool::{NodeId, Pool, PoolStr, PoolVec};
use crate::pool::{NodeId, Pool, PoolStr, PoolVec, ShallowClone};
use crate::scope::Scope;
use crate::types::{to_annotation2, Alias, Annotation2, References, Signature, Type2};
use crate::types::{to_annotation2, Alias, Annotation2, References, Signature, Type2, TypeId};
use roc_can::expr::Output;
use roc_collections::all::{default_hasher, ImMap, ImSet, MutMap, MutSet, SendMap};
use roc_module::ident::Lowercase;
@ -33,7 +33,7 @@ use ven_graph::{strongly_connected_components, topological_sort_into_groups};
enum Def {
AnnotationOnly {
rigids: crate::ast::Rigids,
annotation: Type2,
annotation: TypeId,
},
Value(ValueDef),
Function(FunctionDef),
@ -41,7 +41,14 @@ enum Def {
impl ShallowClone for Def {
fn shallow_clone(&self) -> Self {
todo!()
match self {
Self::AnnotationOnly { rigids, annotation } => Self::AnnotationOnly {
rigids: rigids.shallow_clone(),
annotation: *annotation,
},
Self::Value(def) => Self::Value(def.shallow_clone()),
Self::Function(def) => Self::Function(def.shallow_clone()),
}
}
}
@ -301,6 +308,7 @@ fn canonicalize_pending_def<'a>(
} => Type2::Function(arguments, closure_type_id, return_type_id),
Signature::FunctionWithAliases { annotation, .. } => annotation,
};
let annotation = env.add(annotation, loc_ann.region);
let def = Def::AnnotationOnly { rigids, annotation };

View File

@ -244,8 +244,10 @@ impl PoolStr {
}
}
}
}
pub fn duplicate(&self) -> Self {
impl ShallowClone for PoolStr {
fn shallow_clone(&self) -> Self {
// Question: should this fully clone, or is a shallow copy
// (and the aliasing it entails) OK?
Self {
@ -365,15 +367,6 @@ impl<'a, T: 'a + Sized> PoolVec<T> {
}
}
pub fn duplicate(&self) -> Self {
// Question: should this fully clone, or is a shallow copy
// (and the aliasing it entails) OK?
Self {
first_node_id: self.first_node_id,
len: self.len,
}
}
pub fn free<S>(self, pool: &'a mut Pool) {
// zero out the memory
unsafe {
@ -388,6 +381,17 @@ impl<'a, T: 'a + Sized> PoolVec<T> {
}
}
impl<T> ShallowClone for PoolVec<T> {
fn shallow_clone(&self) -> Self {
// Question: should this fully clone, or is a shallow copy
// (and the aliasing it entails) OK?
Self {
first_node_id: self.first_node_id,
len: self.len,
}
}
}
struct PoolVecIter<'a, T> {
pool: &'a Pool,
current_node_id: NodeId<T>,
@ -551,3 +555,8 @@ impl<T> Iterator for PoolVecIterNodeIds<T> {
}
}
}
/// Clones the outer node, but does not clone any nodeids
pub trait ShallowClone {
fn shallow_clone(&self) -> Self;
}

View File

@ -1,7 +1,7 @@
#![allow(clippy::all)]
#![allow(dead_code)]
#![allow(unused_imports)]
use crate::pool::{Pool, PoolStr, PoolVec};
use crate::pool::{Pool, PoolStr, PoolVec, ShallowClone};
use crate::types::{Alias, TypeId};
use roc_collections::all::{MutMap, MutSet};
use roc_module::ident::{Ident, Lowercase};
@ -40,7 +40,7 @@ impl Scope {
aliases: self
.aliases
.iter()
.map(|(s, a)| (*s, a.duplicate()))
.map(|(s, a)| (*s, a.shallow_clone()))
.collect(),
home: self.home,
}

View File

@ -2,7 +2,7 @@
#![allow(dead_code)]
#![allow(unused_imports)]
use crate::expr::Env;
use crate::pool::{NodeId, Pool, PoolStr, PoolVec};
use crate::pool::{NodeId, Pool, PoolStr, PoolVec, ShallowClone};
use crate::scope::Scope;
// use roc_can::expr::Output;
use roc_collections::all::{MutMap, MutSet};
@ -163,7 +163,7 @@ fn shallow_dealias<'a>(
}
Type2::Function(arguments, closure_type_id, return_type_id) => {
let signature = Signature::FunctionWithAliases {
arguments: arguments.duplicate(),
arguments: arguments.shallow_clone(),
closure_type_id: *closure_type_id,
return_type_id: *return_type_id,
annotation,
@ -370,7 +370,7 @@ pub fn to_type2<'a>(
let poolstr = PoolStr::new(var_name, env.pool);
let type_id = env.pool.add(Type2::Variable(*var));
env.pool[var_id] = (poolstr.duplicate(), type_id);
env.pool[var_id] = (poolstr.shallow_clone(), type_id);
env.pool[named_id] = (poolstr, *var);
env.set_region(named_id, loc_var.region);
@ -381,7 +381,7 @@ pub fn to_type2<'a>(
let poolstr = PoolStr::new(var_name, env.pool);
let type_id = env.pool.add(Type2::Variable(var));
env.pool[var_id] = (poolstr.duplicate(), type_id);
env.pool[var_id] = (poolstr.shallow_clone(), type_id);
env.pool[named_id] = (poolstr, var);
env.set_region(named_id, loc_var.region);
@ -700,7 +700,7 @@ fn to_type_apply<'a>(
for (node_id, (type_id, loc_var_id)) in it {
let loc_var = &env.pool[loc_var_id];
let name = loc_var.0.duplicate();
let name = loc_var.0.shallow_clone();
let var = loc_var.1;
env.pool[node_id] = (name, type_id);
@ -715,7 +715,7 @@ fn to_type_apply<'a>(
if let Type2::RecursiveTagUnion(rvar, ref tags, ext) = &mut env.pool[actual] {
substitutions.insert(*rvar, fresh);
env.pool[actual] = Type2::RecursiveTagUnion(new, tags.duplicate(), *ext);
env.pool[actual] = Type2::RecursiveTagUnion(new, tags.shallow_clone(), *ext);
}
// make sure hidden variables are freshly instantiated
@ -743,11 +743,11 @@ pub struct Alias {
pub hidden_variables: PoolVec<Variable>,
}
impl Alias {
pub fn duplicate(&self) -> Self {
impl ShallowClone for Alias {
fn shallow_clone(&self) -> Self {
Self {
targs: self.targs.duplicate(),
hidden_variables: self.hidden_variables.duplicate(),
targs: self.targs.shallow_clone(),
hidden_variables: self.hidden_variables.shallow_clone(),
actual: self.actual,
}
}