From d79bb51bb1c031f9c0d6af4f73ba9775610383fd Mon Sep 17 00:00:00 2001 From: Emily Herbert <17410721+emilyaherbert@users.noreply.github.com> Date: Tue, 6 Sep 2022 03:47:42 -0500 Subject: [PATCH] Add traits to the `DeclarationEngine` (#2683) * Make the DE a lazy static as a semi-temporary bandaid. * more public methods. * update * Add Span to the DeclarationId type so that it can derive Spanned. * Add new macro to use with DE. * Add the CopyTypes trait to DeclarationId * fmt * Add traits to the DeclarationEngine. * Remove macro requirement. * Fix bad merge. Co-authored-by: Toby Hutton --- .../dead_code_analysis.rs | 139 ++++++++++-------- .../declaration_engine/declaration_engine.rs | 2 +- sway-core/src/declaration_engine/mod.rs | 2 +- sway-core/src/lib.rs | 16 +- sway-core/src/parse_tree/declaration/trait.rs | 8 +- .../semantic_analysis/ast_node/declaration.rs | 36 +++-- .../ast_node/declaration/impl_trait.rs | 9 +- .../ast_node/declaration/trait.rs | 20 ++- .../src/semantic_analysis/ast_node/mod.rs | 33 ++++- sway-core/src/semantic_analysis/module.rs | 59 ++++++-- .../src/semantic_analysis/namespace/module.rs | 31 ++-- sway-core/src/semantic_analysis/program.rs | 33 +++-- .../semantic_analysis/storage_only_types.rs | 3 +- sway-lsp/src/capabilities/hover.rs | 9 +- sway-lsp/src/core/traverse_typed_tree.rs | 5 +- 15 files changed, 274 insertions(+), 131 deletions(-) diff --git a/sway-core/src/control_flow_analysis/dead_code_analysis.rs b/sway-core/src/control_flow_analysis/dead_code_analysis.rs index 0a7ea0ef969..00090f849a7 100644 --- a/sway-core/src/control_flow_analysis/dead_code_analysis.rs +++ b/sway-core/src/control_flow_analysis/dead_code_analysis.rs @@ -1,6 +1,7 @@ use super::*; use crate::{ declaration_engine::declaration_engine::de_get_storage, + declaration_engine::declaration_engine::de_get_trait, parse_tree::{CallPath, Visibility}, semantic_analysis::{ ast_node::{ @@ -143,59 +144,67 @@ impl ControlFlowGraph { .unwrap(), ] } - TreeType::Contract | TreeType::Library { .. } => graph - .graph - .node_indices() - .filter(|i| match graph.graph[*i] { - ControlFlowGraphNode::OrganizationalDominator(_) => false, - ControlFlowGraphNode::ProgramNode(TypedAstNode { - content: - TypedAstNodeContent::Declaration(TypedDeclaration::FunctionDeclaration( - TypedFunctionDeclaration { - visibility: Visibility::Public, - .. - }, - )), - .. - }) => true, - ControlFlowGraphNode::ProgramNode(TypedAstNode { - content: - TypedAstNodeContent::Declaration(TypedDeclaration::TraitDeclaration( - TypedTraitDeclaration { - visibility: Visibility::Public, - .. - }, - )), - .. - }) => true, - ControlFlowGraphNode::ProgramNode(TypedAstNode { - content: - TypedAstNodeContent::Declaration(TypedDeclaration::StructDeclaration( - TypedStructDeclaration { - visibility: Visibility::Public, - .. - }, - )), - .. - }) => true, - ControlFlowGraphNode::ProgramNode(TypedAstNode { - content: - TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait { .. }), - .. - }) => true, - ControlFlowGraphNode::ProgramNode(TypedAstNode { - content: - TypedAstNodeContent::Declaration(TypedDeclaration::ConstantDeclaration( - TypedConstantDeclaration { - visibility: Visibility::Public, - .. - }, - )), - .. - }) => true, - _ => false, - }) - .collect(), + TreeType::Contract | TreeType::Library { .. } => { + let mut ret = vec![]; + for i in graph.graph.node_indices() { + let count_it = match &graph.graph[i] { + ControlFlowGraphNode::OrganizationalDominator(_) => false, + ControlFlowGraphNode::ProgramNode(TypedAstNode { + content: + TypedAstNodeContent::Declaration(TypedDeclaration::FunctionDeclaration( + TypedFunctionDeclaration { + visibility: Visibility::Public, + .. + }, + )), + .. + }) => true, + ControlFlowGraphNode::ProgramNode(TypedAstNode { + content: + TypedAstNodeContent::Declaration(TypedDeclaration::TraitDeclaration( + decl_id, + )), + .. + }) => { + let trait_decl = de_get_trait(decl_id.clone(), &decl_id.span())?; + match trait_decl.visibility { + Visibility::Private => true, + Visibility::Public => false, + } + } + ControlFlowGraphNode::ProgramNode(TypedAstNode { + content: + TypedAstNodeContent::Declaration(TypedDeclaration::StructDeclaration( + TypedStructDeclaration { + visibility: Visibility::Public, + .. + }, + )), + .. + }) => true, + ControlFlowGraphNode::ProgramNode(TypedAstNode { + content: + TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait { .. }), + .. + }) => true, + ControlFlowGraphNode::ProgramNode(TypedAstNode { + content: + TypedAstNodeContent::Declaration(TypedDeclaration::ConstantDeclaration( + TypedConstantDeclaration { + visibility: Visibility::Public, + .. + }, + )), + .. + }) => true, + _ => false, + }; + if count_it { + ret.push(i); + } + } + ret + } }; Ok(()) } @@ -351,8 +360,9 @@ fn connect_declaration( connect_typed_fn_decl(fn_decl, graph, entry_node, span, exit_node, tree_type)?; Ok(leaves.to_vec()) } - TraitDeclaration(trait_decl) => { - connect_trait_declaration(trait_decl, graph, entry_node); + TraitDeclaration(decl_id) => { + let trait_decl = de_get_trait(decl_id.clone(), &span)?; + connect_trait_declaration(&trait_decl, graph, entry_node); Ok(leaves.to_vec()) } AbiDeclaration(abi_decl) => { @@ -1257,15 +1267,18 @@ fn construct_dead_code_warning_from_node(node: &TypedAstNode) -> Option CompileWarning { - span: name.span(), - warning_content: Warning::DeadTrait, - }, + } => { + let span = match de_get_trait(decl_id.clone(), &decl_id.span()) { + Ok(TypedTraitDeclaration { name, .. }) => name.span(), + Err(_) => node.span.clone(), + }; + CompileWarning { + span, + warning_content: Warning::DeadTrait, + } + } TypedAstNode { content: TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait(TypedImplTrait { diff --git a/sway-core/src/declaration_engine/declaration_engine.rs b/sway-core/src/declaration_engine/declaration_engine.rs index 08c44d36587..6d316d48767 100644 --- a/sway-core/src/declaration_engine/declaration_engine.rs +++ b/sway-core/src/declaration_engine/declaration_engine.rs @@ -231,7 +231,7 @@ pub(crate) fn de_insert_trait(r#trait: TypedTraitDeclaration) -> DeclarationId { DECLARATION_ENGINE.de_insert_trait(r#trait) } -pub(crate) fn de_get_trait( +pub fn de_get_trait( index: DeclarationId, span: &Span, ) -> Result { diff --git a/sway-core/src/declaration_engine/mod.rs b/sway-core/src/declaration_engine/mod.rs index 878e3c8ff39..dfe4bbf29a2 100644 --- a/sway-core/src/declaration_engine/mod.rs +++ b/sway-core/src/declaration_engine/mod.rs @@ -17,4 +17,4 @@ pub(crate) mod declaration_engine; pub(crate) mod declaration_id; pub(crate) mod declaration_wrapper; -pub use declaration_engine::de_get_storage; +pub use declaration_engine::{de_get_storage, de_get_trait}; diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index be73db48ffe..b4a96b44c57 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -256,7 +256,21 @@ pub fn parsed_to_ast( }; // Collect information about the types used in this program - let types_metadata = typed_program.collect_types_metadata(); + let CompileResult { + value: types_metadata_result, + warnings: new_warnings, + errors: new_errors, + } = typed_program.collect_types_metadata(); + warnings.extend(new_warnings); + errors.extend(new_errors); + let types_metadata = match types_metadata_result { + Some(types_metadata) => types_metadata, + None => { + errors = dedup_unsorted(errors); + warnings = dedup_unsorted(warnings); + return CompileAstResult::Failure { errors, warnings }; + } + }; // Collect all the types of logged values. These are required when generating the JSON ABI. typed_program.logged_types.extend( diff --git a/sway-core/src/parse_tree/declaration/trait.rs b/sway-core/src/parse_tree/declaration/trait.rs index 4e414d5aed2..eb7bdc95494 100644 --- a/sway-core/src/parse_tree/declaration/trait.rs +++ b/sway-core/src/parse_tree/declaration/trait.rs @@ -6,7 +6,7 @@ use crate::{ type_system::TypeInfo, }; -use sway_types::{ident::Ident, span::Span}; +use sway_types::{ident::Ident, span::Span, Spanned}; #[derive(Debug, Clone)] pub struct TraitDeclaration { @@ -22,6 +22,12 @@ pub(crate) struct Supertrait { pub(crate) name: CallPath, } +impl Spanned for Supertrait { + fn span(&self) -> Span { + self.name.span() + } +} + #[derive(Debug, Clone, Eq, PartialEq)] pub struct TraitFn { pub name: Ident, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration.rs b/sway-core/src/semantic_analysis/ast_node/declaration.rs index 16b17e8a2d1..200a6a9af7e 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration.rs @@ -17,7 +17,10 @@ pub use storage::*; pub use variable::*; use crate::{ - declaration_engine::{declaration_engine::de_get_storage, declaration_id::DeclarationId}, + declaration_engine::{ + declaration_engine::{de_get_storage, de_get_trait}, + declaration_id::DeclarationId, + }, error::*, parse_tree::*, semantic_analysis::*, @@ -32,7 +35,7 @@ pub enum TypedDeclaration { VariableDeclaration(TypedVariableDeclaration), ConstantDeclaration(TypedConstantDeclaration), FunctionDeclaration(TypedFunctionDeclaration), - TraitDeclaration(TypedTraitDeclaration), + TraitDeclaration(DeclarationId), StructDeclaration(TypedStructDeclaration), EnumDeclaration(TypedEnumDeclaration), ImplTrait(TypedImplTrait), @@ -73,7 +76,7 @@ impl Spanned for TypedDeclaration { VariableDeclaration(TypedVariableDeclaration { name, .. }) => name.span(), ConstantDeclaration(TypedConstantDeclaration { name, .. }) => name.span(), FunctionDeclaration(TypedFunctionDeclaration { span, .. }) => span.clone(), - TraitDeclaration(TypedTraitDeclaration { name, .. }) => name.span(), + TraitDeclaration(decl_id) => decl_id.span(), StructDeclaration(TypedStructDeclaration { name, .. }) => name.span(), EnumDeclaration(TypedEnumDeclaration { span, .. }) => span.clone(), AbiDeclaration(TypedAbiDeclaration { span, .. }) => span.clone(), @@ -121,8 +124,12 @@ impl fmt::Display for TypedDeclaration { }) => { name.as_str().into() } - TypedDeclaration::TraitDeclaration(TypedTraitDeclaration { name, .. }) => - name.as_str().into(), + TypedDeclaration::TraitDeclaration(decl_id) => { + match de_get_trait(decl_id.clone(), &decl_id.span()) { + Ok(TypedTraitDeclaration { name, .. }) => name.as_str().into(), + Err(_) => "unknown trait".into(), + } + } TypedDeclaration::StructDeclaration(TypedStructDeclaration { name, .. }) => name.as_str().into(), TypedDeclaration::EnumDeclaration(TypedEnumDeclaration { name, .. }) => @@ -335,9 +342,20 @@ impl TypedDeclaration { ok(type_id, warnings, errors) } - pub(crate) fn visibility(&self) -> Visibility { + pub(crate) fn visibility(&self) -> CompileResult { use TypedDeclaration::*; - match self { + let mut warnings = vec![]; + let mut errors = vec![]; + let visibility = match self { + TraitDeclaration(decl_id) => { + let TypedTraitDeclaration { visibility, .. } = check!( + CompileResult::from(de_get_trait(decl_id.clone(), &decl_id.span())), + return err(warnings, errors), + warnings, + errors + ); + visibility + } GenericTypeForFunctionScope { .. } | ImplTrait { .. } | StorageDeclaration { .. } @@ -350,9 +368,9 @@ impl TypedDeclaration { EnumDeclaration(TypedEnumDeclaration { visibility, .. }) | ConstantDeclaration(TypedConstantDeclaration { visibility, .. }) | FunctionDeclaration(TypedFunctionDeclaration { visibility, .. }) - | TraitDeclaration(TypedTraitDeclaration { visibility, .. }) | StructDeclaration(TypedStructDeclaration { visibility, .. }) => *visibility, - } + }; + ok(visibility, warnings, errors) } } diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index 02de3b395e5..9a0814128ce 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet}; use sway_types::{Ident, Span, Spanned}; use crate::{ + declaration_engine::declaration_engine::de_get_trait, error::{err, ok}, semantic_analysis::{ Mode, TypeCheckContext, TypedAstNodeContent, TypedExpression, TypedExpressionVariant, @@ -102,7 +103,13 @@ impl TypedImplTrait { .ok(&mut warnings, &mut errors) .cloned() { - Some(TypedDeclaration::TraitDeclaration(tr)) => { + Some(TypedDeclaration::TraitDeclaration(decl_id)) => { + let tr = check!( + CompileResult::from(de_get_trait(decl_id, &trait_name.span())), + return err(warnings, errors), + warnings, + errors + ); let functions_buf = check!( type_check_trait_implementation( ctx, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs index 56b29e65183..9e919bd243d 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs @@ -2,6 +2,7 @@ use derivative::Derivative; use sway_types::{Ident, Spanned}; use crate::{ + declaration_engine::declaration_engine::de_get_trait, error::{err, ok}, semantic_analysis::{ ast_node::{type_check_interface_surface, type_check_trait_methods}, @@ -117,12 +118,19 @@ fn handle_supertraits( .ok(&mut warnings, &mut errors) .cloned() { - Some(TypedDeclaration::TraitDeclaration(TypedTraitDeclaration { - ref interface_surface, - ref methods, - ref supertraits, - .. - })) => { + Some(TypedDeclaration::TraitDeclaration(decl_id)) => { + let TypedTraitDeclaration { + ref interface_surface, + ref methods, + ref supertraits, + .. + } = check!( + CompileResult::from(de_get_trait(decl_id.clone(), &supertrait.span())), + return err(warnings, errors), + warnings, + errors + ); + // insert dummy versions of the interfaces for all of the supertraits trait_namespace.insert_trait_implementation( supertrait.name.clone(), diff --git a/sway-core/src/semantic_analysis/ast_node/mod.rs b/sway-core/src/semantic_analysis/ast_node/mod.rs index 3e24baa9d9f..402d418c030 100644 --- a/sway-core/src/semantic_analysis/ast_node/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/mod.rs @@ -13,9 +13,14 @@ pub(crate) use mode::*; pub(crate) use return_statement::*; use crate::{ - declaration_engine::declaration_engine::de_insert_storage, error::*, parse_tree::*, - semantic_analysis::*, style::*, type_system::*, types::DeterministicallyAborts, AstNode, - AstNodeContent, Ident, ReturnStatement, + declaration_engine::declaration_engine::{de_insert_storage, de_insert_trait}, + error::*, + parse_tree::*, + semantic_analysis::*, + style::*, + type_system::*, + types::DeterministicallyAborts, + AstNode, AstNodeContent, Ident, ReturnStatement, }; use sway_types::{span::Span, state::StateIndex, Spanned}; @@ -113,12 +118,23 @@ impl DeterministicallyAborts for TypedAstNode { impl TypedAstNode { /// Returns `true` if this AST node will be exported in a library, i.e. it is a public declaration. - pub(crate) fn is_public(&self) -> bool { + pub(crate) fn is_public(&self) -> CompileResult { use TypedAstNodeContent::*; - match &self.content { - Declaration(decl) => decl.visibility().is_public(), + let mut warnings = vec![]; + let mut errors = vec![]; + let public = match &self.content { + Declaration(decl) => { + let visibility = check!( + decl.visibility(), + return err(warnings, errors), + warnings, + errors + ); + visibility.is_public() + } ReturnStatement(_) | Expression(_) | SideEffect | ImplicitReturnExpression(_) => false, - } + }; + ok(public, warnings, errors) } /// Naive check to see if this node is a function declaration of a function called `main` if @@ -312,7 +328,8 @@ impl TypedAstNode { errors ); let name = trait_decl.name.clone(); - let decl = TypedDeclaration::TraitDeclaration(trait_decl); + let decl_id = de_insert_trait(trait_decl); + let decl = TypedDeclaration::TraitDeclaration(decl_id); ctx.namespace.insert_symbol(name, decl.clone()); decl } diff --git a/sway-core/src/semantic_analysis/module.rs b/sway-core/src/semantic_analysis/module.rs index 51ebf3ed618..d35c75c5d27 100644 --- a/sway-core/src/semantic_analysis/module.rs +++ b/sway-core/src/semantic_analysis/module.rs @@ -1,4 +1,7 @@ -use crate::{error::*, parse_tree::*, semantic_analysis::*, type_system::*}; +use crate::{ + declaration_engine::declaration_engine::de_get_trait, error::*, parse_tree::*, + semantic_analysis::*, type_system::*, +}; use sway_types::{Ident, Spanned}; @@ -108,41 +111,69 @@ fn check_supertraits( ) -> Vec { let mut errors = vec![]; for node in typed_tree_nodes { - if let TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait(TypedImplTrait { - trait_name, - span, - implementing_for_type_id, - .. - })) = &node.content + if let TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait(impl_trait)) = + &node.content { + let TypedImplTrait { + trait_name, + span, + implementing_for_type_id, + .. + } = impl_trait; if let CompileResult { - value: Some(TypedDeclaration::TraitDeclaration(tr)), + value: Some(TypedDeclaration::TraitDeclaration(decl_id)), .. } = namespace.resolve_call_path(trait_name) { + let tr = match de_get_trait(decl_id.clone(), &trait_name.span()) { + Ok(tr) => tr, + Err(e) => { + errors.push(e); + return errors; + } + }; for supertrait in &tr.supertraits { if !typed_tree_nodes.iter().any(|search_node| { if let TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait( - TypedImplTrait { + impl_trait, + )) = &search_node.content + { + let TypedImplTrait { trait_name: search_node_trait_name, implementing_for_type_id: search_node_type_implementing_for, .. - }, - )) = &search_node.content - { + } = impl_trait; if let ( CompileResult { - value: Some(TypedDeclaration::TraitDeclaration(tr1)), + value: Some(TypedDeclaration::TraitDeclaration(decl_id1)), .. }, CompileResult { - value: Some(TypedDeclaration::TraitDeclaration(tr2)), + value: Some(TypedDeclaration::TraitDeclaration(decl_id2)), .. }, ) = ( namespace.resolve_call_path(search_node_trait_name), namespace.resolve_call_path(&supertrait.name), ) { + let tr1 = match de_get_trait( + decl_id1.clone(), + &search_node_trait_name.span(), + ) { + Ok(tr) => tr, + Err(e) => { + errors.push(e); + return false; + } + }; + let tr2 = + match de_get_trait(decl_id2.clone(), &supertrait.name.span()) { + Ok(tr) => tr, + Err(e) => { + errors.push(e); + return false; + } + }; return (tr1.name == tr2.name) && (look_up_type_id(*implementing_for_type_id) == look_up_type_id(*search_node_type_implementing_for)); diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 12d674cde5d..725dc301287 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -214,17 +214,18 @@ impl Module { errors ); let implemented_traits = src_ns.implemented_traits.clone(); - let symbols = src_ns - .symbols - .iter() - .filter_map(|(symbol, decl)| { - if decl.visibility() == Visibility::Public { - Some(symbol.clone()) - } else { - None - } - }) - .collect::>(); + let mut symbols = vec![]; + for (symbol, decl) in src_ns.symbols.iter() { + let visibility = check!( + decl.visibility(), + return err(warnings, errors), + warnings, + errors + ); + if visibility == Visibility::Public { + symbols.push(symbol.clone()); + } + } let dst_ns = &mut self[dst]; dst_ns.implemented_traits.extend(implemented_traits); @@ -274,7 +275,13 @@ impl Module { let mut impls_to_insert = vec![]; match src_ns.symbols.get(item).cloned() { Some(decl) => { - if decl.visibility() != Visibility::Public { + let visibility = check!( + decl.visibility(), + return err(warnings, errors), + warnings, + errors + ); + if visibility != Visibility::Public { errors.push(CompileError::ImportPrivateSymbol { name: item.clone() }); } // if this is a const, insert it into the local namespace directly diff --git a/sway-core/src/semantic_analysis/program.rs b/sway-core/src/semantic_analysis/program.rs index f0f401e331d..a15ef9e0e8a 100644 --- a/sway-core/src/semantic_analysis/program.rs +++ b/sway-core/src/semantic_analysis/program.rs @@ -219,17 +219,27 @@ impl TypedProgram { } /// Ensures there are no unresolved types or types awaiting resolution in the AST. - pub(crate) fn collect_types_metadata(&mut self) -> Vec { + pub(crate) fn collect_types_metadata(&mut self) -> CompileResult> { + let mut warnings = vec![]; + let mut errors = vec![]; // Get all of the entry points for this tree type. For libraries, that's everything // public. For contracts, ABI entries. For scripts and predicates, any function named `main`. - match &self.kind { - TypedProgramKind::Library { .. } => self - .root - .all_nodes - .iter() - .filter(|x| x.is_public()) - .flat_map(CollectTypesMetadata::collect_types_metadata) - .collect(), + let metadata = match &self.kind { + TypedProgramKind::Library { .. } => { + let mut ret = vec![]; + for node in self.root.all_nodes.iter() { + let public = check!( + node.is_public(), + return err(warnings, errors), + warnings, + errors + ); + if public { + ret.append(&mut node.collect_types_metadata()); + } + } + ret + } TypedProgramKind::Script { .. } => self .root .all_nodes @@ -249,6 +259,11 @@ impl TypedProgram { .map(TypedAstNode::from) .flat_map(|x| x.collect_types_metadata()) .collect(), + }; + if errors.is_empty() { + ok(metadata, warnings, errors) + } else { + err(warnings, errors) } } diff --git a/sway-core/src/semantic_analysis/storage_only_types.rs b/sway-core/src/semantic_analysis/storage_only_types.rs index ec7eb6037ef..49ec1d7cefd 100644 --- a/sway-core/src/semantic_analysis/storage_only_types.rs +++ b/sway-core/src/semantic_analysis/storage_only_types.rs @@ -13,7 +13,6 @@ use crate::semantic_analysis::{ use super::{ TypedEnumDeclaration, TypedImplTrait, TypedStorageDeclaration, TypedStructDeclaration, - TypedTraitDeclaration, }; fn ast_node_validate(x: &TypedAstNodeContent) -> CompileResult<()> { @@ -207,7 +206,7 @@ fn decl_validate(decl: &TypedDeclaration) -> CompileResult<()> { } } TypedDeclaration::AbiDeclaration(TypedAbiDeclaration { methods: _, .. }) - | TypedDeclaration::TraitDeclaration(TypedTraitDeclaration { methods: _, .. }) => { + | TypedDeclaration::TraitDeclaration(_) => { // These methods are not typed. They are however handled from ImplTrait. } TypedDeclaration::ImplTrait(TypedImplTrait { methods, .. }) => { diff --git a/sway-lsp/src/capabilities/hover.rs b/sway-lsp/src/capabilities/hover.rs index 6b5621cca4e..a5fa1a370ff 100644 --- a/sway-lsp/src/capabilities/hover.rs +++ b/sway-lsp/src/capabilities/hover.rs @@ -9,7 +9,9 @@ use crate::{ token::to_ident_key, }, }; -use sway_core::{semantic_analysis::ast_node::TypedDeclaration, Declaration, Visibility}; +use sway_core::{ + declaration_engine, semantic_analysis::ast_node::TypedDeclaration, Declaration, Visibility, +}; use sway_types::{Ident, Spanned}; use tower_lsp::lsp_types::{Hover, HoverContents, HoverParams, MarkupContent, MarkupKind}; @@ -63,7 +65,10 @@ fn hover_format(token: &Token, ident: &Ident) -> Hover { TypedDeclaration::StructDeclaration(ref struct_decl) => { format_visibility_hover(struct_decl.visibility, decl.friendly_name()) } - TypedDeclaration::TraitDeclaration(ref trait_decl) => { + TypedDeclaration::TraitDeclaration(ref decl_id) => { + // TODO: do not use unwrap + let trait_decl = + declaration_engine::de_get_trait(decl_id.clone(), &decl_id.span()).unwrap(); format_visibility_hover(trait_decl.visibility, decl.friendly_name()) } TypedDeclaration::EnumDeclaration(ref enum_decl) => { diff --git a/sway-lsp/src/core/traverse_typed_tree.rs b/sway-lsp/src/core/traverse_typed_tree.rs index 4b3f18bbd0f..a1374c420b6 100644 --- a/sway-lsp/src/core/traverse_typed_tree.rs +++ b/sway-lsp/src/core/traverse_typed_tree.rs @@ -58,7 +58,10 @@ fn handle_declaration(declaration: &TypedDeclaration, tokens: &TokenMap) { TypedDeclaration::FunctionDeclaration(func_decl) => { collect_typed_fn_decl(func_decl, tokens); } - TypedDeclaration::TraitDeclaration(trait_decl) => { + TypedDeclaration::TraitDeclaration(decl_id) => { + // TODO: do not use unwrap + let trait_decl = + declaration_engine::de_get_trait(decl_id.clone(), &decl_id.span()).unwrap(); if let Some(mut token) = tokens.get_mut(&to_ident_key(&trait_decl.name)) { token.typed = Some(TypedAstToken::TypedDeclaration(declaration.clone())); }