From 9cf1e3787755d20c6594ef4b7d9d579cfb74f22b Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Thu, 5 Oct 2023 14:53:45 +0200 Subject: [PATCH] Internal Context restructuring --- crates/rune-macros/src/function.rs | 1 + crates/rune/src/compile/context.rs | 393 ++++++++++------------- crates/rune/src/compile/context_error.rs | 14 + crates/rune/src/compile/meta.rs | 3 - crates/rune/src/doc/build.rs | 5 +- crates/rune/src/doc/context.rs | 34 +- crates/rune/src/doc/visitor.rs | 2 + crates/rune/src/module.rs | 169 ++++++---- crates/rune/src/module/function_meta.rs | 16 +- crates/rune/src/module/module.rs | 290 +++++++++++------ crates/rune/src/query/query.rs | 2 - 11 files changed, 497 insertions(+), 432 deletions(-) diff --git a/crates/rune-macros/src/function.rs b/crates/rune-macros/src/function.rs index 79a73ebc7..135e77060 100644 --- a/crates/rune-macros/src/function.rs +++ b/crates/rune-macros/src/function.rs @@ -372,6 +372,7 @@ impl Function { Ok(rune::__private::FunctionMetaData { kind: rune::__private::FunctionMetaKind::#meta_kind(#name, #real_fn_path)?#build_with, name: #name_string, + deprecated: None, docs: &#docs[..], arguments: &#arguments[..], }) diff --git a/crates/rune/src/compile/context.rs b/crates/rune/src/compile/context.rs index 716733d79..1c98182c8 100644 --- a/crates/rune/src/compile/context.rs +++ b/crates/rune/src/compile/context.rs @@ -13,8 +13,8 @@ use crate::compile::MetaInfo; use crate::compile::{ComponentRef, ContextError, IntoComponent, Item, ItemBuf, Names}; use crate::hash; use crate::module::{ - Fields, InternalEnum, Module, ModuleAssociated, ModuleAssociatedKind, ModuleAttributeMacro, - ModuleConstant, ModuleFunction, ModuleMacro, ModuleType, TypeSpecification, + Fields, Module, ModuleAssociated, ModuleAssociatedKind, ModuleItem, ModuleType, + TypeSpecification, }; use crate::runtime::{ AttributeMacroHandler, ConstValue, FunctionHandler, MacroHandler, Protocol, RuntimeContext, @@ -32,6 +32,9 @@ pub(crate) struct ContextMeta { pub(crate) item: Option, /// The kind of the compile meta. pub(crate) kind: meta::Kind, + /// Deprecation notice. + #[cfg(feature = "doc")] + pub(crate) deprecated: Option>, /// Documentation associated with a context meta. #[cfg(feature = "doc")] pub(crate) docs: Docs, @@ -221,24 +224,8 @@ impl Context { self.install_type(module, ty)?; } - for f in &module.functions { - self.install_function(module, f)?; - } - - for m in &module.macros { - self.install_macro(module, m)?; - } - - for m in &module.attribute_macros { - self.install_attribute_macro(module, m)?; - } - - for m in &module.constants { - self.install_constant(module, m)?; - } - - for internal_enum in &module.internal_enums { - self.install_internal_enum(module, internal_enum)?; + for item in &module.items { + self.install_item(module, item)?; } for assoc in &module.associated { @@ -404,16 +391,24 @@ impl Context { fn install_module(&mut self, m: &Module) -> Result<(), ContextError> { self.names.insert(&m.item)?; - let mut current = Some((m.item.as_ref(), Some(&m.docs))); + let mut current = Some((m.item.as_ref(), Some(&m.common))); #[allow(unused)] - while let Some((item, docs)) = current.take() { + while let Some((item, common)) = current.take() { self.install_meta(ContextMeta { hash: Hash::type_hash(item), item: Some(item.try_to_owned()?), kind: meta::Kind::Module, #[cfg(feature = "doc")] - docs: docs.try_cloned()?.unwrap_or_default(), + deprecated: common + .map(|c| c.deprecated.as_ref().try_cloned()) + .transpose()? + .flatten(), + #[cfg(feature = "doc")] + docs: common + .map(|c| c.docs.try_clone()) + .transpose()? + .unwrap_or_default(), })?; current = item.parent().map(|item| (item, None)); @@ -447,8 +442,6 @@ impl Context { #[cfg(feature = "doc")] is_async: false, #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] args: Some(match fields { Fields::Named(names) => names.len(), Fields::Unnamed(args) => *args, @@ -514,8 +507,6 @@ impl Context { #[cfg(feature = "doc")] is_async: false, #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] args: Some(match fields { Fields::Named(names) => names.len(), Fields::Unnamed(args) => *args, @@ -561,6 +552,8 @@ impl Context { constructor, }, #[cfg(feature = "doc")] + deprecated: variant.deprecated.try_clone()?, + #[cfg(feature = "doc")] docs: variant.docs.try_clone()?, })?; } @@ -577,7 +570,9 @@ impl Context { item: Some(item), kind, #[cfg(feature = "doc")] - docs: ty.docs.try_clone()?, + deprecated: ty.common.deprecated.try_clone()?, + #[cfg(feature = "doc")] + docs: ty.common.docs.try_clone()?, })?; Ok(()) @@ -612,115 +607,172 @@ impl Context { } /// Install a function and check for duplicates. - fn install_function( + fn install_item( &mut self, module: &Module, - f: &ModuleFunction, + module_item: &ModuleItem, ) -> Result<(), ContextError> { - let item = module.item.join(&f.item)?; + let item = module.item.join(&module_item.item)?; self.names.insert(&item)?; let hash = Hash::type_hash(&item); - self.constants.try_insert( - Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), - ConstValue::String(item.try_to_string()?), - )?; + let kind = match &module_item.kind { + rune::module::ModuleItemKind::Constant(value) => { + self.constants.try_insert(hash, value.try_clone()?)?; + meta::Kind::Const + } + rune::module::ModuleItemKind::Function(f) => { + self.constants.try_insert( + Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), + ConstValue::String(item.try_to_string()?), + )?; - let signature = meta::Signature { - #[cfg(feature = "doc")] - is_async: f.is_async, - #[cfg(feature = "doc")] - deprecated: f.deprecated.try_clone()?, - #[cfg(feature = "doc")] - args: f.args, - #[cfg(feature = "doc")] - return_type: f.return_type.as_ref().map(|f| f.hash), - #[cfg(feature = "doc")] - argument_types: f - .argument_types - .iter() - .map(|f| f.as_ref().map(|f| f.hash)) - .try_collect()?, - }; + let signature = meta::Signature { + #[cfg(feature = "doc")] + is_async: f.is_async, + #[cfg(feature = "doc")] + args: f.args, + #[cfg(feature = "doc")] + return_type: f.return_type.as_ref().map(|f| f.hash), + #[cfg(feature = "doc")] + argument_types: f + .argument_types + .iter() + .map(|f| f.as_ref().map(|f| f.hash)) + .try_collect()?, + }; - self.insert_native_fn(hash, &f.handler)?; + self.insert_native_fn(hash, &f.handler)?; - self.install_meta(ContextMeta { - hash, - item: Some(item), - kind: meta::Kind::Function { - associated: None, - signature, - is_test: false, - is_bench: false, - parameters: Hash::EMPTY, - #[cfg(feature = "doc")] - container: None, - #[cfg(feature = "doc")] - parameter_types: Vec::new(), - }, - #[cfg(feature = "doc")] - docs: f.docs.try_clone()?, - })?; + meta::Kind::Function { + associated: None, + signature, + is_test: false, + is_bench: false, + parameters: Hash::EMPTY, + #[cfg(feature = "doc")] + container: None, + #[cfg(feature = "doc")] + parameter_types: Vec::new(), + } + } + rune::module::ModuleItemKind::Macro(m) => { + self.macros.try_insert(hash, m.handler.clone())?; + meta::Kind::Macro + } + rune::module::ModuleItemKind::AttributeMacro(m) => { + self.attribute_macros.try_insert(hash, m.handler.clone())?; + meta::Kind::AttributeMacro + } + rune::module::ModuleItemKind::InternalEnum(internal_enum) => { + if !self.internal_enums.try_insert(internal_enum.static_type)? { + return Err(ContextError::InternalAlreadyPresent { + name: internal_enum.name, + }); + } - Ok(()) - } + // Sanity check that the registered item is in the right location. + if internal_enum.static_type.hash != hash { + return Err(ContextError::TypeHashMismatch { + type_info: internal_enum.static_type.type_info(), + item, + hash: internal_enum.static_type.hash, + item_hash: hash, + }); + } - /// Install a macro and check for duplicates. - fn install_macro(&mut self, module: &Module, m: &ModuleMacro) -> Result<(), ContextError> { - let item = module.item.join(&m.item)?; - let hash = Hash::type_hash(&item); - self.macros.try_insert(hash, m.handler.clone())?; + self.install_type_info(ContextType { + item: item.try_clone()?, + hash, + type_check: None, + type_info: internal_enum.static_type.type_info(), + type_parameters: Hash::EMPTY, + })?; + + for (index, variant) in internal_enum.variants.iter().enumerate() { + let Some(fields) = &variant.fields else { + continue; + }; - self.install_meta(ContextMeta { - hash, - item: Some(item), - kind: meta::Kind::Macro, - #[cfg(feature = "doc")] - docs: m.docs.try_clone()?, - })?; + let variant_item = item.extended(variant.name)?; + let variant_hash = Hash::type_hash(&variant_item); - Ok(()) - } + self.install_type_info(ContextType { + item: variant_item.try_clone()?, + hash: variant_hash, + type_check: variant.type_check, + type_info: internal_enum.static_type.type_info(), + type_parameters: Hash::EMPTY, + })?; - /// Install an attribute macro and check for duplicates. - fn install_attribute_macro( - &mut self, - module: &Module, - m: &ModuleAttributeMacro, - ) -> Result<(), ContextError> { - let item = module.item.join(&m.item)?; - let hash = Hash::type_hash(&item); - self.attribute_macros.try_insert(hash, m.handler.clone())?; + let constructor = if let Some(constructor) = &variant.constructor { + self.insert_native_fn(variant_hash, constructor)?; - self.install_meta(ContextMeta { - hash, - item: Some(item), - kind: meta::Kind::AttributeMacro, - #[cfg(feature = "doc")] - docs: m.docs.try_clone()?, - })?; + Some(meta::Signature { + #[cfg(feature = "doc")] + is_async: false, + #[cfg(feature = "doc")] + args: Some(match fields { + Fields::Named(names) => names.len(), + Fields::Unnamed(args) => *args, + Fields::Empty => 0, + }), + #[cfg(feature = "doc")] + return_type: Some(hash), + #[cfg(feature = "doc")] + argument_types: Box::default(), + }) + } else { + None + }; - Ok(()) - } + self.install_meta(ContextMeta { + hash: variant_hash, + item: Some(variant_item), + kind: meta::Kind::Variant { + enum_hash: hash, + index, + fields: match fields { + Fields::Named(fields) => meta::Fields::Named(meta::FieldsNamed { + fields: fields + .iter() + .copied() + .enumerate() + .map(|(position, name)| { + Ok(( + Box::::try_from(name)?, + meta::FieldMeta { position }, + )) + }) + .try_collect::>()??, + }), + Fields::Unnamed(args) => meta::Fields::Unnamed(*args), + Fields::Empty => meta::Fields::Empty, + }, + constructor, + }, + #[cfg(feature = "doc")] + deprecated: variant.deprecated.try_clone()?, + #[cfg(feature = "doc")] + docs: variant.docs.try_clone()?, + })?; + } - /// Install a constant and check for duplicates. - fn install_constant( - &mut self, - module: &Module, - m: &ModuleConstant, - ) -> Result<(), ContextError> { - let item = module.item.join(&m.item)?; - let hash = Hash::type_hash(&item); - self.constants.try_insert(hash, m.value.try_clone()?)?; + meta::Kind::Enum { + parameters: Hash::EMPTY, + } + } + }; self.install_meta(ContextMeta { hash, item: Some(item), - kind: meta::Kind::Const, + kind, + #[cfg(feature = "doc")] + deprecated: module_item.common.deprecated.try_clone()?, #[cfg(feature = "doc")] - docs: m.docs.try_clone()?, + docs: module_item.common.docs.try_clone()?, })?; Ok(()) @@ -760,12 +812,12 @@ impl Context { }; let kind = match &assoc.kind { - ModuleAssociatedKind::Constant(c) => { + ModuleAssociatedKind::Constant(value) => { if let Some((hash, ..)) = &item { - self.constants.try_insert(*hash, c.value.try_clone()?)?; + self.constants.try_insert(*hash, value.try_clone()?)?; } - self.constants.try_insert(hash, c.value.try_clone()?)?; + self.constants.try_insert(hash, value.try_clone()?)?; meta::Kind::Const } ModuleAssociatedKind::Function(f) => { @@ -773,8 +825,6 @@ impl Context { #[cfg(feature = "doc")] is_async: f.is_async, #[cfg(feature = "doc")] - deprecated: assoc.deprecated.try_clone()?, - #[cfg(feature = "doc")] args: f.args, #[cfg(feature = "doc")] return_type: f.return_type.as_ref().map(|f| f.hash), @@ -818,112 +868,11 @@ impl Context { item: item.map(|(_, item)| item), kind, #[cfg(feature = "doc")] - docs: assoc.docs.try_clone()?, - })?; - - Ok(()) - } - - /// Install generator state types. - fn install_internal_enum( - &mut self, - module: &Module, - internal_enum: &InternalEnum, - ) -> Result<(), ContextError> { - if !self.internal_enums.try_insert(internal_enum.static_type)? { - return Err(ContextError::InternalAlreadyPresent { - name: internal_enum.name, - }); - } - - let item = module.item.join(&internal_enum.base_type)?; - - let enum_hash = internal_enum.static_type.hash; - - self.install_meta(ContextMeta { - hash: enum_hash, - item: Some(item.try_clone()?), - kind: meta::Kind::Enum { - parameters: Hash::EMPTY, - }, + deprecated: assoc.common.deprecated.try_clone()?, #[cfg(feature = "doc")] - docs: internal_enum.docs.try_clone()?, - })?; - - self.install_type_info(ContextType { - item: item.try_clone()?, - hash: enum_hash, - type_check: None, - type_info: internal_enum.static_type.type_info(), - type_parameters: Hash::EMPTY, + docs: assoc.common.docs.try_clone()?, })?; - for (index, variant) in internal_enum.variants.iter().enumerate() { - let Some(fields) = &variant.fields else { - continue; - }; - - let item = item.extended(variant.name)?; - let hash = Hash::type_hash(&item); - - self.install_type_info(ContextType { - item: item.try_clone()?, - hash, - type_check: variant.type_check, - type_info: internal_enum.static_type.type_info(), - type_parameters: Hash::EMPTY, - })?; - - let constructor = if let Some(constructor) = &variant.constructor { - self.insert_native_fn(hash, constructor)?; - - Some(meta::Signature { - #[cfg(feature = "doc")] - is_async: false, - #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] - args: Some(match fields { - Fields::Named(names) => names.len(), - Fields::Unnamed(args) => *args, - Fields::Empty => 0, - }), - #[cfg(feature = "doc")] - return_type: Some(enum_hash), - #[cfg(feature = "doc")] - argument_types: Box::default(), - }) - } else { - None - }; - - self.install_meta(ContextMeta { - hash, - item: Some(item), - kind: meta::Kind::Variant { - enum_hash, - index, - fields: match fields { - Fields::Named(fields) => meta::Fields::Named(meta::FieldsNamed { - fields: fields - .iter() - .copied() - .enumerate() - .map(|(position, name)| { - Ok((Box::::try_from(name)?, meta::FieldMeta { position })) - }) - .try_collect::>()??, - }), - Fields::Unnamed(args) => meta::Fields::Unnamed(*args), - Fields::Empty => meta::Fields::Empty, - }, - constructor, - }, - #[cfg(feature = "doc")] - docs: variant.docs.try_clone()?, - })?; - } - Ok(()) } diff --git a/crates/rune/src/compile/context_error.rs b/crates/rune/src/compile/context_error.rs index 19255bfe6..9bc36aadd 100644 --- a/crates/rune/src/compile/context_error.rs +++ b/crates/rune/src/compile/context_error.rs @@ -111,6 +111,12 @@ pub enum ContextError { hash: Hash, item_hash: Hash, }, + StaticTypeHashMismatch { + type_info: TypeInfo, + item: ItemBuf, + hash: Hash, + item_hash: Hash, + }, } impl From for ContextError { @@ -261,6 +267,14 @@ impl fmt::Display for ContextError { } => { write!(f,"Type hash mismatch for `{type_info}`, from module is `{hash}` while from item `{item}` is `{item_hash}`. A possibility is that it has the wrong #[rune(item = ..)] setting.")?; } + ContextError::StaticTypeHashMismatch { + type_info, + item, + hash, + item_hash, + } => { + write!(f, "Static type hash mismatch for `{type_info}`, from module is `{hash}` while from item `{item}` is `{item_hash}`. The static item might be registered in the wrong module, or that the static type hash is miscalculated.")?; + } } Ok(()) diff --git a/crates/rune/src/compile/meta.rs b/crates/rune/src/compile/meta.rs index ab0cdd680..5929ac21f 100644 --- a/crates/rune/src/compile/meta.rs +++ b/crates/rune/src/compile/meta.rs @@ -320,9 +320,6 @@ pub struct Signature { /// An asynchronous function. #[cfg(feature = "doc")] pub(crate) is_async: bool, - /// Deprecation notice. - #[cfg(feature = "doc")] - pub(crate) deprecated: Option>, /// Arguments. #[cfg(feature = "doc")] pub(crate) args: Option, diff --git a/crates/rune/src/doc/build.rs b/crates/rune/src/doc/build.rs index 3e2f9ccf6..00f72447c 100644 --- a/crates/rune/src/doc/build.rs +++ b/crates/rune/src/doc/build.rs @@ -946,7 +946,7 @@ fn module<'m>(cx: &mut Ctxt<'_, 'm>, meta: Meta<'m>, queue: &mut VecDeque(cx: &mut Ctxt<'_, 'm>, meta: Meta<'m>) -> Result(cx: &mut Ctxt<'_, 'm>, meta: Meta<'m>) -> Result { #[derive(Debug, Clone, Copy)] pub(crate) struct Meta<'a> { + /// Kind of the meta item. + pub(crate) kind: Kind<'a>, /// Item of the meta. pub(crate) item: Option<&'a Item>, /// The meta source. @@ -24,8 +26,8 @@ pub(crate) struct Meta<'a> { pub(crate) source: MetaSource<'a>, /// Type hash for the meta item. pub(crate) hash: Hash, - /// Kind of the meta item. - pub(crate) kind: Kind<'a>, + /// Indicates if the item is deprecated. + pub(crate) deprecated: Option<&'a str>, /// Documentation for the meta item. pub(crate) docs: &'a [String], } @@ -33,7 +35,6 @@ pub(crate) struct Meta<'a> { #[derive(Debug, Clone, Copy)] pub(crate) struct Function<'a> { pub(crate) is_async: bool, - pub(crate) deprecated: Option<&'a str>, pub(crate) arg_names: Option<&'a [String]>, pub(crate) args: Option, pub(crate) signature: Signature, @@ -65,15 +66,15 @@ pub(crate) struct AssocVariant<'a> { pub(crate) struct AssocFn<'a> { pub(crate) kind: AssocFnKind<'a>, pub(crate) is_async: bool, - pub(crate) deprecated: Option<&'a str>, pub(crate) return_type: Option, pub(crate) argument_types: &'a [Option], - pub(crate) docs: &'a [String], /// Literal argument replacements. /// TODO: replace this with structured information that includes type hash so it can be linked if it's available. pub(crate) arg_names: Option<&'a [String]>, /// Generic instance parameters for function. pub(crate) parameter_types: &'a [Hash], + pub(crate) deprecated: Option<&'a str>, + pub(crate) docs: &'a [String], } /// Information on an associated item. @@ -127,14 +128,13 @@ impl<'a> Context<'a> { Some(associated.iter().flat_map(move |hash| { let data = visitor.data.get(hash)?; - let (is_async, deprecated, kind) = match &data.kind { + let (is_async, kind) = match &data.kind { Some(meta::Kind::Function { associated: None, signature: f, .. }) => ( f.is_async, - f.deprecated.as_deref(), AssocFnKind::Method(data.item.last()?.as_str()?, f.args, Signature::Function), ), Some(meta::Kind::Function { @@ -143,7 +143,6 @@ impl<'a> Context<'a> { .. }) => ( f.is_async, - f.deprecated.as_deref(), AssocFnKind::Method(name.as_ref(), f.args, Signature::Instance), ), Some(meta::Kind::Variant { .. }) => { @@ -158,12 +157,12 @@ impl<'a> Context<'a> { Some(Assoc::Fn(AssocFn { kind, is_async, - deprecated, return_type: None, argument_types: &[], - docs: &data.docs, arg_names: None, parameter_types: &[], + deprecated: data.deprecated.as_deref(), + docs: &data.docs, })) })) } @@ -191,13 +190,13 @@ impl<'a> Context<'a> { Some(Assoc::Fn(AssocFn { kind, is_async: signature.is_async, - deprecated: signature.deprecated.as_deref(), return_type: signature.return_type, argument_types: &signature .argument_types, - docs: meta.docs.lines(), arg_names: meta.docs.args(), parameter_types: ¶meter_types[..], + deprecated: meta.deprecated.as_deref(), + docs: meta.docs.lines(), })) } meta::Kind::Function { associated: None, signature, .. } => { @@ -207,13 +206,13 @@ impl<'a> Context<'a> { Some(Assoc::Fn(AssocFn { kind, is_async: signature.is_async, - deprecated: signature.deprecated.as_deref(), return_type: signature.return_type, argument_types: &signature .argument_types, - docs: meta.docs.lines(), arg_names: meta.docs.args(), parameter_types: &[], + deprecated: meta.deprecated.as_deref(), + docs: meta.docs.lines(), })) } kind => { @@ -307,7 +306,6 @@ impl<'a> Context<'a> { } => { Kind::Function(Function { is_async: f.is_async, - deprecated: f.deprecated.as_deref(), signature: Signature::Function, arg_names: meta.docs.args(), args: f.args, @@ -322,7 +320,6 @@ impl<'a> Context<'a> { } => { Kind::Function(Function { is_async: f.is_async, - deprecated: f.deprecated.as_deref(), signature: Signature::Instance, arg_names: meta.docs.args(), args: f.args, @@ -340,11 +337,12 @@ impl<'a> Context<'a> { }; Some(Meta { + kind, source: MetaSource::Context, item: meta.item.as_deref(), hash: meta.hash, + deprecated: meta.deprecated.as_deref(), docs: meta.docs.lines(), - kind, }) } @@ -365,7 +363,6 @@ fn visitor_meta_to_meta<'a>(base: &'a Item, data: &'a VisitorData) -> Meta<'a> { Some(meta::Kind::Enum { .. }) => Kind::Enum, Some(meta::Kind::Function { associated, signature: f, .. }) => Kind::Function(Function { is_async: f.is_async, - deprecated: f.deprecated.as_deref(), arg_names: None, args: f.args, signature: match associated { @@ -383,6 +380,7 @@ fn visitor_meta_to_meta<'a>(base: &'a Item, data: &'a VisitorData) -> Meta<'a> { source: MetaSource::Source(base), item: Some(&data.item), hash: data.hash, + deprecated: None, docs: data.docs.as_slice(), kind, } diff --git a/crates/rune/src/doc/visitor.rs b/crates/rune/src/doc/visitor.rs index 45d6f4147..bb59a24dd 100644 --- a/crates/rune/src/doc/visitor.rs +++ b/crates/rune/src/doc/visitor.rs @@ -12,6 +12,7 @@ pub(crate) struct VisitorData { pub(crate) item: ItemBuf, pub(crate) hash: Hash, pub(crate) kind: Option, + pub(crate) deprecated: Option, pub(crate) docs: Vec, pub(crate) field_docs: HashMap, Vec>, } @@ -22,6 +23,7 @@ impl VisitorData { item, hash, kind, + deprecated: None, docs: Vec::new(), field_docs: HashMap::new(), } diff --git a/crates/rune/src/module.rs b/crates/rune/src/module.rs index 2e7be6af5..b456b4dce 100644 --- a/crates/rune/src/module.rs +++ b/crates/rune/src/module.rs @@ -17,7 +17,7 @@ use crate::alloc::prelude::*; #[cfg(feature = "doc")] use crate::alloc::Box; use crate::alloc::{self, Vec}; -use crate::compile::{meta, ContextError, Docs, IntoComponent, Item, ItemBuf}; +use crate::compile::{meta, ContextError, Docs, Item, ItemBuf}; use crate::runtime::{ AttributeMacroHandler, ConstValue, FullTypeOf, FunctionHandler, MacroHandler, MaybeTypeOf, StaticType, TypeCheck, TypeInfo, TypeOf, @@ -48,33 +48,20 @@ pub trait InstallWith { pub(crate) struct InternalEnum { /// The name of the internal enum. pub(crate) name: &'static str, - /// The result type. - pub(crate) base_type: ItemBuf, /// The static type of the enum. pub(crate) static_type: &'static StaticType, /// Internal variants. pub(crate) variants: Vec, - /// Documentation for internal enum. - pub(crate) docs: Docs, } impl InternalEnum { /// Construct a new handler for an internal enum. - fn new( - name: &'static str, - base_type: N, - static_type: &'static StaticType, - ) -> alloc::Result - where - N: IntoComponent, - { - Ok(InternalEnum { + fn new(name: &'static str, static_type: &'static StaticType) -> Self { + InternalEnum { name, - base_type: ItemBuf::with_item([base_type])?, static_type, variants: Vec::new(), - docs: Docs::EMPTY, - }) + } } /// Register a new variant. @@ -95,11 +82,18 @@ impl InternalEnum { type_check: Some(type_check), fields: Some(Fields::Unnamed(C::args())), constructor: Some(constructor), + #[cfg(feature = "doc")] + deprecated: None, docs: Docs::EMPTY, })?; let v = self.variants.last_mut().unwrap(); - Ok(ItemMut { docs: &mut v.docs }) + + Ok(ItemMut { + docs: &mut v.docs, + #[cfg(feature = "doc")] + deprecated: &mut v.deprecated, + }) } } @@ -109,6 +103,8 @@ pub(crate) struct ModuleType { /// The name of the installed type which will be the final component in the /// item it will constitute. pub(crate) item: ItemBuf, + /// Common item metadata. + pub(crate) common: ModuleItemCommon, /// Type hash. pub(crate) hash: Hash, /// Type parameters for this item. @@ -119,8 +115,6 @@ pub(crate) struct ModuleType { pub(crate) spec: Option, /// Handler to use if this type can be constructed through a regular function call. pub(crate) constructor: Option>, - /// Documentation for the type. - pub(crate) docs: Docs, } /// The kind of the variant. @@ -144,6 +138,8 @@ pub struct Variant { pub(crate) fields: Option, /// Handler to use if this variant can be constructed through a regular function call. pub(crate) constructor: Option>, + #[cfg(feature = "doc")] + pub(crate) deprecated: Option>, /// Variant documentation. pub(crate) docs: Docs, } @@ -155,6 +151,8 @@ impl Variant { type_check: None, fields: None, constructor: None, + #[cfg(feature = "doc")] + deprecated: None, docs: Docs::EMPTY, } } @@ -162,11 +160,13 @@ impl Variant { impl fmt::Debug for Variant { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Variant") - .field("fields", &self.fields) - .field("constructor", &self.constructor.is_some()) - .field("docs", &self.docs) - .finish() + let mut f = f.debug_struct("Variant"); + f.field("fields", &self.fields); + f.field("constructor", &self.constructor.is_some()); + #[cfg(feature = "doc")] + f.field("deprecated", &self.deprecated); + f.field("docs", &self.docs); + f.finish() } } @@ -194,30 +194,22 @@ pub(crate) struct AssociatedKey { pub(crate) parameters: Hash, } -#[derive(TryClone)] -pub(crate) struct ModuleFunction { - pub(crate) item: ItemBuf, - pub(crate) docs: Docs, - pub(crate) handler: Arc, - #[cfg(feature = "doc")] - pub(crate) is_async: bool, - #[cfg(feature = "doc")] - pub(crate) deprecated: Option>, - #[cfg(feature = "doc")] - pub(crate) args: Option, - #[cfg(feature = "doc")] - pub(crate) return_type: Option, - #[cfg(feature = "doc")] - pub(crate) argument_types: Box<[Option]>, +pub(crate) enum ModuleItemKind { + Constant(ConstValue), + Function(ModuleFunction), + Macro(ModuleMacro), + AttributeMacro(ModuleAttributeMacro), + InternalEnum(InternalEnum), } -#[derive(TryClone)] -pub(crate) struct ModuleAssociatedConstant { - pub(crate) value: ConstValue, +pub(crate) struct ModuleItem { + pub(crate) item: ItemBuf, + pub(crate) common: ModuleItemCommon, + pub(crate) kind: ModuleItemKind, } #[derive(TryClone)] -pub(crate) struct ModuleAssociatedFunction { +pub(crate) struct ModuleFunction { pub(crate) handler: Arc, #[cfg(feature = "doc")] pub(crate) is_async: bool, @@ -231,8 +223,17 @@ pub(crate) struct ModuleAssociatedFunction { #[derive(TryClone)] pub(crate) enum ModuleAssociatedKind { - Constant(ModuleAssociatedConstant), - Function(ModuleAssociatedFunction), + Constant(ConstValue), + Function(ModuleFunction), +} + +#[derive(Default, TryClone)] +pub(crate) struct ModuleItemCommon { + /// Documentation for the item. + pub(crate) docs: Docs, + /// Deprecation marker for the item. + #[cfg(feature = "doc")] + pub(crate) deprecated: Option>, } #[derive(TryClone)] @@ -240,37 +241,26 @@ pub(crate) struct ModuleAssociated { pub(crate) container: FullTypeOf, pub(crate) container_type_info: TypeInfo, pub(crate) name: AssociatedName, - pub(crate) docs: Docs, - #[cfg(feature = "doc")] - pub(crate) deprecated: Option>, + pub(crate) common: ModuleItemCommon, pub(crate) kind: ModuleAssociatedKind, } /// Handle to a macro inserted into a module. pub(crate) struct ModuleMacro { - pub(crate) item: ItemBuf, pub(crate) handler: Arc, - pub(crate) docs: Docs, } /// Handle to an attribute macro inserted into a module. pub(crate) struct ModuleAttributeMacro { - pub(crate) item: ItemBuf, pub(crate) handler: Arc, - pub(crate) docs: Docs, -} - -/// A constant registered in a module. -pub(crate) struct ModuleConstant { - pub(crate) item: ItemBuf, - pub(crate) value: ConstValue, - pub(crate) docs: Docs, } /// Handle to a an item inserted into a module which allows for mutation of item /// metadata. pub struct ItemMut<'a> { docs: &'a mut Docs, + #[cfg(feature = "doc")] + deprecated: &'a mut Option>, } impl ItemMut<'_> { @@ -293,6 +283,22 @@ impl ItemMut<'_> { self.docs.set_docs(docs)?; Ok(self) } + + /// Mark the given item as deprecated. + pub fn deprecated( + self, + #[cfg_attr(not(feature = "doc"), allow(unused))] deprecated: S, + ) -> Result + where + S: AsRef, + { + #[cfg(feature = "doc")] + { + *self.deprecated = Some(deprecated.as_ref().try_into()?); + } + + Ok(self) + } } impl fmt::Debug for ItemMut<'_> { @@ -318,10 +324,10 @@ impl fmt::Debug for ItemMut<'_> { pub struct ItemFnMut<'a> { docs: &'a mut Docs, #[cfg(feature = "doc")] - is_async: &'a mut bool, - #[cfg(feature = "doc")] deprecated: &'a mut Option>, #[cfg(feature = "doc")] + is_async: &'a mut bool, + #[cfg(feature = "doc")] args: &'a mut Option, #[cfg(feature = "doc")] return_type: &'a mut Option, @@ -556,6 +562,7 @@ where T: ?Sized + TypeOf, { enum_: &'a mut InternalEnum, + common: &'a mut ModuleItemCommon, _marker: PhantomData, } @@ -571,7 +578,7 @@ where I: IntoIterator, I::Item: AsRef, { - self.enum_.docs.set_docs(docs)?; + self.common.docs.set_docs(docs)?; Ok(self) } @@ -579,7 +586,23 @@ where /// /// This completely replaces any existing documentation. pub fn static_docs(self, docs: &'static [&'static str]) -> Result { - self.enum_.docs.set_docs(docs)?; + self.common.docs.set_docs(docs)?; + Ok(self) + } + + /// Mark the given type as deprecated. + pub fn deprecated( + self, + #[cfg_attr(not(feature = "doc"), allow(unused))] deprecated: S, + ) -> Result + where + S: AsRef, + { + #[cfg(feature = "doc")] + { + self.common.deprecated = Some(deprecated.as_ref().try_into()?); + } + Ok(self) } @@ -614,6 +637,8 @@ where T: ?Sized + TypeOf, { docs: &'a mut Docs, + #[cfg(feature = "doc")] + deprecated: &'a mut Option>, spec: &'a mut Option, constructor: &'a mut Option>, item: &'a Item, @@ -644,6 +669,22 @@ where Ok(self) } + /// Mark the given type as deprecated. + pub fn deprecated( + self, + #[cfg_attr(not(feature = "doc"), allow(unused))] deprecated: S, + ) -> Result + where + S: AsRef, + { + #[cfg(feature = "doc")] + { + *self.deprecated = Some(deprecated.as_ref().try_into()?); + } + + Ok(self) + } + /// Mark the current type as a struct with named fields. pub fn make_named_struct(self, fields: &'static [&'static str]) -> Result { self.make_struct(Fields::Named(fields)) diff --git a/crates/rune/src/module/function_meta.rs b/crates/rune/src/module/function_meta.rs index 0bda74d6c..88bdc2977 100644 --- a/crates/rune/src/module/function_meta.rs +++ b/crates/rune/src/module/function_meta.rs @@ -57,8 +57,6 @@ pub struct FunctionData { #[cfg(feature = "doc")] pub(crate) is_async: bool, #[cfg(feature = "doc")] - pub(crate) deprecated: Option>, - #[cfg(feature = "doc")] pub(crate) args: Option, #[cfg(feature = "doc")] pub(crate) return_type: Option, @@ -74,8 +72,6 @@ impl FunctionData { #[cfg(feature = "doc")] is_async: false, #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] args: None, #[cfg(feature = "doc")] return_type: None, @@ -99,8 +95,6 @@ impl FunctionData { #[cfg(feature = "doc")] is_async: K::is_async(), #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] args: Some(F::args()), #[cfg(feature = "doc")] return_type: F::Return::maybe_type_of(), @@ -272,8 +266,6 @@ pub struct AssociatedFunctionData { #[cfg(feature = "doc")] pub(crate) is_async: bool, #[cfg(feature = "doc")] - pub(crate) deprecated: Option>, - #[cfg(feature = "doc")] pub(crate) args: Option, #[cfg(feature = "doc")] pub(crate) return_type: Option, @@ -289,8 +281,6 @@ impl AssociatedFunctionData { #[cfg(feature = "doc")] is_async: false, #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] args: None, #[cfg(feature = "doc")] return_type: None, @@ -313,8 +303,6 @@ impl AssociatedFunctionData { #[cfg(feature = "doc")] is_async: K::is_async(), #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] args: Some(F::args()), #[cfg(feature = "doc")] return_type: F::Return::maybe_type_of(), @@ -337,8 +325,6 @@ impl AssociatedFunctionData { #[cfg(feature = "doc")] is_async: K::is_async(), #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] args: Some(F::args()), #[cfg(feature = "doc")] return_type: F::Return::maybe_type_of(), @@ -528,6 +514,8 @@ pub struct FunctionMetaData { #[doc(hidden)] pub name: &'static str, #[doc(hidden)] + pub deprecated: Option<&'static str>, + #[doc(hidden)] pub docs: &'static [&'static str], #[doc(hidden)] pub arguments: &'static [&'static str], diff --git a/crates/rune/src/module/module.rs b/crates/rune/src/module/module.rs index 7f10fdd32..ea1ddd8d2 100644 --- a/crates/rune/src/module/module.rs +++ b/crates/rune/src/module/module.rs @@ -4,7 +4,7 @@ use ::rust_alloc::sync::Arc; use crate as rune; use crate::alloc::prelude::*; -use crate::alloc::{self, HashMap, HashSet, String, Vec}; +use crate::alloc::{self, Box, HashMap, HashSet, String, Vec}; use crate::compile::{self, meta, ContextError, Docs, IntoComponent, ItemBuf, Named}; use crate::macros::{MacroContext, TokenStream}; use crate::module::function_meta::{ @@ -14,9 +14,9 @@ use crate::module::function_meta::{ }; use crate::module::{ AssociatedKey, Async, EnumMut, Function, FunctionKind, InstallWith, InstanceFunction, - InternalEnum, InternalEnumMut, ItemFnMut, ItemMut, ModuleAssociated, ModuleAssociatedConstant, - ModuleAssociatedFunction, ModuleAssociatedKind, ModuleAttributeMacro, ModuleConstant, - ModuleFunction, ModuleMacro, ModuleType, Plain, TypeMut, TypeSpecification, VariantMut, + InternalEnum, InternalEnumMut, ItemFnMut, ItemMut, ModuleAssociated, ModuleAssociatedKind, + ModuleAttributeMacro, ModuleFunction, ModuleItem, ModuleItemCommon, ModuleItemKind, + ModuleMacro, ModuleType, Plain, TypeMut, TypeSpecification, VariantMut, }; use crate::runtime::{ AttributeMacroHandler, ConstValue, FromValue, FullTypeOf, FunctionHandler, GeneratorState, @@ -404,23 +404,15 @@ pub struct Module { /// The name of the module. pub(crate) item: ItemBuf, /// Functions. - pub(crate) functions: Vec, - /// MacroHandler handlers. - pub(crate) macros: Vec, - /// AttributeMacroHandler handlers. - pub(crate) attribute_macros: Vec, - /// Constant values. - pub(crate) constants: Vec, + pub(crate) items: Vec, /// Associated items. pub(crate) associated: Vec, /// Registered types. pub(crate) types: Vec, /// Type hash to types mapping. pub(crate) types_hash: HashMap, - /// Registered generator state type. - pub(crate) internal_enums: Vec, - /// Module level documentation. - pub(crate) docs: Docs, + /// Module level metadata. + pub(crate) common: ModuleItemCommon, } impl Module { @@ -474,22 +466,24 @@ impl Module { names: HashSet::new(), unique: None, item, - functions: Vec::new(), - macros: Vec::new(), - attribute_macros: Vec::new(), + items: Vec::new(), associated: Vec::new(), types: Vec::new(), types_hash: HashMap::new(), - internal_enums: Vec::new(), - constants: Vec::new(), - docs: Docs::EMPTY, + common: ModuleItemCommon { + docs: Docs::EMPTY, + #[cfg(feature = "doc")] + deprecated: None, + }, } } /// Mutate item-level properties for this module. pub fn item_mut(&mut self) -> ItemMut<'_> { ItemMut { - docs: &mut self.docs, + docs: &mut self.common.docs, + #[cfg(feature = "doc")] + deprecated: &mut self.common.deprecated, } } @@ -556,12 +550,16 @@ impl Module { self.types.try_push(ModuleType { item, + common: ModuleItemCommon { + docs: Docs::EMPTY, + #[cfg(feature = "doc")] + deprecated: None, + }, hash, type_parameters, type_info, spec: None, constructor: None, - docs: Docs::EMPTY, })?; T::install_with(self)?; @@ -569,7 +567,9 @@ impl Module { let ty = self.types.last_mut().unwrap(); Ok(TypeMut { - docs: &mut ty.docs, + docs: &mut ty.common.docs, + #[cfg(feature = "doc")] + deprecated: &mut ty.common.deprecated, spec: &mut ty.spec, constructor: &mut ty.constructor, item: &ty.item, @@ -594,7 +594,9 @@ impl Module { }; Ok(TypeMut { - docs: &mut ty.docs, + docs: &mut ty.common.docs, + #[cfg(feature = "doc")] + deprecated: &mut ty.common.deprecated, spec: &mut ty.spec, constructor: &mut ty.constructor, item: &ty.item, @@ -714,9 +716,8 @@ impl Module { { let mut enum_ = InternalEnum::new( "GeneratorState", - name, crate::runtime::static_type::GENERATOR_STATE_TYPE, - )?; + ); // Note: these numeric variants are magic, and must simply match up with // what's being used in the virtual machine implementation for these @@ -733,12 +734,7 @@ impl Module { GeneratorState::Yielded, )?; - self.internal_enums.try_push(enum_)?; - - Ok(InternalEnumMut { - enum_: self.internal_enums.last_mut().unwrap(), - _marker: PhantomData, - }) + self.install_internal_enum(name, enum_) } /// Construct type information for the `Option` type. /// @@ -760,20 +756,15 @@ impl Module { where N: IntoComponent, { - let mut enum_ = - InternalEnum::new("Option", name, crate::runtime::static_type::OPTION_TYPE)?; + let mut enum_ = InternalEnum::new("Option", crate::runtime::static_type::OPTION_TYPE); // Note: these numeric variants are magic, and must simply match up with // what's being used in the virtual machine implementation for these // types. enum_.variant("Some", TypeCheck::Option(0), Option::::Some)?; enum_.variant("None", TypeCheck::Option(1), || Option::::None)?; - self.internal_enums.try_push(enum_)?; - Ok(InternalEnumMut { - enum_: self.internal_enums.last_mut().unwrap(), - _marker: PhantomData, - }) + self.install_internal_enum(name, enum_) } /// Construct type information for the internal `Result` type. @@ -799,18 +790,42 @@ impl Module { where N: IntoComponent, { - let mut enum_ = - InternalEnum::new("Result", name, crate::runtime::static_type::RESULT_TYPE)?; + let mut enum_ = InternalEnum::new("Result", crate::runtime::static_type::RESULT_TYPE); // Note: these numeric variants are magic, and must simply match up with // what's being used in the virtual machine implementation for these // types. enum_.variant("Ok", TypeCheck::Result(0), Result::::Ok)?; enum_.variant("Err", TypeCheck::Result(1), Result::::Err)?; - self.internal_enums.try_push(enum_)?; + + self.install_internal_enum(name, enum_) + } + + fn install_internal_enum( + &mut self, + name: N, + enum_: InternalEnum, + ) -> Result, ContextError> + where + N: IntoComponent, + T: ?Sized + TypeOf, + { + self.items.try_push(ModuleItem { + item: ItemBuf::with_item([name])?, + common: ModuleItemCommon::default(), + kind: ModuleItemKind::InternalEnum(enum_), + })?; + + let item = self.items.last_mut().unwrap(); + + let internal_enum = match &mut item.kind { + ModuleItemKind::InternalEnum(internal_enum) => internal_enum, + _ => unreachable!(), + }; Ok(InternalEnumMut { - enum_: self.internal_enums.last_mut().unwrap(), + enum_: internal_enum, + common: &mut item.common, _marker: PhantomData, }) } @@ -862,14 +877,23 @@ impl Module { return Err(ContextError::ConflictingConstantName { item, hash }); } - self.constants.try_push(ModuleConstant { + self.items.try_push(ModuleItem { item, - value, - docs: Docs::EMPTY, + common: ModuleItemCommon { + docs: Docs::EMPTY, + #[cfg(feature = "doc")] + deprecated: None, + }, + kind: ModuleItemKind::Constant(value), })?; - let c = self.constants.last_mut().unwrap(); - Ok(ItemMut { docs: &mut c.docs }) + let c = self.items.last_mut().unwrap(); + + Ok(ItemMut { + docs: &mut c.common.docs, + #[cfg(feature = "doc")] + deprecated: &mut c.common.deprecated, + }) } fn insert_associated_constant( @@ -896,16 +920,20 @@ impl Module { container: associated.container, container_type_info: associated.container_type_info, name: associated.name, - #[cfg(feature = "doc")] - deprecated: None, - docs: Docs::EMPTY, - kind: ModuleAssociatedKind::Constant(ModuleAssociatedConstant { value }), + common: ModuleItemCommon { + docs: Docs::EMPTY, + #[cfg(feature = "doc")] + deprecated: None, + }, + kind: ModuleAssociatedKind::Constant(value), })?; let last = self.associated.last_mut().unwrap(); Ok(ItemMut { - docs: &mut last.docs, + docs: &mut last.common.docs, + #[cfg(feature = "doc")] + deprecated: &mut last.common.deprecated, }) } @@ -953,7 +981,7 @@ impl Module { pub fn macro_meta(&mut self, meta: MacroMeta) -> Result, ContextError> { let meta = meta()?; - let docs = match meta.kind { + let item = match meta.kind { MacroMetaKind::Function(data) => { let hash = Hash::type_hash(&data.item); @@ -967,12 +995,19 @@ impl Module { let mut docs = Docs::EMPTY; docs.set_docs(meta.docs)?; - self.macros.try_push(ModuleMacro { + self.items.try_push(ModuleItem { item: data.item, - handler: data.handler, - docs, + common: ModuleItemCommon { + docs, + #[cfg(feature = "doc")] + deprecated: None, + }, + kind: ModuleItemKind::Macro(ModuleMacro { + handler: data.handler, + }), })?; - &mut self.macros.last_mut().unwrap().docs + + self.items.last_mut().unwrap() } MacroMetaKind::Attribute(data) => { let hash = Hash::type_hash(&data.item); @@ -987,16 +1022,27 @@ impl Module { let mut docs = Docs::EMPTY; docs.set_docs(meta.docs)?; - self.attribute_macros.try_push(ModuleAttributeMacro { + self.items.try_push(ModuleItem { item: data.item, - handler: data.handler, - docs, + common: ModuleItemCommon { + docs, + #[cfg(feature = "doc")] + deprecated: None, + }, + kind: ModuleItemKind::AttributeMacro(ModuleAttributeMacro { + handler: data.handler, + }), })?; - &mut self.attribute_macros.last_mut().unwrap().docs + + self.items.last_mut().unwrap() } }; - Ok(ItemMut { docs }) + Ok(ItemMut { + docs: &mut item.common.docs, + #[cfg(feature = "doc")] + deprecated: &mut item.common.deprecated, + }) } /// Register a native macro handler. @@ -1044,15 +1090,19 @@ impl Module { let handler: Arc = Arc::new(f); - self.macros.try_push(ModuleMacro { + self.items.try_push(ModuleItem { item, - handler, - docs: Docs::EMPTY, + common: ModuleItemCommon::default(), + kind: ModuleItemKind::Macro(ModuleMacro { handler }), })?; - let m = self.macros.last_mut().unwrap(); + let m = self.items.last_mut().unwrap(); - Ok(ItemMut { docs: &mut m.docs }) + Ok(ItemMut { + docs: &mut m.common.docs, + #[cfg(feature = "doc")] + deprecated: &mut m.common.deprecated, + }) } /// Register a native attribute macro handler. @@ -1104,15 +1154,23 @@ impl Module { let handler: Arc = Arc::new(f); - self.attribute_macros.try_push(ModuleAttributeMacro { + self.items.try_push(ModuleItem { item, - handler, - docs: Docs::EMPTY, + common: ModuleItemCommon { + docs: Docs::EMPTY, + #[cfg(feature = "doc")] + deprecated: None, + }, + kind: ModuleItemKind::AttributeMacro(ModuleAttributeMacro { handler }), })?; - let m = self.attribute_macros.last_mut().unwrap(); + let m = self.items.last_mut().unwrap(); - Ok(ItemMut { docs: &mut m.docs }) + Ok(ItemMut { + docs: &mut m.common.docs, + #[cfg(feature = "doc")] + deprecated: &mut m.common.deprecated, + }) } /// Register a function handler through its meta. @@ -1195,13 +1253,15 @@ impl Module { let mut docs = Docs::EMPTY; docs.set_docs(meta.docs)?; docs.set_arguments(meta.arguments)?; - self.function_inner(data, docs) + let deprecated = meta.deprecated.map(TryInto::try_into).transpose()?; + self.function_inner(data, docs, deprecated) } FunctionMetaKind::AssociatedFunction(data) => { let mut docs = Docs::EMPTY; docs.set_docs(meta.docs)?; docs.set_arguments(meta.arguments)?; - self.insert_associated_function(data, docs) + let deprecated = meta.deprecated.map(TryInto::try_into).transpose()?; + self.insert_associated_function(data, docs, deprecated) } } } @@ -1211,9 +1271,9 @@ impl Module { kind: FunctionMetaKind, ) -> Result, ContextError> { match kind { - FunctionMetaKind::Function(data) => self.function_inner(data, Docs::EMPTY), + FunctionMetaKind::Function(data) => self.function_inner(data, Docs::EMPTY, None), FunctionMetaKind::AssociatedFunction(data) => { - self.insert_associated_function(data, Docs::EMPTY) + self.insert_associated_function(data, Docs::EMPTY, None) } } } @@ -1302,7 +1362,7 @@ impl Module { N: IntoComponent, A: FunctionArgs, { - self.function_inner(FunctionData::new(name, f)?, Docs::EMPTY) + self.function_inner(FunctionData::new(name, f)?, Docs::EMPTY, None) } /// Register an instance function. @@ -1498,6 +1558,7 @@ impl Module { self.insert_associated_function( AssociatedFunctionData::from_instance_function(name.to_instance()?, f)?, Docs::EMPTY, + None, ) } @@ -1546,6 +1607,7 @@ impl Module { self.insert_associated_function( AssociatedFunctionData::from_instance_function(name.to_field_function(protocol)?, f)?, Docs::EMPTY, + None, ) } @@ -1586,6 +1648,7 @@ impl Module { self.insert_associated_function( AssociatedFunctionData::from_instance_function(name, f)?, Docs::EMPTY, + None, ) } @@ -1665,6 +1728,7 @@ impl Module { &mut self, data: FunctionData, docs: Docs, + #[allow(unused)] deprecated: Option>, ) -> Result, ContextError> { let hash = Hash::type_hash(&data.item); @@ -1675,36 +1739,46 @@ impl Module { }); } - self.functions.try_push(ModuleFunction { + self.items.try_push(ModuleItem { item: data.item, - handler: data.handler, - #[cfg(feature = "doc")] - is_async: data.is_async, - #[cfg(feature = "doc")] - deprecated: data.deprecated, - #[cfg(feature = "doc")] - args: data.args, - #[cfg(feature = "doc")] - return_type: data.return_type, - #[cfg(feature = "doc")] - argument_types: data.argument_types, - docs, + common: ModuleItemCommon { + docs, + #[cfg(feature = "doc")] + deprecated, + }, + kind: ModuleItemKind::Function(ModuleFunction { + handler: data.handler, + #[cfg(feature = "doc")] + is_async: data.is_async, + #[cfg(feature = "doc")] + args: data.args, + #[cfg(feature = "doc")] + return_type: data.return_type, + #[cfg(feature = "doc")] + argument_types: data.argument_types, + }), })?; - let last = self.functions.last_mut().unwrap(); + let last = self.items.last_mut().unwrap(); + + #[cfg(feature = "doc")] + let last_fn = match &mut last.kind { + ModuleItemKind::Function(f) => f, + _ => unreachable!(), + }; Ok(ItemFnMut { - docs: &mut last.docs, + docs: &mut last.common.docs, #[cfg(feature = "doc")] - is_async: &mut last.is_async, + deprecated: &mut last.common.deprecated, #[cfg(feature = "doc")] - deprecated: &mut last.deprecated, + is_async: &mut last_fn.is_async, #[cfg(feature = "doc")] - args: &mut last.args, + args: &mut last_fn.args, #[cfg(feature = "doc")] - return_type: &mut last.return_type, + return_type: &mut last_fn.return_type, #[cfg(feature = "doc")] - argument_types: &mut last.argument_types, + argument_types: &mut last_fn.argument_types, }) } @@ -1713,6 +1787,7 @@ impl Module { &mut self, data: AssociatedFunctionData, docs: Docs, + #[allow(unused)] deprecated: Option>, ) -> Result, ContextError> { self.insert_associated_name(&data.associated)?; @@ -1720,15 +1795,16 @@ impl Module { container: data.associated.container, container_type_info: data.associated.container_type_info, name: data.associated.name, - #[cfg(feature = "doc")] - deprecated: data.deprecated, - docs, - kind: ModuleAssociatedKind::Function(ModuleAssociatedFunction { + common: ModuleItemCommon { + docs, + #[cfg(feature = "doc")] + deprecated, + }, + kind: ModuleAssociatedKind::Function(ModuleFunction { handler: data.handler, #[cfg(feature = "doc")] is_async: data.is_async, #[cfg(feature = "doc")] - #[cfg(feature = "doc")] args: data.args, #[cfg(feature = "doc")] return_type: data.return_type, @@ -1746,11 +1822,11 @@ impl Module { }; Ok(ItemFnMut { - docs: &mut last.docs, + docs: &mut last.common.docs, #[cfg(feature = "doc")] - is_async: &mut last_fn.is_async, + deprecated: &mut last.common.deprecated, #[cfg(feature = "doc")] - deprecated: &mut last.deprecated, + is_async: &mut last_fn.is_async, #[cfg(feature = "doc")] args: &mut last_fn.args, #[cfg(feature = "doc")] diff --git a/crates/rune/src/query/query.rs b/crates/rune/src/query/query.rs index 6d2a9b85c..ba8663207 100644 --- a/crates/rune/src/query/query.rs +++ b/crates/rune/src/query/query.rs @@ -1363,8 +1363,6 @@ impl<'a, 'arena> Query<'a, 'arena> { #[cfg(feature = "doc")] is_async: matches!(f.call, Call::Async | Call::Stream), #[cfg(feature = "doc")] - deprecated: None, - #[cfg(feature = "doc")] args: Some(f.ast.args()), #[cfg(feature = "doc")] return_type: None,