Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ast ordering graph #5711

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion sway-core/src/language/parsed/declaration/struct.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use crate::{language::Visibility, transform, type_system::TypeParameter, TypeArgument};
use std::fmt;

use crate::{
engine_threading::DebugWithEngines, language::Visibility, transform,
type_system::TypeParameter, Engines, TypeArgument,
};
use sway_types::{ident::Ident, span::Span};

#[derive(Debug, Clone)]
Expand All @@ -19,3 +24,9 @@ pub struct StructField {
pub(crate) span: Span,
pub type_argument: TypeArgument,
}

impl DebugWithEngines for StructDeclaration {
fn fmt(&self, f: &mut fmt::Formatter<'_>, _engines: &Engines) -> fmt::Result {
write!(f, "{}", self.name)
}
}
12 changes: 11 additions & 1 deletion sway-core/src/language/parsed/declaration/variable.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use crate::{language::parsed::Expression, Ident, TypeArgument};
use std::fmt;

use crate::{
engine_threading::DebugWithEngines, language::parsed::Expression, Engines, Ident, TypeArgument,
};

#[derive(Debug, Clone)]
pub struct VariableDeclaration {
Expand All @@ -7,3 +11,9 @@ pub struct VariableDeclaration {
pub body: Expression, // will be codeblock variant
pub is_mutable: bool,
}

impl DebugWithEngines for VariableDeclaration {
fn fmt(&self, f: &mut fmt::Formatter<'_>, _engines: &Engines) -> fmt::Result {
write!(f, "{}", self.name)
}
}
7 changes: 6 additions & 1 deletion sway-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub use debug_generation::write_dwarf;
use indexmap::IndexMap;
use metadata::MetadataManager;
use query_engine::{ModuleCacheKey, ModulePath, ProgramsCacheEntry};
use semantic_analysis::node_analysis::{NodeAnalysis, NodeAnalysisContext};
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -489,18 +490,22 @@ pub fn parsed_to_ast(
let module_eval_order = modules_dep_graph.compute_order(handler)?;

// Collect the program symbols.
let _collection_ctx = ty::TyProgram::collect(
let symbol_collection_ctx = ty::TyProgram::collect(
handler,
engines,
parse_program,
initial_namespace.clone(),
&module_eval_order,
)?;

let mut node_analysis_ctx = NodeAnalysisContext::new(engines, &symbol_collection_ctx);
let _ = parse_program.analyze(handler, &mut node_analysis_ctx);

// Type check the program.
let typed_program_opt = ty::TyProgram::type_check(
handler,
engines,
&symbol_collection_ctx,
parse_program,
initial_namespace,
package_name,
Expand Down
1 change: 1 addition & 0 deletions sway-core/src/semantic_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub(crate) mod coins_analysis;
pub mod collection_context;
mod module;
pub mod namespace;
pub mod node_analysis;
mod node_dependencies;
mod program;
mod type_check_analysis;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ impl TyDecl {
let impl_self = engines.pe().get_impl_self(&decl_id).as_ref().clone();
let span = impl_self.block_span.clone();
let impl_trait_decl =
match ty::TyImplTrait::type_check_impl_self(handler, ctx.by_ref(), impl_self) {
match ty::TyImplTrait::type_check_impl_self(handler, ctx.by_ref(), decl_id) {
Ok(val) => val,
Err(err) => return Ok(ty::TyDecl::ErrorRecovery(span, err)),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use sway_error::{
use sway_types::{Ident, Span, Spanned};

use crate::{
decl_engine::*,
decl_engine::{parsed_id::ParsedDeclId, *},
engine_threading::*,
language::{
parsed::*,
Expand All @@ -19,8 +19,9 @@ use crate::{
},
namespace::{IsExtendingExistingImpl, IsImplSelf, TryInsertingTraitImplOnFailure},
semantic_analysis::{
type_check_context::EnforceTypeArguments, AbiMode, ConstShadowingMode,
TyNodeDepGraphNodeId, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext,
node_analysis::{NodeAnalysis, NodeAnalysisContext, ParsedNodeDepGraphNodeId},
type_check_context::EnforceTypeArguments,
AbiMode, ConstShadowingMode, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext,
TypeCheckFinalization, TypeCheckFinalizationContext,
},
type_system::*,
Expand Down Expand Up @@ -277,19 +278,20 @@ impl TyImplTrait {
pub(crate) fn type_check_impl_self(
handler: &Handler,
ctx: TypeCheckContext,
impl_self: ImplSelf,
decl_id: ParsedDeclId<ImplSelf>,
) -> Result<ty::TyDecl, ErrorEmitted> {
let type_engine = ctx.engines.te();
let decl_engine = ctx.engines.de();
let engines = ctx.engines();

let impl_self = engines.pe().get_impl_self(&decl_id).as_ref().clone();
let ImplSelf {
impl_type_parameters,
mut implementing_for,
items,
block_span,
} = impl_self;

let type_engine = ctx.engines.te();
let decl_engine = ctx.engines.de();
let engines = ctx.engines();

// create the namespace for the impl
ctx.with_const_shadowing_mode(ConstShadowingMode::ItemStyle)
.allow_functions()
Expand Down Expand Up @@ -455,12 +457,29 @@ impl TyImplTrait {
IsExtendingExistingImpl::No,
)?;

let new_items = &impl_trait.items;

// First lets perform a node analysis pass.
// This returns a vector with ordered indexes to the items in the order that they
// should be processed.
let ordered_node_indices_opt = ty::TyImplTrait::node_analyze_impl_self_items(
handler,
ctx.by_ref(),
&decl_id,
)?;

// In case there was any issue processing the dependency graph, then lets just
// process them in the original order.
let ordered_node_indices: Vec<_> = match ordered_node_indices_opt {
Some(value) => value.iter().map(|n| n.index()).collect(),
None => (0..new_items.len()).collect(),
};

// Now lets do a partial type check of the body of the functions (while deferring full
// monomorphization of function applications). We will use this tree to perform type check
// analysis (mainly dependency analysis), and re-type check the items ordered by dependency.
let mut defer_ctx = ctx.by_ref().with_defer_monomorphization();

let new_items = &impl_trait.items;
for (item, new_item) in items.clone().into_iter().zip(new_items) {
match (item, new_item) {
(ImplItem::Fn(fn_decl_id), TyTraitItem::Fn(decl_ref)) => {
Expand Down Expand Up @@ -488,29 +507,6 @@ impl TyImplTrait {
}
}

let impl_trait_decl = decl_engine.insert(impl_trait.clone()).into();

// First lets perform an analysis pass.
// This returns a vector with ordered indexes to the items in the order that they
// should be processed.
let ordered_node_indices_opt =
if let TyDecl::ImplTrait(impl_trait) = &impl_trait_decl {
ty::TyImplTrait::type_check_analyze_impl_self_items(
handler,
ctx.by_ref(),
impl_trait,
)?
} else {
unreachable!();
};

// In case there was any issue processing the dependency graph, then lets just
// process them in the original order.
let ordered_node_indices: Vec<_> = match ordered_node_indices_opt {
Some(value) => value.iter().map(|n| n.index()).collect(),
None => (0..new_items.len()).collect(),
};

// Now lets type check the body of the functions (for real this time).
for idx in ordered_node_indices {
match (&items[idx], &new_items[idx]) {
Expand Down Expand Up @@ -575,18 +571,19 @@ impl TyImplTrait {
})
}

pub(crate) fn type_check_analyze_impl_self_items(
pub(crate) fn node_analyze_impl_self_items(
handler: &Handler,
ctx: TypeCheckContext,
impl_self: &ty::ImplTrait,
) -> Result<Option<Vec<TyNodeDepGraphNodeId>>, ErrorEmitted> {
impl_self: &ParsedDeclId<ImplSelf>,
) -> Result<Option<Vec<ParsedNodeDepGraphNodeId>>, ErrorEmitted> {
let engines = ctx.engines;
let symbol_collection_ctx = ctx.symbol_collection_ctx;
handler.scope(|handler| {
let mut analysis_ctx = TypeCheckAnalysisContext::new(engines);
let _ = impl_self.type_check_analyze(handler, &mut analysis_ctx);
let mut analysis_ctx = NodeAnalysisContext::new(engines, symbol_collection_ctx);
let _ = impl_self.analyze(handler, &mut analysis_ctx);

// Build a sub graph that just contains the items for this impl trait.
let impl_trait_node_index = analysis_ctx.nodes.get(&impl_self.decl_id.unique_id());
let impl_trait_node_index = analysis_ctx.nodes.get(&impl_self.unique_id());
let sub_graph = analysis_ctx.get_sub_graph(
*impl_trait_node_index.expect("expected a valid impl trait node id"),
);
Expand Down
1 change: 0 additions & 1 deletion sway-core/src/semantic_analysis/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ impl ty::TyModule {
})
.collect::<Result<Vec<_>, _>>();

// TODO: Ordering should be solved across all modules prior to the beginning of type-check.
let ordered_nodes = node_dependencies::order_ast_nodes_by_dependency(
handler,
ctx.engines(),
Expand Down
10 changes: 8 additions & 2 deletions sway-core/src/semantic_analysis/namespace/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
ty::{self, TyTraitItem},
CallPath, Visibility,
},
semantic_analysis::*,
semantic_analysis::{collection_context::SymbolCollectionContext, *},
transform::to_parsed_lang,
Ident, Namespace, TypeId, TypeInfo,
};
Expand Down Expand Up @@ -166,7 +166,13 @@ impl Module {
ns.root.module.name = ns_name;
ns.root.module.is_external = true;
ns.root.module.visibility = Visibility::Public;
let type_check_ctx = TypeCheckContext::from_namespace(&mut ns, engines, experimental);
let symbol_collection_ctx = SymbolCollectionContext::new(ns.clone());
let type_check_ctx = TypeCheckContext::from_namespace(
&mut ns,
engines,
&symbol_collection_ctx,
experimental,
);
let typed_node = ty::TyAstNode::type_check(handler, type_check_ctx, ast_node).unwrap();
// get the decl out of the typed node:
// we know as an invariant this must be a const decl, as we hardcoded a const decl in
Expand Down
Loading
Loading