diff options
| author | bors <bors@rust-lang.org> | 2021-08-19 20:31:05 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-08-19 20:31:05 +0000 |
| commit | 6d64f7f695943541fe12bb960971403f440d7225 (patch) | |
| tree | e13fba589fabe127b60c3c2756d3cd969fd2a9f7 | |
| parent | 7960030d6915a771f5ab72c3897a7ed50c3ed4bd (diff) | |
| parent | 1095bb1eb25b38a221e35588530269c6219a95a1 (diff) | |
| download | rust-6d64f7f695943541fe12bb960971403f440d7225.tar.gz rust-6d64f7f695943541fe12bb960971403f440d7225.zip | |
Auto merge of #88165 - GuillaumeGomez:rollup-4o0v2ps, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - #86123 (Preserve more spans in internal `rustc_queries!` macro) - #87874 (Add TcpStream type to TcpListener::incoming docs) - #88034 (rustc_privacy: Replace `HirId`s and `DefId`s with `LocalDefId`s where possible) - #88050 (Remove `HashStable` impls for `FileName` and `RealFileName`) - #88093 ([rustdoc] Wrap code blocks in `<code>` tag) - #88146 (Add tests for some `feature(const_evaluatable_checked)` incr comp issues) - #88153 (Update .mailmap) - #88159 (Use a trait instead of the now disallowed missing trait there) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
21 files changed, 638 insertions, 405 deletions
diff --git a/.mailmap b/.mailmap index 56ac5296774..d1f5ca9371f 100644 --- a/.mailmap +++ b/.mailmap @@ -113,6 +113,7 @@ Hanna Kruppe <hanna.kruppe@gmail.com> <robin.kruppe@gmail.com> Heather <heather@cynede.net> <Cynede@Gentoo.org> Heather <heather@cynede.net> <Heather@cynede.net> Herman J. Radtke III <herman@hermanradtke.com> Herman J. Radtke III <hermanradtke@gmail.com> +Hirochika Matsumoto <git@hkmatsumoto.com> <matsujika@gmail.com> Ian Jackson <ijackson@chiark.greenend.org.uk> <ian.jackson@citrix.com> Ian Jackson <ijackson@chiark.greenend.org.uk> <ijackson+github@slimy.greenend.org.uk> Ian Jackson <ijackson@chiark.greenend.org.uk> <iwj@xenproject.org> diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index dcd36d61bc6..7ad36973f46 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -1,6 +1,6 @@ use proc_macro::TokenStream; use proc_macro2::{Delimiter, TokenTree}; -use quote::quote; +use quote::{quote, quote_spanned}; use syn::parse::{Parse, ParseStream, Result}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; @@ -42,19 +42,19 @@ enum QueryModifier { LoadCached(Ident, Ident, Block), /// A cycle error for this query aborting the compilation with a fatal error. - FatalCycle, + FatalCycle(Ident), /// A cycle error results in a delay_bug call - CycleDelayBug, + CycleDelayBug(Ident), /// Don't hash the result, instead just mark a query red if it runs - NoHash, + NoHash(Ident), /// Generate a dep node based on the dependencies of the query - Anon, + Anon(Ident), /// Always evaluate the query, ignoring its dependencies - EvalAlways, + EvalAlways(Ident), } impl Parse for QueryModifier { @@ -111,15 +111,15 @@ impl Parse for QueryModifier { let ty = args.parse()?; Ok(QueryModifier::Storage(ty)) } else if modifier == "fatal_cycle" { - Ok(QueryModifier::FatalCycle) + Ok(QueryModifier::FatalCycle(modifier)) } else if modifier == "cycle_delay_bug" { - Ok(QueryModifier::CycleDelayBug) + Ok(QueryModifier::CycleDelayBug(modifier)) } else if modifier == "no_hash" { - Ok(QueryModifier::NoHash) + Ok(QueryModifier::NoHash(modifier)) } else if modifier == "anon" { - Ok(QueryModifier::Anon) + Ok(QueryModifier::Anon(modifier)) } else if modifier == "eval_always" { - Ok(QueryModifier::EvalAlways) + Ok(QueryModifier::EvalAlways(modifier)) } else { Err(Error::new(modifier.span(), "unknown query modifier")) } @@ -203,19 +203,19 @@ struct QueryModifiers { load_cached: Option<(Ident, Ident, Block)>, /// A cycle error for this query aborting the compilation with a fatal error. - fatal_cycle: bool, + fatal_cycle: Option<Ident>, /// A cycle error results in a delay_bug call - cycle_delay_bug: bool, + cycle_delay_bug: Option<Ident>, /// Don't hash the result, instead just mark a query red if it runs - no_hash: bool, + no_hash: Option<Ident>, /// Generate a dep node based on the dependencies of the query - anon: bool, + anon: Option<Ident>, // Always evaluate the query, ignoring its dependencies - eval_always: bool, + eval_always: Option<Ident>, } /// Process query modifiers into a struct, erroring on duplicates @@ -224,11 +224,11 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut storage = None; let mut cache = None; let mut desc = None; - let mut fatal_cycle = false; - let mut cycle_delay_bug = false; - let mut no_hash = false; - let mut anon = false; - let mut eval_always = false; + let mut fatal_cycle = None; + let mut cycle_delay_bug = None; + let mut no_hash = None; + let mut anon = None; + let mut eval_always = None; for modifier in query.modifiers.0.drain(..) { match modifier { QueryModifier::LoadCached(tcx, id, block) => { @@ -289,35 +289,35 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } desc = Some((tcx, list)); } - QueryModifier::FatalCycle => { - if fatal_cycle { + QueryModifier::FatalCycle(ident) => { + if fatal_cycle.is_some() { panic!("duplicate modifier `fatal_cycle` for query `{}`", query.name); } - fatal_cycle = true; + fatal_cycle = Some(ident); } - QueryModifier::CycleDelayBug => { - if cycle_delay_bug { + QueryModifier::CycleDelayBug(ident) => { + if cycle_delay_bug.is_some() { panic!("duplicate modifier `cycle_delay_bug` for query `{}`", query.name); } - cycle_delay_bug = true; + cycle_delay_bug = Some(ident); } - QueryModifier::NoHash => { - if no_hash { + QueryModifier::NoHash(ident) => { + if no_hash.is_some() { panic!("duplicate modifier `no_hash` for query `{}`", query.name); } - no_hash = true; + no_hash = Some(ident); } - QueryModifier::Anon => { - if anon { + QueryModifier::Anon(ident) => { + if anon.is_some() { panic!("duplicate modifier `anon` for query `{}`", query.name); } - anon = true; + anon = Some(ident); } - QueryModifier::EvalAlways => { - if eval_always { + QueryModifier::EvalAlways(ident) => { + if eval_always.is_some() { panic!("duplicate modifier `eval_always` for query `{}`", query.name); } - eval_always = true; + eval_always = Some(ident); } } } @@ -454,31 +454,39 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { let mut attributes = Vec::new(); // Pass on the fatal_cycle modifier - if modifiers.fatal_cycle { - attributes.push(quote! { fatal_cycle }); + if let Some(fatal_cycle) = &modifiers.fatal_cycle { + attributes.push(quote! { #fatal_cycle }); }; // Pass on the storage modifier if let Some(ref ty) = modifiers.storage { - attributes.push(quote! { storage(#ty) }); + let span = ty.span(); + attributes.push(quote_spanned! {span=> storage(#ty) }); }; // Pass on the cycle_delay_bug modifier - if modifiers.cycle_delay_bug { - attributes.push(quote! { cycle_delay_bug }); + if let Some(cycle_delay_bug) = &modifiers.cycle_delay_bug { + attributes.push(quote! { #cycle_delay_bug }); }; // Pass on the no_hash modifier - if modifiers.no_hash { - attributes.push(quote! { no_hash }); + if let Some(no_hash) = &modifiers.no_hash { + attributes.push(quote! { #no_hash }); }; // Pass on the anon modifier - if modifiers.anon { - attributes.push(quote! { anon }); + if let Some(anon) = &modifiers.anon { + attributes.push(quote! { #anon }); }; // Pass on the eval_always modifier - if modifiers.eval_always { - attributes.push(quote! { eval_always }); + if let Some(eval_always) = &modifiers.eval_always { + attributes.push(quote! { #eval_always }); }; - let attribute_stream = quote! {#(#attributes),*}; + // This uses the span of the query definition for the commas, + // which can be important if we later encounter any ambiguity + // errors with any of the numerous macro_rules! macros that + // we use. Using the call-site span would result in a span pointing + // at the entire `rustc_queries!` invocation, which wouldn't + // be very useful. + let span = name.span(); + let attribute_stream = quote_spanned! {span=> #(#attributes),*}; let doc_comments = query.doc_comments.iter(); // Add the query to the group query_stream.extend(quote! { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3df8ade2169..a683cb05e16 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -11,7 +11,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet}; +use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::intravisit::{self, DeepVisitor, NestedVisitorMap, Visitor}; use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind}; use rustc_middle::bug; @@ -354,9 +355,8 @@ trait VisibilityLike: Sized { // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to // associated types for which we can't determine visibility precisely. - fn of_impl(hir_id: hir::HirId, tcx: TyCtxt<'_>, access_levels: &AccessLevels) -> Self { + fn of_impl(def_id: LocalDefId, tcx: TyCtxt<'_>, access_levels: &AccessLevels) -> Self { let mut find = FindMin { tcx, access_levels, min: Self::MAX }; - let def_id = tcx.hir().local_def_id(hir_id); find.visit(tcx.type_of(def_id)); if let Some(trait_ref) = tcx.impl_trait_ref(def_id) { find.visit_trait(trait_ref); @@ -424,7 +424,7 @@ struct EmbargoVisitor<'tcx> { struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> { access_level: Option<AccessLevel>, - item_def_id: DefId, + item_def_id: LocalDefId, ev: &'a mut EmbargoVisitor<'tcx>, } @@ -448,12 +448,12 @@ impl EmbargoVisitor<'tcx> { fn reach( &mut self, - item_id: hir::HirId, + def_id: LocalDefId, access_level: Option<AccessLevel>, ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { ReachEverythingInTheInterfaceVisitor { access_level: cmp::min(access_level, Some(AccessLevel::Reachable)), - item_def_id: self.tcx.hir().local_def_id(item_id).to_def_id(), + item_def_id: def_id, ev: self, } } @@ -536,10 +536,10 @@ impl EmbargoVisitor<'tcx> { | hir::ItemKind::Union(ref struct_def, _) = item.kind { for field in struct_def.fields() { - let field_vis = - self.tcx.visibility(self.tcx.hir().local_def_id(field.hir_id)); + let def_id = self.tcx.hir().local_def_id(field.hir_id); + let field_vis = self.tcx.visibility(def_id); if field_vis.is_accessible_from(module.to_def_id(), self.tcx) { - self.reach(field.hir_id, level).ty(); + self.reach(def_id, level).ty(); } } } else { @@ -638,7 +638,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { let inherited_item_level = match item.kind { hir::ItemKind::Impl { .. } => { - Option::<AccessLevel>::of_impl(item.hir_id(), self.tcx, &self.access_levels) + Option::<AccessLevel>::of_impl(item.def_id, self.tcx, &self.access_levels) } // Foreign modules inherit level from parents. hir::ItemKind::ForeignMod { .. } => self.prev_level, @@ -750,7 +750,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { // reachable if they are returned via `impl Trait`, even from private functions. let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait)); - self.reach(item.hir_id(), exist_level).generics().predicates().ty(); + self.reach(item.def_id, exist_level).generics().predicates().ty(); } } // Visit everything. @@ -759,15 +759,15 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { | hir::ItemKind::Fn(..) | hir::ItemKind::TyAlias(..) => { if item_level.is_some() { - self.reach(item.hir_id(), item_level).generics().predicates().ty(); + self.reach(item.def_id, item_level).generics().predicates().ty(); } } hir::ItemKind::Trait(.., trait_item_refs) => { if item_level.is_some() { - self.reach(item.hir_id(), item_level).generics().predicates(); + self.reach(item.def_id, item_level).generics().predicates(); for trait_item_ref in trait_item_refs { - let mut reach = self.reach(trait_item_ref.id.hir_id(), item_level); + let mut reach = self.reach(trait_item_ref.id.def_id, item_level); reach.generics().predicates(); if trait_item_ref.kind == AssocItemKind::Type @@ -782,18 +782,18 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } hir::ItemKind::TraitAlias(..) => { if item_level.is_some() { - self.reach(item.hir_id(), item_level).generics().predicates(); + self.reach(item.def_id, item_level).generics().predicates(); } } // Visit everything except for private impl items. hir::ItemKind::Impl(ref impl_) => { if item_level.is_some() { - self.reach(item.hir_id(), item_level).generics().predicates().ty().trait_ref(); + self.reach(item.def_id, item_level).generics().predicates().ty().trait_ref(); for impl_item_ref in impl_.items { let impl_item_level = self.get(impl_item_ref.id.def_id); if impl_item_level.is_some() { - self.reach(impl_item_ref.id.hir_id(), impl_item_level) + self.reach(impl_item_ref.id.def_id, impl_item_level) .generics() .predicates() .ty(); @@ -805,13 +805,14 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { // Visit everything, but enum variants have their own levels. hir::ItemKind::Enum(ref def, _) => { if item_level.is_some() { - self.reach(item.hir_id(), item_level).generics().predicates(); + self.reach(item.def_id, item_level).generics().predicates(); } for variant in def.variants { let variant_level = self.get(self.tcx.hir().local_def_id(variant.id)); if variant_level.is_some() { for field in variant.data.fields() { - self.reach(field.hir_id, variant_level).ty(); + self.reach(self.tcx.hir().local_def_id(field.hir_id), variant_level) + .ty(); } // Corner case: if the variant is reachable, but its // enum is not, make the enum reachable as well. @@ -824,7 +825,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { for foreign_item in items { let foreign_item_level = self.get(foreign_item.id.def_id); if foreign_item_level.is_some() { - self.reach(foreign_item.id.hir_id(), foreign_item_level) + self.reach(foreign_item.id.def_id, foreign_item_level) .generics() .predicates() .ty(); @@ -834,11 +835,12 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { // Visit everything except for private fields. hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { if item_level.is_some() { - self.reach(item.hir_id(), item_level).generics().predicates(); + self.reach(item.def_id, item_level).generics().predicates(); for field in struct_def.fields() { - let field_level = self.get(self.tcx.hir().local_def_id(field.hir_id)); + let def_id = self.tcx.hir().local_def_id(field.hir_id); + let field_level = self.get(def_id); if field_level.is_some() { - self.reach(field.hir_id, field_level).ty(); + self.reach(def_id, field_level).ty(); } } } @@ -992,7 +994,7 @@ impl DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { struct NamePrivacyVisitor<'tcx> { tcx: TyCtxt<'tcx>, maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>, - current_item: Option<hir::HirId>, + current_item: LocalDefId, } impl<'tcx> NamePrivacyVisitor<'tcx> { @@ -1014,11 +1016,15 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { field: &'tcx ty::FieldDef, in_update_syntax: bool, ) { + if def.is_enum() { + return; + } + // definition of the field let ident = Ident::new(kw::Empty, use_ctxt); - let current_hir = self.current_item.unwrap(); - let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, current_hir).1; - if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) { + let hir_id = self.tcx.hir().local_def_id_to_hir_id(self.current_item); + let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, hir_id).1; + if !field.vis.is_accessible_from(def_id, self.tcx) { let label = if in_update_syntax { format!("field `{}` is private", field.ident) } else { @@ -1063,7 +1069,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { } fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - let orig_current_item = self.current_item.replace(item.hir_id()); + let orig_current_item = mem::replace(&mut self.current_item, item.def_id); intravisit::walk_item(self, item); self.current_item = orig_current_item; } @@ -1763,9 +1769,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { struct SearchInterfaceForPrivateItemsVisitor<'tcx> { tcx: TyCtxt<'tcx>, - item_id: hir::HirId, - item_def_id: DefId, - span: Span, + item_def_id: LocalDefId, /// The visitor checks that each component type is at least this visible. required_visibility: ty::Visibility, has_pub_restricted: bool, @@ -1820,8 +1824,8 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> { if self.leaks_private_dep(def_id) { self.tcx.struct_span_lint_hir( lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES, - self.item_id, - self.span, + self.tcx.hir().local_def_id_to_hir_id(self.item_def_id), + self.tcx.def_span(self.item_def_id.to_def_id()), |lint| { lint.build(&format!( "{} `{}` from private dependency '{}' in public \ @@ -1856,15 +1860,16 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> { } }; let make_msg = || format!("{} {} `{}` in public interface", vis_descr, kind, descr); + let span = self.tcx.def_span(self.item_def_id.to_def_id()); if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty { let mut err = if kind == "trait" { - struct_span_err!(self.tcx.sess, self.span, E0445, "{}", make_msg()) + struct_span_err!(self.tcx.sess, span, E0445, "{}", make_msg()) } else { - struct_span_err!(self.tcx.sess, self.span, E0446, "{}", make_msg()) + struct_span_err!(self.tcx.sess, span, E0446, "{}", make_msg()) }; let vis_span = self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id)); - err.span_label(self.span, format!("can't leak {} {}", vis_descr, kind)); + err.span_label(span, format!("can't leak {} {}", vis_descr, kind)); err.span_label(vis_span, format!("`{}` declared as {}", descr, vis_descr)); err.emit(); } else { @@ -1872,7 +1877,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> { self.tcx.struct_span_lint_hir( lint::builtin::PRIVATE_IN_PUBLIC, hir_id, - self.span, + span, |lint| lint.build(&format!("{} (error {})", make_msg(), err_code)).emit(), ); } @@ -1915,35 +1920,33 @@ impl DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> { struct PrivateItemsInPublicInterfacesVisitor<'tcx> { tcx: TyCtxt<'tcx>, has_pub_restricted: bool, - old_error_set_ancestry: HirIdSet, + old_error_set_ancestry: LocalDefIdSet, } impl<'tcx> PrivateItemsInPublicInterfacesVisitor<'tcx> { fn check( &self, - item_id: hir::HirId, + def_id: LocalDefId, required_visibility: ty::Visibility, ) -> SearchInterfaceForPrivateItemsVisitor<'tcx> { SearchInterfaceForPrivateItemsVisitor { tcx: self.tcx, - item_id, - item_def_id: self.tcx.hir().local_def_id(item_id).to_def_id(), - span: self.tcx.hir().span(item_id), + item_def_id: def_id, required_visibility, has_pub_restricted: self.has_pub_restricted, - has_old_errors: self.old_error_set_ancestry.contains(&item_id), + has_old_errors: self.old_error_set_ancestry.contains(&def_id), in_assoc_ty: false, } } fn check_assoc_item( &self, - hir_id: hir::HirId, + def_id: LocalDefId, assoc_item_kind: AssocItemKind, defaultness: hir::Defaultness, vis: ty::Visibility, ) { - let mut check = self.check(hir_id, vis); + let mut check = self.check(def_id, vis); let (check_ty, is_assoc_ty) = match assoc_item_kind { AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false), @@ -1982,38 +1985,38 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> { | hir::ItemKind::Static(..) | hir::ItemKind::Fn(..) | hir::ItemKind::TyAlias(..) => { - self.check(item.hir_id(), item_visibility).generics().predicates().ty(); + self.check(item.def_id, item_visibility).generics().predicates().ty(); } hir::ItemKind::OpaqueTy(..) => { // `ty()` for opaque types is the underlying type, // it's not a part of interface, so we skip it. - self.check(item.hir_id(), item_visibility).generics().bounds(); + self.check(item.def_id, item_visibility).generics().bounds(); } hir::ItemKind::Trait(.., trait_item_refs) => { - self.check(item.hir_id(), item_visibility).generics().predicates(); + self.check(item.def_id, item_visibility).generics().predicates(); for trait_item_ref in trait_item_refs { self.check_assoc_item( - trait_item_ref.id.hir_id(), + trait_item_ref.id.def_id, trait_item_ref.kind, trait_item_ref.defaultness, item_visibility, ); if let AssocItemKind::Type = trait_item_ref.kind { - self.check(trait_item_ref.id.hir_id(), item_visibility).bounds(); + self.check(trait_item_ref.id.def_id, item_visibility).bounds(); } } } hir::ItemKind::TraitAlias(..) => { - self.check(item.hir_id(), item_visibility).generics().predicates(); + self.check(item.def_id, item_visibility).generics().predicates(); } hir::ItemKind::Enum(ref def, _) => { - self.check(item.hir_id(), item_visibility).generics().predicates(); + self.check(item.def_id, item_visibility).generics().predicates(); for variant in def.variants { for field in variant.data.fields() { - self.check(field.hir_id, item_visibility).ty(); + self.check(self.tcx.hir().local_def_id(field.hir_id), item_visibility).ty(); } } } @@ -2021,16 +2024,17 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> { hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { let vis = tcx.visibility(foreign_item.id.def_id); - self.check(foreign_item.id.hir_id(), vis).generics().predicates().ty(); + self.check(foreign_item.id.def_id, vis).generics().predicates().ty(); } } // Subitems of structs and unions have their own publicity. hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { - self.check(item.hir_id(), item_visibility).generics().predicates(); + self.check(item.def_id, item_visibility).generics().predicates(); for field in struct_def.fields() { - let field_visibility = tcx.visibility(tcx.hir().local_def_id(field.hir_id)); - self.check(field.hir_id, min(item_visibility, field_visibility, tcx)).ty(); + let def_id = tcx.hir().local_def_id(field.hir_id); + let field_visibility = tcx.visibility(def_id); + self.check(def_id, min(item_visibility, field_visibility, tcx)).ty(); } } // An inherent impl is public when its type is public @@ -2038,8 +2042,8 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> { // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity. hir::ItemKind::Impl(ref impl_) => { - let impl_vis = ty::Visibility::of_impl(item.hir_id(), tcx, &Default::default()); - self.check(item.hir_id(), impl_vis).generics().predicates(); + let impl_vis = ty::Visibility::of_impl(item.def_id, tcx, &Default::default()); + self.check(item.def_id, impl_vis).generics().predicates(); for impl_item_ref in impl_.items { let impl_item_vis = if impl_.of_trait.is_none() { min(tcx.visibility(impl_item_ref.id.def_id), impl_vis, tcx) @@ -2047,7 +2051,7 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> { impl_vis }; self.check_assoc_item( - impl_item_ref.id.hir_id(), + impl_item_ref.id.def_id, impl_item_ref.kind, impl_item_ref.defaultness, impl_item_vis, @@ -2119,7 +2123,8 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility { fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { // Check privacy of names not checked in previous compilation stages. - let mut visitor = NamePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: None }; + let mut visitor = + NamePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: module_def_id }; let (module, span, hir_id) = tcx.hir().get_module(module_def_id); intravisit::walk_mod(&mut visitor, module, hir_id); @@ -2188,7 +2193,15 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) { } // Check for private types and traits in public interfaces. - let mut visitor = - PrivateItemsInPublicInterfacesVisitor { tcx, has_pub_restricted, old_error_set_ancestry }; + let mut visitor = PrivateItemsInPublicInterfacesVisitor { + tcx, + has_pub_restricted, + // Only definition IDs are ever searched in `old_error_set_ancestry`, + // so we can filter away all non-definition IDs at this point. + old_error_set_ancestry: old_error_set_ancestry + .into_iter() + .filter_map(|hir_id| tcx.hir().opt_local_def_id(hir_id)) + .collect(), + }; krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor)); } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 1c95cc91208..9e127577b61 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -157,7 +157,7 @@ scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals); // FIXME: We should use this enum or something like it to get rid of the // use of magic `/rust/1.x/...` paths across the board. #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd)] -#[derive(HashStable_Generic, Decodable)] +#[derive(Decodable)] pub enum RealFileName { LocalPath(PathBuf), /// For remapped paths (namely paths into libstd that have been mapped @@ -269,7 +269,7 @@ impl RealFileName { /// Differentiates between real files and common virtual files. #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)] -#[derive(HashStable_Generic, Decodable, Encodable)] +#[derive(Decodable, Encodable)] pub enum FileName { Real(RealFileName), /// Call to `quote!`. diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 325acf0b979..c8eb4811f7e 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -767,17 +767,24 @@ impl TcpListener { /// # Examples /// /// ```no_run - /// use std::net::TcpListener; + /// use std::net::{TcpListener, TcpStream}; /// - /// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); + /// fn handle_connection(stream: TcpStream) { + /// //... + /// } /// - /// for stream in listener.incoming() { - /// match stream { - /// Ok(stream) => { - /// println!("new client!"); + /// fn main() -> std::io::Result<()> { + /// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); + /// + /// for stream in listener.incoming() { + /// match stream { + /// Ok(stream) => { + /// handle_connection(stream); + /// } + /// Err(e) => { /* connection failed */ } /// } - /// Err(e) => { /* connection failed */ } /// } + /// Ok(()) /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 3cdb1352bef..f8fc9243e14 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -65,10 +65,11 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf out.push_buffer(extra); } if let Some(class) = class { - writeln!(out, "<pre class=\"rust {}\">", class); + write!(out, "<pre class=\"rust {}\">", class); } else { - writeln!(out, "<pre class=\"rust\">"); + write!(out, "<pre class=\"rust\">"); } + write!(out, "<code>"); } /// Convert the given `src` source code into HTML by adding classes for highlighting. @@ -101,7 +102,7 @@ fn write_code( } fn write_footer(out: &mut Buffer, playground_button: Option<&str>) { - writeln!(out, "</pre>{}</div>", playground_button.unwrap_or_default()); + writeln!(out, "</code></pre>{}</div>", playground_button.unwrap_or_default()); } /// How a span of text is classified. Mostly corresponds to token kinds. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 472323daf30..7c6d7dff816 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -234,7 +234,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { return Some(Event::Html( format!( "<div class=\"example-wrap\">\ - <pre class=\"language-{}\">{}</pre>\ + <pre class=\"language-{}\"><code>{}</code></pre>\ </div>", lang, Escape(&text), diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index a3b01a59f27..96cc67ce97c 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -454,24 +454,25 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: + name.as_str().len() + generics_len; - w.write_str("<pre class=\"rust fn\">"); - render_attributes_in_pre(w, it, ""); - w.reserve(header_len); - write!( - w, - "{vis}{constness}{asyncness}{unsafety}{abi}fn \ - {name}{generics}{decl}{notable_traits}{where_clause}</pre>", - vis = vis, - constness = constness, - asyncness = asyncness, - unsafety = unsafety, - abi = abi, - name = name, - generics = f.generics.print(cx), - where_clause = print_where_clause(&f.generics, cx, 0, true), - decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx), - notable_traits = notable_traits_decl(&f.decl, cx), - ); + wrap_item(w, "fn", |w| { + render_attributes_in_pre(w, it, ""); + w.reserve(header_len); + write!( + w, + "{vis}{constness}{asyncness}{unsafety}{abi}fn \ + {name}{generics}{decl}{notable_traits}{where_clause}", + vis = vis, + constness = constness, + asyncness = asyncness, + unsafety = unsafety, + abi = abi, + name = name, + generics = f.generics.print(cx), + where_clause = print_where_clause(&f.generics, cx, 0, true), + decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx), + notable_traits = notable_traits_decl(&f.decl, cx), + ); + }); document(w, cx, it, None) } @@ -487,108 +488,111 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra // Output the trait definition wrap_into_docblock(w, |w| { - w.write_str("<pre class=\"rust trait\">"); - render_attributes_in_pre(w, it, ""); - write!( - w, - "{}{}{}trait {}{}{}", - it.visibility.print_with_space(it.def_id, cx), - t.unsafety.print_with_space(), - if t.is_auto { "auto " } else { "" }, - it.name.as_ref().unwrap(), - t.generics.print(cx), - bounds - ); - - if !t.generics.where_predicates.is_empty() { - write!(w, "{}", print_where_clause(&t.generics, cx, 0, true)); - } else { - w.write_str(" "); - } + wrap_item(w, "trait", |w| { + render_attributes_in_pre(w, it, ""); + write!( + w, + "{}{}{}trait {}{}{}", + it.visibility.print_with_space(it.def_id, cx), + t.unsafety.print_with_space(), + if t.is_auto { "auto " } else { "" }, + it.name.as_ref().unwrap(), + t.generics.print(cx), + bounds + ); - if t.items.is_empty() { - w.write_str("{ }"); - } else { - // FIXME: we should be using a derived_id for the Anchors here - w.write_str("{\n"); - let mut toggle = false; - - // If there are too many associated types, hide _everything_ - if should_hide_fields(count_types) { - toggle = true; - toggle_open( - w, - format_args!("{} associated items", count_types + count_consts + count_methods), - ); - } - for t in &types { - render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); - w.write_str(";\n"); - } - // If there are too many associated constants, hide everything after them - // We also do this if the types + consts is large because otherwise we could - // render a bunch of types and _then_ a bunch of consts just because both were - // _just_ under the limit - if !toggle && should_hide_fields(count_types + count_consts) { - toggle = true; - toggle_open( - w, - format_args!( - "{} associated constant{} and {} method{}", - count_consts, - pluralize(count_consts), - count_methods, - pluralize(count_methods), - ), - ); - } - if !types.is_empty() && !consts.is_empty() { - w.write_str("\n"); - } - for t in &consts { - render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); - w.write_str(";\n"); - } - if !toggle && should_hide_fields(count_methods) { - toggle = true; - toggle_open(w, format_args!("{} methods", count_methods)); - } - if !consts.is_empty() && !required.is_empty() { - w.write_str("\n"); + if !t.generics.where_predicates.is_empty() { + write!(w, "{}", print_where_clause(&t.generics, cx, 0, true)); + } else { + w.write_str(" "); } - for (pos, m) in required.iter().enumerate() { - render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); - w.write_str(";\n"); - if pos < required.len() - 1 { - w.write_str("<div class=\"item-spacer\"></div>"); + if t.items.is_empty() { + w.write_str("{ }"); + } else { + // FIXME: we should be using a derived_id for the Anchors here + w.write_str("{\n"); + let mut toggle = false; + + // If there are too many associated types, hide _everything_ + if should_hide_fields(count_types) { + toggle = true; + toggle_open( + w, + format_args!( + "{} associated items", + count_types + count_consts + count_methods + ), + ); } - } - if !required.is_empty() && !provided.is_empty() { - w.write_str("\n"); - } - for (pos, m) in provided.iter().enumerate() { - render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); - match *m.kind { - clean::MethodItem(ref inner, _) - if !inner.generics.where_predicates.is_empty() => - { - w.write_str(",\n { ... }\n"); + for t in &types { + render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); + w.write_str(";\n"); + } + // If there are too many associated constants, hide everything after them + // We also do this if the types + consts is large because otherwise we could + // render a bunch of types and _then_ a bunch of consts just because both were + // _just_ under the limit + if !toggle && should_hide_fields(count_types + count_consts) { + toggle = true; + toggle_open( + w, + format_args!( + "{} associated constant{} and {} method{}", + count_consts, + pluralize(count_consts), + count_methods, + pluralize(count_methods), + ), + ); + } + if !types.is_empty() && !consts.is_empty() { + w.write_str("\n"); + } + for t in &consts { + render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); + w.write_str(";\n"); + } + if !toggle && should_hide_fields(count_methods) { + toggle = true; + toggle_open(w, format_args!("{} methods", count_methods)); + } + if !consts.is_empty() && !required.is_empty() { + w.write_str("\n"); + } + for (pos, m) in required.iter().enumerate() { + render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); + w.write_str(";\n"); + + if pos < required.len() - 1 { + w.write_str("<div class=\"item-spacer\"></div>"); } - _ => { - w.write_str(" { ... }\n"); + } + if !required.is_empty() && !provided.is_empty() { + w.write_str("\n"); + } + for (pos, m) in provided.iter().enumerate() { + render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); + match *m.kind { + clean::MethodItem(ref inner, _) + if !inner.generics.where_predicates.is_empty() => + { + w.write_str(",\n { ... }\n"); + } + _ => { + w.write_str(" { ... }\n"); + } + } + if pos < provided.len() - 1 { + w.write_str("<div class=\"item-spacer\"></div>"); } } - if pos < provided.len() - 1 { - w.write_str("<div class=\"item-spacer\"></div>"); + if toggle { + toggle_close(w); } + w.write_str("}"); } - if toggle { - toggle_close(w); - } - w.write_str("}"); - } - w.write_str("</pre>") + }); }); // Trait documentation @@ -811,16 +815,17 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) { - w.write_str("<pre class=\"rust trait-alias\">"); - render_attributes_in_pre(w, it, ""); - write!( - w, - "trait {}{}{} = {};</pre>", - it.name.as_ref().unwrap(), - t.generics.print(cx), - print_where_clause(&t.generics, cx, 0, true), - bounds(&t.bounds, true, cx) - ); + wrap_item(w, "trait-alias", |w| { + render_attributes_in_pre(w, it, ""); + write!( + w, + "trait {}{}{} = {};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + print_where_clause(&t.generics, cx, 0, true), + bounds(&t.bounds, true, cx) + ); + }); document(w, cx, it, None); @@ -832,16 +837,17 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea } fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) { - w.write_str("<pre class=\"rust opaque\">"); - render_attributes_in_pre(w, it, ""); - write!( - w, - "type {}{}{where_clause} = impl {bounds};</pre>", - it.name.as_ref().unwrap(), - t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, true), - bounds = bounds(&t.bounds, false, cx), - ); + wrap_item(w, "opaque", |w| { + render_attributes_in_pre(w, it, ""); + write!( + w, + "type {}{}{where_clause} = impl {bounds};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + where_clause = print_where_clause(&t.generics, cx, 0, true), + bounds = bounds(&t.bounds, false, cx), + ); + }); document(w, cx, it, None); @@ -859,19 +865,20 @@ fn item_typedef( t: &clean::Typedef, is_associated: bool, ) { - w.write_str("<pre class=\"rust typedef\">"); - render_attributes_in_pre(w, it, ""); - if !is_associated { - write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); - } - write!( - w, - "type {}{}{where_clause} = {type_};</pre>", - it.name.as_ref().unwrap(), - t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, true), - type_ = t.type_.print(cx), - ); + wrap_item(w, "typedef", |w| { + render_attributes_in_pre(w, it, ""); + if !is_associated { + write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); + } + write!( + w, + "type {}{}{where_clause} = {type_};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + where_clause = print_where_clause(&t.generics, cx, 0, true), + type_ = t.type_.print(cx), + ); + }); document(w, cx, it, None); @@ -885,10 +892,10 @@ fn item_typedef( fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { wrap_into_docblock(w, |w| { - w.write_str("<pre class=\"rust union\">"); - render_attributes_in_pre(w, it, ""); - render_union(w, it, Some(&s.generics), &s.fields, "", cx); - w.write_str("</pre>") + wrap_item(w, "union", |w| { + render_attributes_in_pre(w, it, ""); + render_union(w, it, Some(&s.generics), &s.fields, "", cx); + }); }); document(w, cx, it, None); @@ -934,59 +941,68 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { wrap_into_docblock(w, |w| { - w.write_str("<pre class=\"rust enum\">"); - render_attributes_in_pre(w, it, ""); - write!( - w, - "{}enum {}{}{}", - it.visibility.print_with_space(it.def_id, cx), - it.name.as_ref().unwrap(), - e.generics.print(cx), - print_where_clause(&e.generics, cx, 0, true), - ); - if e.variants.is_empty() && !e.variants_stripped { - w.write_str(" {}"); - } else { - w.write_str(" {\n"); - let count_variants = e.variants.len(); - let toggle = should_hide_fields(count_variants); - if toggle { - toggle_open(w, format_args!("{} variants", count_variants)); - } - for v in &e.variants { - w.write_str(" "); - let name = v.name.as_ref().unwrap(); - match *v.kind { - clean::VariantItem(ref var) => match var { - clean::Variant::CLike => write!(w, "{}", name), - clean::Variant::Tuple(ref tys) => { - write!(w, "{}(", name); - for (i, ty) in tys.iter().enumerate() { - if i > 0 { - w.write_str(", ") + wrap_item(w, "enum", |w| { + render_attributes_in_pre(w, it, ""); + write!( + w, + "{}enum {}{}{}", + it.visibility.print_with_space(it.def_id, cx), + it.name.as_ref().unwrap(), + e.generics.print(cx), + print_where_clause(&e.generics, cx, 0, true), + ); + if e.variants.is_empty() && !e.variants_stripped { + w.write_str(" {}"); + } else { + w.write_str(" {\n"); + let count_variants = e.variants.len(); + let toggle = should_hide_fields(count_variants); + if toggle { + toggle_open(w, format_args!("{} variants", count_variants)); + } + for v in &e.variants { + w.write_str(" "); + let name = v.name.as_ref().unwrap(); + match *v.kind { + clean::VariantItem(ref var) => match var { + clean::Variant::CLike => write!(w, "{}", name), + clean::Variant::Tuple(ref tys) => { + write!(w, "{}(", name); + for (i, ty) in tys.iter().enumerate() { + if i > 0 { + w.write_str(", ") + } + write!(w, "{}", ty.print(cx)); } - write!(w, "{}", ty.print(cx)); + w.write_str(")"); } - w.write_str(")"); - } - clean::Variant::Struct(ref s) => { - render_struct(w, v, None, s.struct_type, &s.fields, " ", false, cx); - } - }, - _ => unreachable!(), + clean::Variant::Struct(ref s) => { + render_struct( + w, + v, + None, + s.struct_type, + &s.fields, + " ", + false, + cx, + ); + } + }, + _ => unreachable!(), + } + w.write_str(",\n"); } - w.write_str(",\n"); - } - if e.variants_stripped { - w.write_str(" // some variants omitted\n"); - } - if toggle { - toggle_close(w); + if e.variants_stripped { + w.write_str(" // some variants omitted\n"); + } + if toggle { + toggle_close(w); + } + w.write_str("}"); } - w.write_str("}"); - } - w.write_str("</pre>") + }); }); document(w, cx, it, None); @@ -1090,27 +1106,27 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean let name = it.name.as_ref().expect("proc-macros always have names"); match m.kind { MacroKind::Bang => { - w.push_str("<pre class=\"rust macro\">"); - write!(w, "{}!() {{ /* proc-macro */ }}", name); - w.push_str("</pre>"); + wrap_item(w, "macro", |w| { + write!(w, "{}!() {{ /* proc-macro */ }}", name); + }); } MacroKind::Attr => { - w.push_str("<pre class=\"rust attr\">"); - write!(w, "#[{}]", name); - w.push_str("</pre>"); + wrap_item(w, "attr", |w| { + write!(w, "#[{}]", name); + }); } MacroKind::Derive => { - w.push_str("<pre class=\"rust derive\">"); - write!(w, "#[derive({})]", name); - if !m.helpers.is_empty() { - w.push_str("\n{\n"); - w.push_str(" // Attributes available to this derive:\n"); - for attr in &m.helpers { - writeln!(w, " #[{}]", attr); + wrap_item(w, "derive", |w| { + write!(w, "#[derive({})]", name); + if !m.helpers.is_empty() { + w.push_str("\n{\n"); + w.push_str(" // Attributes available to this derive:\n"); + for attr in &m.helpers { + writeln!(w, " #[{}]", attr); + } + w.push_str("}\n"); } - w.push_str("}\n"); - } - w.push_str("</pre>"); + }); } } document(w, cx, it, None) @@ -1122,49 +1138,49 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { } fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) { - w.write_str("<pre class=\"rust const\">"); - render_attributes_in_code(w, it); + wrap_item(w, "const", |w| { + render_attributes_in_code(w, it); - write!( - w, - "{vis}const {name}: {typ}", - vis = it.visibility.print_with_space(it.def_id, cx), - name = it.name.as_ref().unwrap(), - typ = c.type_.print(cx), - ); + write!( + w, + "{vis}const {name}: {typ}", + vis = it.visibility.print_with_space(it.def_id, cx), + name = it.name.as_ref().unwrap(), + typ = c.type_.print(cx), + ); - let value = c.value(cx.tcx()); - let is_literal = c.is_literal(cx.tcx()); - let expr = c.expr(cx.tcx()); - if value.is_some() || is_literal { - write!(w, " = {expr};", expr = Escape(&expr)); - } else { - w.write_str(";"); - } + let value = c.value(cx.tcx()); + let is_literal = c.is_literal(cx.tcx()); + let expr = c.expr(cx.tcx()); + if value.is_some() || is_literal { + write!(w, " = {expr};", expr = Escape(&expr)); + } else { + w.write_str(";"); + } - if !is_literal { - if let Some(value) = &value { - let value_lowercase = value.to_lowercase(); - let expr_lowercase = expr.to_lowercase(); + if !is_literal { + if let Some(value) = &value { + let value_lowercase = value.to_lowercase(); + let expr_lowercase = expr.to_lowercase(); - if value_lowercase != expr_lowercase - && value_lowercase.trim_end_matches("i32") != expr_lowercase - { - write!(w, " // {value}", value = Escape(value)); + if value_lowercase != expr_lowercase + && value_lowercase.trim_end_matches("i32") != expr_lowercase + { + write!(w, " // {value}", value = Escape(value)); + } } } - } + }); - w.write_str("</pre>"); document(w, cx, it, None) } fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) { wrap_into_docblock(w, |w| { - w.write_str("<pre class=\"rust struct\">"); - render_attributes_in_code(w, it); - render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx); - w.write_str("</pre>") + wrap_item(w, "struct", |w| { + render_attributes_in_code(w, it); + render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx); + }); }); document(w, cx, it, None); @@ -1213,28 +1229,31 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St } fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) { - w.write_str("<pre class=\"rust static\">"); - render_attributes_in_code(w, it); - write!( - w, - "{vis}static {mutability}{name}: {typ}</pre>", - vis = it.visibility.print_with_space(it.def_id, cx), - mutability = s.mutability.print_with_space(), - name = it.name.as_ref().unwrap(), - typ = s.type_.print(cx) - ); + wrap_item(w, "static", |w| { + render_attributes_in_code(w, it); + write!( + w, + "{vis}static {mutability}{name}: {typ}", + vis = it.visibility.print_with_space(it.def_id, cx), + mutability = s.mutability.print_with_space(), + name = it.name.as_ref().unwrap(), + typ = s.type_.print(cx) + ); + }); document(w, cx, it, None) } fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { - w.write_str("<pre class=\"rust foreigntype\">extern {\n"); - render_attributes_in_code(w, it); - write!( - w, - " {}type {};\n}}</pre>", - it.visibility.print_with_space(it.def_id, cx), - it.name.as_ref().unwrap(), - ); + wrap_item(w, "foreigntype", |w| { + w.write_str("extern {\n"); + render_attributes_in_code(w, it); + write!( + w, + " {}type {};\n}}", + it.visibility.print_with_space(it.def_id, cx), + it.name.as_ref().unwrap(), + ); + }); document(w, cx, it, None); @@ -1321,6 +1340,15 @@ where w.write_str("</div>") } +fn wrap_item<F>(w: &mut Buffer, item_name: &str, f: F) +where + F: FnOnce(&mut Buffer), +{ + w.write_fmt(format_args!("<pre class=\"rust {}\"><code>", item_name)); + f(w); + w.write_str("</code></pre>"); +} + fn render_stability_since( w: &mut Buffer, item: &clean::Item, diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 0714de9d565..23ca6eeaf3b 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -249,7 +249,6 @@ code, pre, a.test-arrow, .code-header { } .docblock pre code, .docblock-short pre code { padding: 0; - padding-right: 1ex; } pre { padding: 14px; diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-1.rs b/src/test/incremental/const-generics/hash-tyvid-regression-1.rs new file mode 100644 index 00000000000..f98ae59ddfe --- /dev/null +++ b/src/test/incremental/const-generics/hash-tyvid-regression-1.rs @@ -0,0 +1,15 @@ +// revisions: cfail +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +// regression test for #77650 +fn c<T, const N: std::num::NonZeroUsize>() +where + [T; N.get()]: Sized, +{ + use std::convert::TryFrom; + <[T; N.get()]>::try_from(()) + //~^ error: the trait bound + //~^^ error: mismatched types +} + +fn main() {} diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-1.stderr b/src/test/incremental/const-generics/hash-tyvid-regression-1.stderr new file mode 100644 index 00000000000..cb8ca3abd7f --- /dev/null +++ b/src/test/incremental/const-generics/hash-tyvid-regression-1.stderr @@ -0,0 +1,35 @@ +error[E0277]: the trait bound `[T; _]: From<()>` is not satisfied + --> $DIR/hash-tyvid-regression-1.rs:9:5 + | +LL | <[T; N.get()]>::try_from(()) + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `[T; _]` + | + = note: required because of the requirements on the impl of `Into<[T; _]>` for `()` + = note: required because of the requirements on the impl of `TryFrom<()>` for `[T; _]` +note: required by `try_from` + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL + | +LL | fn try_from(value: T) -> Result<Self, Self::Error>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/hash-tyvid-regression-1.rs:9:5 + | +LL | <[T; N.get()]>::try_from(()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found enum `Result` + | + = note: expected unit type `()` + found enum `Result<[T; _], Infallible>` +help: consider using a semicolon here + | +LL | <[T; N.get()]>::try_from(()); + | + +help: try adding a return type + | +LL | -> Result<[T; _], Infallible> where + | +++++++++++++++++++++++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-2.rs b/src/test/incremental/const-generics/hash-tyvid-regression-2.rs new file mode 100644 index 00000000000..22536ff56d7 --- /dev/null +++ b/src/test/incremental/const-generics/hash-tyvid-regression-2.rs @@ -0,0 +1,18 @@ +// revisions: cfail +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +// regression test for #77650 +struct C<T, const N: core::num::NonZeroUsize>([T; N.get()]) +where + [T; N.get()]: Sized; +impl<'a, const N: core::num::NonZeroUsize, A, B: PartialEq<A>> PartialEq<&'a [A]> for C<B, N> +where + [B; N.get()]: Sized, +{ + fn eq(&self, other: &&'a [A]) -> bool { + self.0 == other + //~^ error: can't compare + } +} + +fn main() {} diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-2.stderr b/src/test/incremental/const-generics/hash-tyvid-regression-2.stderr new file mode 100644 index 00000000000..0e6040ef02e --- /dev/null +++ b/src/test/incremental/const-generics/hash-tyvid-regression-2.stderr @@ -0,0 +1,11 @@ +error[E0277]: can't compare `[B; _]` with `&&[A]` + --> $DIR/hash-tyvid-regression-2.rs:12:16 + | +LL | self.0 == other + | ^^ no implementation for `[B; _] == &&[A]` + | + = help: the trait `PartialEq<&&[A]>` is not implemented for `[B; _]` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-3.rs b/src/test/incremental/const-generics/hash-tyvid-regression-3.rs new file mode 100644 index 00000000000..76b1ae11c7d --- /dev/null +++ b/src/test/incremental/const-generics/hash-tyvid-regression-3.rs @@ -0,0 +1,26 @@ +// revisions: cfail +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +// regression test for #79251 +struct Node<const D: usize> +where + SmallVec<{ D * 2 }>: , +{ + keys: SmallVec<{ D * 2 }>, +} + +impl<const D: usize> Node<D> +where + SmallVec<{ D * 2 }>: , +{ + fn new() -> Self { + let mut node = Node::new(); + node.keys.some_function(); + //~^ error: no method named + node + } +} + +struct SmallVec<const D: usize> {} + +fn main() {} diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-3.stderr b/src/test/incremental/const-generics/hash-tyvid-regression-3.stderr new file mode 100644 index 00000000000..555d46756dc --- /dev/null +++ b/src/test/incremental/const-generics/hash-tyvid-regression-3.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `some_function` found for struct `SmallVec` in the current scope + --> $DIR/hash-tyvid-regression-3.rs:17:19 + | +LL | node.keys.some_function(); + | ^^^^^^^^^^^^^ method not found in `SmallVec<{ D * 2 }>` +... +LL | struct SmallVec<const D: usize> {} + | ------------------------------- method `some_function` not found for this + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-4.rs b/src/test/incremental/const-generics/hash-tyvid-regression-4.rs new file mode 100644 index 00000000000..35a675a2ab4 --- /dev/null +++ b/src/test/incremental/const-generics/hash-tyvid-regression-4.rs @@ -0,0 +1,40 @@ +// revisions: cfail +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +// regression test for #79251 +#[derive(Debug)] +struct Node<K, const D: usize> +where + SmallVec<K, { D * 2 }>: , +{ + keys: SmallVec<K, { D * 2 }>, +} + +impl<K, const D: usize> Node<K, D> +where + SmallVec<K, { D * 2 }>: , +{ + fn new() -> Self { + panic!() + } + + #[inline(never)] + fn split(&mut self, i: usize, k: K, right: bool) -> Node<K, D> { + let mut node = Node::new(); + node.keys.push(k); + //~^ error: no method named + node + } +} + +#[derive(Debug)] +struct SmallVec<T, const D: usize> { + data: [T; D], +} +impl<T, const D: usize> SmallVec<T, D> { + fn new() -> Self { + panic!() + } +} + +fn main() {} diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-4.stderr b/src/test/incremental/const-generics/hash-tyvid-regression-4.stderr new file mode 100644 index 00000000000..c9a6715e571 --- /dev/null +++ b/src/test/incremental/const-generics/hash-tyvid-regression-4.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `push` found for struct `SmallVec` in the current scope + --> $DIR/hash-tyvid-regression-4.rs:23:19 + | +LL | node.keys.push(k); + | ^^^^ method not found in `SmallVec<_, { D * 2 }>` +... +LL | struct SmallVec<T, const D: usize> { + | ---------------------------------- method `push` not found for this + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml new file mode 100644 index 00000000000..200569a28d4 --- /dev/null +++ b/src/test/rustdoc-gui/code-tags.goml @@ -0,0 +1,20 @@ +// This test ensures that items and documentation code blocks are wrapped in <pre><code> +goto: file://|DOC_PATH|/test_docs/fn.foo.html +size: (1080, 600) +// There should be three doc codeblocks +// Check that their content is inside <pre><code> +assert-count: (".example-wrap pre > code", 3) +// Check that function signature is inside <pre><code> +assert: "pre.rust.fn > code" + +goto: file://|DOC_PATH|/test_docs/struct.Foo.html +assert: "pre.rust.struct > code" + +goto: file://|DOC_PATH|/test_docs/enum.AnEnum.html +assert: "pre.rust.enum > code" + +goto: file://|DOC_PATH|/test_docs/trait.AnotherOne.html +assert: "pre.rust.trait > code" + +goto: file://|DOC_PATH|/test_docs/type.SomeType.html +assert: "pre.rust.typedef > code" diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index d7bae93c211..5a49807e180 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -12,4 +12,4 @@ assert-attribute: (".line-numbers > span:nth-child(5)", {"class": "line-highligh assert-attribute: (".line-numbers > span:nth-child(6)", {"class": "line-highlighted"}) assert-attribute-false: (".line-numbers > span:nth-child(7)", {"class": "line-highlighted"}) // This is to ensure that the content is correctly align with the line numbers. -compare-elements-position: ("//*[@id='1']", ".rust > span", ("y")) +compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y")) diff --git a/src/test/ui/type-alias-impl-trait/unused_generic_param.rs b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs index 04a5c58cd36..ad5e4918cca 100644 --- a/src/test/ui/type-alias-impl-trait/unused_generic_param.rs +++ b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs @@ -1,16 +1,17 @@ +// check-pass + #![feature(type_alias_impl_trait)] +#![allow(dead_code)] fn main() {} -type PartiallyDefined<T> = impl 'static; -//~^ ERROR: at least one trait must be specified +type PartiallyDefined<T> = impl Sized; fn partially_defined<T: std::fmt::Debug>(_: T) -> PartiallyDefined<T> { 4u32 } -type PartiallyDefined2<T> = impl 'static; -//~^ ERROR: at least one trait must be specified +type PartiallyDefined2<T> = impl Sized; fn partially_defined2<T: std::fmt::Debug>(_: T) -> PartiallyDefined2<T> { 4u32 diff --git a/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr b/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr deleted file mode 100644 index 4e11854b071..00000000000 --- a/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: at least one trait must be specified - --> $DIR/unused_generic_param.rs:5:28 - | -LL | type PartiallyDefined<T> = impl 'static; - | ^^^^^^^^^^^^ - -error: at least one trait must be specified - --> $DIR/unused_generic_param.rs:12:29 - | -LL | type PartiallyDefined2<T> = impl 'static; - | ^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - |
