Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyaherbert committed Jan 12, 2023
1 parent 8440ed7 commit 465e696
Show file tree
Hide file tree
Showing 32 changed files with 999 additions and 206 deletions.
2 changes: 1 addition & 1 deletion sway-ast/src/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt;

#[derive(Eq, PartialEq, Debug, Clone)]
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Intrinsic {
GetStorageKey,
IsReferenceType,
Expand Down
21 changes: 11 additions & 10 deletions sway-core/src/decl_engine/id.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::hash::{Hash, Hasher};

use sway_types::{Span, Spanned};

use crate::{
Expand All @@ -19,16 +21,15 @@ impl Clone for DeclId {
}
}

// NOTE: Hash and PartialEq must uphold the invariant:
// k1 == k2 -> hash(k1) == hash(k2)
// https://doc.rust-lang.org/std/collections/struct.HashMap.html
impl EqWithEngines for DeclId {}
impl PartialEqWithEngines for DeclId {
fn eq(&self, other: &Self, engines: Engines<'_>) -> bool {
let decl_engine = engines.de();
let left = decl_engine.get(self.clone());
let right = decl_engine.get(other.clone());
left.eq(&right, engines)
impl PartialEq for DeclId {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}

impl Hash for DeclId {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}

Expand Down
55 changes: 48 additions & 7 deletions sway-core/src/decl_engine/wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
use std::fmt;
use std::{fmt, hash::Hasher};

use sway_error::error::CompileError;
use sway_types::{Span, Spanned};

use crate::{
engine_threading::*,
language::ty,
type_system::{SubstTypes, TypeSubstMap},
ReplaceSelfType, TypeId,
};
use crate::{engine_threading::*, language::ty, type_system::*};

use super::{DeclMapping, ReplaceDecls, ReplaceFunctionImplementingType};

Expand Down Expand Up @@ -56,6 +51,52 @@ impl PartialEqWithEngines for DeclWrapper {
}
}

impl HashWithEngines for DeclWrapper {
fn hash<H: Hasher>(&self, state: &mut H, type_engine: &TypeEngine) {
match self {
DeclWrapper::Unknown => {
state.write_u8(1);
}
DeclWrapper::Function(decl) => {
state.write_u8(2);
decl.hash(state, type_engine);
}
DeclWrapper::Trait(decl) => {
state.write_u8(3);
decl.hash(state, type_engine);
}
DeclWrapper::TraitFn(decl) => {
state.write_u8(4);
decl.hash(state, type_engine);
}
DeclWrapper::ImplTrait(decl) => {
state.write_u8(5);
decl.hash(state, type_engine);
}
DeclWrapper::Struct(decl) => {
state.write_u8(6);
decl.hash(state, type_engine);
}
DeclWrapper::Storage(decl) => {
state.write_u8(7);
decl.hash(state, type_engine);
}
DeclWrapper::Abi(decl) => {
state.write_u8(8);
decl.hash(state, type_engine);
}
DeclWrapper::Constant(decl) => {
state.write_u8(9);
decl.hash(state, type_engine);
}
DeclWrapper::Enum(decl) => {
state.write_u8(10);
decl.hash(state, type_engine);
}
}
}
}

impl fmt::Display for DeclWrapper {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "decl({})", self.friendly_name())
Expand Down
36 changes: 35 additions & 1 deletion sway-core/src/language/ty/ast_node.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::fmt::{self, Debug};
use std::{
fmt::{self, Debug},
hash::Hasher,
};

use sway_types::{Ident, Span};

Expand All @@ -22,13 +25,22 @@ pub struct TyAstNode {
pub(crate) span: Span,
}

// NOTE: Hash and PartialEq must uphold the invariant:
// k1 == k2 -> hash(k1) == hash(k2)
// https://doc.rust-lang.org/std/collections/struct.HashMap.html
impl EqWithEngines for TyAstNode {}
impl PartialEqWithEngines for TyAstNode {
fn eq(&self, other: &Self, engines: Engines<'_>) -> bool {
self.content.eq(&other.content, engines)
}
}

impl HashWithEngines for TyAstNode {
fn hash<H: Hasher>(&self, state: &mut H, type_engine: &TypeEngine) {
self.content.hash(state, type_engine);
}
}

impl DisplayWithEngines for TyAstNode {
fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: Engines<'_>) -> fmt::Result {
use TyAstNodeContent::*;
Expand Down Expand Up @@ -247,6 +259,28 @@ impl PartialEqWithEngines for TyAstNodeContent {
}
}

impl HashWithEngines for TyAstNodeContent {
fn hash<H: Hasher>(&self, state: &mut H, type_engine: &TypeEngine) {
match self {
TyAstNodeContent::Declaration(decl) => {
state.write_u8(1);
decl.hash(state, type_engine);
}
TyAstNodeContent::Expression(exp) => {
state.write_u8(2);
exp.hash(state, type_engine);
}
TyAstNodeContent::ImplicitReturnExpression(exp) => {
state.write_u8(3);
exp.hash(state, type_engine);
}
TyAstNodeContent::SideEffect => {
state.write_u8(4);
}
}
}
}

impl CollectTypesMetadata for TyAstNodeContent {
fn collect_types_metadata(
&self,
Expand Down
11 changes: 11 additions & 0 deletions sway-core/src/language/ty/code_block.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::hash::Hasher;

use crate::{
decl_engine::*, engine_threading::*, language::ty::*, type_system::*,
types::DeterministicallyAborts,
Expand All @@ -8,13 +10,22 @@ pub struct TyCodeBlock {
pub contents: Vec<TyAstNode>,
}

// NOTE: Hash and PartialEq must uphold the invariant:
// k1 == k2 -> hash(k1) == hash(k2)
// https://doc.rust-lang.org/std/collections/struct.HashMap.html
impl EqWithEngines for TyCodeBlock {}
impl PartialEqWithEngines for TyCodeBlock {
fn eq(&self, other: &Self, engines: Engines<'_>) -> bool {
self.contents.eq(&other.contents, engines)
}
}

impl HashWithEngines for TyCodeBlock {
fn hash<H: Hasher>(&self, state: &mut H, type_engine: &TypeEngine) {
self.contents.hash(state, type_engine);
}
}

impl SubstTypes for TyCodeBlock {
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: Engines<'_>) {
self.contents
Expand Down
4 changes: 2 additions & 2 deletions sway-core/src/language/ty/declaration/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ impl EqWithEngines for TyAbiDeclaration {}
impl PartialEqWithEngines for TyAbiDeclaration {
fn eq(&self, other: &Self, engines: Engines<'_>) -> bool {
self.name == other.name
&& self.interface_surface.eq(&other.interface_surface, engines)
&& self.methods.eq(&other.methods, engines)
&& self.interface_surface == other.interface_surface
&& self.methods == other.methods
// span ignored
&& self.attributes == other.attributes
}
Expand Down
75 changes: 66 additions & 9 deletions sway-core/src/language/ty/declaration/declaration.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::fmt;
use std::{
fmt,
hash::{Hash, Hasher},
};

use sway_error::error::CompileError;
use sway_types::{Ident, Span, Spanned};
Expand Down Expand Up @@ -28,19 +31,22 @@ pub enum TyDeclaration {
StorageDeclaration(DeclId),
}

// NOTE: Hash and PartialEq must uphold the invariant:
// k1 == k2 -> hash(k1) == hash(k2)
// https://doc.rust-lang.org/std/collections/struct.HashMap.html
impl EqWithEngines for TyDeclaration {}
impl PartialEqWithEngines for TyDeclaration {
fn eq(&self, other: &Self, engines: Engines<'_>) -> bool {
match (self, other) {
(Self::VariableDeclaration(x), Self::VariableDeclaration(y)) => x.eq(y, engines),
(Self::ConstantDeclaration(x), Self::ConstantDeclaration(y)) => x.eq(y, engines),
(Self::FunctionDeclaration(x), Self::FunctionDeclaration(y)) => x.eq(y, engines),
(Self::TraitDeclaration(x), Self::TraitDeclaration(y)) => x.eq(y, engines),
(Self::StructDeclaration(x), Self::StructDeclaration(y)) => x.eq(y, engines),
(Self::EnumDeclaration(x), Self::EnumDeclaration(y)) => x.eq(y, engines),
(Self::ImplTrait(x), Self::ImplTrait(y)) => x.eq(y, engines),
(Self::AbiDeclaration(x), Self::AbiDeclaration(y)) => x.eq(y, engines),
(Self::StorageDeclaration(x), Self::StorageDeclaration(y)) => x.eq(y, engines),
(Self::ConstantDeclaration(x), Self::ConstantDeclaration(y)) => x == y,
(Self::FunctionDeclaration(x), Self::FunctionDeclaration(y)) => x == y,
(Self::TraitDeclaration(x), Self::TraitDeclaration(y)) => x == y,
(Self::StructDeclaration(x), Self::StructDeclaration(y)) => x == y,
(Self::EnumDeclaration(x), Self::EnumDeclaration(y)) => x == y,
(Self::ImplTrait(x), Self::ImplTrait(y)) => x == y,
(Self::AbiDeclaration(x), Self::AbiDeclaration(y)) => x == y,
(Self::StorageDeclaration(x), Self::StorageDeclaration(y)) => x == y,
(
Self::GenericTypeForFunctionScope {
name: xn,
Expand All @@ -57,6 +63,57 @@ impl PartialEqWithEngines for TyDeclaration {
}
}

impl HashWithEngines for TyDeclaration {
fn hash<H: Hasher>(&self, state: &mut H, type_engine: &TypeEngine) {
match self {
TyDeclaration::VariableDeclaration(decl) => {
state.write_u8(1);
decl.hash(state, type_engine);
}
TyDeclaration::ConstantDeclaration(decl_id) => {
state.write_u8(2);
decl_id.hash(state);
}
TyDeclaration::FunctionDeclaration(decl_id) => {
state.write_u8(3);
decl_id.hash(state);
}
TyDeclaration::TraitDeclaration(decl_id) => {
state.write_u8(4);
decl_id.hash(state);
}
TyDeclaration::StructDeclaration(decl_id) => {
state.write_u8(5);
decl_id.hash(state);
}
TyDeclaration::EnumDeclaration(decl_id) => {
state.write_u8(6);
decl_id.hash(state);
}
TyDeclaration::ImplTrait(decl_id) => {
state.write_u8(7);
decl_id.hash(state);
}
TyDeclaration::AbiDeclaration(decl_id) => {
state.write_u8(8);
decl_id.hash(state);
}
TyDeclaration::GenericTypeForFunctionScope { name, type_id } => {
state.write_u8(9);
name.hash(state);
type_engine.get(*type_id).hash(state, type_engine);
}
TyDeclaration::ErrorRecovery(_) => {
state.write_u8(10);
}
TyDeclaration::StorageDeclaration(decl_id) => {
state.write_u8(11);
decl_id.hash(state);
}
}
}
}

impl SubstTypes for TyDeclaration {
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: Engines<'_>) {
use TyDeclaration::*;
Expand Down
26 changes: 26 additions & 0 deletions sway-core/src/language/ty/declaration/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ impl PartialEqWithEngines for TyEnumDeclaration {
}
}

impl HashWithEngines for TyEnumDeclaration {
fn hash<H: Hasher>(&self, state: &mut H, type_engine: &TypeEngine) {
self.name.hash(state);
self.variants.hash(state, type_engine);
self.type_parameters.hash(state, type_engine);
self.visibility.hash(state);
}
}

impl SubstTypes for TyEnumDeclaration {
fn subst_inner(&mut self, type_mapping: &TypeSubstMap, engines: Engines<'_>) {
self.variants
Expand All @@ -39,6 +48,17 @@ impl SubstTypes for TyEnumDeclaration {
}
}

impl SubstTypes2 for TyEnumDeclaration {
fn subst_inner2(&mut self, engines: Engines<'_>, subst_list: &TypeSubstList) {
self.variants
.iter_mut()
.for_each(|x| x.subst2(engines, subst_list));
self.type_parameters
.iter_mut()
.for_each(|x| x.subst2(engines, subst_list));
}
}

impl ReplaceSelfType for TyEnumDeclaration {
fn replace_self_type(&mut self, engines: Engines<'_>, self_type: TypeId) {
self.variants
Expand Down Expand Up @@ -149,6 +169,12 @@ impl SubstTypes for TyEnumVariant {
}
}

impl SubstTypes2 for TyEnumVariant {
fn subst_inner2(&mut self, engines: Engines<'_>, subst_list: &TypeSubstList) {
self.type_id.subst2(engines, subst_list);
}
}

impl ReplaceSelfType for TyEnumVariant {
fn replace_self_type(&mut self, engines: Engines<'_>, self_type: TypeId) {
self.type_id.replace_self_type(engines, self_type);
Expand Down
Loading

0 comments on commit 465e696

Please sign in to comment.