mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 13:36:49 +00:00
Merge 75825548e3
into 65fa0ab924
This commit is contained in:
commit
80b8ed17a4
@ -14,6 +14,7 @@ use std::io::{BufWriter, Write, stdout};
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::def_id::{DefId, DefIdSet};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
@ -123,6 +124,58 @@ impl<'tcx> JsonRenderer<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn target(sess: &rustc_session::Session) -> types::Target {
|
||||
// Build a set of which features are enabled on this target
|
||||
let globally_enabled_features: FxHashSet<&str> =
|
||||
sess.unstable_target_features.iter().map(|name| name.as_str()).collect();
|
||||
|
||||
// Build a map of target feature stability by feature name
|
||||
use rustc_target::target_features::Stability;
|
||||
let feature_stability: FxHashMap<&str, Stability> = sess
|
||||
.target
|
||||
.rust_target_features()
|
||||
.into_iter()
|
||||
.copied()
|
||||
.map(|(name, stability, _)| (name, stability))
|
||||
.collect();
|
||||
|
||||
types::Target {
|
||||
triple: sess.opts.target_triple.tuple().into(),
|
||||
target_features: sess
|
||||
.target
|
||||
.rust_target_features()
|
||||
.into_iter()
|
||||
.copied()
|
||||
.filter(|(_, stability, _)| {
|
||||
// Describe only target features which the user can toggle
|
||||
stability.toggle_allowed().is_ok()
|
||||
})
|
||||
.map(|(name, stability, implied_features)| {
|
||||
types::TargetFeature {
|
||||
name: name.into(),
|
||||
unstable_feature_gate: match stability {
|
||||
Stability::Unstable(feature_gate) => Some(feature_gate.as_str().into()),
|
||||
_ => None,
|
||||
},
|
||||
implies_features: implied_features
|
||||
.into_iter()
|
||||
.copied()
|
||||
.filter(|name| {
|
||||
// Imply only target features which the user can toggle
|
||||
feature_stability
|
||||
.get(name)
|
||||
.map(|stability| stability.toggle_allowed().is_ok())
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.map(String::from)
|
||||
.collect(),
|
||||
globally_enabled: globally_enabled_features.contains(name),
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
fn descr() -> &'static str {
|
||||
"json"
|
||||
@ -248,6 +301,12 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
let e = ExternalCrate { crate_num: LOCAL_CRATE };
|
||||
let index = (*self.index).clone().into_inner();
|
||||
|
||||
// Note that tcx.rust_target_features is inappropriate here because rustdoc tries to run for
|
||||
// multiple targets: https://github.com/rust-lang/rust/pull/137632
|
||||
//
|
||||
// We want to describe a single target, so pass tcx.sess rather than tcx.
|
||||
let target = target(self.tcx.sess);
|
||||
|
||||
debug!("Constructing Output");
|
||||
let output_crate = types::Crate {
|
||||
root: self.id_from_item_default(e.def_id().into()),
|
||||
@ -288,6 +347,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
target,
|
||||
format_version: types::FORMAT_VERSION,
|
||||
};
|
||||
if let Some(ref out_dir) = self.out_dir {
|
||||
|
@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
|
||||
/// This integer is incremented with every breaking change to the API,
|
||||
/// and is returned along with the JSON blob as [`Crate::format_version`].
|
||||
/// Consuming code should assert that this value matches the format version(s) that it supports.
|
||||
pub const FORMAT_VERSION: u32 = 43;
|
||||
pub const FORMAT_VERSION: u32 = 44;
|
||||
|
||||
/// The root of the emitted JSON blob.
|
||||
///
|
||||
@ -52,11 +52,67 @@ pub struct Crate {
|
||||
pub paths: HashMap<Id, ItemSummary>,
|
||||
/// Maps `crate_id` of items to a crate name and html_root_url if it exists.
|
||||
pub external_crates: HashMap<u32, ExternalCrate>,
|
||||
/// Information about the target for which this documentation was generated
|
||||
pub target: Target,
|
||||
/// A single version number to be used in the future when making backwards incompatible changes
|
||||
/// to the JSON output.
|
||||
pub format_version: u32,
|
||||
}
|
||||
|
||||
/// Information about a target
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Target {
|
||||
/// The target triple for which this documentation was generated
|
||||
pub triple: String,
|
||||
/// A list of features valid for use in `#[target_feature]` attributes
|
||||
/// for the target where this rustdoc JSON was generated.
|
||||
pub target_features: Vec<TargetFeature>,
|
||||
}
|
||||
|
||||
/// Information about a target feature.
|
||||
///
|
||||
/// Rust target features are used to influence code generation, especially around selecting
|
||||
/// instructions which are not universally supported by the target architecture.
|
||||
///
|
||||
/// Target features are commonly enabled by the [`#[target_feature]` attribute][1] to influence code
|
||||
/// generation for a particular function, and less commonly enabled by compiler options like
|
||||
/// `-Ctarget-feature` or `-Ctarget-cpu`. Targets themselves automatically enable certain target
|
||||
/// features by default, for example because the target's ABI specification requires saving specific
|
||||
/// registers which only exist in an architectural extension.
|
||||
///
|
||||
/// Target features can imply other target features: for example, x86-64 `avx2` implies `avx`, and
|
||||
/// aarch64 `sve2` implies `sve`, since both of these architectural extensions depend on their
|
||||
/// predecessors.
|
||||
///
|
||||
/// Target features can be probed at compile time by [`#[cfg(target_feature)]`][2] or `cfg!(…)`
|
||||
/// conditional compilation to determine whether a target feature is enabled in a particular
|
||||
/// context.
|
||||
///
|
||||
/// [1]: https://doc.rust-lang.org/stable/reference/attributes/codegen.html#the-target_feature-attribute
|
||||
/// [2]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_feature
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct TargetFeature {
|
||||
/// The name of this target feature.
|
||||
pub name: String,
|
||||
/// Other target features which are implied by this target feature, if any.
|
||||
pub implies_features: Vec<String>,
|
||||
/// If this target feature is unstable, the name of the associated language feature gate.
|
||||
pub unstable_feature_gate: Option<String>,
|
||||
/// Whether this feature is globally enabled for this compilation session.
|
||||
///
|
||||
/// Target features can be globally enabled implicitly as a result of the target's definition.
|
||||
/// For example, x86-64 hardware floating point ABIs require saving x87 and SSE2 registers,
|
||||
/// which in turn requires globally enabling the `x87` and `sse2` target features so that the
|
||||
/// generated machine code conforms to the target's ABI.
|
||||
///
|
||||
/// Target features can also be globally enabled explicitly as a result of compiler flags like
|
||||
/// [`-Ctarget-feature`][1] or [`-Ctarget-cpu`][2].
|
||||
///
|
||||
/// [1]: https://doc.rust-lang.org/beta/rustc/codegen-options/index.html#target-feature
|
||||
/// [2]: https://doc.rust-lang.org/beta/rustc/codegen-options/index.html#target-cpu
|
||||
pub globally_enabled: bool,
|
||||
}
|
||||
|
||||
/// Metadata of a crate, either the same crate on which `rustdoc` was invoked, or its dependency.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct ExternalCrate {
|
||||
|
@ -177,6 +177,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"only-32bit",
|
||||
"only-64bit",
|
||||
"only-aarch64",
|
||||
"only-aarch64-apple-darwin",
|
||||
"only-aarch64-unknown-linux-gnu",
|
||||
"only-apple",
|
||||
"only-arm",
|
||||
@ -190,6 +191,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"only-gnu",
|
||||
"only-i686-pc-windows-gnu",
|
||||
"only-i686-pc-windows-msvc",
|
||||
"only-i686-unknown-linux-gnu",
|
||||
"only-ios",
|
||||
"only-linux",
|
||||
"only-loongarch64",
|
||||
@ -221,6 +223,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"only-windows-msvc",
|
||||
"only-x86",
|
||||
"only-x86_64",
|
||||
"only-x86_64-apple-darwin",
|
||||
"only-x86_64-fortanix-unknown-sgx",
|
||||
"only-x86_64-pc-windows-gnu",
|
||||
"only-x86_64-pc-windows-msvc",
|
||||
|
@ -156,7 +156,7 @@ static LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
|
||||
r#"
|
||||
//@\s+
|
||||
(?P<negated>!?)
|
||||
(?P<cmd>[A-Za-z]+(?:-[A-Za-z]+)*)
|
||||
(?P<cmd>[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)
|
||||
(?P<args>.*)$
|
||||
"#,
|
||||
)
|
||||
|
@ -42,6 +42,7 @@ fn errors_on_missing_links() {
|
||||
)]),
|
||||
paths: FxHashMap::default(),
|
||||
external_crates: FxHashMap::default(),
|
||||
target: rustdoc_json_types::Target { triple: "".to_string(), target_features: vec![] },
|
||||
format_version: rustdoc_json_types::FORMAT_VERSION,
|
||||
};
|
||||
|
||||
@ -112,6 +113,7 @@ fn errors_on_local_in_paths_and_not_index() {
|
||||
},
|
||||
)]),
|
||||
external_crates: FxHashMap::default(),
|
||||
target: rustdoc_json_types::Target { triple: "".to_string(), target_features: vec![] },
|
||||
format_version: rustdoc_json_types::FORMAT_VERSION,
|
||||
};
|
||||
|
||||
@ -216,6 +218,7 @@ fn errors_on_missing_path() {
|
||||
ItemSummary { crate_id: 0, path: vec!["foo".to_owned()], kind: ItemKind::Module },
|
||||
)]),
|
||||
external_crates: FxHashMap::default(),
|
||||
target: rustdoc_json_types::Target { triple: "".to_string(), target_features: vec![] },
|
||||
format_version: rustdoc_json_types::FORMAT_VERSION,
|
||||
};
|
||||
|
||||
@ -259,6 +262,7 @@ fn checks_local_crate_id_is_correct() {
|
||||
)]),
|
||||
paths: FxHashMap::default(),
|
||||
external_crates: FxHashMap::default(),
|
||||
target: rustdoc_json_types::Target { triple: "".to_string(), target_features: vec![] },
|
||||
format_version: FORMAT_VERSION,
|
||||
};
|
||||
check(&krate, &[]);
|
||||
|
14
tests/rustdoc-json/targets/aarch64_apple_darwin.rs
Normal file
14
tests/rustdoc-json/targets/aarch64_apple_darwin.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-aarch64-apple-darwin
|
||||
|
||||
//@ is "$.target.triple" \"aarch64-apple-darwin\"
|
||||
//@ is "$.target.target_features[?(@.name=='vh')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='sve')].globally_enabled" false
|
||||
//@ has "$.target.target_features[?(@.name=='sve2')].implies_features" '["sve"]'
|
||||
//@ is "$.target.target_features[?(@.name=='sve2')].unstable_feature_gate" null
|
||||
|
||||
// If this breaks due to stabilization, check rustc_target::target_features for a replacement
|
||||
//@ is "$.target.target_features[?(@.name=='cssc')].unstable_feature_gate" '"aarch64_unstable_target_feature"'
|
||||
//@ is "$.target.target_features[?(@.name=='v9a')].unstable_feature_gate" '"aarch64_ver_target_feature"'
|
||||
|
||||
// Ensure we don't look like x86-64
|
||||
//@ !has "$.target.target_features[?(@.name=='avx2')]"
|
@ -0,0 +1,11 @@
|
||||
//@ only-aarch64
|
||||
|
||||
// If we enable SVE Bit Permute, we should see that it is enabled
|
||||
//@ compile-flags: -Ctarget-feature=+sve2-bitperm
|
||||
//@ is "$.target.target_features[?(@.name=='sve2-bitperm')].globally_enabled" true
|
||||
|
||||
// As well as its dependency chain
|
||||
//@ is "$.target.target_features[?(@.name=='sve2')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='sve')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='fp16')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='neon')].globally_enabled" true
|
14
tests/rustdoc-json/targets/aarch64_unknown_linux_gnu.rs
Normal file
14
tests/rustdoc-json/targets/aarch64_unknown_linux_gnu.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-aarch64-unknown-linux-gnu
|
||||
|
||||
//@ is "$.target.triple" \"aarch64-unknown-linux-gnu\"
|
||||
//@ is "$.target.target_features[?(@.name=='vh')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='sve')].globally_enabled" false
|
||||
//@ has "$.target.target_features[?(@.name=='sve2')].implies_features" '["sve"]'
|
||||
//@ is "$.target.target_features[?(@.name=='sve2')].unstable_feature_gate" null
|
||||
|
||||
// If this breaks due to stabilization, check rustc_target::target_features for a replacement
|
||||
//@ is "$.target.target_features[?(@.name=='cssc')].unstable_feature_gate" '"aarch64_unstable_target_feature"'
|
||||
//@ is "$.target.target_features[?(@.name=='v9a')].unstable_feature_gate" '"aarch64_ver_target_feature"'
|
||||
|
||||
// Ensure we don't look like x86-64
|
||||
//@ !has "$.target.target_features[?(@.name=='avx2')]"
|
14
tests/rustdoc-json/targets/i686_pc_windows_msvc.rs
Normal file
14
tests/rustdoc-json/targets/i686_pc_windows_msvc.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-i686-pc-windows-msvc
|
||||
|
||||
//@ is "$.target.triple" \"i686-pc-windows-msvc\"
|
||||
//@ is "$.target.target_features[?(@.name=='sse2')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].globally_enabled" false
|
||||
//@ has "$.target.target_features[?(@.name=='avx2')].implies_features" '["avx"]'
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].unstable_feature_gate" null
|
||||
|
||||
// If this breaks due to stabilization, check rustc_target::target_features for a replacement
|
||||
//@ is "$.target.target_features[?(@.name=='amx-tile')].unstable_feature_gate" '"x86_amx_intrinsics"'
|
||||
//@ is "$.target.target_features[?(@.name=='x87')].unstable_feature_gate" '"x87_target_feature"'
|
||||
|
||||
// Ensure we don't look like aarch64
|
||||
//@ !has "$.target.target_features[?(@.name=='sve2')]"
|
14
tests/rustdoc-json/targets/i686_unknown_linux_gnu.rs
Normal file
14
tests/rustdoc-json/targets/i686_unknown_linux_gnu.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-i686-unknown-linux-gnu
|
||||
|
||||
//@ is "$.target.triple" \"i686-unknown-linux-gnu\"
|
||||
//@ is "$.target.target_features[?(@.name=='sse2')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].globally_enabled" false
|
||||
//@ has "$.target.target_features[?(@.name=='avx2')].implies_features" '["avx"]'
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].unstable_feature_gate" null
|
||||
|
||||
// If this breaks due to stabilization, check rustc_target::target_features for a replacement
|
||||
//@ is "$.target.target_features[?(@.name=='amx-tile')].unstable_feature_gate" '"x86_amx_intrinsics"'
|
||||
//@ is "$.target.target_features[?(@.name=='x87')].unstable_feature_gate" '"x87_target_feature"'
|
||||
|
||||
// Ensure we don't look like aarch64
|
||||
//@ !has "$.target.target_features[?(@.name=='sve2')]"
|
14
tests/rustdoc-json/targets/x86_64_apple_darwin.rs
Normal file
14
tests/rustdoc-json/targets/x86_64_apple_darwin.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-x86_64-apple-darwin
|
||||
|
||||
//@ is "$.target.triple" \"x86_64-apple-darwin\"
|
||||
//@ is "$.target.target_features[?(@.name=='?')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='?')].globally_enabled" false
|
||||
//@ has "$.target.target_features[?(@.name=='avx2')].implies_features" '["avx"]'
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].unstable_feature_gate" null
|
||||
|
||||
// If this breaks due to stabilization, check rustc_target::target_features for a replacement
|
||||
//@ is "$.target.target_features[?(@.name=='amx-tile')].unstable_feature_gate" '"x86_amx_intrinsics"'
|
||||
//@ is "$.target.target_features[?(@.name=='x87')].unstable_feature_gate" '"x87_target_feature"'
|
||||
|
||||
// Ensure we don't look like aarch64
|
||||
//@ !has "$.target.target_features[?(@.name=='sve2')]"
|
14
tests/rustdoc-json/targets/x86_64_pc_windows_gnu.rs
Normal file
14
tests/rustdoc-json/targets/x86_64_pc_windows_gnu.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-x86_64-pc-windows-gnu
|
||||
|
||||
//@ is "$.target.triple \"x86_64-pc-windows-gnu\"
|
||||
//@ is "$.target.target_features[?(@.name=='sse2')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].globally_enabled" false
|
||||
//@ has "$.target.target_features[?(@.name=='avx2')].implies_features" '["avx"]'
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].unstable_feature_gate" null
|
||||
|
||||
// If this breaks due to stabilization, check rustc_target::target_features for a replacement
|
||||
//@ is "$.target.target_features[?(@.name=='amx-tile')].unstable_feature_gate" '"x86_amx_intrinsics"'
|
||||
//@ is "$.target.target_features[?(@.name=='x87')].unstable_feature_gate" '"x87_target_feature"'
|
||||
|
||||
// Ensure we don't look like aarch64
|
||||
//@ !has "$.target.target_features[?(@.name=='sve2')]"
|
14
tests/rustdoc-json/targets/x86_64_pc_windows_msvc.rs
Normal file
14
tests/rustdoc-json/targets/x86_64_pc_windows_msvc.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-x86_64-pc-windows-msvc
|
||||
|
||||
//@ is "$.target.triple" \"x86_64-pc-windows-msvc\"
|
||||
//@ is "$.target.target_features[?(@.name=='sse2')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].globally_enabled" false
|
||||
//@ has "$.target.target_features[?(@.name=='avx2')].implies_features" '["avx"]'
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].unstable_feature_gate" null
|
||||
|
||||
// If this breaks due to stabilization, check rustc_target::target_features for a replacement
|
||||
//@ is "$.target.target_features[?(@.name=='amx-tile')].unstable_feature_gate" '"x86_amx_intrinsics"'
|
||||
//@ is "$.target.target_features[?(@.name=='x87')].unstable_feature_gate" '"x87_target_feature"'
|
||||
|
||||
// Ensure we don't look like aarch64
|
||||
//@ !has "$.target.target_features[?(@.name=='sve2')]"
|
@ -0,0 +1,10 @@
|
||||
//@ only-x86_64
|
||||
|
||||
// If we enable AVX2, we should see that it is enabled
|
||||
//@ compile-flags: -Ctarget-feature=+avx2
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].globally_enabled" true
|
||||
|
||||
// As well as its dependency chain
|
||||
//@ is "$.target.target_features[?(@.name=='avx')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='sse4.2')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='sse4.1')].globally_enabled" true
|
14
tests/rustdoc-json/targets/x86_64_unknown_linux_gnu.rs
Normal file
14
tests/rustdoc-json/targets/x86_64_unknown_linux_gnu.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//@ only-x86_64-unknown-linux-gnu
|
||||
|
||||
//@ is "$.target.triple" \"x86_64-unknown-linux-gnu\"
|
||||
//@ is "$.target.target_features[?(@.name=='sse2')].globally_enabled" true
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].globally_enabled" false
|
||||
//@ has "$.target.target_features[?(@.name=='avx2')].implies_features" '["avx"]'
|
||||
//@ is "$.target.target_features[?(@.name=='avx2')].unstable_feature_gate" null
|
||||
|
||||
// If this breaks due to stabilization, check rustc_target::target_features for a replacement
|
||||
//@ is "$.target.target_features[?(@.name=='amx-tile')].unstable_feature_gate" '"x86_amx_intrinsics"'
|
||||
//@ is "$.target.target_features[?(@.name=='x87')].unstable_feature_gate" '"x87_target_feature"'
|
||||
|
||||
// Ensure we don't look like aarch64
|
||||
//@ !has "$.target.target_features[?(@.name=='sve2')]"
|
Loading…
Reference in New Issue
Block a user