diff --git a/godot-codegen/Cargo.toml b/godot-codegen/Cargo.toml index eafd1f320..ede355345 100644 --- a/godot-codegen/Cargo.toml +++ b/godot-codegen/Cargo.toml @@ -20,7 +20,6 @@ api-custom = ["godot-bindings/api-custom"] api-custom-json = ["godot-bindings/api-custom-json"] experimental-godot-api = [] experimental-threads = [] -experimental-required-objs = [] [dependencies] godot-bindings = { path = "../godot-bindings", version = "=0.4.2" } diff --git a/godot-codegen/src/conv/type_conversions.rs b/godot-codegen/src/conv/type_conversions.rs index d75a453d1..2f41470ec 100644 --- a/godot-codegen/src/conv/type_conversions.rs +++ b/godot-codegen/src/conv/type_conversions.rs @@ -251,7 +251,7 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy { arg_passing: ctx.get_builtin_arg_passing(full_ty), } } else { - let is_nullable = if cfg!(feature = "experimental-required-objs") { + let is_nullable = if cfg!(since_api = "4.6") { full_ty.meta.as_ref().is_none_or(|m| m != "required") } else { true diff --git a/godot-codegen/src/lib.rs b/godot-codegen/src/lib.rs index 71d5ce128..215525739 100644 --- a/godot-codegen/src/lib.rs +++ b/godot-codegen/src/lib.rs @@ -51,17 +51,6 @@ pub const IS_CODEGEN_FULL: bool = false; #[cfg(feature = "codegen-full")] pub const IS_CODEGEN_FULL: bool = true; -#[cfg(all(feature = "experimental-required-objs", before_api = "4.6"))] -fn __feature_warning() { - // Not a hard error, it's experimental anyway and allows more flexibility like this. - #[must_use = "The `experimental-required-objs` feature needs at least Godot 4.6-dev version"] - fn feature_has_no_effect() -> i32 { - 1 - } - - feature_has_no_effect(); -} - fn write_file(path: &Path, contents: String) { let dir = path.parent().unwrap(); let _ = std::fs::create_dir_all(dir); diff --git a/godot-core/Cargo.toml b/godot-core/Cargo.toml index 69dcc43dd..7bb01787c 100644 --- a/godot-core/Cargo.toml +++ b/godot-core/Cargo.toml @@ -22,7 +22,6 @@ codegen-lazy-fptrs = [ double-precision = ["godot-codegen/double-precision"] experimental-godot-api = ["godot-codegen/experimental-godot-api"] experimental-threads = ["godot-ffi/experimental-threads", "godot-codegen/experimental-threads"] -experimental-required-objs = ["godot-codegen/experimental-required-objs"] experimental-wasm-nothreads = ["godot-ffi/experimental-wasm-nothreads"] debug-log = ["godot-ffi/debug-log"] trace = [] diff --git a/godot-core/src/lib.rs b/godot-core/src/lib.rs index a57539790..f0213e423 100644 --- a/godot-core/src/lib.rs +++ b/godot-core/src/lib.rs @@ -72,3 +72,33 @@ pub mod private; /// Re-export logging macro. #[doc(hidden)] pub use godot_ffi::out; + +// ---------------------------------------------------------------------------------------------------------------------------------------------- + +/// Tests for code that must not compile. +/// +/// To add a new one, simply add a new `__*` named function with a `compile_fail` doc attribute. +mod no_compile_tests { + /// With Godot 4.6+, functions with required parameters accept `Gd` instead of `Option>`. + /// + /// ```compile_fail + /// use godot::prelude::*; + /// let mut node: Gd = unimplemented!(); + /// let option = Some(node.clone()); + /// let option: Option<&Gd> = option.as_ref(); + /// + /// // Following must not compile since `add_child` accepts only required (non-null) arguments. + /// node.add_child(option); + /// ``` + /// + /// Sanity check that without the last line, it _does_ compile. This catches any regressions in the previous statements that would not + /// be caught by the above `compile_fail` test. + /// ```no_run + /// use godot::prelude::*; + /// let mut node: Gd = unimplemented!(); + /// let option = Some(node.clone()); + /// let option: Option<&Gd> = option.as_ref(); + /// ``` + #[cfg(since_api = "4.6")] + fn __required_param_must_not_take_option() {} +} diff --git a/godot/Cargo.toml b/godot/Cargo.toml index 456d48be8..0ce771138 100644 --- a/godot/Cargo.toml +++ b/godot/Cargo.toml @@ -19,7 +19,6 @@ custom-json = ["api-custom-json"] double-precision = ["godot-core/double-precision"] experimental-godot-api = ["godot-core/experimental-godot-api"] experimental-threads = ["godot-core/experimental-threads"] -experimental-required-objs = ["godot-core/experimental-required-objs"] experimental-wasm = [] experimental-wasm-nothreads = ["godot-core/experimental-wasm-nothreads"] codegen-rustfmt = ["godot-core/codegen-rustfmt"] diff --git a/godot/src/lib.rs b/godot/src/lib.rs index 37beda33e..47fcc6fb3 100644 --- a/godot/src/lib.rs +++ b/godot/src/lib.rs @@ -131,12 +131,6 @@ //! Access to `godot::classes` APIs that Godot marks "experimental". These are under heavy development and may change at any time. //! If you opt in to this feature, expect breaking changes at compile and runtime.

//! -//! * **`experimental-required-objs`** -//! -//! Enables _required_ objects in Godot function signatures. When GDExtension advertises parameters or return value as required (non-null), the -//! generated code will use `Gd` instead of `Option>` for type safety. This will undergo many breaking changes as the API evolves; -//! we are explicitly excluding this from any SemVer guarantees. Needs Godot 4.6-dev. See . -//! //! _Rust functionality toggles:_ //! //! * **`lazy-function-tables`** @@ -279,19 +273,3 @@ pub use godot_core::private; /// Often-imported symbols. pub mod prelude; - -/// Tests for code that must not compile. -// Do not add #[cfg(test)], it seems to break `cargo test -p godot --features godot/api-custom,godot/experimental-required-objs`. -mod no_compile_tests { - /// ```compile_fail - /// use godot::prelude::*; - /// let mut node: Gd = todo!(); - /// let option = Some(node.clone()); - /// let option: Option<&Gd> = option.as_ref(); - /// - /// // Following must not compile since `add_child` accepts only required (non-null) arguments. Comment-out for sanity check. - /// node.add_child(option); - /// ``` - #[cfg(feature = "experimental-required-objs")] - fn __test_invalid_patterns() {} -} diff --git a/itest/rust/Cargo.toml b/itest/rust/Cargo.toml index cd7c79ebc..0694779fb 100644 --- a/itest/rust/Cargo.toml +++ b/itest/rust/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["cdylib"] # Default feature MUST be empty for workflow reasons, even if it differs from the default feature set in upstream `godot` crate. default = [] codegen-full = ["godot/__codegen-full"] -codegen-full-experimental = ["codegen-full", "godot/experimental-godot-api", "godot/experimental-required-objs"] +codegen-full-experimental = ["codegen-full", "godot/experimental-godot-api"] experimental-threads = ["godot/experimental-threads"] register-docs = ["godot/register-docs"] serde = ["dep:serde", "dep:serde_json", "godot/serde"] diff --git a/itest/rust/src/engine_tests/node_test.rs b/itest/rust/src/engine_tests/node_test.rs index d4fc4f721..ac4dc17bd 100644 --- a/itest/rust/src/engine_tests/node_test.rs +++ b/itest/rust/src/engine_tests/node_test.rs @@ -75,9 +75,8 @@ fn node_call_group(ctx: &TestContext) { assert!(!node.has_meta("something")); } -// Experimental required parameter/return value. -/* TODO(v0.5): enable once https://github.com/godot-rust/gdext/pull/1383 is merged. -#[cfg(all(feature = "codegen-full-experimental", since_api = "4.6"))] +// Required parameter/return value. +#[cfg(all(feature = "codegen-full", since_api = "4.6"))] #[itest] fn node_required_param_return() { use godot::classes::Tween; @@ -97,4 +96,3 @@ fn node_required_param_return() { parent.free(); } -*/