Update instability (#3836)

This commit is contained in:
Dániel Buga 2025-07-21 11:37:58 +02:00 committed by GitHub
parent de67c31013
commit af6ffb102f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 22 additions and 158 deletions

View File

@ -40,7 +40,7 @@ document-features = "0.2.11"
embassy-futures = "0.1.1"
embassy-sync = "0.6.2"
fugit = "0.3.7"
instability = "0.3.7"
instability = "0.3.9"
strum = { version = "0.27.1", default-features = false, features = ["derive"] }
esp-config = { version = "0.5.0", path = "../esp-config" }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -194,6 +194,11 @@
#![deny(missing_docs, rust_2018_idioms, rustdoc::all)]
#![allow(rustdoc::private_doc_tests)] // compile tests are done via rustdoc
#![cfg_attr(docsrs, feature(doc_cfg, custom_inner_attributes, proc_macro_hygiene))]
// Don't trip up on broken/private links when running semver-checks
#![cfg_attr(
semver_checks,
allow(rustdoc::private_intra_doc_links, rustdoc::broken_intra_doc_links)
)]
#![no_std]
// MUST be the first module
@ -527,7 +532,6 @@ pub(crate) mod private {
}
}
#[cfg(feature = "unstable")]
#[doc(hidden)]
pub use private::Internal;

View File

