diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md
index 17af6b314..6fefe8f4f 100644
--- a/esp-hal/CHANGELOG.md
+++ b/esp-hal/CHANGELOG.md
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `timer::Timer` trait has three new methods, `wait`, `async_interrupt_handler` and `peripheral_interrupt` (#2586)
- Configuration structs in the I2C, SPI, and UART drivers now implement the Builder Lite pattern (#2614)
- Added `I8080::apply_config`, `DPI::apply_config` and `Camera::apply_config` (#2610)
+- Introduced the `unstable` feature which will be used to restrict stable APIs to a subset of esp-hal. (#2628)
### Changed
diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml
index 68ab0ade8..af575e016 100644
--- a/esp-hal/Cargo.toml
+++ b/esp-hal/Cargo.toml
@@ -40,6 +40,7 @@ enumset = "1.1.5"
esp-build = { version = "0.1.0", path = "../esp-build" }
esp-synopsys-usb-otg = { version = "0.4.2", optional = true, features = ["fs", "esp32sx"] }
fugit = "0.3.7"
+instability = "0.3"
log = { version = "0.4.22", optional = true }
nb = "1.1.0"
paste = "1.0.15"
@@ -152,6 +153,9 @@ octal-psram = []
# This feature is intended for testing; you probably don't want to enable it:
ci = ["defmt", "bluetooth"]
+# Enables APIs that are not stable and thus come with no stability guarantees.
+unstable = []
+
[lints.clippy]
mixed_attributes_style = "allow"
diff --git a/esp-hal/MIGRATING-0.22.md b/esp-hal/MIGRATING-0.22.md
index bb941d96f..2a63d1855 100644
--- a/esp-hal/MIGRATING-0.22.md
+++ b/esp-hal/MIGRATING-0.22.md
@@ -1,5 +1,11 @@
# Migration Guide from 0.22.x to v1.0.0-beta.0
+Starting with this release, unstable parts of esp-hal will be gated behind the `unstable` feature.
+The `unstable` feature itself is unstable, we might change the way we hide APIs without notice.
+Unstable APIs are not covered by semver guarantees, they may break even between patch releases.
+
+Please refer to the documentation to see which APIs are marked as unstable.
+
## DMA changes
### Accessing channel objects
diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs
index 25c43ade5..65b938234 100644
--- a/esp-hal/src/gpio/mod.rs
+++ b/esp-hal/src/gpio/mod.rs
@@ -1864,6 +1864,7 @@ where
P: OutputPin,
{
/// Set the GPIO to output mode.
+ #[instability::unstable]
pub fn set_as_output(&mut self) {
self.pin.set_to_push_pull_output(private::Internal);
}
diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs
index aafe8b21e..42f3ee3d2 100644
--- a/esp-hal/src/lib.rs
+++ b/esp-hal/src/lib.rs
@@ -1,5 +1,5 @@
#![cfg_attr(
- docsrs,
+ all(docsrs, not(not_really_docsrs)),
doc = "
You might want to browse the esp-hal
documentation on the esp-rs website instead.
The documentation here on docs.rs is built for a single chip only (ESP32-C6, in particular), while on the esp-rs website you can select your exact chip from the list of supported devices. Available peripherals and their APIs change depending on the chip.
\n\n
\n\n"
)]
//! # Bare-metal (`no_std`) HAL for all Espressif ESP32 devices.
@@ -140,6 +140,7 @@
#![allow(asm_sub_register, async_fn_in_trait, stable_features)]
#![cfg_attr(xtensa, feature(asm_experimental_arch))]
#![deny(missing_docs, rust_2018_idioms)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
#![no_std]
// MUST be the first module
diff --git a/esp-metadata/src/lib.rs b/esp-metadata/src/lib.rs
index 891bfa903..3915602a3 100644
--- a/esp-metadata/src/lib.rs
+++ b/esp-metadata/src/lib.rs
@@ -237,6 +237,9 @@ impl Config {
///
/// This is required to avoid triggering the unexpected-cfgs lint.
fn define_all_possible_symbols() {
+ // Used by our documentation builds to prevent the huge red warning banner.
+ println!("cargo:rustc-check-cfg=cfg(not_really_docsrs)");
+
for chip in Chip::iter() {
let config = Config::for_chip(&chip);
for symbol in config.all() {
diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs
index 924799eac..482e4a334 100644
--- a/esp-wifi/src/lib.rs
+++ b/esp-wifi/src/lib.rs
@@ -1,5 +1,5 @@
#![cfg_attr(
- docsrs,
+ all(docsrs, not(not_really_docsrs)),
doc = "You might want to browse the esp-wifi
documentation on the esp-rs website instead.
The documentation here on docs.rs is built for a single chip only (ESP32-C3, in particular), while on the esp-rs website you can select your exact chip from the list of supported devices. Available peripherals and their APIs might change depending on the chip.
\n\n
\n\n"
)]
//! This documentation is built for the
diff --git a/hil-test/Cargo.toml b/hil-test/Cargo.toml
index cc273714e..19dc56ed5 100644
--- a/hil-test/Cargo.toml
+++ b/hil-test/Cargo.toml
@@ -206,7 +206,7 @@ embedded-hal-async = "1.0.0"
embedded-hal-nb = "1.0.0"
esp-alloc = { path = "../esp-alloc", optional = true }
esp-backtrace = { path = "../esp-backtrace", default-features = false, features = ["exception-handler", "defmt", "semihosting"] }
-esp-hal = { path = "../esp-hal", features = ["digest"], optional = true }
+esp-hal = { path = "../esp-hal", features = ["digest", "unstable"], optional = true }
esp-hal-embassy = { path = "../esp-hal-embassy", optional = true }
esp-wifi = { path = "../esp-wifi", optional = true, features = ["wifi"] }
portable-atomic = "1.9.0"
diff --git a/qa-test/Cargo.toml b/qa-test/Cargo.toml
index d7760ce52..2a1ded08a 100644
--- a/qa-test/Cargo.toml
+++ b/qa-test/Cargo.toml
@@ -13,7 +13,7 @@ embedded-graphics = "0.8.1"
embedded-hal-async = "1.0.0"
esp-alloc = { path = "../esp-alloc" }
esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] }
-esp-hal = { path = "../esp-hal" }
+esp-hal = { path = "../esp-hal", features = ["unstable"] }
esp-hal-embassy = { path = "../esp-hal-embassy" }
esp-println = { path = "../esp-println", features = ["log"] }
lis3dh-async = "0.9.3"
diff --git a/xtask/src/cargo.rs b/xtask/src/cargo.rs
index 8ebd2cd7c..68ddc09cf 100644
--- a/xtask/src/cargo.rs
+++ b/xtask/src/cargo.rs
@@ -1,6 +1,7 @@
//! Tools for working with Cargo.
use std::{
+ ffi::OsStr,
path::Path,
process::{Command, Stdio},
};
@@ -17,6 +18,16 @@ pub enum CargoAction {
/// Execute cargo with the given arguments and from the specified directory.
pub fn run(args: &[String], cwd: &Path) -> Result<()> {
+ run_with_env::<[(&str, &str); 0], _, _>(args, cwd, [])
+}
+
+/// Execute cargo with the given arguments and from the specified directory.
+pub fn run_with_env(args: &[String], cwd: &Path, envs: I) -> Result<()>
+where
+ I: IntoIterator- ,
+ K: AsRef,
+ V: AsRef,
+{
if !cwd.is_dir() {
bail!("The `cwd` argument MUST be a directory");
}
@@ -30,6 +41,7 @@ pub fn run(args: &[String], cwd: &Path) -> Result<()> {
let status = Command::new(get_cargo())
.args(args)
.current_dir(cwd)
+ .envs(envs)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.stdin(Stdio::inherit())
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 44402fb26..2bd27f560 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -137,7 +137,11 @@ pub fn build_documentation(workspace: &Path, package: Package, chip: Chip) -> Re
log::debug!("{args:#?}");
// Execute `cargo doc` from the package root:
- cargo::run(&args, &package_path)?;
+ cargo::run_with_env(
+ &args,
+ &package_path,
+ [("RUSTDOCFLAGS", "--cfg docsrs --cfg not_really_docsrs")],
+ )?;
let docs_path = windows_safe_path(
&workspace