Make and use a newtype for OptVariable

This commit is contained in:
Richard Feldman 2020-01-01 15:29:03 -05:00
parent 5cb9a4ba2d
commit 784b22a28e
3 changed files with 42 additions and 18 deletions

View file

@ -2,7 +2,7 @@ use crate::can::ident::Lowercase;
use crate::can::symbol::Symbol; use crate::can::symbol::Symbol;
use crate::collections::ImMap; use crate::collections::ImMap;
use crate::region::Located; use crate::region::Located;
use crate::subs::{Content, Descriptor, FlatType, Mark, Rank, Subs, Variable}; use crate::subs::{Content, Descriptor, FlatType, Mark, OptVariable, Rank, Subs, Variable};
use crate::types::Constraint::{self, *}; use crate::types::Constraint::{self, *};
use crate::types::Problem; use crate::types::Problem;
use crate::types::Type::{self, *}; use crate::types::Type::{self, *};
@ -662,7 +662,7 @@ fn register(subs: &mut Subs, rank: Rank, pools: &mut Pools, content: Content) ->
content, content,
rank, rank,
mark: Mark::NONE, mark: Mark::NONE,
copy: Variable::NULL, copy: OptVariable::NONE,
}); });
pools.get_mut(rank).push(var); pools.get_mut(rank).push(var);

View file

@ -87,6 +87,35 @@ impl Into<Variable> for VarStore {
} }
} }
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct OptVariable(usize);
impl OptVariable {
pub const NONE: OptVariable = OptVariable(Variable::NULL.0);
pub fn is_none(&self) -> bool {
self == &OptVariable::NONE
}
pub fn is_some(&self) -> bool {
self != &OptVariable::NONE
}
pub fn into_variable(self) -> Option<Variable> {
if self.is_none() {
None
} else {
Some(Variable(self.0))
}
}
}
impl Into<Option<Variable>> for OptVariable {
fn into(self) -> Option<Variable> {
self.into_variable()
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Variable(usize); pub struct Variable(usize);
@ -95,7 +124,7 @@ impl Variable {
// This lets us avoid using Option<Variable> for the Descriptor's // This lets us avoid using Option<Variable> for the Descriptor's
// copy field, which is a relevant space savings because we make // copy field, which is a relevant space savings because we make
// a *ton* of Descriptors. // a *ton* of Descriptors.
pub const NULL: Variable = Variable(0); const NULL: Variable = Variable(0);
const FIRST_USER_SPACE_VAR: Variable = Variable(1); const FIRST_USER_SPACE_VAR: Variable = Variable(1);
@ -103,14 +132,6 @@ impl Variable {
// This is a hack that should only ever be used for testing! // This is a hack that should only ever be used for testing!
Variable(num) Variable(num)
} }
pub fn is_null(&self) -> bool {
self == &Variable::NULL
}
pub fn is_not_null(&self) -> bool {
self != &Variable::NULL
}
} }
impl fmt::Debug for Variable { impl fmt::Debug for Variable {
@ -258,7 +279,7 @@ impl Subs {
pub fn restore(&mut self, var: Variable) { pub fn restore(&mut self, var: Variable) {
let desc = self.get(var); let desc = self.get(var);
if desc.copy.is_not_null() { if desc.copy.is_some() {
let content = desc.content; let content = desc.content;
self.set(var, content.clone().into()); self.set(var, content.clone().into());
@ -326,7 +347,7 @@ pub struct Descriptor {
pub content: Content, pub content: Content,
pub rank: Rank, pub rank: Rank,
pub mark: Mark, pub mark: Mark,
pub copy: Variable, pub copy: OptVariable,
} }
impl fmt::Debug for Descriptor { impl fmt::Debug for Descriptor {
@ -334,7 +355,10 @@ impl fmt::Debug for Descriptor {
write!( write!(
f, f,
"{:?}, r: {:?}, m: {:?} c: {:?}", "{:?}, r: {:?}, m: {:?} c: {:?}",
self.content, self.rank, self.mark, self.copy self.content,
self.rank,
self.mark,
self.copy.into_variable()
) )
} }
} }
@ -351,7 +375,7 @@ impl From<Content> for Descriptor {
content, content,
rank: Rank::NONE, rank: Rank::NONE,
mark: Mark::NONE, mark: Mark::NONE,
copy: Variable::NULL, copy: OptVariable::NONE,
} }
} }
} }

View file

@ -1,7 +1,7 @@
use crate::can::ident::{Lowercase, ModuleName, Uppercase}; use crate::can::ident::{Lowercase, ModuleName, Uppercase};
use crate::collections::ImMap; use crate::collections::ImMap;
use crate::subs::Content::{self, *}; use crate::subs::Content::{self, *};
use crate::subs::{Descriptor, FlatType, Mark, Subs, Variable}; use crate::subs::{Descriptor, FlatType, Mark, OptVariable, Subs, Variable};
use crate::types::RecordFieldLabel; use crate::types::RecordFieldLabel;
use crate::types::{Mismatch, Problem}; use crate::types::{Mismatch, Problem};
@ -397,7 +397,7 @@ fn merge(subs: &mut Subs, ctx: &Context, content: Content) -> Outcome {
content, content,
rank, rank,
mark: Mark::NONE, mark: Mark::NONE,
copy: Variable::NULL, copy: OptVariable::NONE,
}; };
subs.union(ctx.first, ctx.second, desc); subs.union(ctx.first, ctx.second, desc);
@ -420,7 +420,7 @@ fn fresh(subs: &mut Subs, pool: &mut Pool, ctx: &Context, content: Content) -> V
content, content,
rank: ctx.first_desc.rank.min(ctx.second_desc.rank), rank: ctx.first_desc.rank.min(ctx.second_desc.rank),
mark: Mark::NONE, mark: Mark::NONE,
copy: Variable::NULL, copy: OptVariable::NONE,
}, },
pool, pool,
) )