@ -2184,6 +2184,7 @@ struct Config {
impl Config {
fn define_cfgs(&self) {
println!("cargo:rustc-check-cfg=cfg(not_really_docsrs)");
println!("cargo:rustc-check-cfg=cfg(semver_checks)");
println!("cargo:rustc-check-cfg=cfg(esp32)");
println!("cargo:rustc-check-cfg=cfg(xtensa)");
println!("cargo:rustc-check-cfg=cfg(multi_core)");

View File

@ -197,6 +197,7 @@ impl Chip {
// Used by our documentation builds to prevent the huge red warning banner.
cfgs.push(String::from("cargo:rustc-check-cfg=cfg(not_really_docsrs)"));
cfgs.push(String::from("cargo:rustc-check-cfg=cfg(semver_checks)"));
let mut cfg_values: IndexMap<String, Vec<String>> = IndexMap::new();

View File

@ -36,9 +36,6 @@ reqwest = { version = "0.12.12", features = [
# This pulls a gazillion crates - don't include it by default
cargo-semver-checks = { version = "0.41.0", optional = true }
# THIS NEEDS TO MATCH THE rustfmt-json FORMAT - see https://github.com/rust-lang/rustdoc-types/blob/trunk/CHANGELOG.md
rustdoc-types = { version = "0.53.0", optional = true }
flate2 = { version = "1.1.1", optional = true }
temp-file = { version = "0.1.9", optional = true }
urlencoding = { version = "2.1.3", optional = true }
@ -49,5 +46,5 @@ pretty_assertions = "1.2.0"
[features]
deploy-docs = ["dep:reqwest", "dep:kuchikiki"]
preview-docs = ["dep:opener", "dep:rocket"]
semver-checks = [ "dep:cargo-semver-checks", "dep:rustdoc-types", "dep:flate2", "dep:temp-file" ]
semver-checks = [ "dep:cargo-semver-checks", "dep:flate2", "dep:temp-file" ]
release = ["semver-checks", "dep:opener", "dep:urlencoding", "dep:regex"]

View File

@ -61,7 +61,7 @@ pub mod checker {
use crate::{
Package,
semver_check::{build_doc_json, minimum_update, remove_unstable_items},
semver_check::{build_doc_json, minimum_update},
};
pub fn generate_baseline(
@ -79,8 +79,6 @@ pub mod checker {
let current_path = build_doc_json(package, chip, &package_path)?;
remove_unstable_items(&current_path)?;
let file_name = if package.chip_features_matter() {
chip.to_string()
} else {

View File

@ -6,7 +6,6 @@ use std::{
use cargo_semver_checks::{Check, GlobalConfig, ReleaseType, Rustdoc};
use esp_metadata::Chip;
use rustdoc_types::ItemEnum;
use crate::{Package, cargo::CargoArgsBuilder};
@ -22,7 +21,6 @@ pub fn minimum_update(
let package_name = package.to_string();
let package_path = crate::windows_safe_path(&workspace.join(&package_name));
let current_path = build_doc_json(package, &chip, &package_path)?;
remove_unstable_items(&current_path)?;
let file_name = if package.chip_features_matter() {
chip.to_string()
@ -78,9 +76,9 @@ pub(crate) fn build_doc_json(
std::fs::remove_file(&current_path).ok();
let features = if package.chip_features_matter() {
vec![chip.to_string(), "unstable".to_string()]
vec![chip.to_string()]
} else {
vec!["unstable".to_string()]
vec![]
};
log::info!(
@ -89,162 +87,27 @@ pub(crate) fn build_doc_json(
features
);
let envs = vec![("RUSTDOCFLAGS", "--cfg docsrs --cfg not_really_docsrs")];
let envs = vec![(
"RUSTDOCFLAGS",
"--cfg docsrs --cfg not_really_docsrs --cfg semver_checks",
)];
// always use `esp` toolchain so we don't have to deal with potentially
// different versions of the doc-json
let mut cargo_builder = CargoArgsBuilder::default()
let cargo_builder = CargoArgsBuilder::default()
.toolchain("esp")
.subcommand("rustdoc")
.features(&features)
.target(chip.target())
.arg("-Zunstable-options")
.arg("-Zhost-config")
.arg("-Ztarget-applies-to-host")
.arg("--lib")
.arg("--output-format=json");
cargo_builder = cargo_builder.arg("-Zbuild-std=alloc,core");
.arg("--output-format=json")
.arg("-Zbuild-std=alloc,core")
.arg("--config=host.rustflags=[\"--cfg=instability_disable_unstable_docs\"]");
let cargo_args = cargo_builder.build();
log::debug!("{cargo_args:#?}");
crate::cargo::run_with_env(&cargo_args, package_path, envs, false)?;
Ok(current_path)
}
pub(crate) fn remove_unstable_items(path: &Path) -> Result<(), anyhow::Error> {
// this leaves orphaned items! cargo-semver-checks seems to be fine with that
// however the json fmt is unstable - we might fail when using the "wrong"
// version of `rustdoc_types` here
//
// Hopefully this whole pre-processing is just a stop-gap solution until it's
// possible to generate docs for the stable-API only.
log::info!("{:?}", path);
let json_string = std::fs::read_to_string(path)?;
let mut krate: rustdoc_types::Crate = serde_json::from_str(&json_string)?;
let mut to_remove = vec![];
// first pass - just look for cfg-gated items
//
// the string to match depends on the rustfmt-json version!
// later version emit `#[<cfg>(...` instead of `#[cfg(..`
let cfg_gates = vec![
"#[<cfg>(any(doc, feature = \"unstable\"))]",
"#[cfg(any(doc, feature = \"unstable\"))]",
"#[<cfg>(feature = \"unstable\")]",
"#[cfg(feature = \"unstable\")]",
"#[doc(cfg(feature = \"unstable\"))]",
];
for (id, item) in &mut krate.index {
if item
.attrs
.iter()
.any(|attr| cfg_gates.contains(&attr.as_str()))
{
// remove the item itself
to_remove.push(id.clone());
// remove sub-items - shouldn't be needed but shouldn't hurt
match &item.inner {
ItemEnum::Module(module) => {
to_remove.extend(&module.items);
}
ItemEnum::Struct(s) => {
to_remove.extend(&s.impls);
}
ItemEnum::Enum(e) => {
to_remove.extend(&e.impls);
to_remove.extend(&e.variants);
}
ItemEnum::Impl(i) => {
to_remove.extend(&i.items);
}
_ => (),
}
}
}
log::debug!("Items to remove {:?}", to_remove);
for id in &to_remove {
krate.index.remove(&id);
krate.paths.remove(&id);
}
for (_id, item) in &mut krate.index {
match &mut item.inner {
ItemEnum::Module(module) => {
module.items.retain(|id| !to_remove.contains(id));
}
ItemEnum::Struct(struct_) => {
struct_.impls.retain(|id| !to_remove.contains(id));
match &mut struct_.kind {
rustdoc_types::StructKind::Unit => (),
rustdoc_types::StructKind::Tuple(_ids) => (),
rustdoc_types::StructKind::Plain {
fields,
has_stripped_fields: _,
} => {
for id in &to_remove {
if let Some(found) = fields.iter().enumerate().find(|i| i.1 == id) {
fields.remove(found.0);
}
}
}
}
if struct_.impls.is_empty() {
to_remove.push(_id.clone());
}
}
ItemEnum::Enum(enum_) => {
enum_.impls.retain(|id| !to_remove.contains(id));
enum_.variants.retain(|id| !to_remove.contains(id));
if enum_.impls.is_empty() {
to_remove.push(_id.clone());
}
}
ItemEnum::Impl(impl_) => {
impl_.items.retain(|id| !to_remove.contains(id));
if impl_.items.is_empty() {
to_remove.push(_id.clone());
}
}
// don't honor (because they either don't contain sub-items (= already handled in the
// first pass) or we currently don't use them)
//
// ItemEnum::Use(_)
// ItemEnum::Union(union)
// ItemEnum::StructField(_)
// ItemEnum::Variant(variant)
// ItemEnum::Function(function)
// ItemEnum::Trait(_)
// ItemEnum::TraitAlias(trait_alias)
// ItemEnum::TypeAlias(type_alias)
// ItemEnum::Constant {
// ItemEnum::Static(_)
// ItemEnum::ExternType =>
// ItemEnum::Macro(_)
// ItemEnum::ProcMacro(proc_macro)
// ItemEnum::Primitive(primitive)
// ItemEnum::AssocConst {
// ItemEnum::AssocType {
_ => (),
}
}
// if we added something more to remove (because the items are "empty" now -
// remove them, too)
for id in &to_remove {
krate.index.remove(&id);
krate.paths.remove(&id);
}
std::fs::write(path, serde_json::to_string(&krate)?)?;
Ok(())
}