diff options
| author | bors <bors@rust-lang.org> | 2020-11-15 13:19:05 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-11-15 13:19:05 +0000 |
| commit | 5fab31e5ddf5f2613bf57a0a7286dc6f5887e1cb (patch) | |
| tree | bf2540f955bf3e3adb49330b1fd06ee628d9fc35 /src | |
| parent | 04688459242356c0f6b9fdad3ba76c9ec4dcc354 (diff) | |
| parent | 568354f01f22148709e51fe1130826addb455e18 (diff) | |
| download | rust-5fab31e5ddf5f2613bf57a0a7286dc6f5887e1cb.tar.gz rust-5fab31e5ddf5f2613bf57a0a7286dc6f5887e1cb.zip | |
Auto merge of #79070 - jonas-schievink:rollup-wacn2b8, r=jonas-schievink
Rollup of 13 pull requests
Successful merges:
- #77802 (Allow making `RUSTC_BOOTSTRAP` conditional on the crate name)
- #79004 (Add `--color` support to bootstrap)
- #79005 (cleanup: Remove `ParseSess::injected_crate_name`)
- #79016 (Make `_` an expression, to discard values in destructuring assignments)
- #79019 (astconv: extract closures into a separate trait)
- #79026 (Implement BTreeMap::retain and BTreeSet::retain)
- #79031 (Validate that locals have a corresponding `LocalDecl`)
- #79034 (rustc_resolve: Make `macro_rules` scope chain compression lazy)
- #79036 (Move Steal to rustc_data_structures.)
- #79041 (Rename clean::{ItemEnum -> ItemKind}, clean::Item::{inner -> kind})
- #79058 (Move likely/unlikely argument outside of invisible unsafe block)
- #79059 (Print 'checking cranelift artifacts' to easily separate it from other artifacts)
- #79063 (Update rustfmt to v1.4.26)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src')
51 files changed, 420 insertions, 203 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 3d724c14842..508d785834f 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -19,7 +19,7 @@ use crate::compile; use crate::config::TargetSelection; use crate::dist; use crate::doc; -use crate::flags::Subcommand; +use crate::flags::{Color, Subcommand}; use crate::install; use crate::native; use crate::run; @@ -811,6 +811,16 @@ impl<'a> Builder<'a> { cargo.env("REAL_LIBRARY_PATH", e); } + match self.build.config.color { + Color::Always => { + cargo.arg("--color=always"); + } + Color::Never => { + cargo.arg("--color=never"); + } + Color::Auto => {} // nothing to do + } + if cmd != "install" { cargo.arg("--target").arg(target.rustc_target_arg()); } else { diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index ecca12108b6..f65b2b2c79f 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -232,6 +232,11 @@ impl Step for CodegenBackend { .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend))); rustc_cargo_env(builder, &mut cargo, target); + builder.info(&format!( + "Checking {} artifacts ({} -> {})", + backend, &compiler.host.triple, target.triple + )); + run_cargo( builder, cargo, diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index c0753d88504..94319a6d1e9 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -13,8 +13,8 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use crate::cache::{Interned, INTERNER}; -use crate::flags::Flags; pub use crate::flags::Subcommand; +use crate::flags::{Color, Flags}; use crate::util::exe; use build_helper::t; use merge::Merge; @@ -67,6 +67,7 @@ pub struct Config { pub json_output: bool, pub test_compare_mode: bool, pub llvm_libunwind: Option<LlvmLibunwind>, + pub color: Color, pub on_fail: Option<String>, pub stage: u32, @@ -577,6 +578,7 @@ impl Config { config.keep_stage = flags.keep_stage; config.keep_stage_std = flags.keep_stage_std; config.bindir = "bin".into(); // default + config.color = flags.color; if let Some(value) = flags.deny_warnings { config.deny_warnings = value; } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index dbfcf4df9b4..5a8096674c6 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -15,6 +15,31 @@ use crate::config::{Config, TargetSelection}; use crate::setup::Profile; use crate::{Build, DocTests}; +pub enum Color { + Always, + Never, + Auto, +} + +impl Default for Color { + fn default() -> Self { + Self::Auto + } +} + +impl std::str::FromStr for Color { + type Err = (); + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s.to_lowercase().as_str() { + "always" => Ok(Self::Always), + "never" => Ok(Self::Never), + "auto" => Ok(Self::Auto), + _ => Err(()), + } + } +} + /// Deserialized version of all flags for this compile. pub struct Flags { pub verbose: usize, // number of -v args; each extra -v after the first is passed to Cargo @@ -34,6 +59,7 @@ pub struct Flags { pub rustc_error_format: Option<String>, pub json_output: bool, pub dry_run: bool, + pub color: Color, // This overrides the deny-warnings configuration option, // which passes -Dwarnings to the compiler invocations. @@ -184,6 +210,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", ); opts.optopt("", "error-format", "rustc error format", "FORMAT"); opts.optflag("", "json-output", "use message-format=json"); + opts.optopt("", "color", "whether to use color in cargo and rustc output", "STYLE"); opts.optopt( "", "llvm-skip-rebuild", @@ -644,6 +671,9 @@ Arguments: llvm_skip_rebuild: matches.opt_str("llvm-skip-rebuild").map(|s| s.to_lowercase()).map( |s| s.parse::<bool>().expect("`llvm-skip-rebuild` should be either true or false"), ), + color: matches + .opt_get_default("color", Color::Auto) + .expect("`color` should be `always`, `never`, or `auto`"), } } } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index f39b53f3c82..a07d6b73f06 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -125,7 +125,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { def_id: self.cx.next_def_id(param_env_def_id.krate), stability: None, deprecation: None, - inner: ImplItem(Impl { + kind: ImplItem(Impl { unsafety: hir::Unsafety::Normal, generics: new_generics, provided_trait_methods: Default::default(), diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 7030fd9b7f2..f15142f4983 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -114,7 +114,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { def_id: self.cx.next_def_id(impl_def_id.krate), stability: None, deprecation: None, - inner: ImplItem(Impl { + kind: ImplItem(Impl { unsafety: hir::Unsafety::Normal, generics: ( self.cx.tcx.generics_of(impl_def_id), diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index b3de70e5905..d6f8870c859 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -54,7 +54,7 @@ crate fn try_inline( debug!("attrs={:?}", attrs); let attrs_clone = attrs; - let inner = match res { + let kind = match res { Res::Def(DefKind::Trait, did) => { record_extern_fqn(cx, did, clean::TypeKind::Trait); ret.extend(build_impls(cx, Some(parent_module), did, attrs)); @@ -128,7 +128,7 @@ crate fn try_inline( source: cx.tcx.def_span(did).clean(cx), name: Some(name.clean(cx)), attrs, - inner, + kind, visibility: clean::Public, stability: cx.tcx.lookup_stability(did).cloned(), deprecation: cx.tcx.lookup_deprecation(did).clean(cx), @@ -446,7 +446,7 @@ crate fn build_impl( debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id()); ret.push(clean::Item { - inner: clean::ImplItem(clean::Impl { + kind: clean::ImplItem(clean::Impl { unsafety: hir::Unsafety::Normal, generics, provided_trait_methods: provided, @@ -498,7 +498,7 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>) visibility: clean::Public, stability: None, deprecation: None, - inner: clean::ImportItem(clean::Import::new_simple( + kind: clean::ImportItem(clean::Import::new_simple( item.ident.to_string(), clean::ImportSource { path: clean::Path { @@ -555,7 +555,7 @@ fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static } } -fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemEnum { +fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind { let imported_from = cx.tcx.original_crate_name(did.krate); match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) { LoadedMacro::MacroDef(def, _) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 366548d5b5f..56ce0bae8bb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -42,7 +42,7 @@ use utils::*; pub use utils::{get_auto_trait_and_blanket_impls, krate, register_res}; pub use self::types::FnRetTy::*; -pub use self::types::ItemEnum::*; +pub use self::types::ItemKind::*; pub use self::types::SelfTy::*; pub use self::types::Type::*; pub use self::types::Visibility::{Inherited, Public}; @@ -276,7 +276,7 @@ impl Clean<Item> for doctree::Module<'_> { stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), - inner: ModuleItem(Module { is_crate: self.is_crate, items }), + kind: ModuleItem(Module { is_crate: self.is_crate, items }), } } } @@ -916,7 +916,7 @@ impl Clean<Item> for doctree::Function<'_> { stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), def_id: did.to_def_id(), - inner: FunctionItem(Function { + kind: FunctionItem(Function { decl, generics, header: hir::FnHeader { constness, ..self.header }, @@ -1023,7 +1023,7 @@ impl Clean<Item> for doctree::Trait<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: TraitItem(Trait { + kind: TraitItem(Trait { auto: self.is_auto.clean(cx), unsafety: self.unsafety, items: self.items.iter().map(|ti| ti.clean(cx)).collect(), @@ -1047,7 +1047,7 @@ impl Clean<Item> for doctree::TraitAlias<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: TraitAliasItem(TraitAlias { + kind: TraitAliasItem(TraitAlias { generics: self.generics.clean(cx), bounds: self.bounds.clean(cx), }), @@ -1102,7 +1102,7 @@ impl Clean<TypeKind> for hir::def::DefKind { impl Clean<Item> for hir::TraitItem<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let local_did = cx.tcx.hir().local_def_id(self.hir_id); - let inner = match self.kind { + let kind = match self.kind { hir::TraitItemKind::Const(ref ty, default) => { AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx, e))) } @@ -1140,7 +1140,7 @@ impl Clean<Item> for hir::TraitItem<'_> { visibility: Visibility::Inherited, stability: get_stability(cx, local_did.to_def_id()), deprecation: get_deprecation(cx, local_did.to_def_id()), - inner, + kind, } } } @@ -1148,7 +1148,7 @@ impl Clean<Item> for hir::TraitItem<'_> { impl Clean<Item> for hir::ImplItem<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let local_did = cx.tcx.hir().local_def_id(self.hir_id); - let inner = match self.kind { + let kind = match self.kind { hir::ImplItemKind::Const(ref ty, expr) => { AssocConstItem(ty.clean(cx), Some(print_const_expr(cx, expr))) } @@ -1175,14 +1175,14 @@ impl Clean<Item> for hir::ImplItem<'_> { visibility: self.vis.clean(cx), stability: get_stability(cx, local_did.to_def_id()), deprecation: get_deprecation(cx, local_did.to_def_id()), - inner, + kind, } } } impl Clean<Item> for ty::AssocItem { fn clean(&self, cx: &DocContext<'_>) -> Item { - let inner = match self.kind { + let kind = match self.kind { ty::AssocKind::Const => { let ty = cx.tcx.type_of(self.def_id); let default = if self.defaultness.has_value() { @@ -1343,7 +1343,7 @@ impl Clean<Item> for ty::AssocItem { def_id: self.def_id, attrs: inline::load_attrs(cx, self.def_id).clean(cx), source: cx.tcx.def_span(self.def_id).clean(cx), - inner, + kind, } } } @@ -1784,7 +1784,7 @@ impl Clean<Item> for hir::StructField<'_> { stability: get_stability(cx, local_did.to_def_id()), deprecation: get_deprecation(cx, local_did.to_def_id()), def_id: local_did.to_def_id(), - inner: StructFieldItem(self.ty.clean(cx)), + kind: StructFieldItem(self.ty.clean(cx)), } } } @@ -1799,7 +1799,7 @@ impl Clean<Item> for ty::FieldDef { stability: get_stability(cx, self.did), deprecation: get_deprecation(cx, self.did), def_id: self.did, - inner: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)), + kind: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)), } } } @@ -1835,7 +1835,7 @@ impl Clean<Item> for doctree::Struct<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: StructItem(Struct { + kind: StructItem(Struct { struct_type: self.struct_type, generics: self.generics.clean(cx), fields: self.fields.clean(cx), @@ -1855,7 +1855,7 @@ impl Clean<Item> for doctree::Union<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: UnionItem(Union { + kind: UnionItem(Union { struct_type: self.struct_type, generics: self.generics.clean(cx), fields: self.fields.clean(cx), @@ -1885,7 +1885,7 @@ impl Clean<Item> for doctree::Enum<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: EnumItem(Enum { + kind: EnumItem(Enum { variants: self.variants.iter().map(|v| v.clean(cx)).collect(), generics: self.generics.clean(cx), variants_stripped: false, @@ -1904,7 +1904,7 @@ impl Clean<Item> for doctree::Variant<'_> { stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), - inner: VariantItem(Variant { kind: self.def.clean(cx) }), + kind: VariantItem(Variant { kind: self.def.clean(cx) }), } } } @@ -1930,7 +1930,7 @@ impl Clean<Item> for ty::VariantDef { def_id: field.did, stability: get_stability(cx, field.did), deprecation: get_deprecation(cx, field.did), - inner: StructFieldItem(cx.tcx.type_of(field.did).clean(cx)), + kind: StructFieldItem(cx.tcx.type_of(field.did).clean(cx)), }) .collect(), }), @@ -1941,7 +1941,7 @@ impl Clean<Item> for ty::VariantDef { source: cx.tcx.def_span(self.def_id).clean(cx), visibility: Inherited, def_id: self.def_id, - inner: VariantItem(Variant { kind }), + kind: VariantItem(Variant { kind }), stability: get_stability(cx, self.def_id), deprecation: get_deprecation(cx, self.def_id), } @@ -2057,7 +2057,7 @@ impl Clean<Item> for doctree::Typedef<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false), + kind: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false), } } } @@ -2072,7 +2072,7 @@ impl Clean<Item> for doctree::OpaqueTy<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: OpaqueTyItem(OpaqueTy { + kind: OpaqueTyItem(OpaqueTy { bounds: self.opaque_ty.bounds.clean(cx), generics: self.opaque_ty.generics.clean(cx), }), @@ -2100,7 +2100,7 @@ impl Clean<Item> for doctree::Static<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: StaticItem(Static { + kind: StaticItem(Static { type_: self.type_.clean(cx), mutability: self.mutability, expr: print_const_expr(cx, self.expr), @@ -2121,7 +2121,7 @@ impl Clean<Item> for doctree::Constant<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: ConstantItem(Constant { + kind: ConstantItem(Constant { type_: self.type_.clean(cx), expr: print_const_expr(cx, self.expr), value: print_evaluated_const(cx, def_id.to_def_id()), @@ -2175,7 +2175,7 @@ impl Clean<Vec<Item>> for doctree::Impl<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner: ImplItem(Impl { + kind: ImplItem(Impl { unsafety: self.unsafety, generics: self.generics.clean(cx), provided_trait_methods: provided.clone(), @@ -2231,7 +2231,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> { visibility: self.vis.clean(cx), stability: None, deprecation: None, - inner: ExternCrateItem(self.name.clean(cx), self.path.clone()), + kind: ExternCrateItem(self.name.clean(cx), self.path.clone()), }] } } @@ -2302,7 +2302,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> { visibility: self.vis.clean(cx), stability: None, deprecation: None, - inner: ImportItem(Import::new_simple( + kind: ImportItem(Import::new_simple( self.name.clean(cx), resolve_use_source(cx, path), false, @@ -2322,14 +2322,14 @@ impl Clean<Vec<Item>> for doctree::Import<'_> { visibility: self.vis.clean(cx), stability: None, deprecation: None, - inner: ImportItem(inner), + kind: ImportItem(inner), }] } } impl Clean<Item> for doctree::ForeignItem<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { - let inner = match self.kind { + let kind = match self.kind { hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => { let abi = cx.tcx.hir().get_foreign_abi(self.id); let (generics, decl) = @@ -2364,7 +2364,7 @@ impl Clean<Item> for doctree::ForeignItem<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), - inner, + kind, } } } @@ -2380,7 +2380,7 @@ impl Clean<Item> for doctree::Macro<'_> { stability: cx.stability(self.hid), deprecation: cx.deprecation(self.hid).clean(cx), def_id: self.def_id, - inner: MacroItem(Macro { + kind: MacroItem(Macro { source: format!( "macro_rules! {} {{\n{}}}", name, @@ -2405,7 +2405,7 @@ impl Clean<Item> for doctree::ProcMacro<'_> { stability: cx.stability(self.id), deprecation: cx.deprecation(self.id).clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), - inner: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }), + kind: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }), } } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 32b3f69ecd4..3060cf79cd5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -41,7 +41,7 @@ use crate::formats::item_type::ItemType; use crate::html::render::cache::ExternalLocation; use self::FnRetTy::*; -use self::ItemEnum::*; +use self::ItemKind::*; use self::SelfTy::*; use self::Type::*; @@ -81,7 +81,7 @@ pub struct Item { /// Not everything has a name. E.g., impls pub name: Option<String>, pub attrs: Attributes, - pub inner: ItemEnum, + pub kind: ItemKind, pub visibility: Visibility, pub def_id: DefId, pub stability: Option<Stability>, @@ -90,14 +90,13 @@ pub struct Item { impl fmt::Debug for Item { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let fake = self.is_fake(); - let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id }; + let def_id: &dyn fmt::Debug = if self.is_fake() { &"**FAKE**" } else { &self.def_id }; fmt.debug_struct("Item") .field("source", &self.source) .field("name", &self.name) .field("attrs", &self.attrs) - .field("inner", &self.inner) + .field("kind", &self.kind) .field("visibility", &self.visibility) .field("def_id", def_id) .field("stability", &self.stability) @@ -124,7 +123,7 @@ impl Item { } pub fn is_crate(&self) -> bool { - match self.inner { + match self.kind { StrippedItem(box ModuleItem(Module { is_crate: true, .. })) | ModuleItem(Module { is_crate: true, .. }) => true, _ => false, @@ -176,14 +175,14 @@ impl Item { self.type_() == ItemType::Keyword } pub fn is_stripped(&self) -> bool { - match self.inner { + match self.kind { StrippedItem(..) => true, ImportItem(ref i) => !i.should_be_displayed, _ => false, } } pub fn has_stripped_fields(&self) -> Option<bool> { - match self.inner { + match self.kind { StructItem(ref _struct) => Some(_struct.fields_stripped), UnionItem(ref union) => Some(union.fields_stripped), VariantItem(Variant { kind: VariantKind::Struct(ref vstruct) }) => { @@ -227,8 +226,8 @@ impl Item { } pub fn is_default(&self) -> bool { - match self.inner { - ItemEnum::MethodItem(ref meth) => { + match self.kind { + ItemKind::MethodItem(ref meth) => { if let Some(defaultness) = meth.defaultness { defaultness.has_value() && !defaultness.is_final() } else { @@ -248,7 +247,7 @@ impl Item { } #[derive(Clone, Debug)] -pub enum ItemEnum { +pub enum ItemKind { ExternCrateItem(String, Option<String>), ImportItem(Import), StructItem(Struct), @@ -282,23 +281,23 @@ pub enum ItemEnum { AssocConstItem(Type, Option<String>), AssocTypeItem(Vec<GenericBound>, Option<Type>), /// An item that has been stripped by a rustdoc pass - StrippedItem(Box<ItemEnum>), + StrippedItem(Box<ItemKind>), KeywordItem(String), } -impl ItemEnum { +impl ItemKind { pub fn is_type_alias(&self) -> bool { match *self { - ItemEnum::TypedefItem(_, _) | ItemEnum::AssocTypeItem(_, _) => true, + ItemKind::TypedefItem(_, _) | ItemKind::AssocTypeItem(_, _) => true, _ => false, } } pub fn as_assoc_kind(&self) -> Option<AssocKind> { match *self { - ItemEnum::AssocConstItem(..) => Some(AssocKind::Const), - ItemEnum::AssocTypeItem(..) => Some(AssocKind::Type), - ItemEnum::TyMethodItem(..) | ItemEnum::MethodItem(..) => Some(AssocKind::Fn), + ItemKind::AssocConstItem(..) => Some(AssocKind::Const), + ItemKind::AssocTypeItem(..) => Some(AssocKind::Type), + ItemKind::TyMethodItem(..) | ItemKind::MethodItem(..) => Some(AssocKind::Fn), _ => None, } } @@ -681,7 +680,9 @@ impl Attributes { } Some(&(_, _, ExternalLocation::Remote(ref s))) => s.to_string(), Some(&(_, _, ExternalLocation::Unknown)) | None => String::from( - if UnstableFeatures::from_environment().is_nightly_build() { + // NOTE: intentionally doesn't pass crate name to avoid having + // different primitive links between crates + if UnstableFeatures::from_environment(None).is_nightly_build() { "https://doc.rust-lang.org/nightly" } else { "https://doc.rust-lang.org" diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index f6258221e32..e5fb656cbb9 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -2,7 +2,7 @@ use crate::clean::auto_trait::AutoTraitFinder; use crate::clean::blanket_impl::BlanketImplFinder; use crate::clean::{ inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg, - GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, Lifetime, + GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemKind, Lifetime, MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Type, TypeBinding, TypeKind, Visibility, WherePredicate, }; @@ -44,8 +44,8 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { let mut module = module.clean(cx); let mut masked_crates = FxHashSet::default(); - match module.inner { - ItemEnum::ModuleItem(ref module) => { + match module.kind { + ItemKind::ModuleItem(ref module) => { for it in &module.items { // `compiler_builtins` should be masked too, but we can't apply // `#[doc(masked)]` to the injected `extern crate` because it's unstable. @@ -62,8 +62,8 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx); { - let m = match module.inner { - ItemEnum::ModuleItem(ref mut m) => m, + let m = match module.kind { + ItemKind::ModuleItem(ref mut m) => m, _ => unreachable!(), }; m.items.extend(primitives.iter().map(|&(def_id, prim, ref attrs)| Item { @@ -74,7 +74,7 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { stability: get_stability(cx, def_id), deprecation: get_deprecation(cx, def_id), def_id, - inner: ItemEnum::PrimitiveItem(prim), + kind: ItemKind::PrimitiveItem(prim), })); m.items.extend(keywords.into_iter().map(|(def_id, kw, attrs)| Item { source: Span::empty(), @@ -84,7 +84,7 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { stability: get_stability(cx, def_id), deprecation: get_deprecation(cx, def_id), def_id, - inner: ItemEnum::KeywordItem(kw), + kind: ItemKind::KeywordItem(kw), })); } @@ -355,8 +355,8 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V let tcx = cx.tcx; for item in items { - let target = match item.inner { - ItemEnum::TypedefItem(ref t, true) => &t.type_, + let target = match item.kind { + ItemKind::TypedefItem(ref t, true) => &t.type_, _ => continue, }; let primitive = match *target { diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index c248d57a9dd..f0fc0dc6514 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -257,6 +257,7 @@ pub struct RenderOptions { pub document_private: bool, /// Document items that have `doc(hidden)`. pub document_hidden: bool, + pub unstable_features: rustc_feature::UnstableFeatures, } /// Temporary storage for data obtained during `RustdocVisitor::clean()`. @@ -299,7 +300,7 @@ impl Options { println_condition(p.condition); } - if nightly_options::is_nightly_build() { + if nightly_options::match_is_nightly_build(matches) { println!("\nPasses run with `--show-coverage`:"); for p in passes::COVERAGE_PASSES { print!("{:>20}", p.pass.name); @@ -483,6 +484,7 @@ impl Options { &matches.opt_strs("html-after-content"), &matches.opt_strs("markdown-before-content"), &matches.opt_strs("markdown-after-content"), + nightly_options::match_is_nightly_build(&matches), &diag, &mut id_map, edition, @@ -539,7 +541,9 @@ impl Options { let output_format = match matches.opt_str("output-format") { Some(s) => match OutputFormat::try_from(s.as_str()) { Ok(o) => { - if o.is_json() && !(show_coverage || nightly_options::is_nightly_build()) { + if o.is_json() + && !(show_coverage || nightly_options::match_is_nightly_build(matches)) + { diag.struct_err("json output format isn't supported for doc generation") .emit(); return Err(1); @@ -591,7 +595,6 @@ impl Options { Ok(Options { input, - crate_name, proc_macro_crate, error_format, libs, @@ -643,7 +646,11 @@ impl Options { generate_search_filter, document_private, document_hidden, + unstable_features: rustc_feature::UnstableFeatures::from_environment( + crate_name.as_deref(), + ), }, + crate_name, output_format, }) } @@ -661,7 +668,8 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han for flag in deprecated_flags.iter() { if matches.opt_present(flag) { if *flag == "output-format" - && (matches.opt_present("show-coverage") || nightly_options::is_nightly_build()) + && (matches.opt_present("show-coverage") + || nightly_options::match_is_nightly_build(matches)) { continue; } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 4cad6418d6a..14a2def1383 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -371,7 +371,7 @@ pub fn run_core( cg: codegen_options, externs, target_triple: target, - unstable_features: UnstableFeatures::from_environment(), + unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()), actually_rustdoc: true, debugging_opts, error_format, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index eb33890fb5f..5e40e6b151d 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1,7 +1,6 @@ use rustc_ast as ast; use rustc_data_structures::sync::Lrc; use rustc_errors::ErrorReported; -use rustc_feature::UnstableFeatures; use rustc_hir as hir; use rustc_hir::intravisit; use rustc_hir::{HirId, CRATE_HIR_ID}; @@ -70,7 +69,7 @@ pub fn run(options: Options) -> Result<(), ErrorReported> { lint_cap: Some(options.lint_cap.clone().unwrap_or_else(|| lint::Forbid)), cg: options.codegen_options.clone(), externs: options.externs.clone(), - unstable_features: UnstableFeatures::from_environment(), + unstable_features: options.render_options.unstable_features, actually_rustdoc: true, debugging_opts: config::DebuggingOptions { ..config::basic_debugging_options() }, edition: options.edition, diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index c8121d39d0f..900821dbf4a 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -1,6 +1,5 @@ use crate::html::markdown::{ErrorCodes, IdMap, Markdown, Playground}; use crate::rustc_span::edition::Edition; -use rustc_feature::UnstableFeatures; use std::fs; use std::path::Path; use std::str; @@ -25,12 +24,13 @@ impl ExternalHtml { after_content: &[String], md_before_content: &[String], md_after_content: &[String], + nightly_build: bool, diag: &rustc_errors::Handler, id_map: &mut IdMap, edition: Edition, playground: &Option<Playground>, ) -> Option<ExternalHtml> { - let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); + let codes = ErrorCodes::from(nightly_build); let ih = load_external_files(in_header, diag)?; let bc = load_external_files(before_content, diag)?; let m_bc = load_external_files(md_before_content, diag)?; diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index d4ada3278e6..694051aa54f 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -5,9 +5,9 @@ pub struct StripItem(pub Item); impl StripItem { pub fn strip(self) -> Option<Item> { match self.0 { - Item { inner: StrippedItem(..), .. } => Some(self.0), + Item { kind: StrippedItem(..), .. } => Some(self.0), mut i => { - i.inner = StrippedItem(box i.inner); + i.kind = StrippedItem(box i.kind); Some(i) } } @@ -20,8 +20,8 @@ pub trait DocFolder: Sized { } /// don't override! - fn fold_inner_recur(&mut self, inner: ItemEnum) -> ItemEnum { - match inner { + fn fold_inner_recur(&mut self, kind: ItemKind) -> ItemKind { + match kind { StrippedItem(..) => unreachable!(), ModuleItem(i) => ModuleItem(self.fold_mod(i)), StructItem(mut i) => { @@ -72,14 +72,14 @@ pub trait DocFolder: Sized { /// don't override! fn fold_item_recur(&mut self, item: Item) -> Option<Item> { - let Item { attrs, name, source, visibility, def_id, inner, stability, deprecation } = item; + let Item { attrs, name, source, visibility, def_id, kind, stability, deprecation } = item; - let inner = match inner { + let kind = match kind { StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)), - _ => self.fold_inner_recur(inner), + _ => self.fold_inner_recur(kind), }; - Some(Item { attrs, name, source, inner, visibility, stability, deprecation, def_id }) + Some(Item { attrs, name, source, kind, visibility, stability, deprecation, def_id }) } fn fold_mod(&mut self, m: Module) -> Module { diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index b99321e8484..277571b11f5 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -218,7 +218,7 @@ impl DocFolder for Cache { // If this is a stripped module, // we don't want it or its children in the search index. - let orig_stripped_mod = match item.inner { + let orig_stripped_mod = match item.kind { clean::StrippedItem(box clean::ModuleItem(..)) => { mem::replace(&mut self.stripped_mod, true) } @@ -227,7 +227,7 @@ impl DocFolder for Cache { // If the impl is from a masked crate or references something from a // masked crate then remove it completely. - if let clean::ImplItem(ref i) = item.inner { + if let clean::ImplItem(ref i) = item.kind { if self.masked_crates.contains(&item.def_id.krate) || i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) || i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) @@ -238,12 +238,12 @@ impl DocFolder for Cache { // Propagate a trait method's documentation to all implementors of the // trait. - if let clean::TraitItem(ref t) = item.inner { + if let clean::TraitItem(ref t) = item.kind { self.traits.entry(item.def_id).or_insert_with(|| t.clone()); } // Collect all the implementors of traits. - if let clean::ImplItem(ref i) = item.inner { + if let clean::ImplItem(ref i) = item.kind { if let Some(did) = i.trait_.def_id() { if i.blanket_impl.is_none() { self.implementors @@ -256,7 +256,7 @@ impl DocFolder for Cache { // Index this method for searching later on. if let Some(ref s) = item.name { - let (parent, is_inherent_impl_item) = match item.inner { + let (parent, is_inherent_impl_item) = match item.kind { clean::StrippedItem(..) => ((None, None), false), clean::AssocConstItem(..) | clean::TypedefItem(_, true) if self.parent_is_trait_impl => @@ -345,7 +345,7 @@ impl DocFolder for Cache { _ => false, }; - match item.inner { + match item.kind { clean::StructItem(..) | clean::EnumItem(..) | clean::TypedefItem(..) @@ -384,7 +384,7 @@ impl DocFolder for Cache { // Maintain the parent stack let orig_parent_is_trait_impl = self.parent_is_trait_impl; - let parent_pushed = match item.inner { + let parent_pushed = match item.kind { clean::TraitItem(..) | clean::EnumItem(..) | clean::ForeignTypeItem @@ -422,12 +422,12 @@ impl DocFolder for Cache { // Once we've recursively found all the generics, hoard off all the // implementations elsewhere. let ret = self.fold_item_recur(item).and_then(|item| { - if let clean::Item { inner: clean::ImplItem(_), .. } = item { + if let clean::Item { kind: clean::ImplItem(_), .. } = item { // Figure out the id of this impl. This may map to a // primitive rather than always to a struct/enum. // Note: matching twice to restrict the lifetime of the `i` borrow. let mut dids = FxHashSet::default(); - if let clean::Item { inner: clean::ImplItem(ref i), .. } = item { + if let clean::Item { kind: clean::ImplItem(ref i), .. } = item { match i.for_ { clean::ResolvedPath { did, .. } | clean::BorrowedRef { diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 696bdae94fc..a0f4502f750 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -60,12 +60,12 @@ impl Serialize for ItemType { impl<'a> From<&'a clean::Item> for ItemType { fn from(item: &'a clean::Item) -> ItemType { - let inner = match item.inner { + let kind = match item.kind { clean::StrippedItem(box ref item) => item, - ref inner => inner, + ref kind => kind, }; - match *inner { + match *kind { clean::ModuleItem(..) => ItemType::Module, clean::ExternCrateItem(..) => ItemType::ExternCrate, clean::ImportItem(..) => ItemType::Import, diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs index dcb0184c58c..b893d6c64ec 100644 --- a/src/librustdoc/formats/mod.rs +++ b/src/librustdoc/formats/mod.rs @@ -32,7 +32,7 @@ pub struct Impl { impl Impl { pub fn inner_impl(&self) -> &clean::Impl { - match self.impl_item.inner { + match self.impl_item.kind { clean::ImplItem(ref impl_) => impl_, _ => panic!("non-impl item found in impl"), } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 90ace4d44c4..273e2819257 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -86,7 +86,7 @@ pub fn run_format<T: FormatRenderer>( } cx.mod_item_in(&item, &name, &cache)?; - let module = match item.inner { + let module = match item.kind { clean::StrippedItem(box clean::ModuleItem(m)) | clean::ModuleItem(m) => m, _ => unreachable!(), }; diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index add28de17ed..0541bf118e1 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -165,7 +165,7 @@ pub fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { } crate fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> { - let (all_types, ret_types) = match item.inner { + let (all_types, ret_types) = match item.kind { clean::FunctionItem(ref f) => (&f.all_types, &f.ret_types), clean::MethodItem(ref m) => (&m.all_types, &m.ret_types), clean::TyMethodItem(ref m) => (&m.all_types, &m.ret_types), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 5ac0ffcfbf1..eebb07f0476 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -52,7 +52,6 @@ use rustc_ast_pretty::pprust; use rustc_attr::StabilityLevel; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_feature::UnstableFeatures; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Mutability; @@ -397,6 +396,7 @@ impl FormatRenderer for Context { resource_suffix, static_root_path, generate_search_filter, + unstable_features, .. } = options; @@ -466,7 +466,7 @@ impl FormatRenderer for Context { static_root_path, fs: DocFS::new(sender), edition, - codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()), + codes: ErrorCodes::from(unstable_features.is_nightly_build()), playground, }; @@ -618,7 +618,7 @@ impl FormatRenderer for Context { // Render sidebar-items.js used throughout this module. if !self.render_redirect_pages { - let module = match item.inner { + let module = match item.kind { clean::StrippedItem(box clean::ModuleItem(ref m)) | clean::ModuleItem(ref m) => m, _ => unreachable!(), }; @@ -1717,7 +1717,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) write!(buf, "</span>"); // out-of-band write!(buf, "<span class=\"in-band\">"); - let name = match item.inner { + let name = match item.kind { clean::ModuleItem(ref m) => { if m.is_crate { "Crate " @@ -1766,7 +1766,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) write!(buf, "</span></h1>"); // in-band - match item.inner { + match item.kind { clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items), clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => { item_function(buf, cx, item, f) @@ -2133,7 +2133,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: ); } - match myitem.inner { + match myitem.kind { clean::ExternCrateItem(ref name, ref src) => { use crate::html::format::anchor; @@ -2169,7 +2169,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: continue; } - let unsafety_flag = match myitem.inner { + let unsafety_flag = match myitem.kind { clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func) if func.header.unsafety == hir::Unsafety::Unsafe => { @@ -2582,7 +2582,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, } for (pos, m) in provided.iter().enumerate() { render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait); - match m.inner { + match m.kind { clean::MethodItem(ref inner) if !inner.generics.where_predicates.is_empty() => { write!(w, ",\n {{ ... }}\n"); } @@ -2958,7 +2958,7 @@ fn render_assoc_item( where_clause = WhereClause { gens: g, indent, end_newline } ) } - match item.inner { + match item.kind { clean::StrippedItem(..) => {} clean::TyMethodItem(ref m) => method(w, item, m.header, &m.generics, &m.decl, link, parent), clean::MethodItem(ref m) => method(w, item, m.header, &m.generics, &m.decl, link, parent), @@ -2994,7 +2994,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct let mut fields = s .fields .iter() - .filter_map(|f| match f.inner { + .filter_map(|f| match f.kind { clean::StructFieldItem(ref ty) => Some((f, ty)), _ => None, }) @@ -3044,7 +3044,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union, let mut fields = s .fields .iter() - .filter_map(|f| match f.inner { + .filter_map(|f| match f.kind { clean::StructFieldItem(ref ty) => Some((f, ty)), _ => None, }) @@ -3097,7 +3097,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca for v in &e.variants { write!(w, " "); let name = v.name.as_ref().unwrap(); - match v.inner { + match v.kind { clean::VariantItem(ref var) => match var.kind { clean::VariantKind::CLike => write!(w, "{}", name), clean::VariantKind::Tuple(ref tys) => { @@ -3147,7 +3147,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca id = id, name = variant.name.as_ref().unwrap() ); - if let clean::VariantItem(ref var) = variant.inner { + if let clean::VariantItem(ref var) = variant.kind { if let clean::VariantKind::Tuple(ref tys) = var.kind { write!(w, "("); for (i, ty) in tys.iter().enumerate() { @@ -3164,8 +3164,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca document_non_exhaustive(w, variant); use crate::clean::{Variant, VariantKind}; - if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = variant.inner - { + if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = variant.kind { let variant_id = cx.derive_id(format!( "{}.{}.fields", ItemType::Variant, @@ -3179,7 +3178,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca ); for field in &s.fields { use crate::clean::StructFieldItem; - if let StructFieldItem(ref ty) = field.inner { + if let StructFieldItem(ref ty) = field.kind { let id = cx.derive_id(format!( "variant.{}.field.{}", variant.name.as_ref().unwrap(), @@ -3275,7 +3274,7 @@ fn render_struct( let mut has_visible_fields = false; write!(w, " {{"); for field in fields { - if let clean::StructFieldItem(ref ty) = field.inner { + if let clean::StructFieldItem(ref ty) = field.kind { write!( w, "\n{} {}{}: {},", @@ -3306,7 +3305,7 @@ fn render_struct( if i > 0 { write!(w, ", "); } - match field.inner { + match field.kind { clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"), clean::StructFieldItem(ref ty) => { write!(w, "{}{}", field.visibility.print_with_space(), ty.print()) @@ -3352,7 +3351,7 @@ fn render_union( write!(w, " {{\n{}", tab); for field in fields { - if let clean::StructFieldItem(ref ty) = field.inner { + if let clean::StructFieldItem(ref ty) = field.kind { write!( w, " {}{}: {},\n{}", @@ -3516,7 +3515,7 @@ fn render_deref_methods( .inner_impl() .items .iter() - .find_map(|item| match item.inner { + .find_map(|item| match item.kind { clean::TypedefItem(ref t, true) => Some(match *t { clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), _ => (&t.type_, &t.type_), @@ -3538,7 +3537,7 @@ fn render_deref_methods( } fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool { - let self_type_opt = match item.inner { + let self_type_opt = match item.kind { clean::MethodItem(ref method) => method.decl.self_type(), clean::TyMethodItem(ref method) => method.decl.self_type(), _ => None, @@ -3589,7 +3588,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String { )); let t_did = impl_.trait_.def_id().unwrap(); for it in &impl_.items { - if let clean::TypedefItem(ref tydef, _) = it.inner { + if let clean::TypedefItem(ref tydef, _) = it.kind { out.push_str("<span class=\"where fmt-newline\"> "); assoc_type( &mut out, @@ -3657,7 +3656,7 @@ fn render_impl( fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute); if show_def_docs { for it in &i.inner_impl().items { - if let clean::TypedefItem(ref tydef, _) = it.inner { + if let clean::TypedefItem(ref tydef, _) = it.kind { write!(w, "<span class=\"where fmt-newline\"> "); assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None), ""); write!(w, ";</span>"); @@ -3728,14 +3727,14 @@ fn render_impl( }; let (is_hidden, extra_class) = - if (trait_.is_none() || item.doc_value().is_some() || item.inner.is_type_alias()) + if (trait_.is_none() || item.doc_value().is_some() || item.kind.is_type_alias()) && !is_default_item { (false, "") } else { (true, " hidden") }; - match item.inner { + match item.kind { clean::MethodItem(clean::Method { .. }) | clean::TyMethodItem(clean::TyMethod { .. }) => { // Only render when the method is not static or we allow static methods @@ -4000,7 +3999,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca write!( buffer, "<p class=\"location\">{}{}</p>", - match it.inner { + match it.kind { clean::StructItem(..) => "Struct ", clean::TraitItem(..) => "Trait ", clean::PrimitiveItem(..) => "Primitive Type ", @@ -4040,7 +4039,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca it.name.as_ref().expect("crates always have a name") ); } - match it.inner { + match it.kind { clean::StructItem(ref s) => sidebar_struct(buffer, it, s), clean::TraitItem(ref t) => sidebar_trait(buffer, it, t), clean::PrimitiveItem(_) => sidebar_primitive(buffer, it), @@ -4180,7 +4179,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { if let Some((target, real_target)) = - impl_.inner_impl().items.iter().find_map(|item| match item.inner { + impl_.inner_impl().items.iter().find_map(|item| match item.kind { clean::TypedefItem(ref t, true) => Some(match *t { clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), _ => (&t.type_, &t.type_), @@ -4319,8 +4318,8 @@ fn get_id_for_impl_on_foreign_type(for_: &clean::Type, trait_: &clean::Type) -> } fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> { - match item.inner { - clean::ItemEnum::ImplItem(ref i) => { + match item.kind { + clean::ItemKind::ImplItem(ref i) => { if let Some(ref trait_) = i.trait_ { Some(( format!("{:#}", i.for_.print()), @@ -4470,7 +4469,7 @@ fn sidebar_typedef(buf: &mut Buffer, it: &clean::Item) { fn get_struct_fields_name(fields: &[clean::Item]) -> String { let mut fields = fields .iter() - .filter(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) + .filter(|f| if let clean::StructFieldItem(..) = f.kind { true } else { false }) .filter_map(|f| match f.name { Some(ref name) => { Some(format!("<a href=\"#structfield.{name}\">{name}</a>", name = name)) diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 3a87e1c46a6..33bd57223b8 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -2,7 +2,6 @@ use std::fs::{create_dir_all, read_to_string, File}; use std::io::prelude::*; use std::path::Path; -use rustc_feature::UnstableFeatures; use rustc_span::edition::Edition; use rustc_span::source_map::DUMMY_SP; @@ -66,7 +65,7 @@ pub fn render<P: AsRef<Path>>( let title = metadata[0]; let mut ids = IdMap::new(); - let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); + let error_codes = ErrorCodes::from(options.unstable_features.is_nightly_build()); let text = if !options.markdown_no_toc { MarkdownWithToc(text, &mut ids, error_codes, edition, &playground).into_string() } else { @@ -131,7 +130,7 @@ pub fn test(mut options: Options) -> Result<(), String> { options.enable_per_target_ignores, ); collector.set_position(DUMMY_SP); - let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); + let codes = ErrorCodes::from(options.render_options.unstable_features.is_nightly_build()); find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None); diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index ced26fcf5b0..ef68bae1078 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -187,7 +187,7 @@ impl<'a, 'b> CoverageCalculator<'a, 'b> { impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> { - match i.inner { + match i.kind { _ if !i.def_id.is_local() => { // non-local items are skipped because they can be out of the users control, // especially in the case of trait impls, which rustdoc eagerly inlines diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index e0cb5bf1a4e..fd0dd339abd 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -671,7 +671,7 @@ fn resolve_associated_trait_item( let implicit_impls = crate::clean::get_auto_trait_and_blanket_impls(cx, ty, did); let mut candidates: Vec<_> = implicit_impls .flat_map(|impl_outer| { - match impl_outer.inner { + match impl_outer.kind { clean::ImplItem(impl_) => { debug!("considering auto or blanket impl for trait {:?}", impl_.trait_); // Give precedence to methods that were overridden @@ -681,14 +681,14 @@ fn resolve_associated_trait_item( return None; } let kind = assoc - .inner + .kind .as_assoc_kind() .expect("inner items for a trait should be associated items"); if kind.namespace() != ns { return None; } - trace!("considering associated item {:?}", assoc.inner); + trace!("considering associated item {:?}", assoc.kind); // We have a slight issue: normal methods come from `clean` types, // but provided methods come directly from `tcx`. // Fortunately, we don't need the whole method, we just need to know @@ -832,7 +832,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id); } - let current_item = match item.inner { + let current_item = match item.kind { clean::ModuleItem(..) => { if item.attrs.inner_docs { if item.def_id.is_top_level_module() { item.name.clone() } else { None } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 5eb3f98b123..81de0730247 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -55,11 +55,11 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { // scan through included items ahead of time to splice in Deref targets to the "valid" sets for it in &new_items { - if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = it.inner { + if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = it.kind { if cleaner.keep_item(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() { let target = items .iter() - .find_map(|item| match item.inner { + .find_map(|item| match item.kind { TypedefItem(ref t, true) => Some(&t.type_), _ => None, }) @@ -75,7 +75,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { } new_items.retain(|it| { - if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = it.inner { + if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = it.kind { cleaner.keep_item(for_) || trait_.as_ref().map_or(false, |t| cleaner.keep_item(t)) || blanket_impl.is_some() @@ -96,7 +96,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { } if let Some(ref mut it) = krate.module { - if let ModuleItem(Module { ref mut items, .. }) = it.inner { + if let ModuleItem(Module { ref mut items, .. }) = it.kind { items.extend(synth.impls); items.extend(new_items); } else { diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index 686ec51fb06..094f85f2ccb 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -58,7 +58,7 @@ impl crate::doctest::Tester for Tests { } pub fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool { - if matches!(item.inner, + if matches!(item.kind, clean::StructFieldItem(_) | clean::VariantItem(_) | clean::AssocConstItem(_, _) @@ -92,9 +92,7 @@ pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { find_testable_code(&dox, &mut tests, ErrorCodes::No, false, None); - if tests.found_tests == 0 - && rustc_feature::UnstableFeatures::from_environment().is_nightly_build() - { + if tests.found_tests == 0 && cx.tcx.sess.is_nightly_build() { if should_have_doc_example(cx, &item) { debug!("reporting error for {:?} (hir_id={:?})", item, hir_id); let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span()); diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs index 1d9be619ec9..26b64b4905e 100644 --- a/src/librustdoc/passes/html_tags.rs +++ b/src/librustdoc/passes/html_tags.rs @@ -5,7 +5,6 @@ use crate::fold::DocFolder; use crate::html::markdown::opts; use core::ops::Range; use pulldown_cmark::{Event, Parser}; -use rustc_feature::UnstableFeatures; use rustc_session::lint; use std::iter::Peekable; use std::str::CharIndices; @@ -27,7 +26,7 @@ impl<'a, 'tcx> InvalidHtmlTagsLinter<'a, 'tcx> { } pub fn check_invalid_html_tags(krate: Crate, cx: &DocContext<'_>) -> Crate { - if !UnstableFeatures::from_environment().is_nightly_build() { + if !cx.tcx.sess.is_nightly_build() { krate } else { let mut coll = InvalidHtmlTagsLinter::new(cx); diff --git a/src/librustdoc/passes/non_autolinks.rs b/src/librustdoc/passes/non_autolinks.rs index 4a8fc7fc618..964773dc055 100644 --- a/src/librustdoc/passes/non_autolinks.rs +++ b/src/librustdoc/passes/non_autolinks.rs @@ -7,7 +7,6 @@ use core::ops::Range; use pulldown_cmark::{Event, LinkType, Parser, Tag}; use regex::Regex; use rustc_errors::Applicability; -use rustc_feature::UnstableFeatures; use rustc_session::lint; pub const CHECK_NON_AUTOLINKS: Pass = Pass { @@ -54,7 +53,7 @@ impl<'a, 'tcx> NonAutolinksLinter<'a, 'tcx> { } pub fn check_non_autolinks(krate: Crate, cx: &DocContext<'_>) -> Crate { - if !UnstableFeatures::from_environment().is_nightly_build() { + if !cx.tcx.sess.is_nightly_build() { krate } else { let mut coll = NonAutolinksLinter::new(cx); diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index f82e72b488b..4b9e150eb1e 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -41,7 +41,7 @@ impl<'a> DocFolder for Stripper<'a> { if i.attrs.lists(sym::doc).has_word(sym::hidden) { debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name); // use a dedicated hidden item for given item type if any - match i.inner { + match i.kind { clean::StructFieldItem(..) | clean::ModuleItem(..) => { // We need to recurse into stripped modules to // strip things like impl methods but when doing so diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 9b4f62235f5..4250c2b48fc 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -13,7 +13,7 @@ pub struct Stripper<'a> { impl<'a> DocFolder for Stripper<'a> { fn fold_item(&mut self, i: Item) -> Option<Item> { - match i.inner { + match i.kind { clean::StrippedItem(..) => { // We need to recurse into stripped modules to strip things // like impl methods but when doing so we must not add any @@ -86,7 +86,7 @@ impl<'a> DocFolder for Stripper<'a> { clean::KeywordItem(..) => {} } - let fastreturn = match i.inner { + let fastreturn = match i.kind { // nothing left to do for traits (don't want to filter their // methods out, visibility controlled by the trait) clean::TraitItem(..) => true, @@ -123,7 +123,7 @@ pub struct ImplStripper<'a> { impl<'a> DocFolder for ImplStripper<'a> { fn fold_item(&mut self, i: Item) -> Option<Item> { - if let clean::ImplItem(ref imp) = i.inner { + if let clean::ImplItem(ref imp) = i.kind { // emptied none trait impls can be stripped if imp.trait_.is_none() && imp.items.is_empty() { return None; @@ -162,7 +162,7 @@ pub struct ImportStripper; impl DocFolder for ImportStripper { fn fold_item(&mut self, i: Item) -> Option<Item> { - match i.inner { + match i.kind { clean::ExternCrateItem(..) | clean::ImportItem(..) if i.visibility != clean::Public => { None } diff --git a/src/test/ui/cross/cross-file-errors/main.rs b/src/test/ui/cross/cross-file-errors/main.rs index 74e9461803c..1902ab94d4c 100644 --- a/src/test/ui/cross/cross-file-errors/main.rs +++ b/src/test/ui/cross/cross-file-errors/main.rs @@ -3,5 +3,6 @@ mod underscore; fn main() { underscore!(); - //~^ ERROR expected expression, found reserved identifier `_` + //~^ ERROR `_` can only be used on the left-hand side of an assignment + //~| ERROR destructuring assignments are unstable } diff --git a/src/test/ui/cross/cross-file-errors/main.stderr b/src/test/ui/cross/cross-file-errors/main.stderr index f9101d8a583..b8658745060 100644 --- a/src/test/ui/cross/cross-file-errors/main.stderr +++ b/src/test/ui/cross/cross-file-errors/main.stderr @@ -1,15 +1,31 @@ -error: expected expression, found reserved identifier `_` +error[E0658]: destructuring assignments are unstable --> $DIR/underscore.rs:8:9 | LL | _ - | ^ expected expression + | ^ | ::: $DIR/main.rs:5:5 | LL | underscore!(); | -------------- in this macro invocation | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/underscore.rs:8:9 + | +LL | _ + | ^ `_` not allowed here + | + ::: $DIR/main.rs:5:5 + | +LL | underscore!(); + | -------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/destructuring-assignment/nested_destructure.rs b/src/test/ui/destructuring-assignment/nested_destructure.rs index 393dfc16c0a..0d45ff7da72 100644 --- a/src/test/ui/destructuring-assignment/nested_destructure.rs +++ b/src/test/ui/destructuring-assignment/nested_destructure.rs @@ -14,4 +14,7 @@ fn main() { Struct { a: TupleStruct((a, b), c), b: [d] } = Struct { a: TupleStruct((0, 1), 2), b: [3] }; assert_eq!((a, b, c, d), (0, 1, 2, 3)); + + // unnested underscore: just discard + _ = 1; } diff --git a/src/test/ui/destructuring-assignment/slice_destructure.rs b/src/test/ui/destructuring-assignment/slice_destructure.rs index 3dd10aff19c..76cdc1260fc 100644 --- a/src/test/ui/destructuring-assignment/slice_destructure.rs +++ b/src/test/ui/destructuring-assignment/slice_destructure.rs @@ -9,6 +9,8 @@ fn main() { let mut c; [a, .., b, c] = [1, 2, 3, 4, 5]; assert_eq!((a, b, c), (1, 4, 5)); + [_, a, _] = [1, 2, 3]; + assert_eq!((a, b), (2, 4)); [..] = [1, 2, 3]; [c, ..] = [5, 6, 6]; assert_eq!(c, 5); diff --git a/src/test/ui/destructuring-assignment/slice_destructure_fail.rs b/src/test/ui/destructuring-assignment/slice_destructure_fail.rs index f636ea3511c..90d93892f7f 100644 --- a/src/test/ui/destructuring-assignment/slice_destructure_fail.rs +++ b/src/test/ui/destructuring-assignment/slice_destructure_fail.rs @@ -4,4 +4,5 @@ fn main() { let (mut a, mut b); [a, .., b, ..] = [0, 1]; //~ ERROR `..` can only be used once per slice pattern [a, a, b] = [1, 2]; //~ ERROR pattern requires 3 elements but array has 2 + [_] = [1, 2]; //~ ERROR pattern requires 1 element but array has 2 } diff --git a/src/test/ui/destructuring-assignment/slice_destructure_fail.stderr b/src/test/ui/destructuring-assignment/slice_destructure_fail.stderr index 728687deb8b..cc412c72df5 100644 --- a/src/test/ui/destructuring-assignment/slice_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/slice_destructure_fail.stderr @@ -12,6 +12,12 @@ error[E0527]: pattern requires 3 elements but array has 2 LL | [a, a, b] = [1, 2]; | ^^^^^^^^^ expected 2 elements -error: aborting due to 2 previous errors +error[E0527]: pattern requires 1 element but array has 2 + --> $DIR/slice_destructure_fail.rs:7:3 + | +LL | [_] = [1, 2]; + | ^^^ expected 2 elements + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0527`. diff --git a/src/test/ui/destructuring-assignment/struct_destructure.rs b/src/test/ui/destructuring-assignment/struct_destructure.rs index b3a96ee1573..2bcbd9d0d74 100644 --- a/src/test/ui/destructuring-assignment/struct_destructure.rs +++ b/src/test/ui/destructuring-assignment/struct_destructure.rs @@ -12,8 +12,10 @@ fn main() { assert_eq!((a, b), (0, 1)); Struct { a: b, b: a } = Struct { a: 1, b: 2 }; assert_eq!((a,b), (2, 1)); + Struct { a: _, b } = Struct { a: 1, b: 2 }; + assert_eq!((a, b), (2, 2)); Struct { a, .. } = Struct { a: 1, b: 3 }; - assert_eq!((a, b), (1, 1)); + assert_eq!((a, b), (1, 2)); Struct { .. } = Struct { a: 1, b: 4 }; - assert_eq!((a, b), (1, 1)); + assert_eq!((a, b), (1, 2)); } diff --git a/src/test/ui/destructuring-assignment/struct_destructure_fail.rs b/src/test/ui/destructuring-assignment/struct_destructure_fail.rs index c22695ed388..4aa327b61f4 100644 --- a/src/test/ui/destructuring-assignment/struct_destructure_fail.rs +++ b/src/test/ui/destructuring-assignment/struct_destructure_fail.rs @@ -9,6 +9,8 @@ fn main() { let mut c; let d = Struct { a: 0, b: 1 }; Struct { a, b, c } = Struct { a: 0, b: 1 }; //~ ERROR does not have a field named `c` + Struct { a, _ } = Struct { a: 1, b: 2 }; //~ ERROR pattern does not mention field `b` + //~| ERROR expected identifier, found reserved identifier `_` Struct { a, ..d } = Struct { a: 1, b: 2 }; //~^ ERROR functional record updates are not allowed in destructuring assignments Struct { a, .. }; //~ ERROR base expression required after `..` diff --git a/src/test/ui/destructuring-assignment/struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/struct_destructure_fail.stderr index 4da4698804f..81661a357e7 100644 --- a/src/test/ui/destructuring-assignment/struct_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/struct_destructure_fail.stderr @@ -1,11 +1,19 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/struct_destructure_fail.rs:12:17 + | +LL | Struct { a, _ } = Struct { a: 1, b: 2 }; + | ------ ^ expected identifier, found reserved identifier + | | + | while parsing this struct + error: functional record updates are not allowed in destructuring assignments - --> $DIR/struct_destructure_fail.rs:12:19 + --> $DIR/struct_destructure_fail.rs:14:19 | LL | Struct { a, ..d } = Struct { a: 1, b: 2 }; | ^ help: consider removing the trailing pattern error: base expression required after `..` - --> $DIR/struct_destructure_fail.rs:14:19 + --> $DIR/struct_destructure_fail.rs:16:19 | LL | Struct { a, .. }; | ^ add a base expression here @@ -16,6 +24,22 @@ error[E0026]: struct `Struct` does not have a field named `c` LL | Struct { a, b, c } = Struct { a: 0, b: 1 }; | ^ struct `Struct` does not have this field -error: aborting due to 3 previous errors +error[E0027]: pattern does not mention field `b` + --> $DIR/struct_destructure_fail.rs:12:5 + | +LL | Struct { a, _ } = Struct { a: 1, b: 2 }; + | ^^^^^^^^^^^^^^^ missing field `b` + | +help: include the missing field in the pattern + | +LL | Struct { a, b, _ } = Struct { a: 1, b: 2 }; + | ^^^ +help: if you don't care about this missing field, you can explicitly ignore it + | +LL | Struct { a, .., _ } = Struct { a: 1, b: 2 }; + | ^^^^ + +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0026`. +Some errors have detailed explanations: E0026, E0027. +For more information about an error, try `rustc --explain E0026`. diff --git a/src/test/ui/destructuring-assignment/tuple_destructure.rs b/src/test/ui/destructuring-assignment/tuple_destructure.rs index 16aafc4693f..2096182d421 100644 --- a/src/test/ui/destructuring-assignment/tuple_destructure.rs +++ b/src/test/ui/destructuring-assignment/tuple_destructure.rs @@ -16,6 +16,8 @@ fn main() { assert_eq!((a, b), (2, 2)); (b, ..) = (5, 6, 7); assert_eq!(b, 5); + (a, _) = (8, 9); + assert_eq!(a, 8); // Test for a non-Copy type (String): let (mut c, mut d); diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs b/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs index b76f4968e62..5524e91dc40 100644 --- a/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs +++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs @@ -7,4 +7,5 @@ fn main() { (a, .., b, ..) = (0, 1); //~ ERROR `..` can only be used once per tuple pattern (a, a, b) = (1, 2); //~ ERROR mismatched types (C, ..) = (0,1); //~ ERROR invalid left-hand side of assignment + (_,) = (1, 2); //~ ERROR mismatched types } diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr index a60e1cb1eec..1146b88278d 100644 --- a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr @@ -25,7 +25,18 @@ LL | (C, ..) = (0,1); | | | cannot assign to this expression -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/tuple_destructure_fail.rs:10:5 + | +LL | (_,) = (1, 2); + | ^^^^ ------ this expression has type `({integer}, {integer})` + | | + | expected a tuple with 2 elements, found one with 1 element + | + = note: expected type `({integer}, {integer})` + found tuple `(_,)` + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0070, E0308. For more information about an error, try `rustc --explain E0070`. diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure.rs b/src/test/ui/destructuring-assignment/tuple_struct_destructure.rs index 106a9b16db4..7b5c5ad2bae 100644 --- a/src/test/ui/destructuring-assignment/tuple_struct_destructure.rs +++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure.rs @@ -23,8 +23,10 @@ fn main() { assert_eq!((a, b), (0, 1)); TupleStruct(a, .., b) = TupleStruct(1, 2); assert_eq!((a, b), (1, 2)); + TupleStruct(_, a) = TupleStruct(2, 2); + assert_eq!((a, b), (2, 2)); TupleStruct(..) = TupleStruct(3, 4); - assert_eq!((a, b), (1, 2)); + assert_eq!((a, b), (2, 2)); TupleStruct(5,6).assign(&mut a, &mut b); assert_eq!((a, b), (5, 6)); Enum::SingleVariant(a, b) = Enum::SingleVariant(7, 8); diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs index 61ae42a5175..c39db061177 100644 --- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs +++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs @@ -29,8 +29,12 @@ fn main() { TupleStruct(a, a, b) = TupleStruct(1, 2); //~^ ERROR this pattern has 3 fields, but the corresponding tuple struct has 2 fields + TupleStruct(_) = TupleStruct(1, 2); + //~^ ERROR this pattern has 1 field, but the corresponding tuple struct has 2 fields Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2); //~^ ERROR this pattern has 3 fields, but the corresponding tuple variant has 2 fields + Enum::SingleVariant(_) = Enum::SingleVariant(1, 2); + //~^ ERROR this pattern has 1 field, but the corresponding tuple variant has 2 fields // Check if `test` is recognized as not a tuple struct but a function call: test() = TupleStruct(0, 0); diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr index 863eedecf76..0e7174e5b19 100644 --- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr @@ -23,17 +23,35 @@ LL | struct TupleStruct<S, T>(S, T); LL | TupleStruct(a, a, b) = TupleStruct(1, 2); | ^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3 -error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields +error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields --> $DIR/tuple_struct_destructure_fail.rs:32:5 | +LL | struct TupleStruct<S, T>(S, T); + | ------------------------------- tuple struct defined here +... +LL | TupleStruct(_) = TupleStruct(1, 2); + | ^^^^^^^^^^^^^^ expected 2 fields, found 1 + +error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields + --> $DIR/tuple_struct_destructure_fail.rs:34:5 + | LL | SingleVariant(S, T) | ------------------- tuple variant defined here ... LL | Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3 +error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields + --> $DIR/tuple_struct_destructure_fail.rs:36:5 + | +LL | SingleVariant(S, T) + | ------------------- tuple variant defined here +... +LL | Enum::SingleVariant(_) = Enum::SingleVariant(1, 2); + | ^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 1 + error[E0070]: invalid left-hand side of assignment - --> $DIR/tuple_struct_destructure_fail.rs:36:12 + --> $DIR/tuple_struct_destructure_fail.rs:40:12 | LL | test() = TupleStruct(0, 0); | ------ ^ @@ -41,7 +59,7 @@ LL | test() = TupleStruct(0, 0); | cannot assign to this expression error[E0070]: invalid left-hand side of assignment - --> $DIR/tuple_struct_destructure_fail.rs:38:14 + --> $DIR/tuple_struct_destructure_fail.rs:42:14 | LL | (test)() = TupleStruct(0, 0); | -------- ^ @@ -49,14 +67,14 @@ LL | (test)() = TupleStruct(0, 0); | cannot assign to this expression error[E0070]: invalid left-hand side of assignment - --> $DIR/tuple_struct_destructure_fail.rs:40:38 + --> $DIR/tuple_struct_destructure_fail.rs:44:38 | LL | <Alias::<isize> as Test>::test() = TupleStruct(0, 0); | -------------------------------- ^ | | | cannot assign to this expression -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0023, E0070. For more information about an error, try `rustc --explain E0023`. diff --git a/src/test/ui/destructuring-assignment/underscore-range-expr-gating.rs b/src/test/ui/destructuring-assignment/underscore-range-expr-gating.rs index b41f2f52a3d..4ed4f56702c 100644 --- a/src/test/ui/destructuring-assignment/underscore-range-expr-gating.rs +++ b/src/test/ui/destructuring-assignment/underscore-range-expr-gating.rs @@ -4,5 +4,7 @@ struct S { x : u32 } #[cfg(FALSE)] fn foo() { + _; //~ ERROR destructuring assignments are unstable + S { x: 5, .. }; //~ ERROR destructuring assignments are unstable } diff --git a/src/test/ui/destructuring-assignment/underscore-range-expr-gating.stderr b/src/test/ui/destructuring-assignment/underscore-range-expr-gating.stderr index 442e36cd306..a5ed761a01c 100644 --- a/src/test/ui/destructuring-assignment/underscore-range-expr-gating.stderr +++ b/src/test/ui/destructuring-assignment/underscore-range-expr-gating.stderr @@ -1,5 +1,14 @@ error[E0658]: destructuring assignments are unstable - --> $DIR/underscore-range-expr-gating.rs:7:15 + --> $DIR/underscore-range-expr-gating.rs:7:5 + | +LL | _; + | ^ + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error[E0658]: destructuring assignments are unstable + --> $DIR/underscore-range-expr-gating.rs:9:15 | LL | S { x: 5, .. }; | ^^ @@ -7,6 +16,6 @@ LL | S { x: 5, .. }; = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs index a8ea3faefe8..00638e04f5d 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs +++ b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs @@ -8,12 +8,18 @@ trait T { fn main() { let _: usize = foo(_, _); - //~^ ERROR expected expression - //~| ERROR expected expression + //~^ ERROR `_` can only be used on the left-hand side of an assignment + //~| ERROR `_` can only be used on the left-hand side of an assignment + //~| ERROR destructuring assignments are unstable + //~| ERROR destructuring assignments are unstable let _: S = S(_, _); - //~^ ERROR expected expression - //~| ERROR expected expression + //~^ ERROR `_` can only be used on the left-hand side of an assignment + //~| ERROR `_` can only be used on the left-hand side of an assignment + //~| ERROR destructuring assignments are unstable + //~| ERROR destructuring assignments are unstable let _: usize = T::baz(_, _); - //~^ ERROR expected expression - //~| ERROR expected expression + //~^ ERROR `_` can only be used on the left-hand side of an assignment + //~| ERROR `_` can only be used on the left-hand side of an assignment + //~| ERROR destructuring assignments are unstable + //~| ERROR destructuring assignments are unstable } diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr index a6d1c4b859f..248fa6b9c9c 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr +++ b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr @@ -1,38 +1,93 @@ -error: expected expression, found reserved identifier `_` +error[E0658]: destructuring assignments are unstable --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24 | LL | let _: usize = foo(_, _); - | ^ expected expression + | ^ + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error[E0658]: destructuring assignments are unstable + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:27 + | +LL | let _: usize = foo(_, _); + | ^ + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error[E0658]: destructuring assignments are unstable + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:18 + | +LL | let _: S = S(_, _); + | ^ + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error[E0658]: destructuring assignments are unstable + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:21 + | +LL | let _: S = S(_, _); + | ^ + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error[E0658]: destructuring assignments are unstable + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:27 + | +LL | let _: usize = T::baz(_, _); + | ^ + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error[E0658]: destructuring assignments are unstable + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:30 + | +LL | let _: usize = T::baz(_, _); + | ^ + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24 + | +LL | let _: usize = foo(_, _); + | ^ `_` not allowed here -error: expected expression, found reserved identifier `_` +error: in expressions, `_` can only be used on the left-hand side of an assignment --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:27 | LL | let _: usize = foo(_, _); - | ^ expected expression + | ^ `_` not allowed here -error: expected expression, found reserved identifier `_` - --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:18 +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:18 | LL | let _: S = S(_, _); - | ^ expected expression + | ^ `_` not allowed here -error: expected expression, found reserved identifier `_` - --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:21 +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:21 | LL | let _: S = S(_, _); - | ^ expected expression + | ^ `_` not allowed here -error: expected expression, found reserved identifier `_` - --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:27 +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:27 | LL | let _: usize = T::baz(_, _); - | ^ expected expression + | ^ `_` not allowed here -error: expected expression, found reserved identifier `_` - --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:30 +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:30 | LL | let _: usize = T::baz(_, _); - | ^ expected expression + | ^ `_` not allowed here -error: aborting due to 6 previous errors +error: aborting due to 12 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/src/tools/clippy/clippy_lints/src/utils/sugg.rs b/src/tools/clippy/clippy_lints/src/utils/sugg.rs index 625120b880e..1fcd41e4dbf 100644 --- a/src/tools/clippy/clippy_lints/src/utils/sugg.rs +++ b/src/tools/clippy/clippy_lints/src/utils/sugg.rs @@ -170,6 +170,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::MacCall(..) | ast::ExprKind::MethodCall(..) | ast::ExprKind::Paren(..) + | ast::ExprKind::Underscore | ast::ExprKind::Path(..) | ast::ExprKind::Repeat(..) | ast::ExprKind::Ret(..) diff --git a/src/tools/rustfmt b/src/tools/rustfmt -Subproject 0f29ff6da0c5ff622e739beb8fc3bbe77119b3c +Subproject 293d7d01118c9fb5479649399e1dae60322b8e0 |
