-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e7a226d
commit 2e17cca
Showing
13 changed files
with
635 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
use crate::{language::ty, monomorphize::priv_prelude::*}; | ||
|
||
pub(crate) fn gather_from_code_block(ctx: GatherContext, body: &ty::TyCodeBlock) { | ||
body.contents | ||
.iter() | ||
.for_each(|node| gather_from_node(ctx, &node.content)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
use crate::{monomorphize::priv_prelude::*, language::ty::*}; | ||
|
||
pub(crate) trait CollectFrom { | ||
fn collect_from(&self, ctx: CollectContext); | ||
} | ||
|
||
impl CollectFrom for TyModule { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
for (_, submod) in self.submodules_recursive() { | ||
submod.module.collect_from(ctx); | ||
} | ||
for node in self.all_nodes.iter() { | ||
node.content.collect_from(ctx); | ||
} | ||
} | ||
} | ||
|
||
impl CollectFrom for TyAstNodeContent { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
use TyAstNodeContent::*; | ||
match self { | ||
Declaration(decl) => { | ||
decl.collect_from(ctx); | ||
} | ||
Expression(exp) => { | ||
exp.collect_from(ctx); | ||
} | ||
ImplicitReturnExpression(exp) => { | ||
exp.collect_from(ctx); | ||
} | ||
SideEffect(_) => {} | ||
} | ||
} | ||
} | ||
|
||
impl CollectFrom for TyDecl { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
use TyDecl::*; | ||
match self { | ||
VariableDecl(decl) => { | ||
decl.body.collect_from(ctx); | ||
} | ||
ConstantDecl { .. } => todo!(), | ||
FunctionDecl { | ||
decl_id, | ||
subst_list, | ||
.. | ||
} => { | ||
gather_from_fn_decl(ctx, decl_id, subst_list.inner()); | ||
} | ||
TraitDecl { | ||
name: _, | ||
decl_id, | ||
subst_list, | ||
decl_span: _, | ||
} => { | ||
gather_from_trait_decl(ctx, decl_id, subst_list.inner()); | ||
} | ||
StructDecl { | ||
name: _, | ||
decl_id, | ||
subst_list, | ||
decl_span: _, | ||
} => { | ||
gather_from_struct_decl(ctx, decl_id, subst_list.inner()); | ||
} | ||
EnumDecl { | ||
name: _, | ||
decl_id, | ||
subst_list, | ||
decl_span: _, | ||
} => { | ||
gather_from_enum_decl(ctx, decl_id, subst_list.inner()); | ||
} | ||
EnumVariantDecl { .. } => todo!(), | ||
ImplTrait { .. } => todo!(), | ||
AbiDecl { .. } => todo!(), | ||
GenericTypeForFunctionScope { .. } => todo!(), | ||
StorageDecl { .. } => todo!(), | ||
ErrorRecovery(_) => {} | ||
TypeAliasDecl { .. } => todo!(), | ||
} | ||
} | ||
} | ||
|
||
impl CollectFrom for TyFunctionDecl { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
ctx.add_constraint(Constraint::mk_fn_decl(decl_id, subst_list)); | ||
let fn_decl = ctx.decl_engine.get_function(decl_id); | ||
for param in fn_decl.parameters { | ||
gather_from_ty(ctx, param.type_argument.type_id); | ||
} | ||
gather_from_ty(ctx, fn_decl.return_type.type_id); | ||
gather_from_code_block(ctx, &fn_decl.body); | ||
} | ||
} | ||
|
||
impl CollectFrom for TyStructDecl { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
ctx.add_constraint(Constraint::mk_struct_decl(decl_id, subst_list)); | ||
let struct_decl = ctx.decl_engine.get_struct(decl_id); | ||
for field in struct_decl.fields { | ||
gather_from_ty(ctx, field.type_argument.type_id); | ||
} | ||
} | ||
} | ||
|
||
impl CollectFrom for TyEnumDecl { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
ctx.add_constraint(Constraint::mk_enum_decl(decl_id, subst_list)); | ||
let enum_decl = ctx.decl_engine.get_enum(decl_id); | ||
for variant in enum_decl.variants { | ||
gather_from_ty(ctx, variant.type_argument.type_id); | ||
} | ||
} | ||
} | ||
|
||
impl CollectFrom for TyTraitDecl { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
ctx.add_constraint(Constraint::mk_trait_decl(decl_id, subst_list)); | ||
let trait_decl = ctx.decl_engine.get_trait(decl_id); | ||
todo!(); | ||
} | ||
} | ||
|
||
impl CollectFrom for TyExpression { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
gather_from_ty(ctx, return_type); | ||
self.expression.collect_from(ctx); | ||
} | ||
} | ||
|
||
impl CollectFrom for TyExpressionVariant { | ||
fn collect_from(&self, ctx: CollectContext) { | ||
use TyExpressionVariant::*; | ||
match exp { | ||
FunctionApplication { | ||
arguments, | ||
contract_call_params, | ||
call_path, | ||
fn_ref, | ||
.. | ||
} => { | ||
arguments | ||
.iter() | ||
.for_each(|(_, arg)| { | ||
arg.collect_from(ctx); | ||
}); | ||
contract_call_params | ||
.iter() | ||
.for_each(|(_, arg)| { | ||
arg.collect_from(ctx); | ||
}); | ||
ctx.add_constraint(Constraint::mk_fn_call(call_path, arguments, fn_ref)); | ||
} | ||
LazyOperator { lhs, rhs, .. } => { | ||
lhs.collect_from(ctx); | ||
rhs.collect_from(ctx); | ||
} | ||
VariableExpression { .. } => { | ||
// NOTE: may need to do something here later | ||
} | ||
Tuple { fields } => { | ||
fields.iter().for_each(|field| { | ||
field.collect_from(ctx); | ||
}); | ||
} | ||
Array { | ||
contents: _, | ||
elem_type: _, | ||
} => { | ||
todo!(); | ||
// contents | ||
// .iter() | ||
// .for_each(|elem| gather_from_exp(ctx, elem)); | ||
} | ||
ArrayIndex { | ||
prefix: _, | ||
index: _, | ||
} => { | ||
todo!(); | ||
// gather_from_exp(ctx, prefix); | ||
// gather_from_exp(ctx, index); | ||
} | ||
StructExpression { .. } => todo!(), | ||
CodeBlock(block) => { | ||
gather_from_code_block(ctx, block); | ||
} | ||
IfExp { .. } => todo!(), | ||
MatchExp { .. } => todo!(), | ||
AsmExpression { .. } => todo!(), | ||
StructFieldAccess { .. } => todo!(), | ||
TupleElemAccess { prefix, .. } => { | ||
prefix.collect_from(ctx); | ||
} | ||
EnumInstantiation { .. } => todo!(), | ||
AbiCast { .. } => todo!(), | ||
StorageAccess(_) => todo!(), | ||
IntrinsicFunction(_) => todo!(), | ||
AbiName(_) => todo!(), | ||
EnumTag { exp } => { | ||
exp.collect_from(ctx); | ||
} | ||
UnsafeDowncast { .. } => todo!(), | ||
WhileLoop { .. } => todo!(), | ||
Reassignment(_) => todo!(), | ||
StorageReassignment(_) => todo!(), | ||
Return(exp) => { | ||
exp.collect_from(ctx); | ||
} | ||
Literal(_) => {} | ||
Break => {} | ||
Continue => {} | ||
FunctionParameter => {} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
use hashbrown::{hash_map::RawEntryMut, HashMap}; | ||
use std::sync::RwLock; | ||
|
||
use crate::{decl_engine::*, engine_threading::*, monomorphize::priv_prelude::*, TypeEngine}; | ||
|
||
/// Contextual state tracked and accumulated throughout collecting information | ||
/// for monomorphization. | ||
#[derive(Clone, Copy)] | ||
pub(crate) struct CollectContext<'a> { | ||
/// The type engine storing types. | ||
pub(crate) type_engine: &'a TypeEngine, | ||
|
||
/// The declaration engine holds declarations. | ||
pub(crate) decl_engine: &'a DeclEngine, | ||
|
||
/// The list of constraints. | ||
/// NOTE: This only needs to be a [HashSet][hashbrown::HashSet], but there | ||
/// isn't the right method implement on that data type for what we need, so | ||
/// instead we use a dummy [HashMap][hashbrown::HashMap]. | ||
constraints: &'a RwLock<HashMap<Constraint, usize>>, | ||
} | ||
|
||
impl<'a> CollectContext<'a> { | ||
/// Initialize a context. | ||
pub(crate) fn new( | ||
engines: Engines<'a>, | ||
constraints: &'a RwLock<HashMap<Constraint, usize>>, | ||
) -> CollectContext<'a> { | ||
let (type_engine, decl_engine) = engines.unwrap(); | ||
Self { | ||
type_engine, | ||
decl_engine, | ||
constraints, | ||
} | ||
} | ||
|
||
pub(crate) fn add_constraint(&self, constraint: Constraint) { | ||
let engines = Engines::new(self.type_engine, self.decl_engine); | ||
let mut constraints = self.constraints.write().unwrap(); | ||
let hash_builder = constraints.hasher().clone(); | ||
let constraint_hash = make_hasher(&hash_builder, engines)(&constraint); | ||
let raw_entry = constraints | ||
.raw_entry_mut() | ||
.from_hash(constraint_hash, |x| x.eq(&constraint, engines)); | ||
if let RawEntryMut::Vacant(v) = raw_entry { | ||
v.insert_with_hasher( | ||
constraint_hash, | ||
constraint, | ||
0, | ||
make_hasher(&hash_builder, engines), | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
use crate::{decl_engine::DeclId, language::ty::*, monomorphize::priv_prelude::*, type_system::*}; | ||
|
||
pub(crate) fn gather_from_decl(ctx: GatherContext, decl: &TyDecl) { | ||
use TyDecl::*; | ||
match decl { | ||
VariableDecl(decl) => { | ||
gather_from_exp(ctx, &decl.body); | ||
} | ||
ConstantDecl { .. } => todo!(), | ||
FunctionDecl { | ||
decl_id, | ||
subst_list, | ||
.. | ||
} => { | ||
gather_from_fn_decl(ctx, decl_id, subst_list.inner()); | ||
} | ||
TraitDecl { | ||
name: _, | ||
decl_id, | ||
subst_list, | ||
decl_span: _, | ||
} => { | ||
gather_from_trait_decl(ctx, decl_id, subst_list.inner()); | ||
} | ||
StructDecl { | ||
name: _, | ||
decl_id, | ||
subst_list, | ||
decl_span: _, | ||
} => { | ||
gather_from_struct_decl(ctx, decl_id, subst_list.inner()); | ||
} | ||
EnumDecl { | ||
name: _, | ||
decl_id, | ||
subst_list, | ||
decl_span: _, | ||
} => { | ||
gather_from_enum_decl(ctx, decl_id, subst_list.inner()); | ||
} | ||
EnumVariantDecl { .. } => todo!(), | ||
ImplTrait { .. } => todo!(), | ||
AbiDecl { .. } => todo!(), | ||
GenericTypeForFunctionScope { .. } => todo!(), | ||
StorageDecl { .. } => todo!(), | ||
ErrorRecovery(_) => {} | ||
TypeAliasDecl { .. } => todo!(), | ||
} | ||
} | ||
|
||
fn gather_from_fn_decl( | ||
ctx: GatherContext, | ||
decl_id: &DeclId<TyFunctionDecl>, | ||
subst_list: &SubstList, | ||
) { | ||
ctx.add_constraint(Constraint::mk_fn_decl(decl_id, subst_list)); | ||
let fn_decl = ctx.decl_engine.get_function(decl_id); | ||
for param in fn_decl.parameters { | ||
gather_from_ty(ctx, param.type_argument.type_id); | ||
} | ||
gather_from_ty(ctx, fn_decl.return_type.type_id); | ||
gather_from_code_block(ctx, &fn_decl.body); | ||
} | ||
|
||
fn gather_from_trait_decl( | ||
ctx: GatherContext, | ||
decl_id: &DeclId<TyTraitDecl>, | ||
subst_list: &SubstList, | ||
) { | ||
ctx.add_constraint(Constraint::mk_trait_decl(decl_id, subst_list)); | ||
let trait_decl = ctx.decl_engine.get_trait(decl_id); | ||
todo!(); | ||
} | ||
|
||
fn gather_from_struct_decl( | ||
ctx: GatherContext, | ||
decl_id: &DeclId<TyStructDecl>, | ||
subst_list: &SubstList, | ||
) { | ||
ctx.add_constraint(Constraint::mk_struct_decl(decl_id, subst_list)); | ||
let struct_decl = ctx.decl_engine.get_struct(decl_id); | ||
for field in struct_decl.fields { | ||
gather_from_ty(ctx, field.type_argument.type_id); | ||
} | ||
} | ||
|
||
fn gather_from_enum_decl(ctx: GatherContext, decl_id: &DeclId<TyEnumDecl>, subst_list: &SubstList) { | ||
ctx.add_constraint(Constraint::mk_enum_decl(decl_id, subst_list)); | ||
let enum_decl = ctx.decl_engine.get_enum(decl_id); | ||
for variant in enum_decl.variants { | ||
gather_from_ty(ctx, variant.type_argument.type_id); | ||
} | ||
} |
Oops, something went wrong.