From 230d5b1e5f0a7e2e75be11c2324f23445df83850 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Jan 2021 21:30:49 +0100 Subject: [PATCH 01/26] Stabilize std::panic::panic_any. --- library/std/src/panic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index d18b94b6c1aef..bb08fa35d17a3 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -31,7 +31,7 @@ pub use core::panic::{Location, PanicInfo}; /// accessed later using [`PanicInfo::payload`]. /// /// See the [`panic!`] macro for more information about panicking. -#[unstable(feature = "panic_any", issue = "78500")] +#[stable(feature = "panic_any", since = "1.51.0")] #[inline] pub fn panic_any(msg: M) -> ! { crate::panicking::begin_panic(msg); From 8cac04e8b862ba144c51dd4e1e9cb47caec4632b Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Jan 2021 21:41:41 +0100 Subject: [PATCH 02/26] Make 'static bound on panic_any explicit. This was already implied because Any: 'static, but this makes it explicit. --- library/std/src/panic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index bb08fa35d17a3..0f568da459bef 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -33,7 +33,7 @@ pub use core::panic::{Location, PanicInfo}; /// See the [`panic!`] macro for more information about panicking. #[stable(feature = "panic_any", since = "1.51.0")] #[inline] -pub fn panic_any(msg: M) -> ! { +pub fn panic_any(msg: M) -> ! { crate::panicking::begin_panic(msg); } From 6b66749e171e8a9c6718c0107f4ec2e3f47b28ed Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 20 Jan 2021 01:33:38 +0000 Subject: [PATCH 03/26] Use slice::split_first instead of manuall slicing --- library/std/src/net/ip.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index d33b772633d29..5c62ce43afb37 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -1610,9 +1610,9 @@ impl fmt::Display for Ipv6Addr { /// Write a colon-separated part of the address #[inline] fn fmt_subslice(f: &mut fmt::Formatter<'_>, chunk: &[u16]) -> fmt::Result { - if let Some(first) = chunk.first() { + if let Some((first, tail)) = chunk.split_first() { fmt::LowerHex::fmt(first, f)?; - for segment in &chunk[1..] { + for segment in tail { f.write_char(':')?; fmt::LowerHex::fmt(segment, f)?; } From 116b66ad491b3f0a5a809e49a6377d2697d0ed1b Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 20 Jan 2021 03:06:49 +0000 Subject: [PATCH 04/26] Dont prefix 0x when `dbg!(ipv6)` --- library/std/src/net/ip.rs | 4 ++-- library/std/src/net/ip/tests.rs | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 5c62ce43afb37..84449e4876718 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -1611,10 +1611,10 @@ impl fmt::Display for Ipv6Addr { #[inline] fn fmt_subslice(f: &mut fmt::Formatter<'_>, chunk: &[u16]) -> fmt::Result { if let Some((first, tail)) = chunk.split_first() { - fmt::LowerHex::fmt(first, f)?; + write!(f, "{:x}", first)?; for segment in tail { f.write_char(':')?; - fmt::LowerHex::fmt(segment, f)?; + write!(f, "{:x}", segment)?; } } Ok(()) diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs index 44fb3adf07023..ef0d4edc43473 100644 --- a/library/std/src/net/ip/tests.rs +++ b/library/std/src/net/ip/tests.rs @@ -166,6 +166,9 @@ fn ipv6_addr_to_string() { // two runs of zeros, equal length assert_eq!("1::4:5:0:0:8", Ipv6Addr::new(1, 0, 0, 4, 5, 0, 0, 8).to_string()); + + // don't prefix `0x` to each segment in `dbg!`. + assert_eq!("1::4:5:0:0:8", &format!("{:#?}", Ipv6Addr::new(1, 0, 0, 4, 5, 0, 0, 8))); } #[test] From 76511a7a71660b564040bfadb466251fbfa0167b Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Wed, 20 Jan 2021 15:58:03 -0500 Subject: [PATCH 05/26] Make 'docs' optional --- src/librustdoc/json/conversions.rs | 2 +- src/librustdoc/json/types.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 7d05cb016b67c..d8f1f51579624 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -27,7 +27,7 @@ impl JsonRenderer<'_> { name: name.map(|sym| sym.to_string()), source: self.convert_span(source), visibility: self.convert_visibility(visibility), - docs: attrs.collapsed_doc_value().unwrap_or_default(), + docs: attrs.collapsed_doc_value(), links: attrs .links .into_iter() diff --git a/src/librustdoc/json/types.rs b/src/librustdoc/json/types.rs index 9335fe9be1a4b..2f6db0231ab49 100644 --- a/src/librustdoc/json/types.rs +++ b/src/librustdoc/json/types.rs @@ -69,7 +69,7 @@ pub struct Item { /// so this field is needed to differentiate. pub visibility: Visibility, /// The full markdown docstring of this item. - pub docs: String, + pub docs: Option, /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs pub links: FxHashMap, /// Stringified versions of the attributes on this item (e.g. `"#[inline]"`) From 450c5eae1d1cdb6a8d853ca43c848e02a9010d9b Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Wed, 20 Jan 2021 16:46:34 -0500 Subject: [PATCH 06/26] Move StructType to clean, remove it from Unions, make JSON output whether something is a union --- src/librustdoc/clean/inline.rs | 10 ++++------ src/librustdoc/clean/mod.rs | 16 ++++++++++++---- src/librustdoc/clean/types.rs | 16 ++++++++++++---- src/librustdoc/doctree.rs | 20 -------------------- src/librustdoc/html/render/mod.rs | 13 ++++++------- src/librustdoc/json/conversions.rs | 11 +++++------ src/librustdoc/json/types.rs | 1 + 7 files changed, 40 insertions(+), 47 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 916684baf855d..f2439af005325 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -15,9 +15,8 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind}; +use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind, StructType}; use crate::core::DocContext; -use crate::doctree; use super::Clean; @@ -247,9 +246,9 @@ fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct { clean::Struct { struct_type: match variant.ctor_kind { - CtorKind::Fictive => doctree::Plain, - CtorKind::Fn => doctree::Tuple, - CtorKind::Const => doctree::Unit, + CtorKind::Fictive => StructType::Plain, + CtorKind::Fn => StructType::Tuple, + CtorKind::Const => StructType::Unit, }, generics: (cx.tcx.generics_of(did), predicates).clean(cx), fields: variant.fields.clean(cx), @@ -262,7 +261,6 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union { let variant = cx.tcx.adt_def(did).non_enum_variant(); clean::Union { - struct_type: doctree::Plain, generics: (cx.tcx.generics_of(did), predicates).clean(cx), fields: variant.fields.clean(cx), fields_stripped: false, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3ddb2adbf0aa7..4092ff5557533 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1824,10 +1824,19 @@ impl Clean for ty::Visibility { } } +crate fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType { + use StructType::*; + match *vdata { + hir::VariantData::Struct(..) => Plain, + hir::VariantData::Tuple(..) => Tuple, + hir::VariantData::Unit(..) => Unit, + } +} + impl Clean for rustc_hir::VariantData<'_> { fn clean(&self, cx: &DocContext<'_>) -> VariantStruct { VariantStruct { - struct_type: doctree::struct_type_from_def(self), + struct_type: struct_type_from_def(self), fields: self.fields().iter().map(|x| x.clean(cx)).collect(), fields_stripped: false, } @@ -1842,7 +1851,7 @@ impl Clean for ty::VariantDef { self.fields.iter().map(|f| cx.tcx.type_of(f.did).clean(cx)).collect(), ), CtorKind::Fictive => Variant::Struct(VariantStruct { - struct_type: doctree::Plain, + struct_type: StructType::Plain, fields_stripped: false, fields: self .fields @@ -1996,13 +2005,12 @@ impl Clean> for (&hir::Item<'_>, Option) { bounds: bounds.clean(cx), }), ItemKind::Union(ref variant_data, ref generics) => UnionItem(Union { - struct_type: doctree::struct_type_from_def(&variant_data), generics: generics.clean(cx), fields: variant_data.fields().clean(cx), fields_stripped: false, }), ItemKind::Struct(ref variant_data, ref generics) => StructItem(Struct { - struct_type: doctree::struct_type_from_def(&variant_data), + struct_type: struct_type_from_def(&variant_data), generics: generics.clean(cx), fields: variant_data.fields().clean(cx), fields_stripped: false, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 666b11b5f806d..2e272aacd6b9c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -37,7 +37,6 @@ use crate::clean::inline; use crate::clean::types::Type::{QPath, ResolvedPath}; use crate::clean::Clean; use crate::core::DocContext; -use crate::doctree; use crate::formats::cache::cache; use crate::formats::item_type::ItemType; use crate::html::render::cache::ExternalLocation; @@ -1683,9 +1682,19 @@ impl Visibility { } } +#[derive(Debug, Clone, Copy)] +crate enum StructType { + /// A braced struct + Plain, + /// A tuple struct + Tuple, + /// A unit struct + Unit, +} + #[derive(Clone, Debug)] crate struct Struct { - crate struct_type: doctree::StructType, + crate struct_type: StructType, crate generics: Generics, crate fields: Vec, crate fields_stripped: bool, @@ -1693,7 +1702,6 @@ crate struct Struct { #[derive(Clone, Debug)] crate struct Union { - crate struct_type: doctree::StructType, crate generics: Generics, crate fields: Vec, crate fields_stripped: bool, @@ -1704,7 +1712,7 @@ crate struct Union { /// only as a variant in an enum. #[derive(Clone, Debug)] crate struct VariantStruct { - crate struct_type: doctree::StructType, + crate struct_type: StructType, crate fields: Vec, crate fields_stripped: bool, } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index f90623c03118b..645b2bb193ec2 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -1,7 +1,5 @@ //! This module is used to store stuff from Rust's AST in a more convenient //! manner (and with prettier names) before cleaning. -crate use self::StructType::*; - use rustc_span::{self, Span, Symbol}; use rustc_hir as hir; @@ -34,21 +32,3 @@ impl Module<'hir> { } } } - -#[derive(Debug, Clone, Copy)] -crate enum StructType { - /// A braced struct - Plain, - /// A tuple struct - Tuple, - /// A unit struct - Unit, -} - -crate fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType { - match *vdata { - hir::VariantData::Struct(..) => Plain, - hir::VariantData::Tuple(..) => Tuple, - hir::VariantData::Unit(..) => Unit, - } -} diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 03e091297e5b6..29ded0b854ed1 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -68,7 +68,6 @@ use serde::{Serialize, Serializer}; use crate::clean::{self, AttributesExt, GetDefId, RenderedLink, SelfTy, TypeKind}; use crate::config::{RenderInfo, RenderOptions}; use crate::docfs::{DocFS, PathError}; -use crate::doctree; use crate::error::Error; use crate::formats::cache::{cache, Cache}; use crate::formats::item_type::ItemType; @@ -3101,7 +3100,7 @@ fn item_struct( _ => None, }) .peekable(); - if let doctree::Plain = s.struct_type { + if let clean::StructType::Plain = s.struct_type { if fields.peek().is_some() { write!( w, @@ -3351,7 +3350,7 @@ fn render_struct( w: &mut Buffer, it: &clean::Item, g: Option<&clean::Generics>, - ty: doctree::StructType, + ty: clean::StructType, fields: &[clean::Item], tab: &str, structhead: bool, @@ -3368,7 +3367,7 @@ fn render_struct( write!(w, "{}", g.print()) } match ty { - doctree::Plain => { + clean::StructType::Plain => { if let Some(g) = g { write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: true }) } @@ -3400,7 +3399,7 @@ fn render_struct( } write!(w, "}}"); } - doctree::Tuple => { + clean::StructType::Tuple => { write!(w, "("); for (i, field) in fields.iter().enumerate() { if i > 0 { @@ -3425,7 +3424,7 @@ fn render_struct( } write!(w, ";"); } - doctree::Unit => { + clean::StructType::Unit => { // Needed for PhantomData. if let Some(g) = g { write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: false }) @@ -4460,7 +4459,7 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea let fields = get_struct_fields_name(&s.fields); if !fields.is_empty() { - if let doctree::Plain = s.struct_type { + if let clean::StructType::Plain = s.struct_type { sidebar.push_str(&format!( "Fields\
{}
", diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 7d05cb016b67c..b872f94908775 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -9,7 +9,6 @@ use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_span::Pos; use crate::clean; -use crate::doctree; use crate::formats::item_type::ItemType; use crate::json::types::*; use crate::json::JsonRenderer; @@ -210,9 +209,9 @@ impl From for Struct { impl From for Struct { fn from(struct_: clean::Union) -> Self { - let clean::Union { struct_type, generics, fields, fields_stripped } = struct_; + let clean::Union { generics, fields, fields_stripped } = struct_; Struct { - struct_type: struct_type.into(), + struct_type: StructType::Union, generics: generics.into(), fields_stripped, fields: ids(fields), @@ -221,9 +220,9 @@ impl From for Struct { } } -impl From for StructType { - fn from(struct_type: doctree::StructType) -> Self { - use doctree::StructType::*; +impl From for StructType { + fn from(struct_type: clean::StructType) -> Self { + use clean::StructType::*; match struct_type { Plain => StructType::Plain, Tuple => StructType::Tuple, diff --git a/src/librustdoc/json/types.rs b/src/librustdoc/json/types.rs index 9335fe9be1a4b..268cbcc1aece0 100644 --- a/src/librustdoc/json/types.rs +++ b/src/librustdoc/json/types.rs @@ -269,6 +269,7 @@ pub enum StructType { Plain, Tuple, Unit, + Union, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] From 3349b40d471bea1e1b154213b19fbeb5a965943c Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Wed, 20 Jan 2021 17:19:46 -0500 Subject: [PATCH 07/26] Remove StructType entirely and replace it with CtorKind --- src/librustdoc/clean/inline.rs | 10 +++------- src/librustdoc/clean/mod.rs | 15 +++------------ src/librustdoc/clean/types.rs | 16 +++------------- src/librustdoc/html/render/mod.rs | 13 +++++++------ src/librustdoc/json/conversions.rs | 12 ++++++------ 5 files changed, 22 insertions(+), 44 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index f2439af005325..1f9e7f8ae5cd4 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -5,7 +5,7 @@ use std::iter::once; use rustc_ast as ast; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_hir::def::{CtorKind, DefKind, Res}; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_hir::Mutability; use rustc_metadata::creader::LoadedMacro; @@ -15,7 +15,7 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind, StructType}; +use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind}; use crate::core::DocContext; use super::Clean; @@ -245,11 +245,7 @@ fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct { let variant = cx.tcx.adt_def(did).non_enum_variant(); clean::Struct { - struct_type: match variant.ctor_kind { - CtorKind::Fictive => StructType::Plain, - CtorKind::Fn => StructType::Tuple, - CtorKind::Const => StructType::Unit, - }, + struct_type: variant.ctor_kind, generics: (cx.tcx.generics_of(did), predicates).clean(cx), fields: variant.fields.clean(cx), fields_stripped: false, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4092ff5557533..8fa60fa7178ae 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1824,19 +1824,10 @@ impl Clean for ty::Visibility { } } -crate fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType { - use StructType::*; - match *vdata { - hir::VariantData::Struct(..) => Plain, - hir::VariantData::Tuple(..) => Tuple, - hir::VariantData::Unit(..) => Unit, - } -} - impl Clean for rustc_hir::VariantData<'_> { fn clean(&self, cx: &DocContext<'_>) -> VariantStruct { VariantStruct { - struct_type: struct_type_from_def(self), + struct_type: CtorKind::from_hir(self), fields: self.fields().iter().map(|x| x.clean(cx)).collect(), fields_stripped: false, } @@ -1851,7 +1842,7 @@ impl Clean for ty::VariantDef { self.fields.iter().map(|f| cx.tcx.type_of(f.did).clean(cx)).collect(), ), CtorKind::Fictive => Variant::Struct(VariantStruct { - struct_type: StructType::Plain, + struct_type: CtorKind::Fictive, fields_stripped: false, fields: self .fields @@ -2010,7 +2001,7 @@ impl Clean> for (&hir::Item<'_>, Option) { fields_stripped: false, }), ItemKind::Struct(ref variant_data, ref generics) => StructItem(Struct { - struct_type: struct_type_from_def(&variant_data), + struct_type: CtorKind::from_hir(variant_data), generics: generics.clean(cx), fields: variant_data.fields().clean(cx), fields_stripped: false, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 2e272aacd6b9c..c767b9dd85bf9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -16,7 +16,7 @@ use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_feature::UnstableFeatures; use rustc_hir as hir; -use rustc_hir::def::Res; +use rustc_hir::def::{CtorKind, Res}; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::Mutability; @@ -1682,19 +1682,9 @@ impl Visibility { } } -#[derive(Debug, Clone, Copy)] -crate enum StructType { - /// A braced struct - Plain, - /// A tuple struct - Tuple, - /// A unit struct - Unit, -} - #[derive(Clone, Debug)] crate struct Struct { - crate struct_type: StructType, + crate struct_type: CtorKind, crate generics: Generics, crate fields: Vec, crate fields_stripped: bool, @@ -1712,7 +1702,7 @@ crate struct Union { /// only as a variant in an enum. #[derive(Clone, Debug)] crate struct VariantStruct { - crate struct_type: StructType, + crate struct_type: CtorKind, crate fields: Vec, crate fields_stripped: bool, } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 29ded0b854ed1..70ea38892d32f 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -52,6 +52,7 @@ use rustc_attr::{Deprecation, StabilityLevel}; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; +use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Mutability; use rustc_middle::middle::stability; @@ -3100,7 +3101,7 @@ fn item_struct( _ => None, }) .peekable(); - if let clean::StructType::Plain = s.struct_type { + if let CtorKind::Fictive = s.struct_type { if fields.peek().is_some() { write!( w, @@ -3350,7 +3351,7 @@ fn render_struct( w: &mut Buffer, it: &clean::Item, g: Option<&clean::Generics>, - ty: clean::StructType, + ty: CtorKind, fields: &[clean::Item], tab: &str, structhead: bool, @@ -3367,7 +3368,7 @@ fn render_struct( write!(w, "{}", g.print()) } match ty { - clean::StructType::Plain => { + CtorKind::Fictive => { if let Some(g) = g { write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: true }) } @@ -3399,7 +3400,7 @@ fn render_struct( } write!(w, "}}"); } - clean::StructType::Tuple => { + CtorKind::Fn => { write!(w, "("); for (i, field) in fields.iter().enumerate() { if i > 0 { @@ -3424,7 +3425,7 @@ fn render_struct( } write!(w, ";"); } - clean::StructType::Unit => { + CtorKind::Const => { // Needed for PhantomData. if let Some(g) = g { write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: false }) @@ -4459,7 +4460,7 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea let fields = get_struct_fields_name(&s.fields); if !fields.is_empty() { - if let clean::StructType::Plain = s.struct_type { + if let CtorKind::Fictive = s.struct_type { sidebar.push_str(&format!( "Fields\
{}
", diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b872f94908775..32def4dde1b38 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -5,6 +5,7 @@ use std::convert::From; use rustc_ast::ast; +use rustc_hir::def::CtorKind; use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_span::Pos; @@ -220,13 +221,12 @@ impl From for Struct { } } -impl From for StructType { - fn from(struct_type: clean::StructType) -> Self { - use clean::StructType::*; +impl From for StructType { + fn from(struct_type: CtorKind) -> Self { match struct_type { - Plain => StructType::Plain, - Tuple => StructType::Tuple, - Unit => StructType::Unit, + CtorKind::Fictive => StructType::Plain, + CtorKind::Fn => StructType::Tuple, + CtorKind::Const => StructType::Unit, } } } From 811fa59db0210c8c5eeb86e47d858c88e3460d07 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Wed, 20 Jan 2021 17:52:52 -0500 Subject: [PATCH 08/26] Add explanation of None vs Some("") --- src/librustdoc/json/types.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/json/types.rs b/src/librustdoc/json/types.rs index 2f6db0231ab49..c148602009f9a 100644 --- a/src/librustdoc/json/types.rs +++ b/src/librustdoc/json/types.rs @@ -68,7 +68,8 @@ pub struct Item { /// By default all documented items are public, but you can tell rustdoc to output private items /// so this field is needed to differentiate. pub visibility: Visibility, - /// The full markdown docstring of this item. + /// The full markdown docstring of this item. Absent if there is no documentation at all, + /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`). pub docs: Option, /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs pub links: FxHashMap, From d0c1405564024d109ec22b130584d74fcb82d153 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 21 Jan 2021 01:42:37 +0000 Subject: [PATCH 09/26] Document why cannot use concat! in dbg! Co-authored-by: Miguel Ojeda --- library/std/src/macros.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 5a70aa070e870..e466f3151524c 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -282,6 +282,10 @@ macro_rules! eprintln { #[macro_export] #[stable(feature = "dbg_macro", since = "1.32.0")] macro_rules! dbg { + // NOTE: We cannot use `concat!` to make a static string as a format argument + // of `eprintln!` because `file!` could contain a `{` or + // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!` + // will be malformed. () => { $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!()); }; From 758d855bff92cb35e13c5ae078639b862f02001f Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 21 Jan 2021 11:57:01 -0500 Subject: [PATCH 10/26] Enforce statically that `MIN_NON_ZERO_CAP` is calculated at compile time Previously, it would usually get computed by LLVM, but this enforces it. --- library/alloc/src/raw_vec.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 36b7efc33a874..36e2d18d3ddfb 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -114,6 +114,19 @@ impl RawVec { } impl RawVec { + // Tiny Vecs are dumb. Skip to: + // - 8 if the element size is 1, because any heap allocators is likely + // to round up a request of less than 8 bytes to at least 8 bytes. + // - 4 if elements are moderate-sized (<= 1 KiB). + // - 1 otherwise, to avoid wasting too much space for very short Vecs. + const MIN_NON_ZERO_CAP: usize = if mem::size_of::() == 1 { + 8 + } else if mem::size_of::() <= 1024 { + 4 + } else { + 1 + }; + /// Like `new`, but parameterized over the choice of allocator for /// the returned `RawVec`. #[rustc_allow_const_fn_unstable(const_fn)] @@ -399,22 +412,7 @@ impl RawVec { // This guarantees exponential growth. The doubling cannot overflow // because `cap <= isize::MAX` and the type of `cap` is `usize`. let cap = cmp::max(self.cap * 2, required_cap); - - // Tiny Vecs are dumb. Skip to: - // - 8 if the element size is 1, because any heap allocators is likely - // to round up a request of less than 8 bytes to at least 8 bytes. - // - 4 if elements are moderate-sized (<= 1 KiB). - // - 1 otherwise, to avoid wasting too much space for very short Vecs. - // Note that `min_non_zero_cap` is computed statically. - let elem_size = mem::size_of::(); - let min_non_zero_cap = if elem_size == 1 { - 8 - } else if elem_size <= 1024 { - 4 - } else { - 1 - }; - let cap = cmp::max(min_non_zero_cap, cap); + let cap = cmp::max(Self::MIN_NON_ZERO_CAP, cap); let new_layout = Layout::array::(cap); From 8f28a3269e1e9299764f3881880524bf49afcde3 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 21 Jan 2021 17:12:14 +0100 Subject: [PATCH 11/26] Turn alloc's force_expr macro into a regular macro_rules!{}. Otherwise rust-analyzer doesn't understand vec![]. --- library/alloc/src/lib.rs | 7 ------- library/alloc/src/macros.rs | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 8d721ed7487ae..d7ae353282e79 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -189,11 +189,4 @@ pub mod vec; #[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")] pub mod __export { pub use core::format_args; - - /// Force AST node to an expression to improve diagnostics in pattern position. - #[rustc_macro_transparency = "semitransparent"] - #[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")] - pub macro force_expr($e:expr) { - $e - } } diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index 3a46763c3f608..9e5e81595cfdb 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -40,13 +40,13 @@ #[allow_internal_unstable(box_syntax, liballoc_internals)] macro_rules! vec { () => ( - $crate::__export::force_expr!($crate::vec::Vec::new()) + $crate::force_expr!($crate::vec::Vec::new()) ); ($elem:expr; $n:expr) => ( - $crate::__export::force_expr!($crate::vec::from_elem($elem, $n)) + $crate::force_expr!($crate::vec::from_elem($elem, $n)) ); ($($x:expr),+ $(,)?) => ( - $crate::__export::force_expr!(<[_]>::into_vec(box [$($x),+])) + $crate::force_expr!(<[_]>::into_vec(box [$($x),+])) ); } @@ -111,3 +111,13 @@ macro_rules! format { res }} } + +/// Force AST node to an expression to improve diagnostics in pattern position. +#[doc(hidden)] +#[macro_export] +#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")] +macro_rules! force_expr { + ($e:expr) => { + $e + }; +} From 1934eaf6d87df0eb557e80f9c6a63af8569c48bd Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 21 Jan 2021 18:30:49 +0100 Subject: [PATCH 12/26] Rename alloc::force_expr to __rust_force_expr. --- library/alloc/src/macros.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index 9e5e81595cfdb..f1e3ee97ccc39 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -40,13 +40,13 @@ #[allow_internal_unstable(box_syntax, liballoc_internals)] macro_rules! vec { () => ( - $crate::force_expr!($crate::vec::Vec::new()) + $crate::__rust_force_expr!($crate::vec::Vec::new()) ); ($elem:expr; $n:expr) => ( - $crate::force_expr!($crate::vec::from_elem($elem, $n)) + $crate::__rust_force_expr!($crate::vec::from_elem($elem, $n)) ); ($($x:expr),+ $(,)?) => ( - $crate::force_expr!(<[_]>::into_vec(box [$($x),+])) + $crate::__rust_force_expr!(<[_]>::into_vec(box [$($x),+])) ); } @@ -116,7 +116,7 @@ macro_rules! format { #[doc(hidden)] #[macro_export] #[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")] -macro_rules! force_expr { +macro_rules! __rust_force_expr { ($e:expr) => { $e }; From 653bcc8ad20320742e2011b4ad009b28767bcae2 Mon Sep 17 00:00:00 2001 From: Lukas Lueg Date: Mon, 18 Jan 2021 20:40:25 +0100 Subject: [PATCH 13/26] Expand docs on Iterator::intersperse --- library/core/src/iter/adapters/intersperse.rs | 10 ++-- library/core/src/iter/traits/iterator.rs | 51 +++++++++++++++++-- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/library/core/src/iter/adapters/intersperse.rs b/library/core/src/iter/adapters/intersperse.rs index 1d01e9b5fb7dc..4a40f8809aec7 100644 --- a/library/core/src/iter/adapters/intersperse.rs +++ b/library/core/src/iter/adapters/intersperse.rs @@ -151,12 +151,10 @@ where { let (lo, hi) = iter.size_hint(); let next_is_elem = !needs_sep; - let lo = lo.saturating_sub(next_is_elem as usize).saturating_add(lo); - let hi = match hi { - Some(hi) => hi.saturating_sub(next_is_elem as usize).checked_add(hi), - None => None, - }; - (lo, hi) + ( + lo.saturating_sub(next_is_elem as usize).saturating_add(lo), + hi.and_then(|hi| hi.saturating_sub(next_is_elem as usize).checked_add(hi)), + ) } fn intersperse_fold( diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 83d339d8f40a5..e3b2c394e5446 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -569,9 +569,10 @@ pub trait Iterator { Zip::new(self, other.into_iter()) } - /// Places a copy of `separator` between all elements. + /// Creates a new iterator which places a copy of `separator` between adjacent + /// items of the original iterator. /// - /// In case the separator does not implement [`Clone`] or needs to be + /// In case `separator` does not implement [`Clone`] or needs to be /// computed every time, use [`intersperse_with`]. /// /// # Examples @@ -581,6 +582,19 @@ pub trait Iterator { /// ``` /// #![feature(iter_intersperse)] /// + /// let mut a = [0, 1, 2].iter().intersperse(&100); + /// assert_eq!(a.next(), Some(&0)); // The first element from `a`. + /// assert_eq!(a.next(), Some(&100)); // The separator. + /// assert_eq!(a.next(), Some(&1)); // The next element from `a`. + /// assert_eq!(a.next(), Some(&100)); // The separator. + /// assert_eq!(a.next(), Some(&2)); // The last element from `a`. + /// assert_eq!(a.next(), None); // The iterator is finished. + /// ``` + /// + /// `intersperse` can be very useful to join an iterator's items using a common element: + /// ``` + /// #![feature(iter_intersperse)] + /// /// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::(); /// assert_eq!(hello, "Hello World !"); /// ``` @@ -597,7 +611,16 @@ pub trait Iterator { Intersperse::new(self, separator) } - /// Places an element generated by `separator` between all elements. + /// Creates a new iterator which places an item generated by `separator` + /// between adjacent items of the original iterator. + /// + /// The closure will be called exactly once each time an item is placed + /// between two adjacent items from the underlying iterator; specifically, + /// the closure is not called if the underlying iterator yields less than + /// two items and after the last item is yielded. + /// + /// If the iterator's item implements [`Clone`], it may be easier to use + /// [`intersperse`]. /// /// # Examples /// @@ -606,14 +629,36 @@ pub trait Iterator { /// ``` /// #![feature(iter_intersperse)] /// + /// #[derive(PartialEq, Debug)] + /// struct NotClone(usize); + /// + /// let v = vec![NotClone(0), NotClone(1), NotClone(2)]; + /// let mut it = v.into_iter().intersperse_with(|| NotClone(99)); + /// + /// assert_eq!(it.next(), Some(NotClone(0))); // The first element from `v`. + /// assert_eq!(it.next(), Some(NotClone(99))); // The separator. + /// assert_eq!(it.next(), Some(NotClone(1))); // The next element from `v`. + /// assert_eq!(it.next(), Some(NotClone(99))); // The separator. + /// assert_eq!(it.next(), Some(NotClone(2))); // The last element from from `v`. + /// assert_eq!(it.next(), None); // The iterator is finished. + /// ``` + /// + /// `intersperse_with` can be used in situations where the separator needs + /// to be computed: + /// ``` + /// #![feature(iter_intersperse)] + /// /// let src = ["Hello", "to", "all", "people", "!!"].iter().copied(); /// + /// // The closure mutably borrows it's context to generate an item. /// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied(); /// let separator = || happy_emojis.next().unwrap_or(" 🦀 "); /// /// let result = src.intersperse_with(separator).collect::(); /// assert_eq!(result, "Hello ❤️ to 😀 all 🦀 people 🦀 !!"); /// ``` + /// [`Clone`]: crate::clone::Clone + /// [`intersperse`]: Iterator::intersperse #[inline] #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] fn intersperse_with(self, separator: G) -> IntersperseWith From c61785ea44683ca03314dd4ef7150ef98db8a2ad Mon Sep 17 00:00:00 2001 From: Lukas Lueg Date: Thu, 21 Jan 2021 20:31:37 +0100 Subject: [PATCH 14/26] Fix typo --- library/core/src/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index e3b2c394e5446..84a622e042583 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -650,7 +650,7 @@ pub trait Iterator { /// /// let src = ["Hello", "to", "all", "people", "!!"].iter().copied(); /// - /// // The closure mutably borrows it's context to generate an item. + /// // The closure mutably borrows its context to generate an item. /// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied(); /// let separator = || happy_emojis.next().unwrap_or(" 🦀 "); /// From 26565f05c045c15d4304e73639efcaf5b3100842 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Thu, 21 Jan 2021 21:18:31 -0500 Subject: [PATCH 15/26] Bump format version --- src/librustdoc/json/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index df7ab9b7361a0..e96ceb32f2e96 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -236,7 +236,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), - format_version: 1, + format_version: 2, }; let mut p = self.out_path.clone(); p.push(output.index.get(&output.root).unwrap().name.clone().unwrap()); From a194881991e57c6533490aff4c2d536d5569c514 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 31 Dec 2020 23:25:30 -0500 Subject: [PATCH 16/26] Fix rustc::internal lints on rustdoc --- src/librustdoc/config.rs | 4 ++-- src/librustdoc/doctest.rs | 8 ++++---- src/librustdoc/formats/renderer.rs | 6 +++--- src/librustdoc/html/layout.rs | 5 +++-- src/librustdoc/html/markdown.rs | 16 ++++++++-------- src/librustdoc/html/render/mod.rs | 3 +-- src/librustdoc/json/mod.rs | 6 +++--- src/librustdoc/lib.rs | 4 ++-- src/librustdoc/passes/check_code_block_syntax.rs | 2 +- src/librustdoc/passes/collect_intra_doc_links.rs | 6 +++--- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e43ea965c0423..8006c3d277164 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, HashMap}; +use std::collections::BTreeMap; use std::convert::TryFrom; use std::ffi::OsStr; use std::fmt; @@ -219,7 +219,7 @@ crate struct RenderOptions { crate extern_html_root_urls: BTreeMap, /// A map of the default settings (values are as for DOM storage API). Keys should lack the /// `rustdoc-` prefix. - crate default_settings: HashMap, + crate default_settings: FxHashMap, /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages. crate resource_suffix: String, /// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 3de97f2dd2e59..38969e7346826 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1,4 +1,5 @@ use rustc_ast as ast; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_errors::{ColorConfig, ErrorReported}; use rustc_hir as hir; @@ -16,7 +17,6 @@ use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP}; use rustc_target::spec::TargetTriple; use tempfile::Builder as TempFileBuilder; -use std::collections::HashMap; use std::env; use std::io::{self, Write}; use std::panic; @@ -703,7 +703,7 @@ crate struct Collector { position: Span, source_map: Option>, filename: Option, - visited_tests: HashMap<(String, usize), usize>, + visited_tests: FxHashMap<(String, usize), usize>, } impl Collector { @@ -727,7 +727,7 @@ impl Collector { position: DUMMY_SP, source_map, filename, - visited_tests: HashMap::new(), + visited_tests: FxHashMap::default(), } } @@ -1009,7 +1009,7 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> { self.codes, self.collector.enable_per_target_ignores, Some(&crate::html::markdown::ExtraInfo::new( - &self.tcx, + self.tcx, hir_id, span_of_attrs(&attrs).unwrap_or(sp), )), diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index c91d6decc0b67..5c0f5e50c9e2c 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use rustc_middle::ty; +use rustc_middle::ty::TyCtxt; use rustc_span::edition::Edition; use crate::clean; @@ -20,7 +20,7 @@ crate trait FormatRenderer<'tcx>: Clone { render_info: RenderInfo, edition: Edition, cache: &mut Cache, - tcx: ty::TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Result<(Self, clean::Crate), Error>; /// Renders a single non-module item. This means no recursive sub-item rendering is required. @@ -55,7 +55,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( render_info: RenderInfo, diag: &rustc_errors::Handler, edition: Edition, - tcx: ty::TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Result<(), Error> { let (krate, mut cache) = Cache::from_krate( render_info.clone(), diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 4458eea95f3e1..c6ff4b57a6e59 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -1,6 +1,7 @@ -use std::collections::HashMap; use std::path::PathBuf; +use rustc_data_structures::fx::FxHashMap; + use crate::externalfiles::ExternalHtml; use crate::html::escape::Escape; use crate::html::format::{Buffer, Print}; @@ -11,7 +12,7 @@ crate struct Layout { crate logo: String, crate favicon: String, crate external_html: ExternalHtml, - crate default_settings: HashMap, + crate default_settings: FxHashMap, crate krate: String, /// The given user css file which allow to customize the generated /// documentation theme. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index cfa6cd96595d6..7c8b76be374a8 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -620,7 +620,7 @@ crate fn find_testable_code( tests: &mut T, error_codes: ErrorCodes, enable_per_target_ignores: bool, - extra_info: Option<&ExtraInfo<'_, '_>>, + extra_info: Option<&ExtraInfo<'_>>, ) { let mut parser = Parser::new(doc).into_offset_iter(); let mut prev_offset = 0; @@ -681,19 +681,19 @@ crate fn find_testable_code( } } -crate struct ExtraInfo<'a, 'b> { +crate struct ExtraInfo<'tcx> { hir_id: Option, item_did: Option, sp: Span, - tcx: &'a TyCtxt<'b>, + tcx: TyCtxt<'tcx>, } -impl<'a, 'b> ExtraInfo<'a, 'b> { - crate fn new(tcx: &'a TyCtxt<'b>, hir_id: HirId, sp: Span) -> ExtraInfo<'a, 'b> { +impl<'tcx> ExtraInfo<'tcx> { + crate fn new(tcx: TyCtxt<'tcx>, hir_id: HirId, sp: Span) -> ExtraInfo<'tcx> { ExtraInfo { hir_id: Some(hir_id), item_did: None, sp, tcx } } - crate fn new_did(tcx: &'a TyCtxt<'b>, did: DefId, sp: Span) -> ExtraInfo<'a, 'b> { + crate fn new_did(tcx: TyCtxt<'tcx>, did: DefId, sp: Span) -> ExtraInfo<'tcx> { ExtraInfo { hir_id: None, item_did: Some(did), sp, tcx } } @@ -775,7 +775,7 @@ impl LangString { string: &str, allow_error_code_check: ErrorCodes, enable_per_target_ignores: bool, - extra: Option<&ExtraInfo<'_, '_>>, + extra: Option<&ExtraInfo<'_>>, ) -> LangString { let allow_error_code_check = allow_error_code_check.as_bool(); let mut seen_rust_tags = false; @@ -1208,7 +1208,7 @@ crate struct RustCodeBlock { /// Returns a range of bytes for each code block in the markdown that is tagged as `rust` or /// untagged (and assumed to be rust). -crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec { +crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec { let mut code_blocks = vec![]; if md.is_empty() { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 26afd705740b2..37a0f7f4d7c4b 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -55,7 +55,6 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Mutability; use rustc_middle::middle::stability; -use rustc_middle::ty; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; @@ -390,7 +389,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { _render_info: RenderInfo, edition: Edition, cache: &mut Cache, - tcx: ty::TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Result<(Self, clean::Crate), Error> { // need to save a copy of the options for rendering the index page let md_opts = options.clone(); diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 64500c1d91161..c93062c73a870 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -13,7 +13,7 @@ use std::path::PathBuf; use std::rc::Rc; use rustc_data_structures::fx::FxHashMap; -use rustc_middle::ty; +use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; @@ -26,7 +26,7 @@ use crate::html::render::cache::ExternalLocation; #[derive(Clone)] crate struct JsonRenderer<'tcx> { - tcx: ty::TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, /// A mapping of IDs that contains all local items for this crate which gets output as a top /// level field of the JSON blob. index: Rc>>, @@ -131,7 +131,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { _render_info: RenderInfo, _edition: Edition, _cache: &mut Cache, - tcx: ty::TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Result<(Self, clean::Crate), Error> { debug!("Initializing json renderer"); Ok(( diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 719aca612f50d..2dddcd1c34640 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -65,7 +65,7 @@ use std::process; use rustc_driver::abort_on_err; use rustc_errors::ErrorReported; use rustc_interface::interface; -use rustc_middle::ty; +use rustc_middle::ty::TyCtxt; use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup}; use rustc_session::getopts; use rustc_session::{early_error, early_warn}; @@ -471,7 +471,7 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( render_info: config::RenderInfo, diag: &rustc_errors::Handler, edition: rustc_span::edition::Edition, - tcx: ty::TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, ) -> MainResult { match formats::run_format::(krate, renderopts, render_info, &diag, edition, tcx) { Ok(_) => Ok(()), diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 554392c213e24..9516130034b59 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -108,7 +108,7 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> { fn fold_item(&mut self, item: clean::Item) -> Option { if let Some(dox) = &item.attrs.collapsed_doc_value() { let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span()); - let extra = crate::html::markdown::ExtraInfo::new_did(&self.cx.tcx, item.def_id, sp); + let extra = crate::html::markdown::ExtraInfo::new_did(self.cx.tcx, item.def_id, sp); for code_block in markdown::rust_code_blocks(&dox, &extra) { self.check_rust_syntax(&item, &dox, code_block); } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 2694450a520c9..002d8938f694d 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -13,6 +13,7 @@ use rustc_hir::def::{ PerNS, }; use rustc_hir::def_id::{CrateNum, DefId}; +use rustc_middle::ty::TyCtxt; use rustc_middle::{bug, ty}; use rustc_resolve::ParentScope; use rustc_session::lint::{ @@ -85,7 +86,7 @@ impl Res { } } - fn name(self, tcx: ty::TyCtxt<'_>) -> String { + fn name(self, tcx: TyCtxt<'_>) -> String { match self { Res::Def(_, id) => tcx.item_name(id).to_string(), Res::Primitive(prim) => prim.as_str().to_string(), @@ -865,12 +866,11 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { // FIXME(jynelson): this shouldn't go through stringification, rustdoc should just use the DefId directly let self_name = self_id.and_then(|self_id| { - use ty::TyKind; if matches!(self.cx.tcx.def_kind(self_id), DefKind::Impl) { // using `ty.to_string()` (or any variant) has issues with raw idents let ty = self.cx.tcx.type_of(self_id); let name = match ty.kind() { - TyKind::Adt(def, _) => Some(self.cx.tcx.item_name(def.did).to_string()), + ty::Adt(def, _) => Some(self.cx.tcx.item_name(def.did).to_string()), other if other.is_primitive() => Some(ty.to_string()), _ => None, }; From 0797ffec09c79d99943cb95b5b455c0d2278ea2f Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 21 Jan 2021 22:51:58 -0500 Subject: [PATCH 17/26] Deny internal lints for rustdoc --- src/bootstrap/check.rs | 7 +++++++ src/librustdoc/lib.rs | 1 + 2 files changed, 8 insertions(+) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index c19bb536ce83c..6626fead774d6 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -320,6 +320,13 @@ macro_rules! tool_check_step { cargo.arg("--all-targets"); } + // Enable internal lints for clippy and rustdoc + // NOTE: this intentionally doesn't enable lints for any other tools, + // see https://github.com/rust-lang/rust/pull/80573#issuecomment-754010776 + if $path == "src/tools/rustdoc" || $path == "src/tools/clippy" { + cargo.rustflag("-Zunstable-options"); + } + builder.info(&format!( "Checking stage{} {} artifacts ({} -> {})", builder.top_stage, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 2dddcd1c34640..d17189b416dd4 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -18,6 +18,7 @@ #![feature(str_split_once)] #![feature(iter_intersperse)] #![recursion_limit = "256"] +#![deny(rustc::internal)] #[macro_use] extern crate lazy_static; From 707ce2b798ad7bb6c1e0fce0da542d9caef07b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 19 Jan 2021 15:51:51 -0800 Subject: [PATCH 18/26] Account for labels when suggesting `loop` instead of `while true` --- compiler/rustc_lint/src/builtin.rs | 12 +++- src/test/ui/issues/issue-1962.fixed | 4 +- src/test/ui/issues/issue-1962.rs | 4 +- src/test/ui/issues/issue-1962.stderr | 4 +- src/test/ui/issues/issue-27042.stderr | 2 +- src/test/ui/label/label_misspelled.rs | 22 +++++++ src/test/ui/label/label_misspelled.stderr | 80 ++++++++++++++++++++++- 7 files changed, 116 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 8cdb33ea3175f..b37660e4a90d3 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -96,18 +96,24 @@ fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr { impl EarlyLintPass for WhileTrue { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { - if let ast::ExprKind::While(cond, ..) = &e.kind { + if let ast::ExprKind::While(cond, _, label) = &e.kind { if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind { if let ast::LitKind::Bool(true) = lit.kind { if !lit.span.from_expansion() { let msg = "denote infinite loops with `loop { ... }`"; - let condition_span = cx.sess.source_map().guess_head_span(e.span); + let condition_span = e.span.with_hi(cond.span.hi()); cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| { lint.build(msg) .span_suggestion_short( condition_span, "use `loop`", - "loop".to_owned(), + format!( + "{}loop", + label.map_or_else(String::new, |label| format!( + "{}: ", + label.ident, + )) + ), Applicability::MachineApplicable, ) .emit(); diff --git a/src/test/ui/issues/issue-1962.fixed b/src/test/ui/issues/issue-1962.fixed index b810a90ef37f9..897fd172b29f3 100644 --- a/src/test/ui/issues/issue-1962.fixed +++ b/src/test/ui/issues/issue-1962.fixed @@ -3,8 +3,8 @@ fn main() { let mut i = 0; - loop { //~ ERROR denote infinite loops with `loop + 'a: loop { //~ ERROR denote infinite loops with `loop i += 1; - if i == 5 { break; } + if i == 5 { break 'a; } } } diff --git a/src/test/ui/issues/issue-1962.rs b/src/test/ui/issues/issue-1962.rs index 00d2bbd28506e..71e874100874f 100644 --- a/src/test/ui/issues/issue-1962.rs +++ b/src/test/ui/issues/issue-1962.rs @@ -3,8 +3,8 @@ fn main() { let mut i = 0; - while true { //~ ERROR denote infinite loops with `loop + 'a: while true { //~ ERROR denote infinite loops with `loop i += 1; - if i == 5 { break; } + if i == 5 { break 'a; } } } diff --git a/src/test/ui/issues/issue-1962.stderr b/src/test/ui/issues/issue-1962.stderr index 17142912696a7..4c32a4cf3dd59 100644 --- a/src/test/ui/issues/issue-1962.stderr +++ b/src/test/ui/issues/issue-1962.stderr @@ -1,8 +1,8 @@ error: denote infinite loops with `loop { ... }` --> $DIR/issue-1962.rs:6:5 | -LL | while true { - | ^^^^^^^^^^ help: use `loop` +LL | 'a: while true { + | ^^^^^^^^^^^^^^ help: use `loop` | = note: requested on the command line with `-D while-true` diff --git a/src/test/ui/issues/issue-27042.stderr b/src/test/ui/issues/issue-27042.stderr index 7dee1a6a5f044..59ef28481d0e6 100644 --- a/src/test/ui/issues/issue-27042.stderr +++ b/src/test/ui/issues/issue-27042.stderr @@ -4,7 +4,7 @@ warning: denote infinite loops with `loop { ... }` LL | / 'b: LL | | LL | | while true { break }; // but here we cite the whole loop - | |____________________________^ help: use `loop` + | |__________________^ help: use `loop` | = note: `#[warn(while_true)]` on by default diff --git a/src/test/ui/label/label_misspelled.rs b/src/test/ui/label/label_misspelled.rs index ebfd5642c9fa8..7a8ff0360f6ea 100644 --- a/src/test/ui/label/label_misspelled.rs +++ b/src/test/ui/label/label_misspelled.rs @@ -16,3 +16,25 @@ fn main() { //~^ ERROR cannot find value `for_loop` in this scope }; } + +fn foo() { + 'LOOP: loop { + break LOOP; + //~^ ERROR cannot find value `LOOP` in this scope + }; + 'while_loop: while true { //~ WARN denote infinite loops with + break while_loop; + //~^ ERROR cannot find value `while_loop` in this scope + //~| ERROR `break` with value from a `while` loop + }; + 'while_let: while let Some(_) = Some(()) { + break while_let; + //~^ ERROR cannot find value `while_let` in this scope + //~| ERROR `break` with value from a `while` loop + } + 'for_loop: for _ in 0..3 { + break for_loop; + //~^ ERROR cannot find value `for_loop` in this scope + //~| ERROR `break` with value from a `for` loop + }; +} diff --git a/src/test/ui/label/label_misspelled.stderr b/src/test/ui/label/label_misspelled.stderr index 1368ca4126cdd..8282d3ada32f2 100644 --- a/src/test/ui/label/label_misspelled.stderr +++ b/src/test/ui/label/label_misspelled.stderr @@ -34,6 +34,42 @@ LL | for_loop; | not found in this scope | help: a label with a similar name exists: `'for_loop` +error[E0425]: cannot find value `LOOP` in this scope + --> $DIR/label_misspelled.rs:22:15 + | +LL | break LOOP; + | ^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'LOOP` + +error[E0425]: cannot find value `while_loop` in this scope + --> $DIR/label_misspelled.rs:26:15 + | +LL | break while_loop; + | ^^^^^^^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'while_loop` + +error[E0425]: cannot find value `while_let` in this scope + --> $DIR/label_misspelled.rs:31:15 + | +LL | break while_let; + | ^^^^^^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'while_let` + +error[E0425]: cannot find value `for_loop` in this scope + --> $DIR/label_misspelled.rs:36:15 + | +LL | break for_loop; + | ^^^^^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'for_loop` + warning: denote infinite loops with `loop { ... }` --> $DIR/label_misspelled.rs:6:5 | @@ -42,6 +78,46 @@ LL | 'while_loop: while true { | = note: `#[warn(while_true)]` on by default -error: aborting due to 4 previous errors; 1 warning emitted +warning: denote infinite loops with `loop { ... }` + --> $DIR/label_misspelled.rs:25:5 + | +LL | 'while_loop: while true { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop` + +error[E0571]: `break` with value from a `while` loop + --> $DIR/label_misspelled.rs:26:9 + | +LL | break while_loop; + | ^^^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block + | +help: instead, use `break` on its own without a value inside this `while` loop + | +LL | break; + | ^^^^^ + +error[E0571]: `break` with value from a `while` loop + --> $DIR/label_misspelled.rs:31:9 + | +LL | break while_let; + | ^^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block + | +help: instead, use `break` on its own without a value inside this `while` loop + | +LL | break; + | ^^^^^ + +error[E0571]: `break` with value from a `for` loop + --> $DIR/label_misspelled.rs:36:9 + | +LL | break for_loop; + | ^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block + | +help: instead, use `break` on its own without a value inside this `for` loop + | +LL | break; + | ^^^^^ + +error: aborting due to 11 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0425, E0571. +For more information about an error, try `rustc --explain E0425`. From a701ff981d8768e2b81a053bf9189ff67a2bb7ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 19 Jan 2021 17:51:48 -0800 Subject: [PATCH 19/26] Suggest `'a` when given `a` only when appropriate When encountering a name `a` that isn't resolved, but a label `'a` is found in the current ribs, only suggest `'a` if this name is the value expression of a `break` statement. Solve FIXME. --- compiler/rustc_resolve/src/late.rs | 6 +++ .../rustc_resolve/src/late/diagnostics.rs | 22 ++++++---- src/test/ui/label/label_misspelled.stderr | 44 ++++++++++--------- src/test/ui/loops/loop-break-value.stderr | 4 +- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index fff14747e5729..a3a630e14906f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2266,6 +2266,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { visit::walk_expr(self, expr); } + ExprKind::Break(None, Some(ref e)) => { + // We use this instead of `visit::walk_expr` to keep the parent expr around for + // better + self.resolve_expr(e, Some(&expr)); + } + ExprKind::Let(ref pat, ref scrutinee) => { self.visit_expr(scrutinee); self.resolve_pattern_top(pat, PatternSource::Let); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3945afb4724a8..f8f81c9128772 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -547,15 +547,19 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { for label_rib in &self.label_ribs { for (label_ident, _) in &label_rib.bindings { if format!("'{}", ident) == label_ident.to_string() { - let msg = "a label with a similar name exists"; - // FIXME: consider only emitting this suggestion if a label would be valid here - // which is pretty much only the case for `break` expressions. - err.span_suggestion( - span, - &msg, - label_ident.name.to_string(), - Applicability::MaybeIncorrect, - ); + err.span_label(label_ident.span, "a label with a similar name exists"); + if let PathSource::Expr(Some(Expr { + kind: ExprKind::Break(None, Some(_)), + .. + })) = source + { + err.span_suggestion( + span, + "use the similarly named label", + label_ident.name.to_string(), + Applicability::MaybeIncorrect, + ); + } } } } diff --git a/src/test/ui/label/label_misspelled.stderr b/src/test/ui/label/label_misspelled.stderr index 8282d3ada32f2..7cfb6e8147dd9 100644 --- a/src/test/ui/label/label_misspelled.stderr +++ b/src/test/ui/label/label_misspelled.stderr @@ -1,74 +1,78 @@ error[E0425]: cannot find value `LOOP` in this scope --> $DIR/label_misspelled.rs:3:9 | +LL | 'LOOP: loop { + | ----- a label with a similar name exists LL | LOOP; - | ^^^^ - | | - | not found in this scope - | help: a label with a similar name exists: `'LOOP` + | ^^^^ not found in this scope error[E0425]: cannot find value `while_loop` in this scope --> $DIR/label_misspelled.rs:7:9 | +LL | 'while_loop: while true { + | ----------- a label with a similar name exists LL | while_loop; - | ^^^^^^^^^^ - | | - | not found in this scope - | help: a label with a similar name exists: `'while_loop` + | ^^^^^^^^^^ not found in this scope error[E0425]: cannot find value `while_let` in this scope --> $DIR/label_misspelled.rs:11:9 | +LL | 'while_let: while let Some(_) = Some(()) { + | ---------- a label with a similar name exists LL | while_let; - | ^^^^^^^^^ - | | - | not found in this scope - | help: a label with a similar name exists: `'while_let` + | ^^^^^^^^^ not found in this scope error[E0425]: cannot find value `for_loop` in this scope --> $DIR/label_misspelled.rs:15:9 | +LL | 'for_loop: for _ in 0..3 { + | --------- a label with a similar name exists LL | for_loop; - | ^^^^^^^^ - | | - | not found in this scope - | help: a label with a similar name exists: `'for_loop` + | ^^^^^^^^ not found in this scope error[E0425]: cannot find value `LOOP` in this scope --> $DIR/label_misspelled.rs:22:15 | +LL | 'LOOP: loop { + | ----- a label with a similar name exists LL | break LOOP; | ^^^^ | | | not found in this scope - | help: a label with a similar name exists: `'LOOP` + | help: use the similarly named label: `'LOOP` error[E0425]: cannot find value `while_loop` in this scope --> $DIR/label_misspelled.rs:26:15 | +LL | 'while_loop: while true { + | ----------- a label with a similar name exists LL | break while_loop; | ^^^^^^^^^^ | | | not found in this scope - | help: a label with a similar name exists: `'while_loop` + | help: use the similarly named label: `'while_loop` error[E0425]: cannot find value `while_let` in this scope --> $DIR/label_misspelled.rs:31:15 | +LL | 'while_let: while let Some(_) = Some(()) { + | ---------- a label with a similar name exists LL | break while_let; | ^^^^^^^^^ | | | not found in this scope - | help: a label with a similar name exists: `'while_let` + | help: use the similarly named label: `'while_let` error[E0425]: cannot find value `for_loop` in this scope --> $DIR/label_misspelled.rs:36:15 | +LL | 'for_loop: for _ in 0..3 { + | --------- a label with a similar name exists LL | break for_loop; | ^^^^^^^^ | | | not found in this scope - | help: a label with a similar name exists: `'for_loop` + | help: use the similarly named label: `'for_loop` warning: denote infinite loops with `loop { ... }` --> $DIR/label_misspelled.rs:6:5 diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr index 0237435c8b46a..27104118a63a4 100644 --- a/src/test/ui/loops/loop-break-value.stderr +++ b/src/test/ui/loops/loop-break-value.stderr @@ -1,11 +1,13 @@ error[E0425]: cannot find value `LOOP` in this scope --> $DIR/loop-break-value.rs:95:15 | +LL | 'LOOP: for _ in 0 .. 9 { + | ----- a label with a similar name exists LL | break LOOP; | ^^^^ | | | not found in this scope - | help: a label with a similar name exists: `'LOOP` + | help: use the similarly named label: `'LOOP` warning: denote infinite loops with `loop { ... }` --> $DIR/loop-break-value.rs:26:5 From 060dba67b7523a69223a9aef7c9fe2494ec27535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 20 Jan 2021 17:15:08 -0800 Subject: [PATCH 20/26] Add loop head span to hir --- compiler/rustc_ast_lowering/src/expr.rs | 19 +++++++++++++++---- compiler/rustc_hir/src/hir.rs | 4 +++- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 4 +--- compiler/rustc_passes/src/check_const.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 2 +- compiler/rustc_passes/src/loops.rs | 5 ++--- compiler/rustc_passes/src/region.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 2 +- compiler/rustc_typeck/src/check/expr.rs | 2 +- compiler/rustc_typeck/src/expr_use_visitor.rs | 2 +- src/tools/clippy/clippy_lints/src/loops.rs | 8 ++++---- .../clippy_lints/src/needless_continue.rs | 2 +- src/tools/clippy/clippy_lints/src/shadow.rs | 2 +- 15 files changed, 35 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1b9ccbd850bee..31360158e2b4e 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -10,9 +10,9 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_session::parse::feature_err; -use rustc_span::hygiene::ForLoopLoc; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::symbol::{sym, Ident, Symbol}; +use rustc_span::{hygiene::ForLoopLoc, DUMMY_SP}; use rustc_target::asm; use std::collections::hash_map::Entry; use std::fmt::Write; @@ -102,6 +102,7 @@ impl<'hir> LoweringContext<'_, 'hir> { this.lower_block(body, false), opt_label, hir::LoopSource::Loop, + DUMMY_SP, ) }), ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body), @@ -453,7 +454,12 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr_match(span, scrutinee, arena_vec![self; then_arm, else_arm], desugar); // `[opt_ident]: loop { ... }` - hir::ExprKind::Loop(self.block_expr(self.arena.alloc(match_expr)), opt_label, source) + hir::ExprKind::Loop( + self.block_expr(self.arena.alloc(match_expr)), + opt_label, + source, + span.with_hi(cond.span.hi()), + ) } /// Desugar `try { ; }` into `{ ; ::std::ops::Try::from_ok() }`, @@ -748,7 +754,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // loop { .. } let loop_expr = self.arena.alloc(hir::Expr { hir_id: loop_hir_id, - kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop), + kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop, span), span, attrs: ThinVec::new(), }); @@ -1709,7 +1715,12 @@ impl<'hir> LoweringContext<'_, 'hir> { ); // `[opt_ident]: loop { ... }` - let kind = hir::ExprKind::Loop(loop_block, opt_label, hir::LoopSource::ForLoop); + let kind = hir::ExprKind::Loop( + loop_block, + opt_label, + hir::LoopSource::ForLoop, + e.span.with_hi(orig_head_span.hi()), + ); let loop_expr = self.arena.alloc(hir::Expr { hir_id: self.lower_node_id(e.id), kind, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 3673e5c8bf3a5..35170fa7c1d02 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1617,7 +1617,9 @@ pub enum ExprKind<'hir> { /// A conditionless loop (can be exited with `break`, `continue`, or `return`). /// /// I.e., `'label: loop { }`. - Loop(&'hir Block<'hir>, Option