From e8de4c3b1f0ab51fe3ea0a494cf9727ee3e0bf1d Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Sat, 23 Mar 2019 17:00:04 +1000 Subject: [PATCH 01/10] Fix invalid DWARF for enums when using thinlto We were setting the same identifier for both the DW_TAG_structure_type and the DW_TAG_variant_part. This becomes a problem when using thinlto becauses it uses the identifier as a key for a map of types that is used to delete duplicates based on the ODR, so one of them is deleted as a duplicate, resulting in invalid DWARF. The DW_TAG_variant_part isn't a standalone type, so it doesn't need an identifier. Fix by omitting its identifier. --- .../debuginfo/metadata.rs | 20 +++++--- src/librustc_codegen_llvm/llvm/ffi.rs | 3 +- src/rustllvm/RustWrapper.cpp | 4 +- src/test/debuginfo/enum-thinlto.rs | 48 +++++++++++++++++++ 4 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 src/test/debuginfo/enum-thinlto.rs diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index ddcbf29da832b..1859b1f4792e1 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -266,6 +266,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> { // ... and attach them to the stub to complete it. set_members_of_composite_type(cx, unfinished_type, + metadata_stub, member_holding_stub, member_descriptions); return MetadataCreationResult::new(metadata_stub, true); @@ -1215,6 +1216,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { set_members_of_composite_type(cx, self.enum_type, variant_type_metadata, + variant_type_metadata, member_descriptions); vec![ MemberDescription { @@ -1256,6 +1258,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { set_members_of_composite_type(cx, self.enum_type, variant_type_metadata, + variant_type_metadata, member_descriptions); MemberDescription { name: if fallback { @@ -1298,6 +1301,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { set_members_of_composite_type(cx, self.enum_type, variant_type_metadata, + variant_type_metadata, variant_member_descriptions); // Encode the information about the null variant in the union @@ -1358,6 +1362,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { set_members_of_composite_type(cx, self.enum_type, variant_type_metadata, + variant_type_metadata, member_descriptions); let niche_value = if i == dataful_variant { @@ -1698,8 +1703,7 @@ fn prepare_enum_metadata( layout.align.abi.bits() as u32, DIFlags::FlagZero, discriminator_metadata, - empty_array, - unique_type_id_str.as_ptr()) + empty_array) }; // The variant part must be wrapped in a struct according to DWARF. @@ -1770,6 +1774,7 @@ fn composite_type_metadata( set_members_of_composite_type(cx, composite_type, composite_type_metadata, + composite_type_metadata, member_descriptions); composite_type_metadata @@ -1777,7 +1782,8 @@ fn composite_type_metadata( fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>, composite_type: Ty<'tcx>, - composite_type_metadata: &'ll DICompositeType, + metadata_stub: &'ll DICompositeType, + member_holding_stub: &'ll DICompositeType, member_descriptions: Vec>) { // In some rare cases LLVM metadata uniquing would lead to an existing type // description being used instead of a new one created in @@ -1788,11 +1794,11 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>, { let mut composite_types_completed = debug_context(cx).composite_types_completed.borrow_mut(); - if composite_types_completed.contains(&composite_type_metadata) { + if composite_types_completed.contains(&metadata_stub) { bug!("debuginfo::set_members_of_composite_type() - \ Already completed forward declaration re-encountered."); } else { - composite_types_completed.insert(composite_type_metadata); + composite_types_completed.insert(metadata_stub); } } @@ -1803,7 +1809,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>, unsafe { Some(llvm::LLVMRustDIBuilderCreateVariantMemberType( DIB(cx), - composite_type_metadata, + member_holding_stub, member_name.as_ptr(), unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, @@ -1824,7 +1830,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>, unsafe { let type_array = create_DIArray(DIB(cx), &member_metadata[..]); llvm::LLVMRustDICompositeTypeReplaceArrays( - DIB(cx), composite_type_metadata, Some(type_array), type_params); + DIB(cx), member_holding_stub, Some(type_array), type_params); } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 2ad6d9c053a20..eddc509a585d7 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1587,8 +1587,7 @@ extern "C" { AlignInBits: u32, Flags: DIFlags, Discriminator: Option<&'a DIDerivedType>, - Elements: &'a DIArray, - UniqueId: *const c_char) + Elements: &'a DIArray) -> &'a DIDerivedType; pub fn LLVMSetUnnamedAddr(GlobalVar: &Value, UnnamedAddr: Bool); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index a00417a362927..470cdcdd613a5 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -723,12 +723,12 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart( LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator, - LLVMMetadataRef Elements, const char *UniqueId) { + LLVMMetadataRef Elements) { #if LLVM_VERSION_GE(7, 0) return wrap(Builder->createVariantPart( unwrapDI(Scope), Name, unwrapDI(File), LineNumber, SizeInBits, AlignInBits, fromRust(Flags), unwrapDI(Discriminator), - DINodeArray(unwrapDI(Elements)), UniqueId)); + DINodeArray(unwrapDI(Elements)))); #else abort(); #endif diff --git a/src/test/debuginfo/enum-thinlto.rs b/src/test/debuginfo/enum-thinlto.rs new file mode 100644 index 0000000000000..ae736e40bcc1c --- /dev/null +++ b/src/test/debuginfo/enum-thinlto.rs @@ -0,0 +1,48 @@ +// ignore-tidy-linelength + +// Require LLVM with DW_TAG_variant_part and a gdb that can read it. +// min-system-llvm-version: 7.0 +// min-gdb-version: 8.2 + +// compile-flags:-g -Z thinlto + +// === GDB TESTS =================================================================================== + +// gdb-command:run + +// gdb-command:print *abc +// gdbr-check:$1 = enum_thinlto::ABC::TheA{x: 0, y: 8970181431921507452} + +// === LLDB TESTS ================================================================================== + +// lldb-command:run + +// lldb-command:print *abc +// lldbg-check:(enum_thinlto::ABC) $0 = ABC { } + +#![allow(unused_variables)] +#![feature(omit_gdb_pretty_printer_section)] +#![omit_gdb_pretty_printer_section] + +// The first element is to ensure proper alignment, irrespective of the machines word size. Since +// the size of the discriminant value is machine dependent, this has be taken into account when +// datatype layout should be predictable as in this case. +#[derive(Debug)] +enum ABC { + TheA { x: i64, y: i64 }, + TheB (i64, i32, i32), +} + +fn main() { + let abc = ABC::TheA { x: 0, y: 0x7c7c_7c7c_7c7c_7c7c }; + + f(&abc); +} + +fn f(abc: &ABC) { + zzz(); // #break + + println!("{:?}", abc); +} + +fn zzz() {()} From 3a5a8a529a14271f5d8c21bec8746edfa93eec5f Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Wed, 27 Mar 2019 15:22:37 +1000 Subject: [PATCH 02/10] Give variant parts their own unique id and bump llvm version in test --- .../debuginfo/metadata.rs | 36 ++++++++++++------- src/librustc_codegen_llvm/llvm/ffi.rs | 3 +- src/rustllvm/RustWrapper.cpp | 4 +-- src/test/debuginfo/enum-thinlto.rs | 2 +- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 1859b1f4792e1..e7183df2ec3a5 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -188,6 +188,17 @@ impl TypeMap<'ll, 'tcx> { let interner_key = self.unique_id_interner.intern(&enum_variant_type_id); UniqueTypeId(interner_key) } + + // Get the unique type id string for an enum variant part. + // Variant parts are not types and shouldn't really have their own id, + // but it makes set_members_of_composite_type() simpler. + fn get_unique_type_id_str_of_enum_variant_part<'a>(&mut self, + enum_type_id: UniqueTypeId) -> &str { + let variant_part_type_id = format!("{}_variant_part", + self.get_unique_type_id_as_string(enum_type_id)); + let interner_key = self.unique_id_interner.intern(&variant_part_type_id); + self.unique_id_interner.get(interner_key) + } } // A description of some recursive type. It can either be already finished (as @@ -266,7 +277,6 @@ impl RecursiveTypeDescription<'ll, 'tcx> { // ... and attach them to the stub to complete it. set_members_of_composite_type(cx, unfinished_type, - metadata_stub, member_holding_stub, member_descriptions); return MetadataCreationResult::new(metadata_stub, true); @@ -1216,7 +1226,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { set_members_of_composite_type(cx, self.enum_type, variant_type_metadata, - variant_type_metadata, member_descriptions); vec![ MemberDescription { @@ -1258,7 +1267,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { set_members_of_composite_type(cx, self.enum_type, variant_type_metadata, - variant_type_metadata, member_descriptions); MemberDescription { name: if fallback { @@ -1301,7 +1309,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { set_members_of_composite_type(cx, self.enum_type, variant_type_metadata, - variant_type_metadata, variant_member_descriptions); // Encode the information about the null variant in the union @@ -1362,7 +1369,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { set_members_of_composite_type(cx, self.enum_type, variant_type_metadata, - variant_type_metadata, member_descriptions); let niche_value = if i == dataful_variant { @@ -1691,6 +1697,11 @@ fn prepare_enum_metadata( }, }; + let variant_part_unique_type_id_str = SmallCStr::new( + debug_context(cx).type_map + .borrow_mut() + .get_unique_type_id_str_of_enum_variant_part(unique_type_id) + ); let empty_array = create_DIArray(DIB(cx), &[]); let variant_part = unsafe { llvm::LLVMRustDIBuilderCreateVariantPart( @@ -1703,7 +1714,8 @@ fn prepare_enum_metadata( layout.align.abi.bits() as u32, DIFlags::FlagZero, discriminator_metadata, - empty_array) + empty_array, + variant_part_unique_type_id_str.as_ptr()) }; // The variant part must be wrapped in a struct according to DWARF. @@ -1774,7 +1786,6 @@ fn composite_type_metadata( set_members_of_composite_type(cx, composite_type, composite_type_metadata, - composite_type_metadata, member_descriptions); composite_type_metadata @@ -1782,8 +1793,7 @@ fn composite_type_metadata( fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>, composite_type: Ty<'tcx>, - metadata_stub: &'ll DICompositeType, - member_holding_stub: &'ll DICompositeType, + composite_type_metadata: &'ll DICompositeType, member_descriptions: Vec>) { // In some rare cases LLVM metadata uniquing would lead to an existing type // description being used instead of a new one created in @@ -1794,11 +1804,11 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>, { let mut composite_types_completed = debug_context(cx).composite_types_completed.borrow_mut(); - if composite_types_completed.contains(&metadata_stub) { + if composite_types_completed.contains(&composite_type_metadata) { bug!("debuginfo::set_members_of_composite_type() - \ Already completed forward declaration re-encountered."); } else { - composite_types_completed.insert(metadata_stub); + composite_types_completed.insert(composite_type_metadata); } } @@ -1809,7 +1819,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>, unsafe { Some(llvm::LLVMRustDIBuilderCreateVariantMemberType( DIB(cx), - member_holding_stub, + composite_type_metadata, member_name.as_ptr(), unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, @@ -1830,7 +1840,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>, unsafe { let type_array = create_DIArray(DIB(cx), &member_metadata[..]); llvm::LLVMRustDICompositeTypeReplaceArrays( - DIB(cx), member_holding_stub, Some(type_array), type_params); + DIB(cx), composite_type_metadata, Some(type_array), type_params); } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index eddc509a585d7..2ad6d9c053a20 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1587,7 +1587,8 @@ extern "C" { AlignInBits: u32, Flags: DIFlags, Discriminator: Option<&'a DIDerivedType>, - Elements: &'a DIArray) + Elements: &'a DIArray, + UniqueId: *const c_char) -> &'a DIDerivedType; pub fn LLVMSetUnnamedAddr(GlobalVar: &Value, UnnamedAddr: Bool); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 470cdcdd613a5..a00417a362927 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -723,12 +723,12 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart( LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator, - LLVMMetadataRef Elements) { + LLVMMetadataRef Elements, const char *UniqueId) { #if LLVM_VERSION_GE(7, 0) return wrap(Builder->createVariantPart( unwrapDI(Scope), Name, unwrapDI(File), LineNumber, SizeInBits, AlignInBits, fromRust(Flags), unwrapDI(Discriminator), - DINodeArray(unwrapDI(Elements)))); + DINodeArray(unwrapDI(Elements)), UniqueId)); #else abort(); #endif diff --git a/src/test/debuginfo/enum-thinlto.rs b/src/test/debuginfo/enum-thinlto.rs index ae736e40bcc1c..7f15ed90e67b3 100644 --- a/src/test/debuginfo/enum-thinlto.rs +++ b/src/test/debuginfo/enum-thinlto.rs @@ -1,7 +1,7 @@ // ignore-tidy-linelength // Require LLVM with DW_TAG_variant_part and a gdb that can read it. -// min-system-llvm-version: 7.0 +// min-system-llvm-version: 8.0 // min-gdb-version: 8.2 // compile-flags:-g -Z thinlto From 6046f4a673abc39cec5405f51a17e614d5839f26 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 27 Mar 2019 14:43:29 +0100 Subject: [PATCH 03/10] Do not lint `dyn` tokens under macros. The existing `KeywordIdents` lint blindly scans the token stream for a macro or macro definition. It does not attempt to parse the input, which means it cannot distinguish between occurrences of `dyn` that are truly instances of it as an identifier (e.g. `let dyn = 3;`) versus occurrences that follow its usage as a contextual keyword (e.g. the type `Box`). In an ideal world the lint would parse the token stream in order to distinguish such occurrences; but in general we cannot do this, because a macro_rules definition does not specify what parsing contexts the macro being defined is allowed to be used within. So rather than put a lot of work into attempting to come up with a more precise but still incomplete solution, I am just taking the short cut of not linting any instance of `dyn` under a macro. This prevents `rustfix` from injecting bugs into legal 2015 edition code. --- src/librustc_lint/builtin.rs | 47 +++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 304e6eb712e3c..dba8981c8a680 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1618,6 +1618,8 @@ impl LintPass for KeywordIdents { } } +struct UnderMacro(bool); + impl KeywordIdents { fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: TokenStream) { for tt in tokens.into_trees() { @@ -1625,7 +1627,7 @@ impl KeywordIdents { TokenTree::Token(span, tok) => match tok.ident() { // only report non-raw idents Some((ident, false)) => { - self.check_ident(cx, ast::Ident { + self.check_ident_token(cx, UnderMacro(true), ast::Ident { span: span.substitute_dummy(ident.span), ..ident }); @@ -1638,16 +1640,12 @@ impl KeywordIdents { } } } -} -impl EarlyLintPass for KeywordIdents { - fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef, _id: ast::NodeId) { - self.check_tokens(cx, mac_def.stream()); - } - fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) { - self.check_tokens(cx, mac.node.tts.clone().into()); - } - fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) { + fn check_ident_token(&mut self, + cx: &EarlyContext<'_>, + UnderMacro(under_macro): UnderMacro, + ident: ast::Ident) + { let ident_str = &ident.as_str()[..]; let cur_edition = cx.sess.edition(); let is_raw_ident = |ident: ast::Ident| { @@ -1656,7 +1654,22 @@ impl EarlyLintPass for KeywordIdents { let next_edition = match cur_edition { Edition::Edition2015 => { match ident_str { - "async" | "try" | "dyn" => Edition::Edition2018, + "async" | "try" => Edition::Edition2018, + + // rust-lang/rust#56327: Conservatively do not + // attempt to report occurrences of `dyn` within + // macro definitions or invocations, because `dyn` + // can legitimately occur as a contextual keyword + // in 2015 code denoting its 2018 meaning, and we + // do not want rustfix to inject bugs into working + // code by rewriting such occurrences. + // + // But if we see `dyn` outside of a macro, we know + // its precise role in the parsed AST and thus are + // assured this is truly an attempt to use it as + // an identifier. + "dyn" if !under_macro => Edition::Edition2018, + // Only issue warnings for `await` if the `async_await` // feature isn't being used. Otherwise, users need // to keep using `await` for the macro exposed by std. @@ -1714,6 +1727,18 @@ impl EarlyLintPass for KeywordIdents { } } +impl EarlyLintPass for KeywordIdents { + fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef, _id: ast::NodeId) { + self.check_tokens(cx, mac_def.stream()); + } + fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) { + self.check_tokens(cx, mac.node.tts.clone().into()); + } + fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) { + self.check_ident_token(cx, UnderMacro(false), ident); + } +} + pub struct ExplicitOutlivesRequirements; From 6d7e5df3d92fcb5f67a790dfc56acec2a33170d3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 27 Mar 2019 17:13:51 +0100 Subject: [PATCH 04/10] Some tests illustrating where the revised lint does and does not apply. --- .../dyn-2015-edition-keyword-ident-lint.fixed | 81 +++++++++++ .../dyn-2015-edition-keyword-ident-lint.rs | 81 +++++++++++ ...dyn-2015-edition-keyword-ident-lint.stderr | 133 ++++++++++++++++++ .../dyn-2015-idents-in-macros-unlinted.rs | 24 ++++ .../dyn-2015-no-warnings-without-lints.rs | 27 ++++ 5 files changed, 346 insertions(+) create mode 100644 src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed create mode 100644 src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs create mode 100644 src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr create mode 100644 src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs create mode 100644 src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed new file mode 100644 index 0000000000000..153d73c9ea501 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed @@ -0,0 +1,81 @@ +// Under the 2015 edition with the keyword_idents lint, `dyn` is not +// entirely acceptable as an identifier. We currently do not attempt +// to detect or fix uses of `dyn` under a macro. Since we are testing +// this file via `rustfix`, we want the rustfix output to be +// compilable; so the macros here carefully use `dyn` "correctly." + +// run-rustfix + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod r#dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + pub struct r#dyn; +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + } +} +use outer_mod::r#dyn::r#dyn; +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + +fn main() { + match r#dyn { r#dyn => {} } +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + macro_defn::r#dyn(); +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + + macro_defn::boxed(); +} + +mod macro_defn { + use super::Trait; + + macro_rules! r#dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + + // Note that we do not lint nor fix occurrences under macros + ($dyn:ident) => { Box } + } + + pub fn r#dyn() -> ::outer_mod::r#dyn::r#dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + ::outer_mod::r#dyn::r#dyn +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + } + + + + pub fn boxed() -> r#dyn!( + //~^ ERROR `dyn` is a keyword + //~| WARN was previously accepted + + // Note that we do not lint nor fix occurrences under macros + dyn + ) + { + Box::new(10) + } +} + +pub trait Trait { } + +impl Trait for u32 { } diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs new file mode 100644 index 0000000000000..98ad3a78c13ff --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs @@ -0,0 +1,81 @@ +// Under the 2015 edition with the keyword_idents lint, `dyn` is not +// entirely acceptable as an identifier. We currently do not attempt +// to detect or fix uses of `dyn` under a macro. Since we are testing +// this file via `rustfix`, we want the rustfix output to be +// compilable; so the macros here carefully use `dyn` "correctly." + +// run-rustfix + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + pub struct dyn; +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + } +} +use outer_mod::dyn::dyn; +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + +fn main() { + match dyn { dyn => {} } +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + macro_defn::dyn(); +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + + macro_defn::boxed(); +} + +mod macro_defn { + use super::Trait; + + macro_rules! dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + + // Note that we do not lint nor fix occurrences under macros + ($dyn:ident) => { Box } + } + + pub fn dyn() -> ::outer_mod::dyn::dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + ::outer_mod::dyn::dyn +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + } + + + + pub fn boxed() -> dyn!( + //~^ ERROR `dyn` is a keyword + //~| WARN was previously accepted + + // Note that we do not lint nor fix occurrences under macros + dyn + ) + { + Box::new(10) + } +} + +pub trait Trait { } + +impl Trait for u32 { } diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr new file mode 100644 index 0000000000000..361727733bc57 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr @@ -0,0 +1,133 @@ +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:13:13 + | +LL | pub mod dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | +note: lint level defined here + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:10:9 + | +LL | #![deny(keyword_idents)] + | ^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:16:20 + | +LL | pub struct dyn; + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:21:16 + | +LL | use outer_mod::dyn::dyn; + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:21:21 + | +LL | use outer_mod::dyn::dyn; + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:28:11 + | +LL | match dyn { dyn => {} } + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:28:17 + | +LL | match dyn { dyn => {} } + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:33:17 + | +LL | macro_defn::dyn(); + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:43:18 + | +LL | macro_rules! dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:51:12 + | +LL | pub fn dyn() -> ::outer_mod::dyn::dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:51:34 + | +LL | pub fn dyn() -> ::outer_mod::dyn::dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:51:39 + | +LL | pub fn dyn() -> ::outer_mod::dyn::dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:58:22 + | +LL | ::outer_mod::dyn::dyn + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:58:27 + | +LL | ::outer_mod::dyn::dyn + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:67:23 + | +LL | pub fn boxed() -> dyn!( + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: aborting due to 14 previous errors + diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs new file mode 100644 index 0000000000000..a4ed970bc287f --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs @@ -0,0 +1,24 @@ +// compile-pass + +// Under the 2015 edition with the keyword_idents lint, `dyn` is +// not entirely acceptable as an identifier. +// +// We currently do not attempt to detect or fix uses of `dyn` as an +// identifier under a macro. + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod r#dyn { + pub struct r#dyn; + } +} + +macro_rules! defn_has_dyn_idents { + ($arg:ident) => { ::outer_mod::dyn::dyn } +} + +fn main() { + defn_has_dyn_idents!(dyn); +} diff --git a/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs b/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs new file mode 100644 index 0000000000000..8cef5c2b34947 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs @@ -0,0 +1,27 @@ +// Under the 2015 edition without the keyword_idents lint, `dyn` is +// entirely acceptable as an identifier. + +// compile-pass + +#![allow(non_camel_case_types)] + +mod outer_mod { + pub mod dyn { + pub struct dyn; + } +} +use outer_mod::dyn::dyn; + +fn main() { + match dyn { dyn => {} } + macro_defn::dyn(); +} +mod macro_defn { + macro_rules! dyn { + () => { ::outer_mod::dyn::dyn } + } + + pub fn dyn() -> ::outer_mod::dyn::dyn { + dyn!() + } +} From 1f63a52ca26ac2a59591a1b23e8d2c73baff5d6b Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 27 Mar 2019 17:18:49 +0100 Subject: [PATCH 05/10] Regression test for rust-lang/rust#56327. --- .../issue-56327-dyn-trait-in-macro-is-okay.rs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs diff --git a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs new file mode 100644 index 0000000000000..ff3830d61755a --- /dev/null +++ b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs @@ -0,0 +1,25 @@ +// compile-pass + +// rust-lang/rust#56327: Some occurrences of `dyn` within a macro are +// not instances of identifiers, and thus should *not* be caught by the +// keyword_ident lint. +// +// Otherwise, rustfix replaces the type `Box` with +// `Box`, which is injecting a bug rather than fixing +// anything. + +#![deny(rust_2018_compatibility)] + +macro_rules! foo { + () => { + fn generated_foo() { + let _x: Box; + } + } +} + +foo!(); + +fn main() { + generated_foo(); +} From f043d2da65a4da355aae4773204e073fef3e7cba Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 28 Mar 2019 12:49:50 +0100 Subject: [PATCH 06/10] Revise test slightly so that `dyn` in macro invocation *must* be parsed as keyword in test. Back-story: After reflection this morning, I realized that the previous form of this test would allow the macro invocation to treat the `dyn` input as a raw-identifier rather than a keyword, and since the input was discarded by that version of the macro, the test would pass despite the detail that the input `dyn` should not have been parsed as a raw-identifier. This revision fixes that oversight, by actually *using* the macro input to construct a `Box` type. --- .../ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed | 4 ++-- .../ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed index 153d73c9ea501..003736208ed38 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed @@ -45,7 +45,7 @@ mod macro_defn { //~| WARN was previously accepted // Note that we do not lint nor fix occurrences under macros - ($dyn:ident) => { Box } + ($dyn:tt) => { (Box, Box<$dyn Trait>) } } pub fn r#dyn() -> ::outer_mod::r#dyn::r#dyn { @@ -72,7 +72,7 @@ mod macro_defn { dyn ) { - Box::new(10) + (Box::new(1), Box::new(2)) } } diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs index 98ad3a78c13ff..0e5c39fc501be 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs @@ -45,7 +45,7 @@ mod macro_defn { //~| WARN was previously accepted // Note that we do not lint nor fix occurrences under macros - ($dyn:ident) => { Box } + ($dyn:tt) => { (Box, Box<$dyn Trait>) } } pub fn dyn() -> ::outer_mod::dyn::dyn { @@ -72,7 +72,7 @@ mod macro_defn { dyn ) { - Box::new(10) + (Box::new(1), Box::new(2)) } } From 528366d3ffe0564c2e300aae6df06e6a1bfafde2 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 28 Mar 2019 13:08:56 +0100 Subject: [PATCH 07/10] Revise and generalize the macros-unlinted tests. Review feedback asked for the test to be generalized to include macros 2.0; that generalization is dyn-2015-idents-in-decl-macros-unlinted.rs As a drive-by, I also decided to revise the test to make it clear *why* we cannot generally lint these cases. (I already had similar demonstrations in dyn-2015-edition-keyword-ident-lint.rs, but it does not hurt to try to emphasize matters.) I also added some commentary on the cases where we could choose to make the lint smarter, namely the situations where a macro is *definitely* using `dyn` as an identifier (because it is using it as a path component). --- ...dyn-2015-idents-in-decl-macros-unlinted.rs | 51 +++++++++++++++++++ .../dyn-2015-idents-in-macros-unlinted.rs | 36 ++++++++++++- 2 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs new file mode 100644 index 0000000000000..f535791d7fbe4 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs @@ -0,0 +1,51 @@ +// compile-pass + +// Under the 2015 edition with the keyword_idents lint, `dyn` is +// not entirely acceptable as an identifier. +// +// We currently do not attempt to detect or fix uses of `dyn` as an +// identifier under a macro, including under the declarative `macro` +// forms from macros 1.2 and macros 2.0. + +#![feature(decl_macro)] +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod r#dyn { + pub struct r#dyn; + } +} + +// Here we are illustrating that the current lint does not flag the +// occurrences of `dyn` in this macro definition; however, it +// certainly *could* (and it would be nice if it did), since these +// occurrences are not compatible with the 2018 edition's +// interpretation of `dyn` as a keyword. +macro defn_has_dyn_idents() { ::outer_mod::dyn::dyn } + +struct X; +trait Trait { fn hello(&self) { }} +impl Trait for X { } + +macro tt_trait($arg:tt) { & $arg Trait } +macro id_trait($id:ident) { & $id Trait } + +fn main() { + defn_has_dyn_idents!(); + + // Here we are illustrating that the current lint does not flag + // the occurrences of `dyn` in these macro invocations. It + // definitely should *not* flag the one in `tt_trait`, since that + // is expanding in a valid fashion to `&dyn Trait`. + // + // It is arguable whether it would be valid to flag the occurrence + // in `id_trait`, since that macro specifies that it takes an + // `ident` as its input. + fn f_tt(x: &X) -> tt_trait!(dyn) { x } + fn f_id(x: &X) -> id_trait!(dyn) { x } + + let x = X; + f_tt(&x).hello(); + f_id(&x).hello(); +} diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs index a4ed970bc287f..27e490558689f 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs @@ -15,10 +15,42 @@ mod outer_mod { } } +// Here we are illustrating that the current lint does not flag the +// occurrences of `dyn` in this macro definition; however, it +// certainly *could* (and it would be nice if it did), since these +// occurrences are not compatible with the 2018 edition's +// interpretation of `dyn` as a keyword. macro_rules! defn_has_dyn_idents { - ($arg:ident) => { ::outer_mod::dyn::dyn } + () => { ::outer_mod::dyn::dyn } +} + +struct X; +trait Trait { fn hello(&self) { }} +impl Trait for X { } + +macro_rules! tt_trait { + ($arg:tt) => { & $arg Trait } +} + +macro_rules! id_trait { + ($id:ident) => { & $id Trait } } fn main() { - defn_has_dyn_idents!(dyn); + defn_has_dyn_idents!(); + + // Here we are illustrating that the current lint does not flag + // the occurrences of `dyn` in these macro invocations. It + // definitely should *not* flag the one in `tt_trait`, since that + // is expanding in a valid fashion to `&dyn Trait`. + // + // It is arguable whether it would be valid to flag the occurrence + // in `id_trait`, since that macro specifies that it takes an + // `ident` as its input. + fn f_tt(x: &X) -> tt_trait!(dyn) { x } + fn f_id(x: &X) -> id_trait!(dyn) { x } + + let x = X; + f_tt(&x).hello(); + f_id(&x).hello(); } From 03639a2bff351315ca59fc080b10de1df60bf910 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 21 Mar 2019 18:06:04 +0200 Subject: [PATCH 08/10] rustc(codegen): uncache `def_symbol_name` prefix from `symbol_name`. --- src/librustc/dep_graph/dep_node.rs | 3 +- src/librustc/ty/query/config.rs | 1 - src/librustc/ty/query/mod.rs | 3 +- src/librustc/ty/query/on_disk_cache.rs | 1 - src/librustc/ty/query/plumbing.rs | 4 +- src/librustc_codegen_utils/symbol_names.rs | 53 ++++++---------------- src/librustc_mir/transform/lower_128bit.rs | 2 +- 7 files changed, 19 insertions(+), 48 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 1f4f7d344245d..03fa5c04ec721 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -500,8 +500,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] ConstEval { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> }, [] ConstEvalRaw { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> }, [] CheckMatch(DefId), - [] SymbolName(DefId), - [] InstanceSymbolName { instance: Instance<'tcx> }, + [] SymbolName { instance: Instance<'tcx> }, [] SpecializationGraph(DefId), [] ObjectSafety(DefId), [] FulfillObligation { param_env: ParamEnv<'tcx>, trait_ref: PolyTraitRef<'tcx> }, diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 5cb5a0030f4eb..bc5caffb93464 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -941,7 +941,6 @@ impl_disk_cacheable_query!(mir_borrowck, |tcx, def_id| { impl_disk_cacheable_query!(unsafety_check_result, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(borrowck, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local()); -impl_disk_cacheable_query!(def_symbol_name, |_, _| true); impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(used_trait_imports, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(codegen_fn_attrs, |_, _| true); diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 9c705104d1888..f64156beeaa2d 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -315,7 +315,6 @@ rustc_query_append! { [define_queries!][ <'tcx> [] fn mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx>, - [] fn def_symbol_name: SymbolName(DefId) -> ty::SymbolName, [] fn symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName, [] fn describe_def: DescribeDef(DefId) -> Option, @@ -727,7 +726,7 @@ fn mir_shim_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx>) -> DepConstructo } fn symbol_name_dep_node<'tcx>(instance: ty::Instance<'tcx>) -> DepConstructor<'tcx> { - DepConstructor::InstanceSymbolName { instance } + DepConstructor::SymbolName { instance } } fn typeck_item_bodies_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index c16f861dedb50..1b4c36b8b06c3 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -218,7 +218,6 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index c35cea7883f00..973291d94acdd 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1217,7 +1217,7 @@ pub fn force_from_dep_node<'tcx>( DepKind::Layout | DepKind::ConstEval | DepKind::ConstEvalRaw | - DepKind::InstanceSymbolName | + DepKind::SymbolName | DepKind::MirShim | DepKind::BorrowCheckKrate | DepKind::Specializes | @@ -1304,7 +1304,6 @@ pub fn force_from_dep_node<'tcx>( DepKind::TypeckTables => { force!(typeck_tables_of, def_id!()); } DepKind::UsedTraitImports => { force!(used_trait_imports, def_id!()); } DepKind::HasTypeckTables => { force!(has_typeck_tables, def_id!()); } - DepKind::SymbolName => { force!(def_symbol_name, def_id!()); } DepKind::SpecializationGraph => { force!(specialization_graph_of, def_id!()); } DepKind::ObjectSafety => { force!(is_object_safe, def_id!()); } DepKind::TraitImpls => { force!(trait_impls_of, def_id!()); } @@ -1486,7 +1485,6 @@ impl_load_from_cache!( BorrowCheck => borrowck, MirBorrowCheck => mir_borrowck, mir_const_qualif => mir_const_qualif, - SymbolName => def_symbol_name, ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static, CheckMatch => check_match, type_of => type_of, diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index ebd48f0ae1e2b..d50a9a1607b24 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -101,7 +101,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt}; use rustc_mir::monomorphize::Instance; -use syntax_pos::symbol::Symbol; +use syntax_pos::symbol::{Symbol, InternedString}; use log::debug; @@ -110,7 +110,6 @@ use std::mem::{self, discriminant}; pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { - def_symbol_name, symbol_name, ..*providers @@ -222,21 +221,13 @@ fn get_symbol_hash<'a, 'tcx>( hasher.finish() } -fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - SymbolPrinter { - tcx, - path: SymbolPath::new(), - keep_within_component: false, - }.print_def_path(def_id, &[]).unwrap().path.into_interned() -} - -fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { +fn symbol_name(tcx: TyCtxt<'_, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { ty::SymbolName { - name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str(), + name: compute_symbol_name(tcx, instance), } } -fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> String { +fn compute_symbol_name(tcx: TyCtxt<'_, 'tcx, 'tcx>, instance: Instance<'tcx>) -> InternedString { let def_id = instance.def_id(); let substs = instance.substs; @@ -247,11 +238,13 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance if def_id.is_local() { if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return tcx.sess.generate_plugin_registrar_symbol(disambiguator); + return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator)) + .as_interned_str(); } if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return tcx.sess.generate_proc_macro_decls_symbol(disambiguator); + return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator)) + .as_interned_str(); } } @@ -268,20 +261,20 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let attrs = tcx.codegen_fn_attrs(def_id); if is_foreign { if let Some(name) = attrs.link_name { - return name.to_string(); + return name.as_interned_str(); } // Don't mangle foreign items. - return tcx.item_name(def_id).to_string(); + return tcx.item_name(def_id); } if let Some(name) = &attrs.export_name { // Use provided name - return name.to_string(); + return name.as_interned_str(); } if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { // Don't mangle - return tcx.item_name(def_id).to_string(); + return tcx.item_name(def_id); } // We want to compute the "type" of this item. Unfortunately, some @@ -321,15 +314,15 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let mut printer = SymbolPrinter { tcx, - path: SymbolPath::from_interned(tcx.def_symbol_name(def_id)), + path: SymbolPath::new(), keep_within_component: false, - }; + }.print_def_path(def_id, &[]).unwrap(); if instance.is_vtable_shim() { let _ = printer.write_str("{{vtable-shim}}"); } - printer.path.finish(hash) + Symbol::intern(&printer.path.finish(hash)).as_interned_str() } // Follow C++ namespace-mangling style, see @@ -361,22 +354,6 @@ impl SymbolPath { result } - fn from_interned(symbol: ty::SymbolName) -> Self { - let mut result = SymbolPath { - result: String::with_capacity(64), - temp_buf: String::with_capacity(16), - }; - result.result.push_str(&symbol.as_str()); - result - } - - fn into_interned(mut self) -> ty::SymbolName { - self.finalize_pending_component(); - ty::SymbolName { - name: Symbol::intern(&self.result).as_interned_str(), - } - } - fn finalize_pending_component(&mut self) { if !self.temp_buf.is_empty() { let _ = write!(self.result, "{}{}", self.temp_buf.len(), self.temp_buf); diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs index ad108587247fb..54fc63f30571e 100644 --- a/src/librustc_mir/transform/lower_128bit.rs +++ b/src/librustc_mir/transform/lower_128bit.rs @@ -138,7 +138,7 @@ fn check_lang_item_type<'a, 'tcx, D>( let place_ty = place.ty(local_decls, tcx).to_ty(tcx); let expected = [lhs_ty, rhs_ty, place_ty]; assert_eq!(sig.inputs_and_output[..], expected, - "lang item {}", tcx.def_symbol_name(did)); + "lang item `{}`", tcx.def_path_str(did)); did } From b222b6fa7f4607ef1b0e8e5a950295550b3b1db0 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 29 Mar 2019 17:59:07 -0700 Subject: [PATCH 09/10] manifest: only include miri on the nightly channel miri needs to build std with xargo, which doesn't allow stable/beta: Therefore, at this time there's no point in making miri available on any but the nightly channel. If we get a stable way to build `std`, like [RFC 2663], then we can re-evaluate whether to start including miri, perhaps still as `miri-preview`. [RFC 2663]: https://github.com/rust-lang/rfcs/pull/2663 --- src/tools/build-manifest/src/main.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 3c360a81ba5be..65a7e6f2c39a6 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -522,12 +522,18 @@ impl Builder { pkgname: &str, dst: &mut BTreeMap, targets: &[&str]) { - let (version, is_present) = self.cached_version(pkgname) + let (version, mut is_present) = self.cached_version(pkgname) .as_ref() .cloned() .map(|version| (version, true)) .unwrap_or_default(); + // miri needs to build std with xargo, which doesn't allow stable/beta: + // + if pkgname == "miri-preview" && self.rust_release != "nightly" { + is_present = false; // ignore it + } + let targets = targets.iter().map(|name| { if is_present { let filename = self.filename(pkgname, name); From 29885ff2915665f1e5b53c6c21609a12812bf29e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 29 Mar 2019 23:57:03 +0100 Subject: [PATCH 10/10] Fix infinite recursion --- src/librustdoc/clean/mod.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 396488c981dfd..7a2b5ceb7b4e8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1766,9 +1766,13 @@ fn get_real_types( generics: &Generics, arg: &Type, cx: &DocContext<'_>, + recurse: i32, ) -> FxHashSet { let arg_s = arg.to_string(); let mut res = FxHashSet::default(); + if recurse >= 10 { // FIXME: remove this whole recurse thing when the recursion bug is fixed + return res; + } if arg.is_full_generic() { if let Some(where_pred) = generics.where_predicates.iter().find(|g| { match g { @@ -1785,7 +1789,7 @@ fn get_real_types( continue } if let Some(ty) = x.get_type(cx) { - let adds = get_real_types(generics, &ty, cx); + let adds = get_real_types(generics, &ty, cx, recurse + 1); if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { @@ -1803,7 +1807,7 @@ fn get_real_types( }) { for bound in bound.get_bounds().unwrap_or_else(|| &[]) { if let Some(ty) = bound.get_trait_type() { - let adds = get_real_types(generics, &ty, cx); + let adds = get_real_types(generics, &ty, cx, recurse + 1); if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { @@ -1817,7 +1821,7 @@ fn get_real_types( if let Some(gens) = arg.generics() { for gen in gens.iter() { if gen.is_full_generic() { - let adds = get_real_types(generics, gen, cx); + let adds = get_real_types(generics, gen, cx, recurse + 1); if !adds.is_empty() { res.extend(adds); } @@ -1844,7 +1848,7 @@ pub fn get_all_types( if arg.type_.is_self_type() { continue; } - let args = get_real_types(generics, &arg.type_, cx); + let args = get_real_types(generics, &arg.type_, cx, 0); if !args.is_empty() { all_types.extend(args); } else { @@ -1854,7 +1858,7 @@ pub fn get_all_types( let ret_types = match decl.output { FunctionRetTy::Return(ref return_type) => { - let mut ret = get_real_types(generics, &return_type, cx); + let mut ret = get_real_types(generics, &return_type, cx, 0); if ret.is_empty() { ret.insert(return_type.clone()); }