From f4731dcd1d77172f4b568b5df5a84e73fb2ef433 Mon Sep 17 00:00:00 2001 From: Yuval Goldberg Date: Tue, 12 Mar 2024 10:23:37 +0200 Subject: [PATCH] ImplTypeDefId/ImplTypeId distinction --- crates/cairo-lang-defs/src/db.rs | 2 +- crates/cairo-lang-defs/src/ids.rs | 20 +++---- crates/cairo-lang-semantic/src/db.rs | 31 ++++++----- .../src/items/attribute.rs | 6 +-- .../src/items/functions.rs | 12 +++++ crates/cairo-lang-semantic/src/items/imp.rs | 51 +++++++++++------- crates/cairo-lang-semantic/src/lookup_item.rs | 4 +- crates/cairo-lang-semantic/src/types.rs | 52 ++++++++++++++++++- 8 files changed, 126 insertions(+), 52 deletions(-) diff --git a/crates/cairo-lang-defs/src/db.rs b/crates/cairo-lang-defs/src/db.rs index 4bdb985db7b..637e3a93d9f 100644 --- a/crates/cairo-lang-defs/src/db.rs +++ b/crates/cairo-lang-defs/src/db.rs @@ -40,7 +40,7 @@ pub trait DefsGroup: #[salsa::interned] fn intern_free_function(&self, id: FreeFunctionLongId) -> FreeFunctionId; #[salsa::interned] - fn intern_impl_type(&self, id: ImplTypeLongId) -> ImplTypeId; + fn intern_impl_type_def(&self, id: ImplTypeDefLongId) -> ImplTypeDefId; #[salsa::interned] fn intern_impl_function(&self, id: ImplFunctionLongId) -> ImplFunctionId; #[salsa::interned] diff --git a/crates/cairo-lang-defs/src/ids.rs b/crates/cairo-lang-defs/src/ids.rs index 0e609d50760..983222e923f 100644 --- a/crates/cairo-lang-defs/src/ids.rs +++ b/crates/cairo-lang-defs/src/ids.rs @@ -352,21 +352,21 @@ define_top_level_language_element_id!(ImplDefId, ImplDefLongId, ast::ItemImpl, l // --- Impl type items --- define_named_language_element_id!( - ImplTypeId, - ImplTypeLongId, + ImplTypeDefId, + ImplTypeDefLongId, ast::ItemTypeAlias, - lookup_intern_impl_type + lookup_intern_impl_type_def ); -impl ImplTypeId { +impl ImplTypeDefId { pub fn impl_def_id(&self, db: &dyn DefsGroup) -> ImplDefId { - let ImplTypeLongId(module_file_id, ptr) = db.lookup_intern_impl_type(*self); + let ImplTypeDefLongId(module_file_id, ptr) = db.lookup_intern_impl_type_def(*self); // Impl type ast lies 3 levels below the impl ast. let impl_ptr = ast::ItemImplPtr(ptr.untyped().nth_parent(db.upcast(), 3)); db.intern_impl(ImplDefLongId(module_file_id, impl_ptr)) } } -impl TopLevelLanguageElementId for ImplTypeId { +impl TopLevelLanguageElementId for ImplTypeDefId { fn full_path(&self, db: &dyn DefsGroup) -> String { format!("{}::{}", self.impl_def_id(db).name(db), self.name(db)) } @@ -627,7 +627,7 @@ define_language_element_id_as_enum! { #[toplevel] /// The ID of a impl item with generic parameters. pub enum GenericImplItemId { - Type(ImplTypeId), + Type(ImplTypeDefId), } } @@ -732,8 +732,8 @@ impl GenericItemId { )), ), SyntaxKind::ImplItemList => { - GenericItemId::ImplItem(GenericImplItemId::Type(db.intern_impl_type( - ImplTypeLongId(module_file, ast::ItemTypeAliasPtr(stable_ptr)), + GenericItemId::ImplItem(GenericImplItemId::Type(db.intern_impl_type_def( + ImplTypeDefLongId(module_file, ast::ItemTypeAliasPtr(stable_ptr)), ))) } _ => panic!(), @@ -917,7 +917,7 @@ define_language_element_id_as_enum! { /// Id for direct children of an impl. pub enum ImplItemId { Function(ImplFunctionId), - Type(ImplTypeId), + Type(ImplTypeDefId), } } impl ImplItemId { diff --git a/crates/cairo-lang-semantic/src/db.rs b/crates/cairo-lang-semantic/src/db.rs index 49bf37f9e1e..65136b92374 100644 --- a/crates/cairo-lang-semantic/src/db.rs +++ b/crates/cairo-lang-semantic/src/db.rs @@ -5,8 +5,8 @@ use cairo_lang_defs::diagnostic_utils::StableLocation; use cairo_lang_defs::ids::{ ConstantId, EnumId, ExternFunctionId, ExternTypeId, FreeFunctionId, FunctionTitleId, FunctionWithBodyId, GenericParamId, GenericTypeId, ImplAliasId, ImplDefId, ImplFunctionId, - ImplTypeId, LookupItemId, ModuleId, ModuleItemId, ModuleTypeAliasId, StructId, TraitFunctionId, - TraitId, TraitTypeId, UseId, VariantId, + ImplTypeDefId, LookupItemId, ModuleId, ModuleItemId, ModuleTypeAliasId, StructId, + TraitFunctionId, TraitId, TraitTypeId, UseId, VariantId, }; use cairo_lang_diagnostics::{Diagnostics, DiagnosticsBuilder, Maybe}; use cairo_lang_filesystem::db::{AsFilesGroupMut, FilesGroup}; @@ -586,20 +586,20 @@ pub trait SemanticGroup: fn impl_types( &self, impl_def_id: ImplDefId, - ) -> Maybe>>; + ) -> Maybe>>; /// Returns the ids of the type items in the impl. #[salsa::invoke(items::imp::impl_type_ids)] - fn impl_type_ids(&self, impl_def_id: ImplDefId) -> Maybe>>; + fn impl_type_ids(&self, impl_def_id: ImplDefId) -> Maybe>>; /// Returns the impl AST of the impl type that matches the given id, if exists. #[salsa::invoke(items::imp::impl_type_by_id)] - fn impl_type_by_id(&self, impl_type_id: ImplTypeId) -> Maybe>; + fn impl_type_by_id(&self, impl_type_id: ImplTypeDefId) -> Maybe>; /// Returns the impl type item that matches the given trait type item, if exists. #[salsa::invoke(items::imp::impl_type_by_trait_type)] fn impl_type_by_trait_type( &self, impl_def_id: ImplDefId, trait_type_id: TraitTypeId, - ) -> Maybe>; + ) -> Maybe>; /// Returns the functions in the impl. #[salsa::invoke(items::imp::impl_functions)] fn impl_functions( @@ -629,34 +629,37 @@ pub trait SemanticGroup: #[salsa::invoke(items::imp::impl_type_semantic_diagnostics)] fn impl_type_semantic_diagnostics( &self, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Diagnostics; /// Returns the resolved type of an impl item type. #[salsa::invoke(items::imp::impl_type_resolved_type)] - fn impl_type_resolved_type(&self, impl_type_id: ImplTypeId) -> Maybe; + fn impl_type_resolved_type(&self, impl_type_id: ImplTypeDefId) -> Maybe; /// Returns the generic parameters of an impl item type. #[salsa::invoke(items::imp::impl_type_generic_params)] - fn impl_type_generic_params(&self, enum_id: ImplTypeId) -> Maybe>; + fn impl_type_generic_params(&self, enum_id: ImplTypeDefId) -> Maybe>; /// Returns the attributes of an impl type. #[salsa::invoke(items::imp::impl_type_attributes)] - fn impl_type_attributes(&self, impl_type_id: ImplTypeId) -> Maybe>; + fn impl_type_attributes(&self, impl_type_id: ImplTypeDefId) -> Maybe>; /// Returns the resolution resolved_items of an impl item type. #[salsa::invoke(items::imp::impl_type_resolver_data)] - fn impl_type_resolver_data(&self, impl_type_id: ImplTypeId) -> Maybe>; + fn impl_type_resolver_data(&self, impl_type_id: ImplTypeDefId) -> Maybe>; /// Returns the trait type of an impl type. #[salsa::invoke(items::imp::impl_type_trait_type)] - fn impl_type_trait_type(&self, impl_type_id: ImplTypeId) -> Maybe; + fn impl_type_trait_type(&self, impl_type_id: ImplTypeDefId) -> Maybe; /// Private query to compute data about an impl item type. #[salsa::invoke(items::imp::priv_impl_type_semantic_data)] #[salsa::cycle(items::imp::priv_impl_type_semantic_data_cycle)] fn priv_impl_type_semantic_data( &self, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Maybe; /// Private query to compute data about the generic parameters of an impl item type. #[salsa::invoke(items::imp::priv_impl_type_generic_params_data)] - fn priv_impl_type_generic_params_data(&self, enum_id: ImplTypeId) -> Maybe; + fn priv_impl_type_generic_params_data( + &self, + enum_id: ImplTypeDefId, + ) -> Maybe; // Impl function. // ================ diff --git a/crates/cairo-lang-semantic/src/items/attribute.rs b/crates/cairo-lang-semantic/src/items/attribute.rs index ada4e2bb678..8451ba8e856 100644 --- a/crates/cairo-lang-semantic/src/items/attribute.rs +++ b/crates/cairo-lang-semantic/src/items/attribute.rs @@ -1,6 +1,6 @@ use cairo_lang_defs::ids::{ - EnumId, FreeFunctionId, FunctionWithBodyId, ImplAliasId, ImplDefId, ImplFunctionId, ImplTypeId, - ModuleId, StructId, SubmoduleId, TraitFunctionId, TraitId, TraitTypeId, + EnumId, FreeFunctionId, FunctionWithBodyId, ImplAliasId, ImplDefId, ImplFunctionId, + ImplTypeDefId, ModuleId, StructId, SubmoduleId, TraitFunctionId, TraitId, TraitTypeId, }; use cairo_lang_diagnostics::Maybe; use cairo_lang_syntax::attribute::structured::Attribute; @@ -135,7 +135,7 @@ impl SemanticQueryAttrs for TraitFunctionId { } } -impl SemanticQueryAttrs for ImplTypeId { +impl SemanticQueryAttrs for ImplTypeDefId { fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe> { db.impl_type_attributes(*self) } diff --git a/crates/cairo-lang-semantic/src/items/functions.rs b/crates/cairo-lang-semantic/src/items/functions.rs index 6a1e808c2a1..f4f794044fc 100644 --- a/crates/cairo-lang-semantic/src/items/functions.rs +++ b/crates/cairo-lang-semantic/src/items/functions.rs @@ -40,10 +40,13 @@ use crate::{ #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, SemanticObject)] pub struct ImplGenericFunctionId { // TODO(spapini): Consider making these private and enforcing invariants in the ctor. + /// The impl the function is in. pub impl_id: ImplId, + /// The trait function this impl function implements. pub function: TraitFunctionId, } impl ImplGenericFunctionId { + /// Gets the impl function language element, if self.impl_id is of a concrete impl. pub fn impl_function(&self, db: &dyn SemanticGroup) -> Maybe> { match self.impl_id { ImplId::Concrete(concrete_impl_id) => { @@ -81,6 +84,15 @@ impl ImplGenericFunctionId { format!("{}::{}", self.impl_id.name(db.upcast()), self.function.name(db.upcast())).into() } } +impl DebugWithDb for ImplGenericFunctionId { + fn fmt( + &self, + f: &mut std::fmt::Formatter<'_>, + db: &(dyn SemanticGroup + 'static), + ) -> std::fmt::Result { + write!(f, "{}", self.format(db)) + } +} /// The ID of a generic function that can be concretized. #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, SemanticObject)] diff --git a/crates/cairo-lang-semantic/src/items/imp.rs b/crates/cairo-lang-semantic/src/items/imp.rs index aba11317a97..f52d81d54ce 100644 --- a/crates/cairo-lang-semantic/src/items/imp.rs +++ b/crates/cairo-lang-semantic/src/items/imp.rs @@ -5,9 +5,10 @@ use std::vec; use cairo_lang_debug::DebugWithDb; use cairo_lang_defs::ids::{ FunctionTitleId, FunctionWithBodyId, GenericKind, GenericParamId, ImplAliasId, ImplDefId, - ImplFunctionId, ImplFunctionLongId, ImplItemId, ImplTypeId, ImplTypeLongId, LanguageElementId, - LookupItemId, ModuleId, ModuleItemId, NamedLanguageElementId, NamedLanguageElementLongId, - TopLevelLanguageElementId, TraitFunctionId, TraitId, TraitOrImplContext, TraitTypeId, + ImplFunctionId, ImplFunctionLongId, ImplItemId, ImplTypeDefId, ImplTypeDefLongId, + LanguageElementId, LookupItemId, ModuleId, ModuleItemId, NamedLanguageElementId, + NamedLanguageElementLongId, TopLevelLanguageElementId, TraitFunctionId, TraitId, + TraitOrImplContext, TraitTypeId, }; use cairo_lang_diagnostics::{ skip_diagnostic, Diagnostics, DiagnosticsBuilder, Maybe, ToMaybe, ToOption, @@ -108,6 +109,13 @@ impl ConcreteImplId { ) -> Maybe> { db.impl_function_by_trait_function(self.impl_def_id(db), function) } + pub fn get_impl_type_def( + &self, + db: &dyn SemanticGroup, + ty: TraitTypeId, + ) -> Maybe> { + db.impl_type_by_trait_type(self.impl_def_id(db), ty) + } pub fn name(&self, db: &dyn SemanticGroup) -> SmolStr { self.impl_def_id(db).name(db.upcast()) } @@ -427,7 +435,7 @@ pub struct ImplDefinitionData { /// queries. Adding the items' diagnostics only after the whole computation breaks this cycle. diagnostics: Diagnostics, function_asts: OrderedHashMap, - item_type_asts: Arc>, + item_type_asts: Arc>, } // --- Selectors --- @@ -493,7 +501,7 @@ pub fn impl_function_by_trait_function( pub fn impl_types( db: &dyn SemanticGroup, impl_def_id: ImplDefId, -) -> Maybe>> { +) -> Maybe>> { Ok(db.priv_impl_definition_data(impl_def_id)?.item_type_asts) } @@ -501,14 +509,14 @@ pub fn impl_types( pub fn impl_type_ids( db: &dyn SemanticGroup, impl_def_id: ImplDefId, -) -> Maybe>> { +) -> Maybe>> { Ok(Arc::new(db.impl_types(impl_def_id)?.keys().copied().collect())) } /// Query implementation of [crate::db::SemanticGroup::impl_type_by_id]. pub fn impl_type_by_id( db: &dyn SemanticGroup, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Maybe> { let impl_types = db.impl_types(impl_type_id.impl_def_id(db.upcast()))?; Ok(impl_types.get(&impl_type_id).cloned()) @@ -519,11 +527,11 @@ pub fn impl_type_by_trait_type( db: &dyn SemanticGroup, impl_def_id: ImplDefId, trait_type_id: TraitTypeId, -) -> Maybe> { +) -> Maybe> { let defs_db = db.upcast(); let name = trait_type_id.name(defs_db); for impl_type_id in db.priv_impl_definition_data(impl_def_id)?.item_type_asts.keys() { - if db.lookup_intern_impl_type(*impl_type_id).name(defs_db) == name { + if db.lookup_intern_impl_type_def(*impl_type_id).name(defs_db) == name { return Ok(Some(*impl_type_id)); } } @@ -618,7 +626,7 @@ pub fn priv_impl_definition_data( } ImplItem::Type(ty) => { let impl_type_id = - db.intern_impl_type(ImplTypeLongId(module_file_id, ty.stable_ptr())); + db.intern_impl_type_def(ImplTypeDefLongId(module_file_id, ty.stable_ptr())); let name_node = ty.name(syntax_db); let name = name_node.text(syntax_db); if !impl_item_names.insert(name.clone()) { @@ -1155,20 +1163,23 @@ pub struct ImplItemTypeData { /// Query implementation of [crate::db::SemanticGroup::impl_type_semantic_diagnostics]. pub fn impl_type_semantic_diagnostics( db: &dyn SemanticGroup, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Diagnostics { db.priv_impl_type_semantic_data(impl_type_id).map(|data| data.diagnostics).unwrap_or_default() } /// Query implementation of [crate::db::SemanticGroup::impl_type_resolved_type]. -pub fn impl_type_resolved_type(db: &dyn SemanticGroup, impl_type_id: ImplTypeId) -> Maybe { +pub fn impl_type_resolved_type( + db: &dyn SemanticGroup, + impl_type_id: ImplTypeDefId, +) -> Maybe { db.priv_impl_type_semantic_data(impl_type_id)?.type_alias_data.resolved_type } /// Query implementation of [crate::db::SemanticGroup::impl_type_generic_params]. pub fn impl_type_generic_params( db: &dyn SemanticGroup, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Maybe> { Ok(db.priv_impl_type_generic_params_data(impl_type_id)?.generic_params) } @@ -1176,7 +1187,7 @@ pub fn impl_type_generic_params( /// Query implementation of [crate::db::SemanticGroup::impl_type_attributes]. pub fn impl_type_attributes( db: &dyn SemanticGroup, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Maybe> { Ok(db.priv_impl_type_semantic_data(impl_type_id)?.type_alias_data.attributes) } @@ -1184,7 +1195,7 @@ pub fn impl_type_attributes( /// Query implementation of [crate::db::SemanticGroup::impl_type_resolver_data]. pub fn impl_type_resolver_data( db: &dyn SemanticGroup, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Maybe> { Ok(db.priv_impl_type_semantic_data(impl_type_id)?.type_alias_data.resolver_data) } @@ -1192,7 +1203,7 @@ pub fn impl_type_resolver_data( /// Query implementation of [crate::db::SemanticGroup::impl_type_trait_type]. pub fn impl_type_trait_type( db: &dyn SemanticGroup, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Maybe { db.priv_impl_type_semantic_data(impl_type_id)?.trait_type_id } @@ -1202,7 +1213,7 @@ pub fn impl_type_trait_type( /// Query implementation of [crate::db::SemanticGroup::priv_impl_type_semantic_data]. pub fn priv_impl_type_semantic_data( db: &dyn SemanticGroup, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Maybe { let module_file_id = impl_type_id.module_file_id(db.upcast()); let mut diagnostics = SemanticDiagnostics::new(module_file_id.file_id(db.upcast())?); @@ -1230,7 +1241,7 @@ pub fn priv_impl_type_semantic_data( pub fn priv_impl_type_semantic_data_cycle( db: &dyn SemanticGroup, _cycle: &[String], - impl_type_id: &ImplTypeId, + impl_type_id: &ImplTypeDefId, ) -> Maybe { let module_file_id = impl_type_id.module_file_id(db.upcast()); let mut diagnostics = SemanticDiagnostics::new(module_file_id.file_id(db.upcast())?); @@ -1257,7 +1268,7 @@ pub fn priv_impl_type_semantic_data_cycle( /// Query implementation of [crate::db::SemanticGroup::priv_impl_type_generic_params_data]. pub fn priv_impl_type_generic_params_data( db: &dyn SemanticGroup, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, ) -> Maybe { let defs_db = db.upcast(); let module_file_id = impl_type_id.module_file_id(defs_db); @@ -1278,7 +1289,7 @@ pub fn priv_impl_type_generic_params_data( fn validate_impl_item_type( db: &dyn SemanticGroup, diagnostics: &mut SemanticDiagnostics, - impl_type_id: ImplTypeId, + impl_type_id: ImplTypeDefId, impl_type_ast: &ast::ItemTypeAlias, ) -> Maybe { let defs_db = db.upcast(); diff --git a/crates/cairo-lang-semantic/src/lookup_item.rs b/crates/cairo-lang-semantic/src/lookup_item.rs index 04b0a4a5840..e6066e7ebfa 100644 --- a/crates/cairo-lang-semantic/src/lookup_item.rs +++ b/crates/cairo-lang-semantic/src/lookup_item.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use cairo_lang_defs::ids::{ ConstantId, EnumId, ExternFunctionId, ExternTypeId, FileIndex, FreeFunctionId, - FunctionWithBodyId, ImplAliasId, ImplDefId, ImplFunctionId, ImplItemId, ImplTypeId, + FunctionWithBodyId, ImplAliasId, ImplDefId, ImplFunctionId, ImplItemId, ImplTypeDefId, LanguageElementId, LookupItemId, ModuleFileId, ModuleId, ModuleItemId, ModuleTypeAliasId, StructId, SubmoduleId, TraitFunctionId, TraitId, TraitItemId, TraitTypeId, UseId, }; @@ -203,7 +203,7 @@ impl HasResolverData for ImplItemId { } } -impl HasResolverData for ImplTypeId { +impl HasResolverData for ImplTypeDefId { fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe> { db.impl_type_resolver_data(*self) } diff --git a/crates/cairo-lang-semantic/src/types.rs b/crates/cairo-lang-semantic/src/types.rs index 3a547b6fb34..17a9329b4dd 100644 --- a/crates/cairo-lang-semantic/src/types.rs +++ b/crates/cairo-lang-semantic/src/types.rs @@ -1,6 +1,7 @@ use cairo_lang_debug::DebugWithDb; use cairo_lang_defs::ids::{ - EnumId, ExternTypeId, GenericParamId, GenericTypeId, ModuleFileId, StructId, + EnumId, ExternTypeId, GenericParamId, GenericTypeId, ImplTypeDefId, ModuleFileId, + NamedLanguageElementId, StructId, TraitTypeId, }; use cairo_lang_diagnostics::{DiagnosticAdded, Maybe}; use cairo_lang_proc_macros::SemanticObject; @@ -12,6 +13,7 @@ use cairo_lang_utils::{define_short_id, try_extract_matches, OptionFrom}; use itertools::Itertools; use num_bigint::BigInt; use num_traits::Zero; +use smol_str::SmolStr; use crate::corelib::{ concrete_copy_trait, concrete_destruct_trait, concrete_drop_trait, @@ -338,6 +340,52 @@ impl ConcreteExternTypeId { } } +/// An impl item of kind type. +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, SemanticObject)] +pub struct ImplTypeId { + /// The impl the item type is in. + impl_id: ImplId, + /// The trait type this impl type "implements". + ty: TraitTypeId, +} +impl ImplTypeId { + /// Creates a new impl type id. For an impl type of a concrete impl, asserts that the trait + /// type belongs to the same trait that the impl implements (panics if not). + pub fn new(impl_id: ImplId, ty: TraitTypeId, db: &dyn SemanticGroup) -> Self { + if let crate::items::imp::ImplId::Concrete(concrete_impl) = impl_id { + let impl_def_id = concrete_impl.impl_def_id(db); + assert_eq!(Some(ty.trait_id(db.upcast())), db.impl_def_trait(impl_def_id)); + } + + ImplTypeId { impl_id, ty } + } + pub fn impl_id(&self) -> ImplId { + self.impl_id + } + pub fn ty(&self) -> TraitTypeId { + self.ty + } + /// Gets the impl type def (language element), if `self.impl_id` is of a concrete impl. + pub fn impl_type_def(&self, db: &dyn SemanticGroup) -> Maybe> { + match self.impl_id { + ImplId::Concrete(concrete_impl_id) => concrete_impl_id.get_impl_type_def(db, self.ty), + ImplId::GenericParameter(_) | ImplId::ImplVar(_) => Ok(None), + } + } + pub fn format(&self, db: &dyn SemanticGroup) -> SmolStr { + format!("{}::{}", self.impl_id.name(db.upcast()), self.ty.name(db.upcast())).into() + } +} +impl DebugWithDb for ImplTypeId { + fn fmt( + &self, + f: &mut std::fmt::Formatter<'_>, + db: &(dyn SemanticGroup + 'static), + ) -> std::fmt::Result { + write!(f, "{}", self.format(db)) + } +} + // TODO(spapini): add a query wrapper. /// Resolves a type given a module and a path. pub fn resolve_type( @@ -540,7 +588,7 @@ pub fn single_value_type(db: &dyn SemanticGroup, ty: TypeId) -> Maybe { semantic::TypeLongId::Coupon(_) => false, semantic::TypeLongId::FixedSizeArray { type_id, size } => { db.single_value_type(type_id)? - || matches!(db.lookup_intern_const_value(size), + || matches!(db.lookup_intern_const_value(size), ConstValue::Int(value) if value.is_zero()) } })