From 9b9b8fd44f92bbdac20fe2623c7d9b930f1089fb Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Tue, 18 Feb 2025 12:41:28 +0000 Subject: [PATCH] feat(ast)!: add `pure` field to `Function`, `CallExpression`, and `NewExpression` --- crates/oxc_ast/src/ast/js.rs | 12 ++ crates/oxc_ast/src/ast_builder_impl.rs | 47 +++++- .../oxc_ast/src/generated/assert_layouts.rs | 12 +- crates/oxc_ast/src/generated/ast_builder.rs | 153 +++++++++++++++++- .../oxc_ast/src/generated/derive_clone_in.rs | 3 + .../src/generated/derive_content_eq.rs | 3 + crates/oxc_traverse/src/generated/ancestor.rs | 63 ++++++++ 7 files changed, 281 insertions(+), 12 deletions(-) diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index a4c006cd1ba671..a1d75a19f0996f 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -576,6 +576,10 @@ pub struct CallExpression<'a> { pub type_parameters: Option>>, pub arguments: Vec<'a, Argument<'a>>, pub optional: bool, // for optional chaining + /// `true` if the call expression is marked with a `/* @__PURE__ */` comment + #[builder(default)] + #[estree(skip)] + pub pure: bool, } /// `new C()` in `class C {}; new C();` @@ -599,6 +603,10 @@ pub struct NewExpression<'a> { pub arguments: Vec<'a, Argument<'a>>, #[ts] pub type_parameters: Option>>, + /// `true` if the new expression is marked with a `/* @__PURE__ */` comment + #[builder(default)] + #[estree(skip)] + pub pure: bool, } /// `import.meta` in `console.log(import.meta);` @@ -1706,6 +1714,10 @@ pub struct Function<'a> { /// ``` pub body: Option>>, pub scope_id: Cell>, + /// `true` if the function is marked with a `/*#__NO_SIDE_EFFECTS__*/` comment + #[builder(default)] + #[estree(skip)] + pub pure: bool, } #[ast] diff --git a/crates/oxc_ast/src/ast_builder_impl.rs b/crates/oxc_ast/src/ast_builder_impl.rs index f18332ad8adb03..ea00fa29cd82f6 100644 --- a/crates/oxc_ast/src/ast_builder_impl.rs +++ b/crates/oxc_ast/src/ast_builder_impl.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, mem}; -use oxc_allocator::{Allocator, Box, FromIn, Vec}; +use oxc_allocator::{Allocator, Box, FromIn, IntoIn, Vec}; use oxc_span::{Atom, Span, SPAN}; use oxc_syntax::{number::NumberBase, operator::UnaryOperator, scope::ScopeId}; @@ -273,7 +273,7 @@ impl<'a> AstBuilder<'a> { body: FunctionBody<'a>, scope_id: ScopeId, ) -> Box<'a, Function<'a>> { - self.alloc_function_with_scope_id( + self.alloc_function_with_scope_id_and_pure( span, r#type, id, @@ -286,6 +286,49 @@ impl<'a> AstBuilder<'a> { NONE, Some(body), scope_id, + false, + ) + } + + /// Build a [`Function`] with `scope_id`. + #[expect(clippy::too_many_arguments)] + #[inline] + pub fn alloc_function_with_scope_id( + self, + span: Span, + r#type: FunctionType, + id: Option>, + generator: bool, + r#async: bool, + declare: bool, + type_parameters: T1, + this_param: T2, + params: T3, + return_type: T4, + body: T5, + scope_id: ScopeId, + ) -> Box<'a, Function<'a>> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Option>>>, + T3: IntoIn<'a, Box<'a, FormalParameters<'a>>>, + T4: IntoIn<'a, Option>>>, + T5: IntoIn<'a, Option>>>, + { + self.alloc_function_with_scope_id_and_pure( + span, + r#type, + id, + generator, + r#async, + declare, + type_parameters, + this_param, + params, + return_type, + body, + scope_id, + false, ) } diff --git a/crates/oxc_ast/src/generated/assert_layouts.rs b/crates/oxc_ast/src/generated/assert_layouts.rs index 52b330af838fdc..a4f76c0d9eedea 100644 --- a/crates/oxc_ast/src/generated/assert_layouts.rs +++ b/crates/oxc_ast/src/generated/assert_layouts.rs @@ -145,13 +145,15 @@ const _: () = { assert!(offset_of!(CallExpression, type_parameters) == 24); assert!(offset_of!(CallExpression, arguments) == 32); assert!(offset_of!(CallExpression, optional) == 64); + assert!(offset_of!(CallExpression, pure) == 65); - assert!(size_of::() == 64); + assert!(size_of::() == 72); assert!(align_of::() == 8); assert!(offset_of!(NewExpression, span) == 0); assert!(offset_of!(NewExpression, callee) == 8); assert!(offset_of!(NewExpression, arguments) == 24); assert!(offset_of!(NewExpression, type_parameters) == 56); + assert!(offset_of!(NewExpression, pure) == 64); assert!(size_of::() == 56); assert!(align_of::() == 8); @@ -516,6 +518,7 @@ const _: () = { assert!(offset_of!(Function, return_type) == 80); assert!(offset_of!(Function, body) == 88); assert!(offset_of!(Function, scope_id) == 96); + assert!(offset_of!(Function, pure) == 100); assert!(size_of::() == 1); assert!(align_of::() == 1); @@ -1722,13 +1725,15 @@ const _: () = { assert!(offset_of!(CallExpression, type_parameters) == 16); assert!(offset_of!(CallExpression, arguments) == 20); assert!(offset_of!(CallExpression, optional) == 36); + assert!(offset_of!(CallExpression, pure) == 37); - assert!(size_of::() == 36); + assert!(size_of::() == 40); assert!(align_of::() == 4); assert!(offset_of!(NewExpression, span) == 0); assert!(offset_of!(NewExpression, callee) == 8); assert!(offset_of!(NewExpression, arguments) == 16); assert!(offset_of!(NewExpression, type_parameters) == 32); + assert!(offset_of!(NewExpression, pure) == 36); assert!(size_of::() == 40); assert!(align_of::() == 4); @@ -2079,7 +2084,7 @@ const _: () = { assert!(offset_of!(BindingRestElement, span) == 0); assert!(offset_of!(BindingRestElement, argument) == 8); - assert!(size_of::() == 60); + assert!(size_of::() == 64); assert!(align_of::() == 4); assert!(offset_of!(Function, span) == 0); assert!(offset_of!(Function, r#type) == 8); @@ -2093,6 +2098,7 @@ const _: () = { assert!(offset_of!(Function, return_type) == 48); assert!(offset_of!(Function, body) == 52); assert!(offset_of!(Function, scope_id) == 56); + assert!(offset_of!(Function, pure) == 60); assert!(size_of::() == 1); assert!(align_of::() == 1); diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index b476eaa0d8137c..dc20dbb8a4d95a 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -1843,6 +1843,7 @@ impl<'a> AstBuilder<'a> { type_parameters: type_parameters.into_in(self.allocator), arguments, optional, + pure: Default::default(), } } @@ -1874,6 +1875,77 @@ impl<'a> AstBuilder<'a> { ) } + /// Build a [`CallExpression`] with `pure`. + /// + /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_call_expression_with_pure`] instead. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `callee` + /// * `type_parameters` + /// * `arguments` + /// * `optional` + /// * `pure`: `true` if the call expression is marked with a `/* @__PURE__ */` comment + #[inline] + pub fn call_expression_with_pure( + self, + span: Span, + callee: Expression<'a>, + type_parameters: T1, + arguments: Vec<'a, Argument<'a>>, + optional: bool, + pure: bool, + ) -> CallExpression<'a> + where + T1: IntoIn<'a, Option>>>, + { + CallExpression { + span, + callee, + type_parameters: type_parameters.into_in(self.allocator), + arguments, + optional, + pure, + } + } + + /// Build a [`CallExpression`] with `pure`, and store it in the memory arena. + /// + /// Returns a [`Box`] containing the newly-allocated node. If you want a stack-allocated node, use [`AstBuilder::call_expression_with_pure`] instead. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `callee` + /// * `type_parameters` + /// * `arguments` + /// * `optional` + /// * `pure`: `true` if the call expression is marked with a `/* @__PURE__ */` comment + #[inline] + pub fn alloc_call_expression_with_pure( + self, + span: Span, + callee: Expression<'a>, + type_parameters: T1, + arguments: Vec<'a, Argument<'a>>, + optional: bool, + pure: bool, + ) -> Box<'a, CallExpression<'a>> + where + T1: IntoIn<'a, Option>>>, + { + Box::new_in( + self.call_expression_with_pure( + span, + callee, + type_parameters, + arguments, + optional, + pure, + ), + self.allocator, + ) + } + /// Build a [`NewExpression`]. /// /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_new_expression`] instead. @@ -1899,6 +1971,7 @@ impl<'a> AstBuilder<'a> { callee, arguments, type_parameters: type_parameters.into_in(self.allocator), + pure: Default::default(), } } @@ -1925,6 +1998,65 @@ impl<'a> AstBuilder<'a> { Box::new_in(self.new_expression(span, callee, arguments, type_parameters), self.allocator) } + /// Build a [`NewExpression`] with `pure`. + /// + /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_new_expression_with_pure`] instead. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `callee` + /// * `arguments` + /// * `type_parameters` + /// * `pure`: `true` if the new expression is marked with a `/* @__PURE__ */` comment + #[inline] + pub fn new_expression_with_pure( + self, + span: Span, + callee: Expression<'a>, + arguments: Vec<'a, Argument<'a>>, + type_parameters: T1, + pure: bool, + ) -> NewExpression<'a> + where + T1: IntoIn<'a, Option>>>, + { + NewExpression { + span, + callee, + arguments, + type_parameters: type_parameters.into_in(self.allocator), + pure, + } + } + + /// Build a [`NewExpression`] with `pure`, and store it in the memory arena. + /// + /// Returns a [`Box`] containing the newly-allocated node. If you want a stack-allocated node, use [`AstBuilder::new_expression_with_pure`] instead. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `callee` + /// * `arguments` + /// * `type_parameters` + /// * `pure`: `true` if the new expression is marked with a `/* @__PURE__ */` comment + #[inline] + pub fn alloc_new_expression_with_pure( + self, + span: Span, + callee: Expression<'a>, + arguments: Vec<'a, Argument<'a>>, + type_parameters: T1, + pure: bool, + ) -> Box<'a, NewExpression<'a>> + where + T1: IntoIn<'a, Option>>>, + { + Box::new_in( + self.new_expression_with_pure(span, callee, arguments, type_parameters, pure), + self.allocator, + ) + } + /// Build a [`MetaProperty`]. /// /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_meta_property`] instead. @@ -5085,6 +5217,7 @@ impl<'a> AstBuilder<'a> { return_type: return_type.into_in(self.allocator), body: body.into_in(self.allocator), scope_id: Default::default(), + pure: Default::default(), } } @@ -5144,9 +5277,9 @@ impl<'a> AstBuilder<'a> { ) } - /// Build a [`Function`] with `scope_id`. + /// Build a [`Function`] with `scope_id` and `pure`. /// - /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_function_with_scope_id`] instead. + /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_function_with_scope_id_and_pure`] instead. /// /// ## Parameters /// * `span`: The [`Span`] covering this node @@ -5161,8 +5294,9 @@ impl<'a> AstBuilder<'a> { /// * `return_type`: The TypeScript return type annotation. /// * `body`: The function body. /// * `scope_id` + /// * `pure`: `true` if the function is marked with a `/*#__NO_SIDE_EFFECTS__*/` comment #[inline] - pub fn function_with_scope_id( + pub fn function_with_scope_id_and_pure( self, span: Span, r#type: FunctionType, @@ -5176,6 +5310,7 @@ impl<'a> AstBuilder<'a> { return_type: T4, body: T5, scope_id: ScopeId, + pure: bool, ) -> Function<'a> where T1: IntoIn<'a, Option>>>, @@ -5197,12 +5332,13 @@ impl<'a> AstBuilder<'a> { return_type: return_type.into_in(self.allocator), body: body.into_in(self.allocator), scope_id: Cell::new(Some(scope_id)), + pure, } } - /// Build a [`Function`] with `scope_id`, and store it in the memory arena. + /// Build a [`Function`] with `scope_id` and `pure`, and store it in the memory arena. /// - /// Returns a [`Box`] containing the newly-allocated node. If you want a stack-allocated node, use [`AstBuilder::function_with_scope_id`] instead. + /// Returns a [`Box`] containing the newly-allocated node. If you want a stack-allocated node, use [`AstBuilder::function_with_scope_id_and_pure`] instead. /// /// ## Parameters /// * `span`: The [`Span`] covering this node @@ -5217,8 +5353,9 @@ impl<'a> AstBuilder<'a> { /// * `return_type`: The TypeScript return type annotation. /// * `body`: The function body. /// * `scope_id` + /// * `pure`: `true` if the function is marked with a `/*#__NO_SIDE_EFFECTS__*/` comment #[inline] - pub fn alloc_function_with_scope_id( + pub fn alloc_function_with_scope_id_and_pure( self, span: Span, r#type: FunctionType, @@ -5232,6 +5369,7 @@ impl<'a> AstBuilder<'a> { return_type: T4, body: T5, scope_id: ScopeId, + pure: bool, ) -> Box<'a, Function<'a>> where T1: IntoIn<'a, Option>>>, @@ -5241,7 +5379,7 @@ impl<'a> AstBuilder<'a> { T5: IntoIn<'a, Option>>>, { Box::new_in( - self.function_with_scope_id( + self.function_with_scope_id_and_pure( span, r#type, id, @@ -5254,6 +5392,7 @@ impl<'a> AstBuilder<'a> { return_type, body, scope_id, + pure, ), self.allocator, ) diff --git a/crates/oxc_ast/src/generated/derive_clone_in.rs b/crates/oxc_ast/src/generated/derive_clone_in.rs index 6faaae0bd28db5..fa16edada37167 100644 --- a/crates/oxc_ast/src/generated/derive_clone_in.rs +++ b/crates/oxc_ast/src/generated/derive_clone_in.rs @@ -621,6 +621,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for CallExpression<'_> { type_parameters: CloneIn::clone_in(&self.type_parameters, allocator), arguments: CloneIn::clone_in(&self.arguments, allocator), optional: CloneIn::clone_in(&self.optional, allocator), + pure: CloneIn::clone_in(&self.pure, allocator), } } } @@ -633,6 +634,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for NewExpression<'_> { callee: CloneIn::clone_in(&self.callee, allocator), arguments: CloneIn::clone_in(&self.arguments, allocator), type_parameters: CloneIn::clone_in(&self.type_parameters, allocator), + pure: CloneIn::clone_in(&self.pure, allocator), } } } @@ -1828,6 +1830,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for Function<'_> { return_type: CloneIn::clone_in(&self.return_type, allocator), body: CloneIn::clone_in(&self.body, allocator), scope_id: Default::default(), + pure: CloneIn::clone_in(&self.pure, allocator), } } } diff --git a/crates/oxc_ast/src/generated/derive_content_eq.rs b/crates/oxc_ast/src/generated/derive_content_eq.rs index 251cb7834d8884..14058aec83d000 100644 --- a/crates/oxc_ast/src/generated/derive_content_eq.rs +++ b/crates/oxc_ast/src/generated/derive_content_eq.rs @@ -341,6 +341,7 @@ impl ContentEq for CallExpression<'_> { && ContentEq::content_eq(&self.type_parameters, &other.type_parameters) && ContentEq::content_eq(&self.arguments, &other.arguments) && ContentEq::content_eq(&self.optional, &other.optional) + && ContentEq::content_eq(&self.pure, &other.pure) } } @@ -349,6 +350,7 @@ impl ContentEq for NewExpression<'_> { ContentEq::content_eq(&self.callee, &other.callee) && ContentEq::content_eq(&self.arguments, &other.arguments) && ContentEq::content_eq(&self.type_parameters, &other.type_parameters) + && ContentEq::content_eq(&self.pure, &other.pure) } } @@ -1061,6 +1063,7 @@ impl ContentEq for Function<'_> { && ContentEq::content_eq(&self.params, &other.params) && ContentEq::content_eq(&self.return_type, &other.return_type) && ContentEq::content_eq(&self.body, &other.body) + && ContentEq::content_eq(&self.pure, &other.pure) } } diff --git a/crates/oxc_traverse/src/generated/ancestor.rs b/crates/oxc_traverse/src/generated/ancestor.rs index 4e8dc8097c63d8..79e3b75e80de3c 100644 --- a/crates/oxc_traverse/src/generated/ancestor.rs +++ b/crates/oxc_traverse/src/generated/ancestor.rs @@ -3297,6 +3297,7 @@ pub(crate) const OFFSET_CALL_EXPRESSION_TYPE_PARAMETERS: usize = offset_of!(CallExpression, type_parameters); pub(crate) const OFFSET_CALL_EXPRESSION_ARGUMENTS: usize = offset_of!(CallExpression, arguments); pub(crate) const OFFSET_CALL_EXPRESSION_OPTIONAL: usize = offset_of!(CallExpression, optional); +pub(crate) const OFFSET_CALL_EXPRESSION_PURE: usize = offset_of!(CallExpression, pure); #[repr(transparent)] #[derive(Clone, Copy, Debug)] @@ -3331,6 +3332,11 @@ impl<'a, 't> CallExpressionWithoutCallee<'a, 't> { pub fn optional(self) -> &'t bool { unsafe { &*((self.0 as *const u8).add(OFFSET_CALL_EXPRESSION_OPTIONAL) as *const bool) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CALL_EXPRESSION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for CallExpressionWithoutCallee<'a, 't> { @@ -3372,6 +3378,11 @@ impl<'a, 't> CallExpressionWithoutTypeParameters<'a, 't> { pub fn optional(self) -> &'t bool { unsafe { &*((self.0 as *const u8).add(OFFSET_CALL_EXPRESSION_OPTIONAL) as *const bool) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CALL_EXPRESSION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for CallExpressionWithoutTypeParameters<'a, 't> { @@ -3413,6 +3424,11 @@ impl<'a, 't> CallExpressionWithoutArguments<'a, 't> { pub fn optional(self) -> &'t bool { unsafe { &*((self.0 as *const u8).add(OFFSET_CALL_EXPRESSION_OPTIONAL) as *const bool) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CALL_EXPRESSION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for CallExpressionWithoutArguments<'a, 't> { @@ -3427,6 +3443,7 @@ pub(crate) const OFFSET_NEW_EXPRESSION_CALLEE: usize = offset_of!(NewExpression, pub(crate) const OFFSET_NEW_EXPRESSION_ARGUMENTS: usize = offset_of!(NewExpression, arguments); pub(crate) const OFFSET_NEW_EXPRESSION_TYPE_PARAMETERS: usize = offset_of!(NewExpression, type_parameters); +pub(crate) const OFFSET_NEW_EXPRESSION_PURE: usize = offset_of!(NewExpression, pure); #[repr(transparent)] #[derive(Clone, Copy, Debug)] @@ -3456,6 +3473,11 @@ impl<'a, 't> NewExpressionWithoutCallee<'a, 't> { as *const Option>>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_NEW_EXPRESSION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for NewExpressionWithoutCallee<'a, 't> { @@ -3492,6 +3514,11 @@ impl<'a, 't> NewExpressionWithoutArguments<'a, 't> { as *const Option>>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_NEW_EXPRESSION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for NewExpressionWithoutArguments<'a, 't> { @@ -3528,6 +3555,11 @@ impl<'a, 't> NewExpressionWithoutTypeParameters<'a, 't> { as *const Vec<'a, Argument<'a>>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_NEW_EXPRESSION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for NewExpressionWithoutTypeParameters<'a, 't> { @@ -6510,6 +6542,7 @@ pub(crate) const OFFSET_FUNCTION_PARAMS: usize = offset_of!(Function, params); pub(crate) const OFFSET_FUNCTION_RETURN_TYPE: usize = offset_of!(Function, return_type); pub(crate) const OFFSET_FUNCTION_BODY: usize = offset_of!(Function, body); pub(crate) const OFFSET_FUNCTION_SCOPE_ID: usize = offset_of!(Function, scope_id); +pub(crate) const OFFSET_FUNCTION_PURE: usize = offset_of!(Function, pure); #[repr(transparent)] #[derive(Clone, Copy, Debug)] @@ -6590,6 +6623,11 @@ impl<'a, 't> FunctionWithoutId<'a, 't> { &*((self.0 as *const u8).add(OFFSET_FUNCTION_SCOPE_ID) as *const Cell>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for FunctionWithoutId<'a, 't> { @@ -6678,6 +6716,11 @@ impl<'a, 't> FunctionWithoutTypeParameters<'a, 't> { &*((self.0 as *const u8).add(OFFSET_FUNCTION_SCOPE_ID) as *const Cell>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for FunctionWithoutTypeParameters<'a, 't> { @@ -6766,6 +6809,11 @@ impl<'a, 't> FunctionWithoutThisParam<'a, 't> { &*((self.0 as *const u8).add(OFFSET_FUNCTION_SCOPE_ID) as *const Cell>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for FunctionWithoutThisParam<'a, 't> { @@ -6854,6 +6902,11 @@ impl<'a, 't> FunctionWithoutParams<'a, 't> { &*((self.0 as *const u8).add(OFFSET_FUNCTION_SCOPE_ID) as *const Cell>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for FunctionWithoutParams<'a, 't> { @@ -6942,6 +6995,11 @@ impl<'a, 't> FunctionWithoutReturnType<'a, 't> { &*((self.0 as *const u8).add(OFFSET_FUNCTION_SCOPE_ID) as *const Cell>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for FunctionWithoutReturnType<'a, 't> { @@ -7030,6 +7088,11 @@ impl<'a, 't> FunctionWithoutBody<'a, 't> { &*((self.0 as *const u8).add(OFFSET_FUNCTION_SCOPE_ID) as *const Cell>) } } + + #[inline] + pub fn pure(self) -> &'t bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_FUNCTION_PURE) as *const bool) } + } } impl<'a, 't> GetAddress for FunctionWithoutBody<'a, 't> {