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

Implement DelineatedPathExpression AST resolution #6309

Draft
wants to merge 3 commits 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
24 changes: 23 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@
"name": "Attach to forc-lsp",
"pid": "${command:pickProcess}",
"program": "${env:HOME}/.cargo/bin/forc-lsp"
}
},
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'forc'",
"cargo": {
"args": [
"build",
"--bin=forc",
"--package=forc"
],
"filter": {
"name": "forc",
"kind": "bin"
}
},
"args": [
"build",
"--path",
"const_rec"
],
"cwd": "${workspaceFolder}"
},
]
}
8 changes: 8 additions & 0 deletions sway-core/src/abi_generation/abi_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ impl TypeInfo {
Numeric => "u64".into(), // u64 is the default
Contract => "contract".into(),
ErrorRecovery(_) => "unknown due to error".into(),
UntypedEnum(decl_id) => {
let decl = engines.pe().get_enum(decl_id);
format!("untyped enum {}", decl.name)
}
UntypedStruct(decl_id) => {
let decl = engines.pe().get_struct(decl_id);
format!("untyped struct {}", decl.name)
}
Enum(decl_ref) => {
let decl = decl_engine.get_enum(decl_ref);
let type_params = if (ctx.abi_root_type_without_generic_type_parameters && is_root)
Expand Down
8 changes: 8 additions & 0 deletions sway-core/src/abi_generation/evm_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ pub fn abi_str(type_info: &TypeInfo, engines: &Engines) -> String {
Numeric => "u64".into(), // u64 is the default
Contract => "contract".into(),
ErrorRecovery(_) => "unknown due to error".into(),
UntypedEnum(decl_id) => {
let decl = engines.pe().get_enum(decl_id);
format!("untyped enum {}", decl.name)
}
UntypedStruct(decl_id) => {
let decl = engines.pe().get_struct(decl_id);
format!("untyped struct {}", decl.name)
}
Enum(decl_ref) => {
let decl = decl_engine.get_enum(decl_ref);
format!("enum {}", decl.call_path.suffix)
Expand Down
1 change: 1 addition & 0 deletions sway-core/src/decl_engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub use engine::*;
pub(crate) use id::*;
pub use interface_decl_id::*;
pub(crate) use mapping::*;
pub use parsed_engine::*;
pub use r#ref::*;
pub(crate) use replace_decls::*;
use sway_types::Ident;
Expand Down
22 changes: 20 additions & 2 deletions sway-core/src/decl_engine/parsed_engine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{
concurrent_slab::ConcurrentSlab,
decl_engine::*,
language::parsed::{
AbiDeclaration, ConfigurableDeclaration, ConstantDeclaration, EnumDeclaration, EnumVariant,
FunctionDeclaration, ImplSelfOrTrait, StorageDeclaration, StructDeclaration,
Expand Down Expand Up @@ -47,7 +46,7 @@ pub trait ParsedDeclEngineReplace<T> {

#[allow(unused)]
pub trait ParsedDeclEngineIndex<T>:
ParsedDeclEngineGet<DeclId<T>, T> + ParsedDeclEngineInsert<T> + ParsedDeclEngineReplace<T>
ParsedDeclEngineGet<ParsedDeclId<T>, T> + ParsedDeclEngineInsert<T> + ParsedDeclEngineReplace<T>
{
}

Expand Down Expand Up @@ -136,6 +135,25 @@ macro_rules! decl_engine_clear {
};
}

macro_rules! decl_engine_index {
($slab:ident, $decl:ty) => {
impl ParsedDeclEngineIndex<$decl> for ParsedDeclEngine {}
};
}
decl_engine_index!(variable_slab, VariableDeclaration);
decl_engine_index!(function_slab, FunctionDeclaration);
decl_engine_index!(trait_slab, TraitDeclaration);
decl_engine_index!(trait_fn_slab, TraitFn);
decl_engine_index!(trait_type_slab, TraitTypeDeclaration);
decl_engine_index!(impl_self_or_trait_slab, ImplSelfOrTrait);
decl_engine_index!(struct_slab, StructDeclaration);
decl_engine_index!(storage_slab, StorageDeclaration);
decl_engine_index!(abi_slab, AbiDeclaration);
decl_engine_index!(configurable_slab, ConfigurableDeclaration);
decl_engine_index!(constant_slab, ConstantDeclaration);
decl_engine_index!(enum_slab, EnumDeclaration);
decl_engine_index!(type_alias_slab, TypeAliasDeclaration);

decl_engine_clear!(
variable_slab, VariableDeclaration;
function_slab, FunctionDeclaration;
Expand Down
21 changes: 20 additions & 1 deletion sway-core/src/decl_engine/parsed_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ use std::hash::{DefaultHasher, Hasher};
use std::marker::PhantomData;
use std::{fmt, hash::Hash};

use crate::engine_threading::{EqWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext};
use sway_types::{Named, Spanned};

use crate::engine_threading::{
EqWithEngines, HashWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext,
};
use crate::Engines;

use super::parsed_engine::{ParsedDeclEngine, ParsedDeclEngineGet, ParsedDeclEngineIndex};
use super::DeclUniqueId;

pub type ParsedDeclIdIndexType = usize;
Expand Down Expand Up @@ -61,6 +67,19 @@ impl<T> Hash for ParsedDeclId<T> {
}
}

impl<T> HashWithEngines for ParsedDeclId<T>
where
ParsedDeclEngine: ParsedDeclEngineIndex<T>,
T: Named + Spanned + HashWithEngines,
{
fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
let decl_engine = engines.pe();
let decl = decl_engine.get(self);
decl.name().hash(state);
decl.hash(state, engines);
}
}

impl<T> PartialOrd for ParsedDeclId<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/decl_engine/ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ where
let decl_engine = ctx.engines.de();
if ctx
.type_subst_map
.source_ids_contains_concrete_type(ctx.engines)
.is_some_and(|tsm| tsm.source_ids_contains_concrete_type(ctx.engines))
|| !decl_engine.get(&self.id).is_concrete(ctx.engines)
{
let mut decl = (*decl_engine.get(&self.id)).clone();
Expand Down
2 changes: 2 additions & 0 deletions sway-core/src/ir_generation/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ fn convert_resolved_type_info(
TypeInfo::Custom { .. } => reject_type!("Custom"),
TypeInfo::Contract => reject_type!("Contract"),
TypeInfo::ContractCaller { .. } => reject_type!("ContractCaller"),
TypeInfo::UntypedEnum(_) => reject_type!("UntypedEnum"),
TypeInfo::UntypedStruct(_) => reject_type!("UntypedStruct"),
TypeInfo::Unknown => reject_type!("Unknown"),
TypeInfo::UnknownGeneric { .. } => reject_type!("Generic"),
TypeInfo::Placeholder(_) => reject_type!("Placeholder"),
Expand Down
30 changes: 29 additions & 1 deletion sway-core/src/language/parsed/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl Declaration {
}
}

pub(crate) fn to_fn_ref(
pub(crate) fn to_fn_decl(
&self,
handler: &Handler,
engines: &Engines,
Expand Down Expand Up @@ -166,6 +166,34 @@ impl Declaration {
}
}

pub(crate) fn to_enum_decl(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<ParsedDeclId<EnumDeclaration>, ErrorEmitted> {
match self {
Declaration::EnumDeclaration(decl_id) => Ok(*decl_id),
decl => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
actually: decl.friendly_type_name().to_string(),
span: decl.span(engines),
})),
}
}

pub(crate) fn to_const_decl(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<ParsedDeclId<ConstantDeclaration>, ErrorEmitted> {
match self {
Declaration::ConstantDeclaration(decl_id) => Ok(*decl_id),
decl => Err(handler.emit_err(CompileError::DeclIsNotAConstant {
actually: decl.friendly_type_name().to_string(),
span: decl.span(engines),
})),
}
}

#[allow(unused)]
pub(crate) fn visibility(&self, decl_engine: &ParsedDeclEngine) -> Visibility {
match self {
Expand Down
4 changes: 4 additions & 0 deletions sway-core/src/language/parsed/declaration/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use crate::{
};
use sway_types::{ident::Ident, span::Span, Named, Spanned};

use super::ImplSelfOrTrait;

#[derive(Debug, Clone)]
pub struct StructDeclaration {
pub name: Ident,
Expand All @@ -15,6 +17,8 @@ pub struct StructDeclaration {
pub type_parameters: Vec<TypeParameter>,
pub visibility: Visibility,
pub(crate) span: Span,
// the impl blocks implementing this struct
pub impls: Vec<ImplSelfOrTrait>,
}

impl EqWithEngines for StructDeclaration {}
Expand Down
4 changes: 3 additions & 1 deletion sway-core/src/language/parsed/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub use method_name::MethodName;
pub use scrutinee::*;
use sway_ast::intrinsics::Intrinsic;

use super::{FunctionDeclaration, StructDeclaration};
use super::{Declaration, FunctionDeclaration, StructDeclaration};

/// Represents a parsed, but not yet type checked, [Expression](https://en.wikipedia.org/wiki/Expression_(computer_science)).
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -295,6 +295,8 @@ impl PartialEqWithEngines for AmbiguousPathExpression {
#[derive(Debug, Clone)]
pub struct DelineatedPathExpression {
pub call_path_binding: TypeBinding<QualifiedCallPath>,
pub resolved_call_path_binding: Option<TypeBinding<ResolvedCallPath<Declaration>>>,

/// When args is equal to Option::None then it means that the
/// [DelineatedPathExpression] was initialized from an expression
/// that does not end with parenthesis.
Expand Down
15 changes: 11 additions & 4 deletions sway-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub use debug_generation::write_dwarf;
use indexmap::IndexMap;
use metadata::MetadataManager;
use query_engine::{ModuleCacheKey, ModuleCommonInfo, ParsedModuleInfo, ProgramsCacheEntry};
use semantic_analysis::symbol_resolve::ResolveSymbols;
use semantic_analysis::symbol_resolve_context::SymbolResolveContext;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -568,18 +570,23 @@ pub fn parsed_to_ast(
// Build the dependency graph for the submodules.
build_module_dep_graph(handler, &mut parse_program.root)?;

let namespace = Namespace::init_root(initial_namespace);
let initial_namespace = Namespace::init_root(initial_namespace);
// Collect the program symbols.
let mut collection_ctx =
ty::TyProgram::collect(handler, engines, parse_program, namespace.clone())?;
let namespace = initial_namespace.clone();
let mut collection_ctx = ty::TyProgram::collect(handler, engines, parse_program, namespace)?;

println!("namespace {:#?}", collection_ctx.namespace);

let resolve_ctx = SymbolResolveContext::new(engines, &mut collection_ctx);
parse_program.resolve_symbols(handler, resolve_ctx);

// Type check the program.
let typed_program_opt = ty::TyProgram::type_check(
handler,
engines,
parse_program,
&mut collection_ctx,
namespace,
initial_namespace,
package_name,
build_config,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ use crate::{
},
namespace::{IsExtendingExistingImpl, IsImplSelf, TryInsertingTraitImplOnFailure},
semantic_analysis::{
symbol_collection_context::SymbolCollectionContext, AbiMode, ConstShadowingMode,
TyNodeDepGraphNodeId, TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext,
TypeCheckFinalization, TypeCheckFinalizationContext,
symbol_collection_context::SymbolCollectionContext, type_resolve::resolve_type, AbiMode,
ConstShadowingMode, TyNodeDepGraphNodeId, TypeCheckAnalysis, TypeCheckAnalysisContext,
TypeCheckContext, TypeCheckFinalization, TypeCheckFinalizationContext,
},
type_system::*,
};
Expand All @@ -37,15 +37,22 @@ impl TyImplSelfOrTrait {
ctx: &mut SymbolCollectionContext,
decl_id: &ParsedDeclId<ImplSelfOrTrait>,
) -> Result<(), ErrorEmitted> {
let impl_trait = engines.pe().get_impl_self_or_trait(decl_id);
ctx.insert_parsed_symbol(
handler,
engines,
impl_trait.trait_name.suffix.clone(),
Declaration::ImplSelfOrTrait(*decl_id),
)?;
let mut impl_trait = engines
.pe()
.get_impl_self_or_trait(decl_id)
.as_ref()
.clone();

if !impl_trait.is_self {
ctx.insert_parsed_symbol(
handler,
engines,
impl_trait.trait_name.suffix.clone(),
Declaration::ImplSelfOrTrait(*decl_id),
)?;
}

let _ = ctx.scoped(engines, impl_trait.block_span.clone(), |scoped_ctx| {
let (_ret, _scope) = ctx.scoped(engines, impl_trait.block_span.clone(), |scoped_ctx| {
impl_trait.items.iter().for_each(|item| match item {
ImplItem::Fn(decl_id) => {
let _ = TyFunctionDecl::collect(handler, engines, scoped_ctx, decl_id);
Expand All @@ -59,6 +66,32 @@ impl TyImplSelfOrTrait {
});
Ok(())
});

// println!(
// "impl type id {:?}",
// engines.help_out(impl_trait.implementing_for.type_id)
// );

impl_trait.implementing_for.type_id = resolve_type(
handler,
engines,
&ctx.namespace,
ctx.namespace.mod_path(),
impl_trait.implementing_for.type_id,
&impl_trait.implementing_for.span,
EnforceTypeArguments::Yes,
None,
None,
&SubstTypesContext::dummy(engines),
)?;

// println!(
// "after impl type id resolve {:?}",
// engines.help_out(impl_trait.implementing_for.type_id)
// );

engines.pe().replace(*decl_id, impl_trait);

Ok(())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ impl ty::TyExpression {
ExpressionKind::DelineatedPath(delineated_path_expression) => {
let DelineatedPathExpression {
call_path_binding,
resolved_call_path_binding: _,
args,
} = *delineated_path_expression.clone();
Self::type_check_delineated_path(
Expand Down
Loading
Loading