diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 29eba278750b1..d57eaf92d0fc6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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 { +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 = 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() { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 706c97975f760..db95b8bca2f8c 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -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()))); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f90da95d51668..1d23634b6aacf 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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 { 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> + 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>, + ) -> Result { + 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( diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 14367eb09bc75..818721062d7f7 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -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(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(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(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(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(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(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(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( dst: *mut T, @@ -3115,7 +3121,8 @@ unsafe fn atomic_compare_exchange( } #[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( dst: *mut T, @@ -3150,7 +3157,8 @@ unsafe fn atomic_compare_exchange_weak( } #[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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(dst: *mut T, val: T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_umin` diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index 1a2c125566139..bf3c81fcc980b 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -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")); diff --git a/library/stdarch b/library/stdarch index 790411f93c4b5..a0c30f3e3c75a 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit 790411f93c4b5eada3c23abb4c9a063fb0b24d99 +Subproject commit a0c30f3e3c75adcd6ee7efc94014ebcead61c507 diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 34a7068e5da53..3cb6ad10e72b8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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, ) { 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, - import_id: Option, + import_id: Option, ) -> Vec { 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 { 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::>(); - 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, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index a020ccd53b842..3b258c4d919f8 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -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, - 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, @@ -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) } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index c1a652c75f4a1..37a1005cba1fc 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -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( &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); }); } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 4ff67fe1551dd..d7739b8534f30 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -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>> 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>> 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( } 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), + ); + } } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index f824c9e3ad2bd..508b2bab0eb64 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -391,7 +391,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: }; write!( w, - "
\ + "
\ {vis}{imp}\
\ {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, - "
\ + "
\ {name}\ {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::>() diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index bf83ff2044e69..8699508e43916 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -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; } diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 02b2278960869..0b22f943dab99 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -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: diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 6aa2dda980cf3..f3961d5017ef4 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -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) } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 075951312a639..e42921c080945 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -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) { diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 7158355ffdacc..03be5e7997167 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -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; \ diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index de3a4b3390595..a4bc486900b3e 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -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; } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 00ea6ca4152c8..a89d6fa83983d 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -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>, - pub(crate) id: hir::HirId, + pub(crate) def_id: LocalDefId, // (item, renamed, import_id) - pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option, Option)>, + pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option, Option)>, pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option)>, } 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 { 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, + parent_id: Option, ) -> 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, 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, om: &mut Module<'tcx>, - parent_id: Option, + parent_id: Option, ) { 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(..) diff --git a/tests/rustdoc-gui/label-next-to-symbol.goml b/tests/rustdoc-gui/label-next-to-symbol.goml index 05f8ddc716e87..3f4f65890b422 100644 --- a/tests/rustdoc-gui/label-next-to-symbol.goml +++ b/tests/rustdoc-gui/label-next-to-symbol.goml @@ -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"), ) diff --git a/tests/rustdoc-gui/module-items-font.goml b/tests/rustdoc-gui/module-items-font.goml index cd3676a987138..5940962a8ddba 100644 --- a/tests/rustdoc-gui/module-items-font.goml +++ b/tests/rustdoc-gui/module-items-font.goml @@ -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, ) diff --git a/tests/rustdoc-gui/unsafe-fn.goml b/tests/rustdoc-gui/unsafe-fn.goml index d3a672ddde6e4..3ecb25c82a44e 100644 --- a/tests/rustdoc-gui/unsafe-fn.goml +++ b/tests/rustdoc-gui/unsafe-fn.goml @@ -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"] ) diff --git a/tests/rustdoc/cfg_doc_reexport.rs b/tests/rustdoc/cfg_doc_reexport.rs index addb6709db1da..89c7f0a6f342c 100644 --- a/tests/rustdoc/cfg_doc_reexport.rs +++ b/tests/rustdoc/cfg_doc_reexport.rs @@ -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 { diff --git a/tests/rustdoc/deprecated.rs b/tests/rustdoc/deprecated.rs index b3178da98eeb2..5cbe4d59108a4 100644 --- a/tests/rustdoc/deprecated.rs +++ b/tests/rustdoc/deprecated.rs @@ -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' diff --git a/tests/rustdoc/doc-cfg.rs b/tests/rustdoc/doc-cfg.rs index 4cddb0b76d410..1cfbfec6fcd30 100644 --- a/tests/rustdoc/doc-cfg.rs +++ b/tests/rustdoc/doc-cfg.rs @@ -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"]' \ diff --git a/tests/rustdoc/duplicate-cfg.rs b/tests/rustdoc/duplicate-cfg.rs index 18f3900b263b0..1ac2e52324964 100644 --- a/tests/rustdoc/duplicate-cfg.rs +++ b/tests/rustdoc/duplicate-cfg.rs @@ -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' diff --git a/tests/rustdoc/glob-shadowing.rs b/tests/rustdoc/glob-shadowing.rs index 66a31c42bcfc7..2668b33349790 100644 --- a/tests/rustdoc/glob-shadowing.rs +++ b/tests/rustdoc/glob-shadowing.rs @@ -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' diff --git a/tests/rustdoc/inline_cross/macros.rs b/tests/rustdoc/inline_cross/macros.rs index 5daa0d4baad63..d5b0de5725bce 100644 --- a/tests/rustdoc/inline_cross/macros.rs +++ b/tests/rustdoc/inline_cross/macros.rs @@ -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 diff --git a/tests/rustdoc/issue-32374.rs b/tests/rustdoc/issue-32374.rs index 8d2c27cf3d77d..8296d7a81f2b1 100644 --- a/tests/rustdoc/issue-32374.rs +++ b/tests/rustdoc/issue-32374.rs @@ -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' diff --git a/tests/rustdoc/issue-55364.rs b/tests/rustdoc/issue-55364.rs index 14a6f5041f208..b987da30ed290 100644 --- a/tests/rustdoc/issue-55364.rs +++ b/tests/rustdoc/issue-55364.rs @@ -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 { diff --git a/tests/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline-last-item.rs b/tests/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline-last-item.rs index d3a7a870b580a..9bce25846d858 100644 --- a/tests/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline-last-item.rs +++ b/tests/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline-last-item.rs @@ -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 {} diff --git a/tests/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline.rs b/tests/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline.rs index b836925099364..d0960dfef4362 100644 --- a/tests/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline.rs +++ b/tests/rustdoc/issue-83375-multiple-mods-w-same-name-doc-inline.rs @@ -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 {} diff --git a/tests/rustdoc/issue-95873.rs b/tests/rustdoc/issue-95873.rs index ff33fb63a0bab..3df93eb7cf16f 100644 --- a/tests/rustdoc/issue-95873.rs +++ b/tests/rustdoc/issue-95873.rs @@ -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; diff --git a/tests/rustdoc/issue-99221-multiple-structs-w-same-name.rs b/tests/rustdoc/issue-99221-multiple-structs-w-same-name.rs index 41e64726a3246..ba29a77ebdff8 100644 --- a/tests/rustdoc/issue-99221-multiple-structs-w-same-name.rs +++ b/tests/rustdoc/issue-99221-multiple-structs-w-same-name.rs @@ -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; diff --git a/tests/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs b/tests/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs index 3208fea05b376..b56ec6e11eafc 100644 --- a/tests/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs +++ b/tests/rustdoc/issue-99734-multiple-foreigns-w-same-name.rs @@ -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; diff --git a/tests/rustdoc/issue-99734-multiple-mods-w-same-name.rs b/tests/rustdoc/issue-99734-multiple-mods-w-same-name.rs index b2f9b8b46578b..8f5d6fa3d56d3 100644 --- a/tests/rustdoc/issue-99734-multiple-mods-w-same-name.rs +++ b/tests/rustdoc/issue-99734-multiple-mods-w-same-name.rs @@ -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 {} diff --git a/tests/rustdoc/playground-arg.rs b/tests/rustdoc/playground-arg.rs index 69c8962653931..f3811fe0b0ad1 100644 --- a/tests/rustdoc/playground-arg.rs +++ b/tests/rustdoc/playground-arg.rs @@ -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" diff --git a/tests/rustdoc/playground.rs b/tests/rustdoc/playground.rs index 877ea1cfba15a..5c7fa33efc5e5 100644 --- a/tests/rustdoc/playground.rs +++ b/tests/rustdoc/playground.rs @@ -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" diff --git a/tests/rustdoc/reexport-check.rs b/tests/rustdoc/reexport-check.rs index db1f90c699978..acac0c9919716 100644 --- a/tests/rustdoc/reexport-check.rs +++ b/tests/rustdoc/reexport-check.rs @@ -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'