Auto merge of #107343 - JohnTitor:rollup-s6l94aj, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #105784 (update stdarch) - #106856 (core: Support variety of atomic widths in width-agnostic functions) - #107171 (rustc_metadata: Fix `encode_attrs`) - #107242 (rustdoc: make item links consistently use `title="{shortty} {path}"`) - #107279 (Use new solver during selection) - #107284 (rustdoc: use smarter encoding for playground URL) - #107325 (rustdoc: Stop using `HirId`s) - #107336 (rustdoc: remove mostly-unused CSS classes `import-item` and `module-item`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
18890f05f6
38 changed files with 302 additions and 253 deletions
|
@ -3,6 +3,7 @@ use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
|
|||
use crate::rmeta::table::TableBuilder;
|
||||
use crate::rmeta::*;
|
||||
|
||||
use rustc_ast::util::comments;
|
||||
use rustc_ast::Attribute;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
|
@ -759,36 +760,54 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
struct AnalyzeAttrState {
|
||||
is_exported: bool,
|
||||
may_have_doc_links: bool,
|
||||
is_doc_hidden: bool,
|
||||
}
|
||||
|
||||
/// Returns whether an attribute needs to be recorded in metadata, that is, if it's usable and
|
||||
/// useful in downstream crates. Local-only attributes are an obvious example, but some
|
||||
/// rustdoc-specific attributes can equally be of use while documenting the current crate only.
|
||||
///
|
||||
/// Removing these superfluous attributes speeds up compilation by making the metadata smaller.
|
||||
///
|
||||
/// Note: the `is_def_id_public` parameter is used to cache whether the given `DefId` has a public
|
||||
/// Note: the `is_exported` parameter is used to cache whether the given `DefId` has a public
|
||||
/// visibility: this is a piece of data that can be computed once per defid, and not once per
|
||||
/// attribute. Some attributes would only be usable downstream if they are public.
|
||||
#[inline]
|
||||
fn should_encode_attr(
|
||||
tcx: TyCtxt<'_>,
|
||||
attr: &Attribute,
|
||||
def_id: LocalDefId,
|
||||
is_def_id_public: &mut Option<bool>,
|
||||
) -> bool {
|
||||
fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState) -> bool {
|
||||
let mut should_encode = false;
|
||||
if rustc_feature::is_builtin_only_local(attr.name_or_empty()) {
|
||||
// Attributes marked local-only don't need to be encoded for downstream crates.
|
||||
false
|
||||
} else if attr.doc_str().is_some() {
|
||||
// We keep all public doc comments because they might be "imported" into downstream crates
|
||||
// if they use `#[doc(inline)]` to copy an item's documentation into their own.
|
||||
*is_def_id_public.get_or_insert_with(|| tcx.effective_visibilities(()).is_exported(def_id))
|
||||
} else if let Some(s) = attr.doc_str() {
|
||||
// We keep all doc comments reachable to rustdoc because they might be "imported" into
|
||||
// downstream crates if they use `#[doc(inline)]` to copy an item's documentation into
|
||||
// their own.
|
||||
if state.is_exported {
|
||||
should_encode = true;
|
||||
if comments::may_have_doc_links(s.as_str()) {
|
||||
state.may_have_doc_links = true;
|
||||
}
|
||||
}
|
||||
} else if attr.has_name(sym::doc) {
|
||||
// If this is a `doc` attribute, and it's marked `inline` (as in `#[doc(inline)]`), we can
|
||||
// remove it. It won't be inlinable in downstream crates.
|
||||
attr.meta_item_list().map(|l| l.iter().any(|l| !l.has_name(sym::inline))).unwrap_or(false)
|
||||
// If this is a `doc` attribute that doesn't have anything except maybe `inline` (as in
|
||||
// `#[doc(inline)]`), then we can remove it. It won't be inlinable in downstream crates.
|
||||
if let Some(item_list) = attr.meta_item_list() {
|
||||
for item in item_list {
|
||||
if !item.has_name(sym::inline) {
|
||||
should_encode = true;
|
||||
if item.has_name(sym::hidden) {
|
||||
state.is_doc_hidden = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
true
|
||||
should_encode = true;
|
||||
}
|
||||
should_encode
|
||||
}
|
||||
|
||||
fn should_encode_visibility(def_kind: DefKind) -> bool {
|
||||
|
@ -1108,24 +1127,24 @@ fn should_encode_trait_impl_trait_tys(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
fn encode_attrs(&mut self, def_id: LocalDefId) {
|
||||
let tcx = self.tcx;
|
||||
let mut is_public: Option<bool> = None;
|
||||
|
||||
let hir_attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(def_id));
|
||||
let mut attrs = hir_attrs
|
||||
let mut state = AnalyzeAttrState {
|
||||
is_exported: tcx.effective_visibilities(()).is_exported(def_id),
|
||||
may_have_doc_links: false,
|
||||
is_doc_hidden: false,
|
||||
};
|
||||
let attr_iter = tcx
|
||||
.hir()
|
||||
.attrs(tcx.hir().local_def_id_to_hir_id(def_id))
|
||||
.iter()
|
||||
.filter(move |attr| should_encode_attr(tcx, attr, def_id, &mut is_public));
|
||||
.filter(|attr| analyze_attr(attr, &mut state));
|
||||
|
||||
record_array!(self.tables.attributes[def_id.to_def_id()] <- attr_iter);
|
||||
|
||||
record_array!(self.tables.attributes[def_id.to_def_id()] <- attrs.clone());
|
||||
let mut attr_flags = AttrFlags::empty();
|
||||
if attrs.any(|attr| attr.may_have_doc_links()) {
|
||||
if state.may_have_doc_links {
|
||||
attr_flags |= AttrFlags::MAY_HAVE_DOC_LINKS;
|
||||
}
|
||||
if hir_attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.has_name(sym::doc))
|
||||
.filter_map(|attr| attr.meta_item_list())
|
||||
.any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
|
||||
{
|
||||
if state.is_doc_hidden {
|
||||
attr_flags |= AttrFlags::IS_DOC_HIDDEN;
|
||||
}
|
||||
if !attr_flags.is_empty() {
|
||||
|
|
|
@ -945,6 +945,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
|
|||
if sess.target.has_thread_local {
|
||||
ret.insert((sym::target_thread_local, None));
|
||||
}
|
||||
let mut has_atomic = false;
|
||||
for (i, align) in [
|
||||
(8, layout.i8_align.abi),
|
||||
(16, layout.i16_align.abi),
|
||||
|
@ -953,6 +954,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
|
|||
(128, layout.i128_align.abi),
|
||||
] {
|
||||
if i >= min_atomic_width && i <= max_atomic_width {
|
||||
has_atomic = true;
|
||||
let mut insert_atomic = |s, align: Align| {
|
||||
ret.insert((sym::target_has_atomic_load_store, Some(Symbol::intern(s))));
|
||||
if atomic_cas {
|
||||
|
@ -969,6 +971,12 @@ fn default_configuration(sess: &Session) -> CrateConfig {
|
|||
}
|
||||
}
|
||||
}
|
||||
if sess.is_nightly_build() && has_atomic {
|
||||
ret.insert((sym::target_has_atomic_load_store, None));
|
||||
if atomic_cas {
|
||||
ret.insert((sym::target_has_atomic, None));
|
||||
}
|
||||
}
|
||||
|
||||
let panic_strategy = sess.panic_strategy();
|
||||
ret.insert((sym::panic, Some(panic_strategy.desc_symbol())));
|
||||
|
|
|
@ -38,6 +38,8 @@ use rustc_errors::Diagnostic;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
use rustc_infer::traits::TraitEngineExt;
|
||||
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||
|
@ -47,6 +49,7 @@ use rustc_middle::ty::relate::TypeRelation;
|
|||
use rustc_middle::ty::SubstsRef;
|
||||
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
|
||||
use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
||||
use rustc_session::config::TraitSolver;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
@ -544,10 +547,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
self.evaluation_probe(|this| {
|
||||
this.evaluate_predicate_recursively(
|
||||
TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
|
||||
obligation.clone(),
|
||||
)
|
||||
if this.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
|
||||
this.evaluate_predicate_recursively(
|
||||
TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
|
||||
obligation.clone(),
|
||||
)
|
||||
} else {
|
||||
this.evaluate_predicates_recursively_in_new_solver([obligation.clone()])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -586,18 +593,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
where
|
||||
I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,
|
||||
{
|
||||
let mut result = EvaluatedToOk;
|
||||
for obligation in predicates {
|
||||
let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?;
|
||||
if let EvaluatedToErr = eval {
|
||||
// fast-path - EvaluatedToErr is the top of the lattice,
|
||||
// so we don't need to look on the other predicates.
|
||||
return Ok(EvaluatedToErr);
|
||||
} else {
|
||||
result = cmp::max(result, eval);
|
||||
if self.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
|
||||
let mut result = EvaluatedToOk;
|
||||
for obligation in predicates {
|
||||
let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?;
|
||||
if let EvaluatedToErr = eval {
|
||||
// fast-path - EvaluatedToErr is the top of the lattice,
|
||||
// so we don't need to look on the other predicates.
|
||||
return Ok(EvaluatedToErr);
|
||||
} else {
|
||||
result = cmp::max(result, eval);
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
} else {
|
||||
self.evaluate_predicates_recursively_in_new_solver(predicates)
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Evaluates the predicates using the new solver when `-Ztrait-solver=next` is enabled
|
||||
fn evaluate_predicates_recursively_in_new_solver(
|
||||
&mut self,
|
||||
predicates: impl IntoIterator<Item = PredicateObligation<'tcx>>,
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
let mut fulfill_cx = crate::solve::FulfillmentCtxt::new();
|
||||
fulfill_cx.register_predicate_obligations(self.infcx, predicates);
|
||||
// True errors
|
||||
if !fulfill_cx.select_where_possible(self.infcx).is_empty() {
|
||||
return Ok(EvaluatedToErr);
|
||||
}
|
||||
if !fulfill_cx.select_all_or_error(self.infcx).is_empty() {
|
||||
return Ok(EvaluatedToAmbig);
|
||||
}
|
||||
// Regions and opaques are handled in the `evaluation_probe` by looking at the snapshot
|
||||
Ok(EvaluatedToOk)
|
||||
}
|
||||
|
||||
#[instrument(
|
||||
|
|
|
@ -1861,7 +1861,8 @@ macro_rules! if_not_8_bit {
|
|||
($_:ident, $($tt:tt)*) => { $($tt)* };
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic_load_store = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic_load_store))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic_load_store = "8"))]
|
||||
macro_rules! atomic_int {
|
||||
($cfg_cas:meta,
|
||||
$cfg_align:meta,
|
||||
|
@ -2988,7 +2989,8 @@ atomic_int_ptr_sized! {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
fn strongest_failure_ordering(order: Ordering) -> Ordering {
|
||||
match order {
|
||||
Release => Relaxed,
|
||||
|
@ -3030,7 +3032,8 @@ unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_swap`.
|
||||
|
@ -3047,7 +3050,8 @@ unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// Returns the previous value (like __sync_fetch_and_add).
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_add`.
|
||||
|
@ -3064,7 +3068,8 @@ unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// Returns the previous value (like __sync_fetch_and_sub).
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_sub`.
|
||||
|
@ -3080,7 +3085,8 @@ unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_compare_exchange<T: Copy>(
|
||||
dst: *mut T,
|
||||
|
@ -3115,7 +3121,8 @@ unsafe fn atomic_compare_exchange<T: Copy>(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_compare_exchange_weak<T: Copy>(
|
||||
dst: *mut T,
|
||||
|
@ -3150,7 +3157,8 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_and`
|
||||
|
@ -3166,7 +3174,8 @@ unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_nand`
|
||||
|
@ -3182,7 +3191,8 @@ unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_or`
|
||||
|
@ -3198,7 +3208,8 @@ unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_xor`
|
||||
|
@ -3215,7 +3226,8 @@ unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// returns the max value (signed comparison)
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_max`
|
||||
|
@ -3232,7 +3244,8 @@ unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// returns the min value (signed comparison)
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_min`
|
||||
|
@ -3249,7 +3262,8 @@ unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// returns the max value (unsigned comparison)
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_umax`
|
||||
|
@ -3266,7 +3280,8 @@ unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// returns the min value (unsigned comparison)
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
|
||||
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
// SAFETY: the caller must uphold the safety contract for `atomic_umin`
|
||||
|
|
|
@ -120,16 +120,13 @@ fn x86_all() {
|
|||
println!("avx512dq: {:?}", is_x86_feature_detected!("avx512dq"));
|
||||
println!("avx512er: {:?}", is_x86_feature_detected!("avx512er"));
|
||||
println!("avx512f: {:?}", is_x86_feature_detected!("avx512f"));
|
||||
println!("avx512gfni: {:?}", is_x86_feature_detected!("avx512gfni"));
|
||||
println!("avx512ifma: {:?}", is_x86_feature_detected!("avx512ifma"));
|
||||
println!("avx512pf: {:?}", is_x86_feature_detected!("avx512pf"));
|
||||
println!("avx512vaes: {:?}", is_x86_feature_detected!("avx512vaes"));
|
||||
println!("avx512vbmi2: {:?}", is_x86_feature_detected!("avx512vbmi2"));
|
||||
println!("avx512vbmi: {:?}", is_x86_feature_detected!("avx512vbmi"));
|
||||
println!("avx512vl: {:?}", is_x86_feature_detected!("avx512vl"));
|
||||
println!("avx512vnni: {:?}", is_x86_feature_detected!("avx512vnni"));
|
||||
println!("avx512vp2intersect: {:?}", is_x86_feature_detected!("avx512vp2intersect"));
|
||||
println!("avx512vpclmulqdq: {:?}", is_x86_feature_detected!("avx512vpclmulqdq"));
|
||||
println!("avx512vpopcntdq: {:?}", is_x86_feature_detected!("avx512vpopcntdq"));
|
||||
println!("avx: {:?}", is_x86_feature_detected!("avx"));
|
||||
println!("bmi1: {:?}", is_x86_feature_detected!("bmi1"));
|
||||
|
@ -138,6 +135,7 @@ fn x86_all() {
|
|||
println!("f16c: {:?}", is_x86_feature_detected!("f16c"));
|
||||
println!("fma: {:?}", is_x86_feature_detected!("fma"));
|
||||
println!("fxsr: {:?}", is_x86_feature_detected!("fxsr"));
|
||||
println!("gfni: {:?}", is_x86_feature_detected!("gfni"));
|
||||
println!("lzcnt: {:?}", is_x86_feature_detected!("lzcnt"));
|
||||
//println!("movbe: {:?}", is_x86_feature_detected!("movbe")); // movbe is unsupported as a target feature
|
||||
println!("pclmulqdq: {:?}", is_x86_feature_detected!("pclmulqdq"));
|
||||
|
@ -154,6 +152,8 @@ fn x86_all() {
|
|||
println!("sse: {:?}", is_x86_feature_detected!("sse"));
|
||||
println!("ssse3: {:?}", is_x86_feature_detected!("ssse3"));
|
||||
println!("tbm: {:?}", is_x86_feature_detected!("tbm"));
|
||||
println!("vaes: {:?}", is_x86_feature_detected!("vaes"));
|
||||
println!("vpclmulqdq: {:?}", is_x86_feature_detected!("vpclmulqdq"));
|
||||
println!("xsave: {:?}", is_x86_feature_detected!("xsave"));
|
||||
println!("xsavec: {:?}", is_x86_feature_detected!("xsavec"));
|
||||
println!("xsaveopt: {:?}", is_x86_feature_detected!("xsaveopt"));
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 790411f93c4b5eada3c23abb4c9a063fb0b24d99
|
||||
Subproject commit a0c30f3e3c75adcd6ee7efc94014ebcead61c507
|
|
@ -15,7 +15,7 @@ use rustc_attr as attr;
|
|||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE};
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::PredicateOrigin;
|
||||
use rustc_hir_analysis::hir_ty_to_ty;
|
||||
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
|
@ -116,7 +116,8 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
|||
}
|
||||
});
|
||||
|
||||
Item::from_hir_id_and_parts(doc.id, Some(doc.name), ModuleItem(Module { items, span }), cx)
|
||||
let kind = ModuleItem(Module { items, span });
|
||||
Item::from_def_id_and_parts(doc.def_id.to_def_id(), Some(doc.name), kind, cx)
|
||||
}
|
||||
|
||||
fn clean_generic_bound<'tcx>(
|
||||
|
@ -2067,12 +2068,12 @@ struct OneLevelVisitor<'hir> {
|
|||
map: rustc_middle::hir::map::Map<'hir>,
|
||||
item: Option<&'hir hir::Item<'hir>>,
|
||||
looking_for: Ident,
|
||||
target_hir_id: hir::HirId,
|
||||
target_def_id: LocalDefId,
|
||||
}
|
||||
|
||||
impl<'hir> OneLevelVisitor<'hir> {
|
||||
fn new(map: rustc_middle::hir::map::Map<'hir>, target_hir_id: hir::HirId) -> Self {
|
||||
Self { map, item: None, looking_for: Ident::empty(), target_hir_id }
|
||||
fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self {
|
||||
Self { map, item: None, looking_for: Ident::empty(), target_def_id }
|
||||
}
|
||||
|
||||
fn reset(&mut self, looking_for: Ident) {
|
||||
|
@ -2092,7 +2093,7 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
|
|||
if self.item.is_none()
|
||||
&& item.ident == self.looking_for
|
||||
&& matches!(item.kind, hir::ItemKind::Use(_, _))
|
||||
|| item.hir_id() == self.target_hir_id
|
||||
|| item.owner_id.def_id == self.target_def_id
|
||||
{
|
||||
self.item = Some(item);
|
||||
}
|
||||
|
@ -2106,11 +2107,11 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
|
|||
fn get_all_import_attributes<'hir>(
|
||||
mut item: &hir::Item<'hir>,
|
||||
tcx: TyCtxt<'hir>,
|
||||
target_hir_id: hir::HirId,
|
||||
target_def_id: LocalDefId,
|
||||
attributes: &mut Vec<ast::Attribute>,
|
||||
) {
|
||||
let hir_map = tcx.hir();
|
||||
let mut visitor = OneLevelVisitor::new(hir_map, target_hir_id);
|
||||
let mut visitor = OneLevelVisitor::new(hir_map, target_def_id);
|
||||
// If the item is an import and has at least a path with two parts, we go into it.
|
||||
while let hir::ItemKind::Use(path, _) = item.kind &&
|
||||
path.segments.len() > 1 &&
|
||||
|
@ -2138,7 +2139,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||
cx: &mut DocContext<'tcx>,
|
||||
item: &hir::Item<'tcx>,
|
||||
renamed: Option<Symbol>,
|
||||
import_id: Option<hir::HirId>,
|
||||
import_id: Option<LocalDefId>,
|
||||
) -> Vec<Item> {
|
||||
use hir::ItemKind;
|
||||
|
||||
|
@ -2183,7 +2184,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||
generics: clean_generics(generics, cx),
|
||||
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
|
||||
}),
|
||||
ItemKind::Impl(impl_) => return clean_impl(impl_, item.hir_id(), cx),
|
||||
ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx),
|
||||
// proc macros can have a name set by attributes
|
||||
ItemKind::Fn(ref sig, generics, body_id) => {
|
||||
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
|
||||
|
@ -2218,10 +2219,10 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||
|
||||
let mut extra_attrs = Vec::new();
|
||||
if let Some(hir::Node::Item(use_node)) =
|
||||
import_id.and_then(|hir_id| cx.tcx.hir().find(hir_id))
|
||||
import_id.and_then(|def_id| cx.tcx.hir().find_by_def_id(def_id))
|
||||
{
|
||||
// We get all the various imports' attributes.
|
||||
get_all_import_attributes(use_node, cx.tcx, item.hir_id(), &mut extra_attrs);
|
||||
get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs);
|
||||
}
|
||||
|
||||
if !extra_attrs.is_empty() {
|
||||
|
@ -2244,12 +2245,12 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||
|
||||
fn clean_variant<'tcx>(variant: &hir::Variant<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
|
||||
let kind = VariantItem(clean_variant_data(&variant.data, &variant.disr_expr, cx));
|
||||
Item::from_hir_id_and_parts(variant.hir_id, Some(variant.ident.name), kind, cx)
|
||||
Item::from_def_id_and_parts(variant.def_id.to_def_id(), Some(variant.ident.name), kind, cx)
|
||||
}
|
||||
|
||||
fn clean_impl<'tcx>(
|
||||
impl_: &hir::Impl<'tcx>,
|
||||
hir_id: hir::HirId,
|
||||
def_id: LocalDefId,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> Vec<Item> {
|
||||
let tcx = cx.tcx;
|
||||
|
@ -2260,7 +2261,6 @@ fn clean_impl<'tcx>(
|
|||
.iter()
|
||||
.map(|ii| clean_impl_item(tcx.hir().impl_item(ii.id), cx))
|
||||
.collect::<Vec<_>>();
|
||||
let def_id = tcx.hir().local_def_id(hir_id);
|
||||
|
||||
// If this impl block is an implementation of the Deref trait, then we
|
||||
// need to try inlining the target's inherent impl blocks as well.
|
||||
|
@ -2289,7 +2289,7 @@ fn clean_impl<'tcx>(
|
|||
ImplKind::Normal
|
||||
},
|
||||
}));
|
||||
Item::from_hir_id_and_parts(hir_id, None, kind, cx)
|
||||
Item::from_def_id_and_parts(def_id.to_def_id(), None, kind, cx)
|
||||
};
|
||||
if let Some(type_alias) = type_alias {
|
||||
ret.push(make_item(trait_.clone(), type_alias, items.clone()));
|
||||
|
@ -2510,8 +2510,8 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
|
|||
hir::ForeignItemKind::Type => ForeignTypeItem,
|
||||
};
|
||||
|
||||
Item::from_hir_id_and_parts(
|
||||
item.hir_id(),
|
||||
Item::from_def_id_and_parts(
|
||||
item.owner_id.def_id.to_def_id(),
|
||||
Some(renamed.unwrap_or(item.ident.name)),
|
||||
kind,
|
||||
cx,
|
||||
|
|
|
@ -439,17 +439,6 @@ impl Item {
|
|||
self.attrs.doc_value()
|
||||
}
|
||||
|
||||
/// Convenience wrapper around [`Self::from_def_id_and_parts`] which converts
|
||||
/// `hir_id` to a [`DefId`]
|
||||
pub(crate) fn from_hir_id_and_parts(
|
||||
hir_id: hir::HirId,
|
||||
name: Option<Symbol>,
|
||||
kind: ItemKind,
|
||||
cx: &mut DocContext<'_>,
|
||||
) -> Item {
|
||||
Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx)
|
||||
}
|
||||
|
||||
pub(crate) fn from_def_id_and_parts(
|
||||
def_id: DefId,
|
||||
name: Option<Symbol>,
|
||||
|
@ -2416,10 +2405,7 @@ impl ConstantKind {
|
|||
|
||||
pub(crate) fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
match *self {
|
||||
ConstantKind::TyConst { .. } => false,
|
||||
ConstantKind::Extern { def_id } => def_id.as_local().map_or(false, |def_id| {
|
||||
is_literal_expr(tcx, tcx.hir().local_def_id_to_hir_id(def_id))
|
||||
}),
|
||||
ConstantKind::TyConst { .. } | ConstantKind::Extern { .. } => false,
|
||||
ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
|
||||
is_literal_expr(tcx, body.hir_id)
|
||||
}
|
||||
|
|
|
@ -2,10 +2,8 @@ use rustc_ast as ast;
|
|||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{ColorConfig, ErrorGuaranteed, FatalError};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::{HirId, CRATE_HIR_ID};
|
||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::{self as hir, intravisit, CRATE_HIR_ID};
|
||||
use rustc_interface::interface;
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
@ -140,7 +138,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
|
|||
};
|
||||
hir_collector.visit_testable(
|
||||
"".to_string(),
|
||||
CRATE_HIR_ID,
|
||||
CRATE_DEF_ID,
|
||||
tcx.hir().span(CRATE_HIR_ID),
|
||||
|this| tcx.hir().walk_toplevel_module(this),
|
||||
);
|
||||
|
@ -1214,11 +1212,11 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> {
|
|||
fn visit_testable<F: FnOnce(&mut Self)>(
|
||||
&mut self,
|
||||
name: String,
|
||||
hir_id: HirId,
|
||||
def_id: LocalDefId,
|
||||
sp: Span,
|
||||
nested: F,
|
||||
) {
|
||||
let ast_attrs = self.tcx.hir().attrs(hir_id);
|
||||
let ast_attrs = self.tcx.hir().attrs(self.tcx.hir().local_def_id_to_hir_id(def_id));
|
||||
if let Some(ref cfg) = ast_attrs.cfg(self.tcx, &FxHashSet::default()) {
|
||||
if !cfg.matches(&self.sess.parse_sess, Some(self.tcx.features())) {
|
||||
return;
|
||||
|
@ -1247,7 +1245,7 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> {
|
|||
self.collector.enable_per_target_ignores,
|
||||
Some(&crate::html::markdown::ExtraInfo::new(
|
||||
self.tcx,
|
||||
hir_id,
|
||||
def_id.to_def_id(),
|
||||
span_of_attrs(&attrs).unwrap_or(sp),
|
||||
)),
|
||||
);
|
||||
|
@ -1276,37 +1274,37 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
|
|||
_ => item.ident.to_string(),
|
||||
};
|
||||
|
||||
self.visit_testable(name, item.hir_id(), item.span, |this| {
|
||||
self.visit_testable(name, item.owner_id.def_id, item.span, |this| {
|
||||
intravisit::walk_item(this, item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, item: &'hir hir::TraitItem<'_>) {
|
||||
self.visit_testable(item.ident.to_string(), item.hir_id(), item.span, |this| {
|
||||
self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| {
|
||||
intravisit::walk_trait_item(this, item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, item: &'hir hir::ImplItem<'_>) {
|
||||
self.visit_testable(item.ident.to_string(), item.hir_id(), item.span, |this| {
|
||||
self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| {
|
||||
intravisit::walk_impl_item(this, item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, item: &'hir hir::ForeignItem<'_>) {
|
||||
self.visit_testable(item.ident.to_string(), item.hir_id(), item.span, |this| {
|
||||
self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| {
|
||||
intravisit::walk_foreign_item(this, item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &'hir hir::Variant<'_>) {
|
||||
self.visit_testable(v.ident.to_string(), v.hir_id, v.span, |this| {
|
||||
self.visit_testable(v.ident.to_string(), v.def_id, v.span, |this| {
|
||||
intravisit::walk_variant(this, v);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_field_def(&mut self, f: &'hir hir::FieldDef<'_>) {
|
||||
self.visit_testable(f.ident.to_string(), f.hir_id, f.span, |this| {
|
||||
self.visit_testable(f.ident.to_string(), f.def_id, f.span, |this| {
|
||||
intravisit::walk_field_def(this, f);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::HirId;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
@ -296,7 +295,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" };
|
||||
|
||||
// These characters don't need to be escaped in a URI.
|
||||
// FIXME: use a library function for percent encoding.
|
||||
// See https://url.spec.whatwg.org/#query-percent-encode-set
|
||||
// and https://url.spec.whatwg.org/#urlencoded-parsing
|
||||
// and https://url.spec.whatwg.org/#url-code-points
|
||||
fn dont_escape(c: u8) -> bool {
|
||||
(b'a' <= c && c <= b'z')
|
||||
|| (b'A' <= c && c <= b'Z')
|
||||
|
@ -304,17 +305,32 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
|| c == b'-'
|
||||
|| c == b'_'
|
||||
|| c == b'.'
|
||||
|| c == b','
|
||||
|| c == b'~'
|
||||
|| c == b'!'
|
||||
|| c == b'\''
|
||||
|| c == b'('
|
||||
|| c == b')'
|
||||
|| c == b'*'
|
||||
|| c == b'/'
|
||||
|| c == b';'
|
||||
|| c == b':'
|
||||
|| c == b'?'
|
||||
// As described in urlencoded-parsing, the
|
||||
// first `=` is the one that separates key from
|
||||
// value. Following `=`s are part of the value.
|
||||
|| c == b'='
|
||||
}
|
||||
let mut test_escaped = String::new();
|
||||
for b in test.bytes() {
|
||||
if dont_escape(b) {
|
||||
test_escaped.push(char::from(b));
|
||||
} else if b == b' ' {
|
||||
// URL queries are decoded with + replaced with SP
|
||||
test_escaped.push('+');
|
||||
} else if b == b'%' {
|
||||
test_escaped.push('%');
|
||||
test_escaped.push('%');
|
||||
} else {
|
||||
write!(test_escaped, "%{:02X}", b).unwrap();
|
||||
}
|
||||
|
@ -784,45 +800,26 @@ pub(crate) fn find_testable_code<T: doctest::Tester>(
|
|||
}
|
||||
|
||||
pub(crate) struct ExtraInfo<'tcx> {
|
||||
id: ExtraInfoId,
|
||||
def_id: DefId,
|
||||
sp: Span,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
enum ExtraInfoId {
|
||||
Hir(HirId),
|
||||
Def(DefId),
|
||||
}
|
||||
|
||||
impl<'tcx> ExtraInfo<'tcx> {
|
||||
pub(crate) fn new(tcx: TyCtxt<'tcx>, hir_id: HirId, sp: Span) -> ExtraInfo<'tcx> {
|
||||
ExtraInfo { id: ExtraInfoId::Hir(hir_id), sp, tcx }
|
||||
}
|
||||
|
||||
pub(crate) fn new_did(tcx: TyCtxt<'tcx>, did: DefId, sp: Span) -> ExtraInfo<'tcx> {
|
||||
ExtraInfo { id: ExtraInfoId::Def(did), sp, tcx }
|
||||
pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: DefId, sp: Span) -> ExtraInfo<'tcx> {
|
||||
ExtraInfo { def_id, sp, tcx }
|
||||
}
|
||||
|
||||
fn error_invalid_codeblock_attr(&self, msg: &str, help: &str) {
|
||||
let hir_id = match self.id {
|
||||
ExtraInfoId::Hir(hir_id) => hir_id,
|
||||
ExtraInfoId::Def(item_did) => {
|
||||
match item_did.as_local() {
|
||||
Some(item_did) => self.tcx.hir().local_def_id_to_hir_id(item_did),
|
||||
None => {
|
||||
// If non-local, no need to check anything.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
self.tcx.struct_span_lint_hir(
|
||||
crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
|
||||
hir_id,
|
||||
self.sp,
|
||||
msg,
|
||||
|lint| lint.help(help),
|
||||
);
|
||||
if let Some(def_id) = self.def_id.as_local() {
|
||||
self.tcx.struct_span_lint_hir(
|
||||
crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
|
||||
self.tcx.hir().local_def_id_to_hir_id(def_id),
|
||||
self.sp,
|
||||
msg,
|
||||
|lint| lint.help(help),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -391,7 +391,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
|||
};
|
||||
write!(
|
||||
w,
|
||||
"<div class=\"item-left {stab}{add}import-item\"{id}>\
|
||||
"<div class=\"item-left{add}{stab}\"{id}>\
|
||||
<code>{vis}{imp}</code>\
|
||||
</div>\
|
||||
{stab_tags_before}{stab_tags}{stab_tags_after}",
|
||||
|
@ -437,7 +437,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
|||
};
|
||||
write!(
|
||||
w,
|
||||
"<div class=\"item-left {stab}{add}module-item\">\
|
||||
"<div class=\"item-left{add}{stab}\">\
|
||||
<a class=\"{class}\" href=\"{href}\" title=\"{title}\">{name}</a>\
|
||||
{visibility_emoji}\
|
||||
{unsafety_flag}\
|
||||
|
@ -452,7 +452,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
|||
stab = stab.unwrap_or_default(),
|
||||
unsafety_flag = unsafety_flag,
|
||||
href = item_path(myitem.type_(), myitem.name.unwrap().as_str()),
|
||||
title = [full_path(cx, myitem), myitem.type_().to_string()]
|
||||
title = [myitem.type_().to_string(), full_path(cx, myitem)]
|
||||
.iter()
|
||||
.filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None })
|
||||
.collect::<Vec<_>>()
|
||||
|
|
|
@ -977,8 +977,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
|
|||
0 -1px 0 black;
|
||||
}
|
||||
|
||||
.module-item.unstable,
|
||||
.import-item.unstable {
|
||||
.item-left.unstable {
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
|
|
|
@ -216,13 +216,7 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> {
|
|||
);
|
||||
|
||||
let has_doc_example = tests.found_tests != 0;
|
||||
// The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
|
||||
// would presumably panic if a fake `DefIndex` were passed.
|
||||
let hir_id = self
|
||||
.ctx
|
||||
.tcx
|
||||
.hir()
|
||||
.local_def_id_to_hir_id(i.item_id.expect_def_id().expect_local());
|
||||
let hir_id = DocContext::as_local_hir_id(self.ctx.tcx, i.item_id).unwrap();
|
||||
let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id);
|
||||
|
||||
// In case we have:
|
||||
|
|
|
@ -14,8 +14,8 @@ use crate::visit::DocVisitor;
|
|||
use crate::visit_ast::inherits_doc_hidden;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::lint::LintLevelSource;
|
||||
use rustc_middle::ty::DefIdTree;
|
||||
use rustc_session::lint;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
pub(crate) const CHECK_DOC_TEST_VISIBILITY: Pass = Pass {
|
||||
name: "check_doc_test_visibility",
|
||||
|
@ -79,11 +79,11 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
|
|||
|
||||
// The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
|
||||
// would presumably panic if a fake `DefIndex` were passed.
|
||||
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.item_id.expect_def_id().expect_local());
|
||||
let def_id = item.item_id.expect_def_id().expect_local();
|
||||
|
||||
// check if parent is trait impl
|
||||
if let Some(parent_hir_id) = cx.tcx.hir().opt_parent_id(hir_id) {
|
||||
if let Some(parent_node) = cx.tcx.hir().find(parent_hir_id) {
|
||||
if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id) {
|
||||
if let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id) {
|
||||
if matches!(
|
||||
parent_node,
|
||||
hir::Node::Item(hir::Item {
|
||||
|
@ -96,13 +96,16 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
|
|||
}
|
||||
}
|
||||
|
||||
if cx.tcx.hir().attrs(hir_id).lists(sym::doc).has_word(sym::hidden)
|
||||
|| inherits_doc_hidden(cx.tcx, hir_id)
|
||||
|| cx.tcx.hir().span(hir_id).in_derive_expansion()
|
||||
if cx.tcx.is_doc_hidden(def_id.to_def_id())
|
||||
|| inherits_doc_hidden(cx.tcx, def_id)
|
||||
|| cx.tcx.def_span(def_id.to_def_id()).in_derive_expansion()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
let (level, source) = cx.tcx.lint_level_at_node(crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id);
|
||||
let (level, source) = cx.tcx.lint_level_at_node(
|
||||
crate::lint::MISSING_DOC_CODE_EXAMPLES,
|
||||
cx.tcx.hir().local_def_id_to_hir_id(def_id),
|
||||
);
|
||||
level != lint::Level::Allow || matches!(source, LintLevelSource::Default)
|
||||
}
|
||||
|
||||
|
|
|
@ -1194,14 +1194,9 @@ impl LinkCollector<'_, '_> {
|
|||
}
|
||||
|
||||
// item can be non-local e.g. when using #[doc(primitive = "pointer")]
|
||||
if let Some((src_id, dst_id)) = id
|
||||
.as_local()
|
||||
// The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
|
||||
// would presumably panic if a fake `DefIndex` were passed.
|
||||
.and_then(|dst_id| {
|
||||
item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
|
||||
})
|
||||
{
|
||||
if let Some((src_id, dst_id)) = id.as_local().and_then(|dst_id| {
|
||||
item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
|
||||
}) {
|
||||
if self.cx.tcx.effective_visibilities(()).is_exported(src_id)
|
||||
&& !self.cx.tcx.effective_visibilities(()).is_exported(dst_id)
|
||||
{
|
||||
|
|
|
@ -19,8 +19,7 @@ use crate::passes::source_span_for_markdown_range;
|
|||
pub(crate) fn visit_item(cx: &DocContext<'_>, item: &clean::Item) {
|
||||
if let Some(dox) = &item.attrs.collapsed_doc_value() {
|
||||
let sp = item.attr_span(cx.tcx);
|
||||
let extra =
|
||||
crate::html::markdown::ExtraInfo::new_did(cx.tcx, item.item_id.expect_def_id(), sp);
|
||||
let extra = crate::html::markdown::ExtraInfo::new(cx.tcx, item.item_id.expect_def_id(), sp);
|
||||
for code_block in markdown::rust_code_blocks(dox, &extra) {
|
||||
check_rust_syntax(cx, item, dox, code_block);
|
||||
}
|
||||
|
@ -73,7 +72,6 @@ fn check_rust_syntax(
|
|||
return;
|
||||
};
|
||||
|
||||
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
|
||||
let empty_block = code_block.lang_string == Default::default() && code_block.is_fenced;
|
||||
let is_ignore = code_block.lang_string.ignore != markdown::Ignore::None;
|
||||
|
||||
|
@ -93,6 +91,7 @@ fn check_rust_syntax(
|
|||
// Finally build and emit the completed diagnostic.
|
||||
// All points of divergence have been handled earlier so this can be
|
||||
// done the same way whether the span is precise or not.
|
||||
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
|
||||
cx.tcx.struct_span_lint_hir(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, msg, |lint| {
|
||||
let explanation = if is_ignore {
|
||||
"`ignore` code blocks require valid Rust code for syntax highlighting; \
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::fold::DocFolder;
|
|||
use crate::passes::Pass;
|
||||
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::ty::DefIdTree;
|
||||
|
||||
pub(crate) const PROPAGATE_DOC_CFG: Pass = Pass {
|
||||
name: "propagate-doc-cfg",
|
||||
|
@ -41,24 +42,22 @@ impl<'a, 'tcx> CfgPropagator<'a, 'tcx> {
|
|||
let Some(def_id) = item.item_id.as_def_id().and_then(|def_id| def_id.as_local())
|
||||
else { return };
|
||||
|
||||
let hir = self.cx.tcx.hir();
|
||||
let hir_id = hir.local_def_id_to_hir_id(def_id);
|
||||
|
||||
if check_parent {
|
||||
let expected_parent = hir.get_parent_item(hir_id);
|
||||
let expected_parent = self.cx.tcx.opt_local_parent(def_id);
|
||||
// If parents are different, it means that `item` is a reexport and we need
|
||||
// to compute the actual `cfg` by iterating through its "real" parents.
|
||||
if self.parent == Some(expected_parent.def_id) {
|
||||
if self.parent.is_some() && self.parent == expected_parent {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let mut attrs = Vec::new();
|
||||
for (parent_hir_id, _) in hir.parent_iter(hir_id) {
|
||||
if let Some(def_id) = hir.opt_local_def_id(parent_hir_id) {
|
||||
attrs.extend_from_slice(load_attrs(self.cx, def_id.to_def_id()));
|
||||
}
|
||||
let mut next_def_id = def_id;
|
||||
while let Some(parent_def_id) = self.cx.tcx.opt_local_parent(next_def_id) {
|
||||
attrs.extend_from_slice(load_attrs(self.cx, parent_def_id.to_def_id()));
|
||||
next_def_id = parent_def_id;
|
||||
}
|
||||
|
||||
let (_, cfg) = merge_attrs(self.cx, None, item.attrs.other_attrs.as_slice(), Some(&attrs));
|
||||
item.cfg = cfg;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, DefIdMap};
|
||||
use rustc_hir::{HirIdSet, Node, CRATE_HIR_ID};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet};
|
||||
use rustc_hir::{Node, CRATE_HIR_ID};
|
||||
use rustc_middle::ty::{DefIdTree, TyCtxt};
|
||||
use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
@ -23,19 +23,26 @@ pub(crate) struct Module<'hir> {
|
|||
pub(crate) name: Symbol,
|
||||
pub(crate) where_inner: Span,
|
||||
pub(crate) mods: Vec<Module<'hir>>,
|
||||
pub(crate) id: hir::HirId,
|
||||
pub(crate) def_id: LocalDefId,
|
||||
// (item, renamed, import_id)
|
||||
pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<hir::HirId>)>,
|
||||
pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>)>,
|
||||
pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
|
||||
}
|
||||
|
||||
impl Module<'_> {
|
||||
pub(crate) fn new(name: Symbol, id: hir::HirId, where_inner: Span) -> Self {
|
||||
Module { name, id, where_inner, mods: Vec::new(), items: Vec::new(), foreigns: Vec::new() }
|
||||
pub(crate) fn new(name: Symbol, def_id: LocalDefId, where_inner: Span) -> Self {
|
||||
Module {
|
||||
name,
|
||||
def_id,
|
||||
where_inner,
|
||||
mods: Vec::new(),
|
||||
items: Vec::new(),
|
||||
foreigns: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn where_outer(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
tcx.hir().span(self.id)
|
||||
tcx.def_span(self.def_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,10 +53,10 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<Symbol> {
|
|||
std::iter::once(crate_name).chain(relative).collect()
|
||||
}
|
||||
|
||||
pub(crate) fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut node: hir::HirId) -> bool {
|
||||
while let Some(id) = tcx.hir().get_enclosing_scope(node) {
|
||||
pub(crate) fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut node: LocalDefId) -> bool {
|
||||
while let Some(id) = tcx.opt_local_parent(node) {
|
||||
node = id;
|
||||
if tcx.hir().attrs(node).lists(sym::doc).has_word(sym::hidden) {
|
||||
if tcx.is_doc_hidden(node.to_def_id()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +68,7 @@ pub(crate) fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut node: hir::HirId) -> bool
|
|||
|
||||
pub(crate) struct RustdocVisitor<'a, 'tcx> {
|
||||
cx: &'a mut core::DocContext<'tcx>,
|
||||
view_item_stack: HirIdSet,
|
||||
view_item_stack: LocalDefIdSet,
|
||||
inlining: bool,
|
||||
/// Are the current module and all of its parents public?
|
||||
inside_public_path: bool,
|
||||
|
@ -71,8 +78,8 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
|
|||
impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
pub(crate) fn new(cx: &'a mut core::DocContext<'tcx>) -> RustdocVisitor<'a, 'tcx> {
|
||||
// If the root is re-exported, terminate all recursion.
|
||||
let mut stack = HirIdSet::default();
|
||||
stack.insert(hir::CRATE_HIR_ID);
|
||||
let mut stack = LocalDefIdSet::default();
|
||||
stack.insert(CRATE_DEF_ID);
|
||||
RustdocVisitor {
|
||||
cx,
|
||||
view_item_stack: stack,
|
||||
|
@ -89,7 +96,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
|
||||
pub(crate) fn visit(mut self) -> Module<'tcx> {
|
||||
let mut top_level_module = self.visit_mod_contents(
|
||||
hir::CRATE_HIR_ID,
|
||||
CRATE_DEF_ID,
|
||||
self.cx.tcx.hir().root_module(),
|
||||
self.cx.tcx.crate_name(LOCAL_CRATE),
|
||||
None,
|
||||
|
@ -152,16 +159,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
|
||||
fn visit_mod_contents(
|
||||
&mut self,
|
||||
id: hir::HirId,
|
||||
def_id: LocalDefId,
|
||||
m: &'tcx hir::Mod<'tcx>,
|
||||
name: Symbol,
|
||||
parent_id: Option<hir::HirId>,
|
||||
parent_id: Option<LocalDefId>,
|
||||
) -> Module<'tcx> {
|
||||
let mut om = Module::new(name, id, m.spans.inner_span);
|
||||
let def_id = self.cx.tcx.hir().local_def_id(id).to_def_id();
|
||||
let mut om = Module::new(name, def_id, m.spans.inner_span);
|
||||
// Keep track of if there were any private modules in the path.
|
||||
let orig_inside_public_path = self.inside_public_path;
|
||||
self.inside_public_path &= self.cx.tcx.visibility(def_id).is_public();
|
||||
self.inside_public_path &= self.cx.tcx.local_visibility(def_id).is_public();
|
||||
for &i in m.item_ids {
|
||||
let item = self.cx.tcx.hir().item(i);
|
||||
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
|
||||
|
@ -193,7 +199,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
/// Returns `true` if the target has been inlined.
|
||||
fn maybe_inline_local(
|
||||
&mut self,
|
||||
id: hir::HirId,
|
||||
def_id: LocalDefId,
|
||||
res: Res,
|
||||
renamed: Option<Symbol>,
|
||||
glob: bool,
|
||||
|
@ -211,10 +217,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
return false;
|
||||
};
|
||||
|
||||
let use_attrs = tcx.hir().attrs(id);
|
||||
let use_attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(def_id));
|
||||
// Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
|
||||
let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline)
|
||||
|| use_attrs.lists(sym::doc).has_word(sym::hidden);
|
||||
|| tcx.is_doc_hidden(def_id.to_def_id());
|
||||
|
||||
// For cross-crate impl inlining we need to know whether items are
|
||||
// reachable in documentation -- a previously unreachable item can be
|
||||
|
@ -225,37 +231,39 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
return false;
|
||||
}
|
||||
|
||||
let res_hir_id = match res_did.as_local() {
|
||||
Some(n) => tcx.hir().local_def_id_to_hir_id(n),
|
||||
None => return false,
|
||||
let Some(res_did) = res_did.as_local() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let is_private =
|
||||
!self.cx.cache.effective_visibilities.is_directly_public(self.cx.tcx, res_did);
|
||||
let is_hidden = inherits_doc_hidden(self.cx.tcx, res_hir_id);
|
||||
let is_private = !self
|
||||
.cx
|
||||
.cache
|
||||
.effective_visibilities
|
||||
.is_directly_public(self.cx.tcx, res_did.to_def_id());
|
||||
let is_hidden = inherits_doc_hidden(self.cx.tcx, res_did);
|
||||
|
||||
// Only inline if requested or if the item would otherwise be stripped.
|
||||
if (!please_inline && !is_private && !is_hidden) || is_no_inline {
|
||||
return false;
|
||||
}
|
||||
|
||||
if !self.view_item_stack.insert(res_hir_id) {
|
||||
if !self.view_item_stack.insert(res_did) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let ret = match tcx.hir().get(res_hir_id) {
|
||||
let ret = match tcx.hir().get_by_def_id(res_did) {
|
||||
Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => {
|
||||
let prev = mem::replace(&mut self.inlining, true);
|
||||
for &i in m.item_ids {
|
||||
let i = self.cx.tcx.hir().item(i);
|
||||
self.visit_item(i, None, om, Some(id));
|
||||
self.visit_item(i, None, om, Some(def_id));
|
||||
}
|
||||
self.inlining = prev;
|
||||
true
|
||||
}
|
||||
Node::Item(it) if !glob => {
|
||||
let prev = mem::replace(&mut self.inlining, true);
|
||||
self.visit_item(it, renamed, om, Some(id));
|
||||
self.visit_item(it, renamed, om, Some(def_id));
|
||||
self.inlining = prev;
|
||||
true
|
||||
}
|
||||
|
@ -267,7 +275,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
}
|
||||
_ => false,
|
||||
};
|
||||
self.view_item_stack.remove(&res_hir_id);
|
||||
self.view_item_stack.remove(&res_did);
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -276,7 +284,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
item: &'tcx hir::Item<'_>,
|
||||
renamed: Option<Symbol>,
|
||||
om: &mut Module<'tcx>,
|
||||
parent_id: Option<hir::HirId>,
|
||||
parent_id: Option<LocalDefId>,
|
||||
) {
|
||||
debug!("visiting item {:?}", item);
|
||||
let name = renamed.unwrap_or(item.ident.name);
|
||||
|
@ -321,7 +329,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
let is_glob = kind == hir::UseKind::Glob;
|
||||
let ident = if is_glob { None } else { Some(name) };
|
||||
if self.maybe_inline_local(
|
||||
item.hir_id(),
|
||||
item.owner_id.def_id,
|
||||
res,
|
||||
ident,
|
||||
is_glob,
|
||||
|
@ -356,7 +364,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
hir::ItemKind::Mod(ref m) => {
|
||||
om.mods.push(self.visit_mod_contents(item.hir_id(), m, name, parent_id));
|
||||
om.mods.push(self.visit_mod_contents(item.owner_id.def_id, m, name, parent_id));
|
||||
}
|
||||
hir::ItemKind::Fn(..)
|
||||
| hir::ItemKind::ExternCrate(..)
|
||||
|
|
|
@ -20,7 +20,7 @@ assert-css: (
|
|||
// table like view
|
||||
assert-css: (".item-right.docblock-short", { "padding-left": "0px" })
|
||||
compare-elements-position-near: (
|
||||
"//*[@class='item-left module-item']//a[text()='replaced_function']",
|
||||
"//*[@class='item-left']//a[text()='replaced_function']",
|
||||
".item-left .stab.deprecated",
|
||||
{"y": 2},
|
||||
)
|
||||
|
@ -32,7 +32,7 @@ compare-elements-position: (
|
|||
|
||||
// Ensure no wrap
|
||||
compare-elements-position: (
|
||||
"//*[@class='item-left module-item']//a[text()='replaced_function']/..",
|
||||
"//*[@class='item-left']//a[text()='replaced_function']/..",
|
||||
"//*[@class='item-right docblock-short'][text()='a thing with a label']",
|
||||
("y"),
|
||||
)
|
||||
|
@ -43,7 +43,7 @@ size: (600, 600)
|
|||
// staggered layout with 2em spacing
|
||||
assert-css: (".item-right.docblock-short", { "padding-left": "32px" })
|
||||
compare-elements-position-near: (
|
||||
"//*[@class='item-left module-item']//a[text()='replaced_function']",
|
||||
"//*[@class='item-left']//a[text()='replaced_function']",
|
||||
".item-left .stab.deprecated",
|
||||
{"y": 2},
|
||||
)
|
||||
|
@ -55,7 +55,7 @@ compare-elements-position: (
|
|||
|
||||
// Ensure wrap
|
||||
compare-elements-position-false: (
|
||||
"//*[@class='item-left module-item']//a[text()='replaced_function']/..",
|
||||
"//*[@class='item-left']//a[text()='replaced_function']/..",
|
||||
"//*[@class='item-right docblock-short'][text()='a thing with a label']",
|
||||
("y"),
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// This test checks that the correct font is used on module items (in index.html pages).
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
assert-css: (
|
||||
".item-table .module-item a",
|
||||
".item-table .item-left > a",
|
||||
{"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
|
||||
ALL,
|
||||
)
|
||||
|
|
|
@ -4,8 +4,8 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
|||
show-text: true
|
||||
|
||||
compare-elements-property: (
|
||||
"//a[@title='test_docs::safe_fn fn']/..",
|
||||
"//a[@title='test_docs::unsafe_fn fn']/..",
|
||||
"//a[@title='fn test_docs::safe_fn']/..",
|
||||
"//a[@title='fn test_docs::unsafe_fn']/..",
|
||||
["clientHeight"]
|
||||
)
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#![no_core]
|
||||
|
||||
// @has 'foo/index.html'
|
||||
// @has - '//*[@class="item-left module-item"]/*[@class="stab portability"]' 'foobar'
|
||||
// @has - '//*[@class="item-left module-item"]/*[@class="stab portability"]' 'bar'
|
||||
// @has - '//*[@class="item-left"]/*[@class="stab portability"]' 'foobar'
|
||||
// @has - '//*[@class="item-left"]/*[@class="stab portability"]' 'bar'
|
||||
|
||||
#[doc(cfg(feature = "foobar"))]
|
||||
mod imp_priv {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// @has deprecated/index.html '//*[@class="item-left module-item"]/span[@class="stab deprecated"]' \
|
||||
// @has deprecated/index.html '//*[@class="item-left"]/span[@class="stab deprecated"]' \
|
||||
// 'Deprecated'
|
||||
// @has - '//*[@class="item-right docblock-short"]' 'Deprecated docs'
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ pub struct Portable;
|
|||
// @has doc_cfg/unix_only/index.html \
|
||||
// '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
|
||||
// 'Available on Unix only.'
|
||||
// @matches - '//*[@class="item-left module-item"]//*[@class="stab portability"]' '\AARM\Z'
|
||||
// @matches - '//*[@class="item-left"]//*[@class="stab portability"]' '\AARM\Z'
|
||||
// @count - '//*[@class="stab portability"]' 2
|
||||
#[doc(cfg(unix))]
|
||||
pub mod unix_only {
|
||||
|
@ -42,7 +42,7 @@ pub mod unix_only {
|
|||
// @has doc_cfg/wasi_only/index.html \
|
||||
// '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
|
||||
// 'Available on WASI only.'
|
||||
// @matches - '//*[@class="item-left module-item"]//*[@class="stab portability"]' '\AWebAssembly\Z'
|
||||
// @matches - '//*[@class="item-left"]//*[@class="stab portability"]' '\AWebAssembly\Z'
|
||||
// @count - '//*[@class="stab portability"]' 2
|
||||
#[doc(cfg(target_os = "wasi"))]
|
||||
pub mod wasi_only {
|
||||
|
@ -74,7 +74,7 @@ pub mod wasi_only {
|
|||
|
||||
// the portability header is different on the module view versus the full view
|
||||
// @has doc_cfg/index.html
|
||||
// @matches - '//*[@class="item-left module-item"]//*[@class="stab portability"]' '\Aavx\Z'
|
||||
// @matches - '//*[@class="item-left"]//*[@class="stab portability"]' '\Aavx\Z'
|
||||
|
||||
// @has doc_cfg/fn.uses_target_feature.html
|
||||
// @has - '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#![feature(doc_cfg)]
|
||||
|
||||
// @has 'foo/index.html'
|
||||
// @matches '-' '//*[@class="item-left module-item"]//*[@class="stab portability"]' '^sync$'
|
||||
// @has '-' '//*[@class="item-left module-item"]//*[@class="stab portability"]/@title' 'Available on crate feature `sync` only'
|
||||
// @matches '-' '//*[@class="item-left"]//*[@class="stab portability"]' '^sync$'
|
||||
// @has '-' '//*[@class="item-left"]//*[@class="stab portability"]/@title' 'Available on crate feature `sync` only'
|
||||
|
||||
// @has 'foo/struct.Foo.html'
|
||||
// @has '-' '//*[@class="stab portability"]' 'sync'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @has 'glob_shadowing/index.html'
|
||||
// @count - '//div[@class="item-left module-item"]' 6
|
||||
// @count - '//div[@class="item-left"]' 6
|
||||
// @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe'
|
||||
// @has - '//div[@class="item-right docblock-short"]' 'sub2::describe'
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
extern crate macros;
|
||||
|
||||
// @has foo/index.html '//*[@class="item-left unstable deprecated module-item"]/span[@class="stab deprecated"]' \
|
||||
// @has foo/index.html '//*[@class="item-left unstable deprecated"]/span[@class="stab deprecated"]' \
|
||||
// Deprecated
|
||||
// @has - '//*[@class="item-left unstable deprecated module-item"]/span[@class="stab unstable"]' \
|
||||
// @has - '//*[@class="item-left unstable deprecated"]/span[@class="stab unstable"]' \
|
||||
// Experimental
|
||||
|
||||
// @has foo/macro.my_macro.html
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#![doc(issue_tracker_base_url = "https://issue_url/")]
|
||||
#![unstable(feature = "test", issue = "32374")]
|
||||
|
||||
// @matches issue_32374/index.html '//*[@class="item-left unstable deprecated module-item"]/span[@class="stab deprecated"]' \
|
||||
// @matches issue_32374/index.html '//*[@class="item-left unstable deprecated"]/span[@class="stab deprecated"]' \
|
||||
// 'Deprecated'
|
||||
// @matches issue_32374/index.html '//*[@class="item-left unstable deprecated module-item"]/span[@class="stab unstable"]' \
|
||||
// @matches issue_32374/index.html '//*[@class="item-left unstable deprecated"]/span[@class="stab unstable"]' \
|
||||
// 'Experimental'
|
||||
// @matches issue_32374/index.html '//*[@class="item-right docblock-short"]/text()' 'Docs'
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ pub mod subone {
|
|||
// @has - '//section[@id="main-content"]/details/div[@class="docblock"]//a[@href="../fn.foo.html"]' 'foo'
|
||||
// @has - '//section[@id="main-content"]/details/div[@class="docblock"]//a[@href="../fn.bar.html"]' 'bar'
|
||||
// Though there should be such links later
|
||||
// @has - '//section[@id="main-content"]/div[@class="item-table"]//div[@class="item-left module-item"]/a[@class="fn"][@href="fn.foo.html"]' 'foo'
|
||||
// @has - '//section[@id="main-content"]/div[@class="item-table"]//div[@class="item-left module-item"]/a[@class="fn"][@href="fn.bar.html"]' 'bar'
|
||||
// @has - '//section[@id="main-content"]/div[@class="item-table"]//div[@class="item-left"]/a[@class="fn"][@href="fn.foo.html"]' 'foo'
|
||||
// @has - '//section[@id="main-content"]/div[@class="item-table"]//div[@class="item-left"]/a[@class="fn"][@href="fn.bar.html"]' 'bar'
|
||||
/// See either [foo] or [bar].
|
||||
pub mod subtwo {
|
||||
|
||||
|
|
|
@ -11,6 +11,6 @@ pub mod sub {
|
|||
#[doc(inline)]
|
||||
pub use sub::*;
|
||||
|
||||
// @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1
|
||||
// @count foo/index.html '//a[@class="mod"][@title="mod foo::prelude"]' 1
|
||||
// @count foo/prelude/index.html '//div[@class="item-row"]' 0
|
||||
pub mod prelude {}
|
||||
|
|
|
@ -8,7 +8,7 @@ pub mod sub {
|
|||
}
|
||||
}
|
||||
|
||||
// @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1
|
||||
// @count foo/index.html '//a[@class="mod"][@title="mod foo::prelude"]' 1
|
||||
// @count foo/prelude/index.html '//div[@class="item-row"]' 0
|
||||
pub mod prelude {}
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// @has issue_95873/index.html "//*[@class='item-left import-item']" "pub use ::std as x;"
|
||||
// @has issue_95873/index.html "//*[@class='item-left']" "pub use ::std as x;"
|
||||
pub use ::std as x;
|
||||
|
|
|
@ -9,6 +9,6 @@ extern crate issue_99221_aux;
|
|||
|
||||
pub use issue_99221_aux::*;
|
||||
|
||||
// @count foo/index.html '//a[@class="struct"][@title="foo::Print struct"]' 1
|
||||
// @count foo/index.html '//a[@class="struct"][@title="struct foo::Print"]' 1
|
||||
|
||||
pub struct Print;
|
||||
|
|
|
@ -9,7 +9,7 @@ extern crate issue_99734_aux;
|
|||
|
||||
pub use issue_99734_aux::*;
|
||||
|
||||
// @count foo/index.html '//a[@class="fn"][@title="foo::main fn"]' 1
|
||||
// @count foo/index.html '//a[@class="fn"][@title="fn foo::main"]' 1
|
||||
|
||||
extern "C" {
|
||||
pub fn main() -> std::ffi::c_int;
|
||||
|
|
|
@ -9,6 +9,6 @@ extern crate issue_99734_aux;
|
|||
|
||||
pub use issue_99734_aux::*;
|
||||
|
||||
// @count foo/index.html '//a[@class="mod"][@title="foo::task mod"]' 1
|
||||
// @count foo/index.html '//a[@class="mod"][@title="mod foo::task"]' 1
|
||||
|
||||
pub mod task {}
|
||||
|
|
|
@ -10,4 +10,4 @@
|
|||
pub fn dummy() {}
|
||||
|
||||
// ensure that `extern crate foo;` was inserted into code snips automatically:
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20r%23foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D&edition=2015"]' "Run"
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0Ause+foo::dummy;%0Adummy();%0A%7D&edition=2015"]' "Run"
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
//! }
|
||||
//! ```
|
||||
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&edition=2015"]' "Run"
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D&edition=2015"]' "Run"
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&version=nightly&edition=2015"]' "Run"
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0Aprintln!(%22Hello,+world!%22);%0A%7D&edition=2015"]' "Run"
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' "Run"
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&version=nightly&edition=2015"]' "Run"
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
extern crate reexport_check;
|
||||
|
||||
// @!has 'foo/index.html' '//code' 'pub use self::i32;'
|
||||
// @has 'foo/index.html' '//div[@class="item-left deprecated module-item"]' 'i32'
|
||||
// @has 'foo/index.html' '//div[@class="item-left deprecated"]' 'i32'
|
||||
// @has 'foo/i32/index.html'
|
||||
#[allow(deprecated, deprecated_in_future)]
|
||||
pub use std::i32;
|
||||
// @!has 'foo/index.html' '//code' 'pub use self::string::String;'
|
||||
// @has 'foo/index.html' '//div[@class="item-left module-item"]' 'String'
|
||||
// @has 'foo/index.html' '//div[@class="item-left"]' 'String'
|
||||
pub use std::string::String;
|
||||
|
||||
// @has 'foo/index.html' '//div[@class="item-right docblock-short"]' 'Docs in original'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue