]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #88824 - Manishearth:rollup-7bzk9h6, r=Manishearth
authorbors <bors@rust-lang.org>
Sat, 11 Sep 2021 03:30:55 +0000 (03:30 +0000)
committerbors <bors@rust-lang.org>
Sat, 11 Sep 2021 03:30:55 +0000 (03:30 +0000)
Rollup of 15 pull requests

Successful merges:

 - #85200 (Ignore derived Clone and Debug implementations during dead code analysis)
 - #86165 (Add proc_macro::Span::{before, after}.)
 - #87088 (Fix stray notes when the source code is not available)
 - #87441 (Emit suggestion when passing byte literal to format macro)
 - #88546 (Emit proper errors when on missing closure braces)
 - #88578 (fix(rustc): suggest `items` be borrowed in `for i in items[x..]`)
 - #88632 (Fix issues with Markdown summary options)
 - #88639 (rustdoc: Fix ICE with `doc(hidden)` on tuple variant fields)
 - #88667 (Tweak `write_fmt` doc.)
 - #88720 (Rustdoc coverage fields count)
 - #88732 (RustWrapper: avoid deleted unclear attribute methods)
 - #88742 (Fix table in docblocks)
 - #88776 (Workaround blink/chromium grid layout limitation of 1000 rows)
 - #88807 (Fix typo in docs for iterators)
 - #88812 (Fix typo `option` -> `options`.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup

93 files changed:
compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
compiler/rustc_builtin_macros/src/asm.rs
compiler/rustc_builtin_macros/src/format.rs
compiler/rustc_expand/src/base.rs
compiler/rustc_expand/src/proc_macro_server.rs
compiler/rustc_feature/src/accepted.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_feature/src/builtin_attrs.rs
compiler/rustc_feature/src/lib.rs
compiler/rustc_feature/src/removed.rs
compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
compiler/rustc_middle/src/hir/map/collector.rs
compiler/rustc_middle/src/ich/hcx.rs
compiler/rustc_mir_build/src/build/matches/mod.rs
compiler/rustc_mir_build/src/build/matches/simplify.rs
compiler/rustc_mir_build/src/build/scope.rs
compiler/rustc_mir_transform/src/coverage/mod.rs
compiler/rustc_parse/src/parser/expr.rs
compiler/rustc_parse/src/parser/mod.rs
compiler/rustc_passes/src/dead.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
library/core/src/clone.rs
library/core/src/fmt/mod.rs
library/core/tests/fmt/builders.rs
library/proc_macro/src/bridge/mod.rs
library/proc_macro/src/lib.rs
library/std/src/collections/mod.rs
library/std/src/io/buffered/tests.rs
library/std/src/io/mod.rs
library/test/src/term/terminfo/mod.rs
src/doc/unstable-book/src/library-features/asm.md
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/types.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render/mod.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/html/static/css/rustdoc.css
src/librustdoc/passes/bare_urls.rs
src/librustdoc/passes/calculate_doc_coverage.rs
src/librustdoc/passes/html_tags.rs
src/test/rustdoc-gui/docblock-table-overflow.goml
src/test/rustdoc-gui/src/lib2/lib.rs
src/test/rustdoc-ui/coverage/enum-tuple-documented.rs [new file with mode: 0644]
src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout [new file with mode: 0644]
src/test/rustdoc-ui/coverage/enum-tuple.rs [new file with mode: 0644]
src/test/rustdoc-ui/coverage/enum-tuple.stdout [new file with mode: 0644]
src/test/rustdoc-ui/coverage/enums.stdout
src/test/rustdoc/issue-88600.rs [new file with mode: 0644]
src/test/rustdoc/table-in-docblock.rs [new file with mode: 0644]
src/test/ui/array-slice-vec/slice_binary_search.rs
src/test/ui/borrowck/borrowck-unused-mut-locals.rs
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs
src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs
src/test/ui/const-generics/broken-mir-2.rs
src/test/ui/derives/clone-debug-dead-code.rs [new file with mode: 0644]
src/test/ui/derives/clone-debug-dead-code.stderr [new file with mode: 0644]
src/test/ui/deriving/deriving-clone-generic-struct.rs
src/test/ui/deriving/deriving-clone-struct.rs
src/test/ui/deriving/deriving-clone-tuple-struct.rs
src/test/ui/deriving/deriving-in-fn.rs
src/test/ui/expr/malformed_closure/missing_braces_around_block.fixed [new file with mode: 0644]
src/test/ui/expr/malformed_closure/missing_braces_around_block.rs [new file with mode: 0644]
src/test/ui/expr/malformed_closure/missing_braces_around_block.stderr [new file with mode: 0644]
src/test/ui/expr/malformed_closure/ruby_style_closure.rs [new file with mode: 0644]
src/test/ui/expr/malformed_closure/ruby_style_closure.stderr [new file with mode: 0644]
src/test/ui/issues/issue-19358.rs
src/test/ui/issues/issue-20605.stderr
src/test/ui/issues/issue-3794.rs
src/test/ui/issues/issue-86865.rs [new file with mode: 0644]
src/test/ui/issues/issue-86865.stderr [new file with mode: 0644]
src/test/ui/monomorphize-abi-alignment.rs
src/test/ui/moves/move-1-unique.rs
src/test/ui/moves/move-3-unique.rs
src/test/ui/overloaded/overloaded-autoderef-order.rs
src/test/ui/self/ufcs-explicit-self.rs
src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs
src/test/ui/structs-enums/class-implement-traits.rs
src/test/ui/structs-enums/functional-struct-upd.rs
src/test/ui/structs-enums/tag-align-shape.rs
src/test/ui/suggestions/slice-issue-87994.rs [new file with mode: 0644]
src/test/ui/suggestions/slice-issue-87994.stderr [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/macro_use.rs
src/tools/clippy/clippy_lints/src/regex.rs
src/tools/clippy/tests/ui/default_trait_access.fixed
src/tools/clippy/tests/ui/default_trait_access.rs
src/tools/rustfmt/src/macros.rs
src/tools/rustfmt/src/modules.rs

index ce1e7c14b1ff673b249fd3bc4fca294296c28403..f4cbbb60b053a2625f1c4578c96545d09a04a53c 100644 (file)
@@ -218,7 +218,19 @@ pub(crate) fn report_use_of_moved_or_uninitialized(
                             );
                             if self.fn_self_span_reported.insert(fn_span) {
                                 err.span_note(
-                                    self_arg.span,
+                                    // Check whether the source is accessible
+                                    if self
+                                        .infcx
+                                        .tcx
+                                        .sess
+                                        .source_map()
+                                        .span_to_snippet(self_arg.span)
+                                        .is_ok()
+                                    {
+                                        self_arg.span
+                                    } else {
+                                        fn_call_span
+                                    },
                                     "calling this operator moves the left-hand side",
                                 );
                             }
@@ -429,7 +441,10 @@ pub(crate) fn report_use_of_moved_or_uninitialized(
                     deref_target_ty
                 ));
 
-                err.span_note(deref_target, "deref defined here");
+                // Check first whether the source is accessible (issue #87060)
+                if self.infcx.tcx.sess.source_map().span_to_snippet(deref_target).is_ok() {
+                    err.span_note(deref_target, "deref defined here");
+                }
             }
 
             if let Some((_, mut old_err)) =
index 652165fb9b60b1f646c7827aaa07d17548a6e8a1..693114e378664851ccc7179b65f1f87db5f0fd46 100644 (file)
@@ -510,7 +510,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
             match expr_to_spanned_string(ecx, template_expr, msg) {
                 Ok(template_part) => template_part,
                 Err(err) => {
-                    if let Some(mut err) = err {
+                    if let Some((mut err, _)) = err {
                         err.emit();
                     }
                     return None;
index 8508b3b7ae6edb9a273d9f05e16950b75096e030..c7626dec4d7c0b29bc5c07efb1f0f2c1a0154906 100644 (file)
@@ -964,17 +964,19 @@ pub fn expand_preparsed_format_args(
         }
         Ok(fmt) => fmt,
         Err(err) => {
-            if let Some(mut err) = err {
+            if let Some((mut err, suggested)) = err {
                 let sugg_fmt = match args.len() {
                     0 => "{}".to_string(),
                     _ => format!("{}{{}}", "{} ".repeat(args.len())),
                 };
-                err.span_suggestion(
-                    fmt_sp.shrink_to_lo(),
-                    "you might be missing a string literal to format with",
-                    format!("\"{}\", ", sugg_fmt),
-                    Applicability::MaybeIncorrect,
-                );
+                if !suggested {
+                    err.span_suggestion(
+                        fmt_sp.shrink_to_lo(),
+                        "you might be missing a string literal to format with",
+                        format!("\"{}\", ", sugg_fmt),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
                 err.emit();
             }
             return DummyResult::raw_expr(sp, true);
index 35df8aae4babb99d5488b87b99234a5d4ce6d7d1..6a135dd4f1f6a79903cfba89111e5cacd59c9eb6 100644 (file)
@@ -10,7 +10,7 @@
 use rustc_attr::{self as attr, Deprecation, Stability};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
-use rustc_errors::{DiagnosticBuilder, ErrorReported};
+use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported};
 use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
 use rustc_lint_defs::BuiltinLintDiagnostics;
 use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS};
@@ -1136,13 +1136,15 @@ pub fn resolve_path(
 }
 
 /// Extracts a string literal from the macro expanded version of `expr`,
-/// emitting `err_msg` if `expr` is not a string literal. This does not stop
-/// compilation on error, merely emits a non-fatal error and returns `None`.
+/// returning a diagnostic error of `err_msg` if `expr` is not a string literal.
+/// The returned bool indicates whether an applicable suggestion has already been
+/// added to the diagnostic to avoid emitting multiple suggestions. `Err(None)`
+/// indicates that an ast error was encountered.
 pub fn expr_to_spanned_string<'a>(
     cx: &'a mut ExtCtxt<'_>,
     expr: P<ast::Expr>,
     err_msg: &str,
-) -> Result<(Symbol, ast::StrStyle, Span), Option<DiagnosticBuilder<'a>>> {
+) -> Result<(Symbol, ast::StrStyle, Span), Option<(DiagnosticBuilder<'a>, bool)>> {
     // Perform eager expansion on the expression.
     // We want to be able to handle e.g., `concat!("foo", "bar")`.
     let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
@@ -1150,14 +1152,27 @@ pub fn expr_to_spanned_string<'a>(
     Err(match expr.kind {
         ast::ExprKind::Lit(ref l) => match l.kind {
             ast::LitKind::Str(s, style) => return Ok((s, style, expr.span)),
+            ast::LitKind::ByteStr(_) => {
+                let mut err = cx.struct_span_err(l.span, err_msg);
+                err.span_suggestion(
+                    expr.span.shrink_to_lo(),
+                    "consider removing the leading `b`",
+                    String::new(),
+                    Applicability::MaybeIncorrect,
+                );
+                Some((err, true))
+            }
             ast::LitKind::Err(_) => None,
-            _ => Some(cx.struct_span_err(l.span, err_msg)),
+            _ => Some((cx.struct_span_err(l.span, err_msg), false)),
         },
         ast::ExprKind::Err => None,
-        _ => Some(cx.struct_span_err(expr.span, err_msg)),
+        _ => Some((cx.struct_span_err(expr.span, err_msg), false)),
     })
 }
 
+/// Extracts a string literal from the macro expanded version of `expr`,
+/// emitting `err_msg` if `expr` is not a string literal. This does not stop
+/// compilation on error, merely emits a non-fatal error and returns `None`.
 pub fn expr_to_string(
     cx: &mut ExtCtxt<'_>,
     expr: P<ast::Expr>,
@@ -1165,7 +1180,7 @@ pub fn expr_to_string(
 ) -> Option<(Symbol, ast::StrStyle)> {
     expr_to_spanned_string(cx, expr, err_msg)
         .map_err(|err| {
-            err.map(|mut err| {
+            err.map(|(mut err, _)| {
                 err.emit();
             })
         })
index 55700f7b0d495e119b07b2fda73c744314082cce..02d92e7c90a0d07c89c5ac58f21df53caaab58ec 100644 (file)
@@ -758,6 +758,12 @@ fn end(&mut self, span: Self::Span) -> LineColumn {
         let loc = self.sess.source_map().lookup_char_pos(span.hi());
         LineColumn { line: loc.line, column: loc.col.to_usize() }
     }
+    fn before(&mut self, span: Self::Span) -> Self::Span {
+        span.shrink_to_lo()
+    }
+    fn after(&mut self, span: Self::Span) -> Self::Span {
+        span.shrink_to_hi()
+    }
     fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
         let self_loc = self.sess.source_map().lookup_char_pos(first.lo());
         let other_loc = self.sess.source_map().lookup_char_pos(second.lo());
index 725f8b8763af17d3d048395884ede1d07caec3c3..61e27d2e4cd41053db35dc55d60c8effeabdc63b 100644 (file)
@@ -16,7 +16,6 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                     edition: None,
-                    description: concat!($($doc,)*),
                 }
             ),+
         ];
index a3807a2bb9fde64cb5a3a6e2574de2a9176f145f..366ed715434eda4e2598b6ea7558588881b43e72 100644 (file)
@@ -37,7 +37,6 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                     edition: $edition,
-                    description: concat!($($doc,)*),
                 }
             ),+];
 
index e2aa54a59b2021401c8ab1f7fb751a34c50c1ac9..f74ea0e0c4d271c979df7f85c251922e1eb59f12 100644 (file)
@@ -453,6 +453,9 @@ macro_rules! experimental {
     ),
     // Enumerates "identity-like" conversion methods to suggest on type mismatch.
     rustc_attr!(rustc_conversion_suggestion, Normal, template!(Word), INTERNAL_UNSTABLE),
+    // Prevents field reads in the marked trait or method to be considered
+    // during dead code analysis.
+    rustc_attr!(rustc_trivial_field_reads, Normal, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Const related:
index cf102aa16e0571ffbf89dbbb64ced39c99282ebf..b25aab21e491afa1a54ac74cf7ad3fb7bff7bcc5 100644 (file)
@@ -51,7 +51,6 @@ pub struct Feature {
     pub since: &'static str,
     issue: Option<NonZeroU32>,
     pub edition: Option<Edition>,
-    description: &'static str,
 }
 
 #[derive(Copy, Clone, Debug)]
index efab0200ff502dbe26ea6c51fd9a563cc3eebe01..7b9b68268eacd8df4f5d51e684b5796f11a59e96 100644 (file)
@@ -16,7 +16,6 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                     edition: None,
-                    description: concat!($($doc,)*),
                 }
             ),+
         ];
@@ -34,7 +33,6 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                     edition: None,
-                    description: concat!($($doc,)*),
                 }
             ),+
         ];
index 4f07a0c67c13f43f50b1962a992b0c9b6ad50136..9850f395a0f650a05d9bbb3e06ddb24b248e17d1 100644 (file)
@@ -203,56 +203,57 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
   report_fatal_error("bad AttributeKind");
 }
 
+template<typename T> static inline void AddAttribute(T *t, unsigned Index, Attribute Attr) {
+#if LLVM_VERSION_LT(14, 0)
+  t->addAttribute(Index, Attr);
+#else
+  t->addAttributeAtIndex(Index, Attr);
+#endif
+}
+
 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
                                              LLVMRustAttribute RustAttr) {
   CallBase *Call = unwrap<CallBase>(Instr);
   Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
-  Call->addAttribute(Index, Attr);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
                                               const char *Name) {
   CallBase *Call = unwrap<CallBase>(Instr);
   Attribute Attr = Attribute::get(Call->getContext(), Name);
-  Call->addAttribute(Index, Attr);
+  AddAttribute(Call, Index, Attr);
 }
 
-
 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
                                                  unsigned Index,
                                                  uint32_t Bytes) {
   CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addAlignmentAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
+  Attribute Attr = Attribute::getWithAlignment(Call->getContext(), Align(Bytes));
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
                                                        unsigned Index,
                                                        uint64_t Bytes) {
   CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addDereferenceableAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
+  Attribute Attr = Attribute::getWithDereferenceableBytes(Call->getContext(), Bytes);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
                                                              unsigned Index,
                                                              uint64_t Bytes) {
   CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addDereferenceableOrNullAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
+  Attribute Attr = Attribute::getWithDereferenceableOrNullBytes(Call->getContext(), Bytes);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
                                              LLVMTypeRef Ty) {
   CallBase *Call = unwrap<CallBase>(Instr);
   Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
-  Call->addAttribute(Index, Attr);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned Index,
@@ -263,28 +264,28 @@ extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned In
 #else
   Attribute Attr = Attribute::get(Call->getContext(), Attribute::StructRet);
 #endif
-  Call->addAttribute(Index, Attr);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
                                              LLVMRustAttribute RustAttr) {
   Function *A = unwrap<Function>(Fn);
   Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
-  A->addAttribute(Index, Attr);
+  AddAttribute(A, Index, Attr);
 }
 
 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
                                          unsigned Index,
                                          uint32_t Bytes) {
   Function *A = unwrap<Function>(Fn);
-  A->addAttribute(Index, Attribute::getWithAlignment(
+  AddAttribute(A, Index, Attribute::getWithAlignment(
       A->getContext(), llvm::Align(Bytes)));
 }
 
 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
                                                uint64_t Bytes) {
   Function *A = unwrap<Function>(Fn);
-  A->addAttribute(Index, Attribute::getWithDereferenceableBytes(A->getContext(),
+  AddAttribute(A, Index, Attribute::getWithDereferenceableBytes(A->getContext(),
                                                                 Bytes));
 }
 
@@ -292,7 +293,7 @@ extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
                                                      unsigned Index,
                                                      uint64_t Bytes) {
   Function *A = unwrap<Function>(Fn);
-  A->addAttribute(Index, Attribute::getWithDereferenceableOrNullBytes(
+  AddAttribute(A, Index, Attribute::getWithDereferenceableOrNullBytes(
       A->getContext(), Bytes));
 }
 
@@ -300,7 +301,7 @@ extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
                                      LLVMTypeRef Ty) {
   Function *F = unwrap<Function>(Fn);
   Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
-  F->addAttribute(Index, Attr);
+  AddAttribute(F, Index, Attr);
 }
 
 extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
@@ -311,7 +312,7 @@ extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
 #else
   Attribute Attr = Attribute::get(F->getContext(), Attribute::StructRet);
 #endif
-  F->addAttribute(Index, Attr);
+  AddAttribute(F, Index, Attr);
 }
 
 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
@@ -319,7 +320,7 @@ extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
                                                    const char *Name,
                                                    const char *Value) {
   Function *F = unwrap<Function>(Fn);
-  F->addAttribute(Index, Attribute::get(
+  AddAttribute(F, Index, Attribute::get(
       F->getContext(), StringRef(Name), StringRef(Value)));
 }
 
@@ -330,7 +331,12 @@ extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
   Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
   AttrBuilder B(Attr);
   auto PAL = F->getAttributes();
-  auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
+  AttributeList PALNew;
+#if LLVM_VERSION_LT(14, 0)
+  PALNew = PAL.removeAttributes(F->getContext(), Index, B);
+#else
+  PALNew = PAL.removeAttributesAtIndex(F->getContext(), Index, B);
+#endif
   F->setAttributes(PALNew);
 }
 
index 1351b4950f143cb9714bd4cc95fbe2ca7ba208ee..082948eba416d62c08714c36ac92d1b9be971e53 100644 (file)
@@ -62,13 +62,6 @@ fn hash_body(
     stable_hasher.finish()
 }
 
-/// Represents an entry and its parent `HirId`.
-#[derive(Copy, Clone, Debug)]
-pub struct Entry<'hir> {
-    parent: HirId,
-    node: Node<'hir>,
-}
-
 impl<'a, 'hir> NodeCollector<'a, 'hir> {
     pub(super) fn root(
         sess: &'a Session,
index 32ccdafaeb48c926a87609b2d77ae89564a19b9d..1c7e022673d95f68b2c9e94fa6bfba389f890809 100644 (file)
@@ -28,7 +28,6 @@ fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
 /// things (e.g., each `DefId`/`DefPath` is only hashed once).
 #[derive(Clone)]
 pub struct StableHashingContext<'a> {
-    sess: &'a Session,
     definitions: &'a Definitions,
     cstore: &'a dyn CrateStore,
     pub(super) body_resolver: BodyResolver<'a>,
@@ -78,7 +77,6 @@ fn new_with_or_without_spans(
             !always_ignore_spans && !sess.opts.debugging_opts.incremental_ignore_spans;
 
         StableHashingContext {
-            sess,
             body_resolver: BodyResolver(krate),
             definitions,
             cstore,
index ba94e15444a1905f5c7efcd3da76cca26eab0edd..0ff3fc60995bf0a011082412a42f79d874b4cf73 100644 (file)
@@ -900,10 +900,7 @@ fn traverse_candidate<'pat, 'tcx: 'pat, C, T, I>(
 struct Binding<'tcx> {
     span: Span,
     source: Place<'tcx>,
-    name: Symbol,
     var_id: HirId,
-    var_ty: Ty<'tcx>,
-    mutability: Mutability,
     binding_mode: BindingMode,
 }
 
index 1feb8b0d7a06d4d670606ad508537afe718fa858..4ce26cc8dff46a10f4ecde92cba0feb3833425ac 100644 (file)
@@ -176,17 +176,22 @@ fn simplify_match_pair<'pat>(
                 Ok(())
             }
 
-            PatKind::Binding { name, mutability, mode, var, ty, ref subpattern, is_primary: _ } => {
+            PatKind::Binding {
+                name: _,
+                mutability: _,
+                mode,
+                var,
+                ty: _,
+                ref subpattern,
+                is_primary: _,
+            } => {
                 if let Ok(place_resolved) =
                     match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
                 {
                     candidate.bindings.push(Binding {
-                        name,
-                        mutability,
                         span: match_pair.pattern.span,
                         source: place_resolved.into_place(self.tcx, self.typeck_results),
                         var_id: var,
-                        var_ty: ty,
                         binding_mode: mode,
                     });
                 }
index bd8d14fcd012c2ec5965940a517e50b568c234ef..b74208edafea6172643d9c02f41a5a8cfb7679d2 100644 (file)
@@ -118,9 +118,6 @@ struct Scope {
     /// the region span of this scope within source code.
     region_scope: region::Scope,
 
-    /// the span of that region_scope
-    region_scope_span: Span,
-
     /// set of places to drop when exiting this scope. This starts
     /// out empty but grows as variables are declared during the
     /// building process. This is a stack, so we always drop from the
@@ -420,7 +417,6 @@ fn push_scope(&mut self, region_scope: (region::Scope, SourceInfo), vis_scope: S
         self.scopes.push(Scope {
             source_scope: vis_scope,
             region_scope: region_scope.0,
-            region_scope_span: region_scope.1.span,
             drops: vec![],
             moved_locals: vec![],
             cached_unwind_block: None,
index 6043606c37957da13fb600d9926ccdb49181a21a..b9e3c058ad7ec355e98206308bc31bb0e368cc5b 100644 (file)
@@ -263,7 +263,7 @@ fn inject_counters(&'a mut self) {
         }
 
         if let Err(e) = result {
-            bug!("Error processing: {:?}: {:?}", self.mir_body.source.def_id(), e)
+            bug!("Error processing: {:?}: {:?}", self.mir_body.source.def_id(), e.message)
         };
 
         // Depending on current `debug_options()`, `alert_on_unused_expressions()` could panic, so
index 05156745105a1c0a10b839720f00c8a957d153ef..dc80dab8c6c5f9d55f4c480a1ae932966fd74141 100644 (file)
@@ -1,9 +1,12 @@
 use super::pat::{RecoverColon, RecoverComma, PARAM_EXPECTED};
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
-use super::{AttrWrapper, BlockMode, ForceCollect, Parser, PathStyle, Restrictions, TokenType};
+use super::{
+    AttrWrapper, BlockMode, ClosureSpans, ForceCollect, Parser, PathStyle, Restrictions, TokenType,
+};
 use super::{SemiColonMode, SeqSep, TokenExpectType, TrailingToken};
 use crate::maybe_recover_from_interpolated_ty_qpath;
 
+use ast::token::DelimToken;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::tokenstream::Spacing;
@@ -91,6 +94,8 @@ impl<'a> Parser<'a> {
     /// Parses an expression.
     #[inline]
     pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
+        self.current_closure.take();
+
         self.parse_expr_res(Restrictions::empty(), None)
     }
 
@@ -1736,7 +1741,7 @@ fn parse_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
         let capture_clause = self.parse_capture_clause()?;
         let decl = self.parse_fn_block_decl()?;
         let decl_hi = self.prev_token.span;
-        let body = match decl.output {
+        let mut body = match decl.output {
             FnRetTy::Default(_) => {
                 let restrictions = self.restrictions - Restrictions::STMT_EXPR;
                 self.parse_expr_res(restrictions, None)?
@@ -1753,11 +1758,28 @@ fn parse_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
             self.sess.gated_spans.gate(sym::async_closure, span);
         }
 
-        Ok(self.mk_expr(
+        if self.token.kind == TokenKind::Semi && self.token_cursor.frame.delim == DelimToken::Paren
+        {
+            // It is likely that the closure body is a block but where the
+            // braces have been removed. We will recover and eat the next
+            // statements later in the parsing process.
+            body = self.mk_expr_err(body.span);
+        }
+
+        let body_span = body.span;
+
+        let closure = self.mk_expr(
             lo.to(body.span),
             ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)),
             attrs,
-        ))
+        );
+
+        // Disable recovery for closure body
+        let spans =
+            ClosureSpans { whole_closure: closure.span, closing_pipe: decl_hi, body: body_span };
+        self.current_closure = Some(spans);
+
+        Ok(closure)
     }
 
     /// Parses an optional `move` prefix to a closure-like construct.
index c4419e995edac84940900418d87186aecdb89235..5c701fefd17de95b0d95dfaeaa64f625f61f27e2 100644 (file)
@@ -142,6 +142,17 @@ pub struct Parser<'a> {
     /// If present, this `Parser` is not parsing Rust code but rather a macro call.
     subparser_name: Option<&'static str>,
     capture_state: CaptureState,
+    /// This allows us to recover when the user forget to add braces around
+    /// multiple statements in the closure body.
+    pub current_closure: Option<ClosureSpans>,
+}
+
+/// Stores span informations about a closure.
+#[derive(Clone)]
+pub struct ClosureSpans {
+    pub whole_closure: Span,
+    pub closing_pipe: Span,
+    pub body: Span,
 }
 
 /// Indicates a range of tokens that should be replaced by
@@ -440,6 +451,7 @@ pub fn new(
                 replace_ranges: Vec::new(),
                 inner_attr_ranges: Default::default(),
             },
+            current_closure: None,
         };
 
         // Make parser point to the first token.
@@ -761,8 +773,11 @@ fn parse_seq_to_before_tokens<T>(
                     first = false;
                 } else {
                     match self.expect(t) {
-                        Ok(false) => {}
+                        Ok(false) => {
+                            self.current_closure.take();
+                        }
                         Ok(true) => {
+                            self.current_closure.take();
                             recovered = true;
                             break;
                         }
@@ -770,10 +785,29 @@ fn parse_seq_to_before_tokens<T>(
                             let sp = self.prev_token.span.shrink_to_hi();
                             let token_str = pprust::token_kind_to_string(t);
 
-                            // Attempt to keep parsing if it was a similar separator.
-                            if let Some(ref tokens) = t.similar_tokens() {
-                                if tokens.contains(&self.token.kind) && !unclosed_delims {
-                                    self.bump();
+                            match self.current_closure.take() {
+                                Some(closure_spans) if self.token.kind == TokenKind::Semi => {
+                                    // Finding a semicolon instead of a comma
+                                    // after a closure body indicates that the
+                                    // closure body may be a block but the user
+                                    // forgot to put braces around its
+                                    // statements.
+
+                                    self.recover_missing_braces_around_closure_body(
+                                        closure_spans,
+                                        expect_err,
+                                    )?;
+
+                                    continue;
+                                }
+
+                                _ => {
+                                    // Attempt to keep parsing if it was a similar separator.
+                                    if let Some(ref tokens) = t.similar_tokens() {
+                                        if tokens.contains(&self.token.kind) && !unclosed_delims {
+                                            self.bump();
+                                        }
+                                    }
                                 }
                             }
 
@@ -839,6 +873,65 @@ fn parse_seq_to_before_tokens<T>(
         Ok((v, trailing, recovered))
     }
 
+    fn recover_missing_braces_around_closure_body(
+        &mut self,
+        closure_spans: ClosureSpans,
+        mut expect_err: DiagnosticBuilder<'_>,
+    ) -> PResult<'a, ()> {
+        let initial_semicolon = self.token.span;
+
+        while self.eat(&TokenKind::Semi) {
+            let _ = self.parse_stmt(ForceCollect::Yes)?;
+        }
+
+        expect_err.set_primary_message(
+            "closure bodies that contain statements must be surrounded by braces",
+        );
+
+        let preceding_pipe_span = closure_spans.closing_pipe;
+        let following_token_span = self.token.span;
+
+        let mut first_note = MultiSpan::from(vec![initial_semicolon]);
+        first_note.push_span_label(
+            initial_semicolon,
+            "this `;` turns the preceding closure into a statement".to_string(),
+        );
+        first_note.push_span_label(
+            closure_spans.body,
+            "this expression is a statement because of the trailing semicolon".to_string(),
+        );
+        expect_err.span_note(first_note, "statement found outside of a block");
+
+        let mut second_note = MultiSpan::from(vec![closure_spans.whole_closure]);
+        second_note.push_span_label(
+            closure_spans.whole_closure,
+            "this is the parsed closure...".to_string(),
+        );
+        second_note.push_span_label(
+            following_token_span,
+            "...but likely you meant the closure to end here".to_string(),
+        );
+        expect_err.span_note(second_note, "the closure body may be incorrectly delimited");
+
+        expect_err.set_span(vec![preceding_pipe_span, following_token_span]);
+
+        let opening_suggestion_str = " {".to_string();
+        let closing_suggestion_str = "}".to_string();
+
+        expect_err.multipart_suggestion(
+            "try adding braces",
+            vec![
+                (preceding_pipe_span.shrink_to_hi(), opening_suggestion_str),
+                (following_token_span.shrink_to_lo(), closing_suggestion_str),
+            ],
+            Applicability::MaybeIncorrect,
+        );
+
+        expect_err.emit();
+
+        Ok(())
+    }
+
     /// Parses a sequence, not including the closing delimiter. The function
     /// `f` must consume tokens until reaching the next separator or
     /// closing bracket.
index 25ad00aaf1f753caa8f98f37224d898d5e1528ee..0a3093757166afee7641ddea25449c5322b27b17 100644 (file)
@@ -239,7 +239,69 @@ fn mark_live_symbols(&mut self) {
         }
     }
 
+    /// Automatically generated items marked with `rustc_trivial_field_reads`
+    /// will be ignored for the purposes of dead code analysis (see PR #85200
+    /// for discussion).
+    fn should_ignore_item(&self, def_id: DefId) -> bool {
+        if !self.tcx.has_attr(def_id, sym::automatically_derived)
+            && !self
+                .tcx
+                .impl_of_method(def_id)
+                .map_or(false, |impl_id| self.tcx.has_attr(impl_id, sym::automatically_derived))
+        {
+            return false;
+        }
+
+        let has_attr = |def_id| self.tcx.has_attr(def_id, sym::rustc_trivial_field_reads);
+
+        if has_attr(def_id) {
+            return true;
+        }
+
+        if let Some(impl_of) = self.tcx.impl_of_method(def_id) {
+            if has_attr(impl_of) {
+                return true;
+            }
+
+            if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of) {
+                if has_attr(trait_of) {
+                    return true;
+                }
+
+                if let Some(method_ident) = self.tcx.opt_item_name(def_id) {
+                    if let Some(trait_method) = self
+                        .tcx
+                        .associated_items(trait_of)
+                        .find_by_name_and_kind(self.tcx, method_ident, ty::AssocKind::Fn, trait_of)
+                    {
+                        if has_attr(trait_method.def_id) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        } else if let Some(trait_of) = self.tcx.trait_of_item(def_id) {
+            if has_attr(trait_of) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     fn visit_node(&mut self, node: Node<'tcx>) {
+        if let Some(item_def_id) = match node {
+            Node::Item(hir::Item { def_id, .. })
+            | Node::ForeignItem(hir::ForeignItem { def_id, .. })
+            | Node::TraitItem(hir::TraitItem { def_id, .. })
+            | Node::ImplItem(hir::ImplItem { def_id, .. }) => Some(def_id.to_def_id()),
+            _ => None,
+        } {
+            if self.should_ignore_item(item_def_id) {
+                return;
+            }
+        }
+
         let had_repr_c = self.repr_has_repr_c;
         let had_inherited_pub_visibility = self.inherited_pub_visibility;
         let had_pub_visibility = self.pub_visibility;
index 24023163cc30eb2b2ca072313f21f421f86b5764..c816d06045681ddebc9d40cf9417ade9768973da 100644 (file)
         rustc_synthetic,
         rustc_test_marker,
         rustc_then_this_would_need,
+        rustc_trivial_field_reads,
         rustc_unsafe_specialization_marker,
         rustc_variance,
         rustdoc,
index 0d3fd748645edb266980aa635a32a72f011529d5..9371ff3405eb04aefe6c3eca22c305faffd2349e 100644 (file)
@@ -23,7 +23,7 @@
 use rustc_middle::ty::{TypeAndMut, TypeckResults};
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
+use rustc_span::{BytePos, DesugaringKind, ExpnKind, ForLoopLoc, MultiSpan, Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use std::fmt;
 
@@ -680,7 +680,13 @@ fn suggest_add_reference_to_arg(
         points_at_arg: bool,
         has_custom_message: bool,
     ) -> bool {
-        if !points_at_arg {
+        let span = obligation.cause.span;
+        let points_at_for_iter = matches!(
+            span.ctxt().outer_expn_data().kind,
+            ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
+        );
+
+        if !points_at_arg && !points_at_for_iter {
             return false;
         }
 
@@ -695,7 +701,6 @@ fn suggest_add_reference_to_arg(
 
         never_suggest_borrow.push(self.tcx.get_diagnostic_item(sym::send_trait).unwrap());
 
-        let span = obligation.cause.span;
         let param_env = obligation.param_env;
         let trait_ref = trait_ref.skip_binder();
 
@@ -754,7 +759,11 @@ fn suggest_add_reference_to_arg(
                     );
 
                     // This if is to prevent a special edge-case
-                    if !span.from_expansion() {
+                    if matches!(
+                        span.ctxt().outer_expn_data().kind,
+                        ExpnKind::Root
+                            | ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
+                    ) {
                         // We don't want a borrowing suggestion on the fields in structs,
                         // ```
                         // struct Foo {
index 19faf9cddac6faa392a946742d00807d7441bf29..b02333b028850fd7a831adeb811e3bd6c7b37e61 100644 (file)
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "clone"]
 #[rustc_diagnostic_item = "Clone"]
+#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
 pub trait Clone: Sized {
     /// Returns a copy of the value.
     ///
index 0a29843c9cf271b5ddd45c528748009d70903fff..166a8e3f28a4190e9adfeda75b90ec29153b8429 100644 (file)
@@ -582,6 +582,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
 )]
 #[doc(alias = "{:?}")]
 #[rustc_diagnostic_item = "debug_trait"]
+#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
 pub trait Debug {
     /// Formats the value using the given formatter.
     ///
index 7580010a28b4a5394ef5665d09f0a0a12a509e62..9567479c8137b5d4f0a7e8e0f07d7ee8edc0da12 100644 (file)
@@ -653,6 +653,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
 fn test_formatting_parameters_are_forwarded() {
     use std::collections::{BTreeMap, BTreeSet};
     #[derive(Debug)]
+    #[allow(dead_code)]
     struct Foo {
         bar: u32,
         baz: u32,
index 7001e827ad8456778b1225f190a2fcdf596551d2..bb05506defd0778c8f1f24e72d2a9d1617a64121 100644 (file)
@@ -162,6 +162,8 @@ fn sub(
                 fn source($self: $S::Span) -> $S::Span;
                 fn start($self: $S::Span) -> LineColumn;
                 fn end($self: $S::Span) -> LineColumn;
+                fn before($self: $S::Span) -> $S::Span;
+                fn after($self: $S::Span) -> $S::Span;
                 fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
                 fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
                 fn source_text($self: $S::Span) -> Option<String>;
index 243922b18b565dfd0a5b55fdf944f04d9f7aa555..e21a1507a62e200689e9a2d182d2673461baaa0f 100644 (file)
@@ -357,6 +357,18 @@ pub fn end(&self) -> LineColumn {
         self.0.end().add_1_to_column()
     }
 
+    /// Creates an empty span pointing to directly before this span.
+    #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
+    pub fn before(&self) -> Span {
+        Span(self.0.before())
+    }
+
+    /// Creates an empty span pointing to directly after this span.
+    #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
+    pub fn after(&self) -> Span {
+        Span(self.0.after())
+    }
+
     /// Creates a new span encompassing `self` and `other`.
     ///
     /// Returns `None` if `self` and `other` are from different files.
index 130bb5cb2b3c2b77f6b7402330dd2ded199be0f7..71645aadb1d88b717eb03e341be65ef07a24982b 100644 (file)
 //! Iterators also provide a series of *adapter* methods for performing common
 //! threads to sequences. Among the adapters are functional favorites like `map`,
 //! `fold`, `skip` and `take`. Of particular interest to collections is the
-//! `rev` adapter, that reverses any iterator that supports this operation. Most
+//! `rev` adapter, which reverses any iterator that supports this operation. Most
 //! collections provide reversible iterators as the way to iterate over them in
 //! reverse order.
 //!
index f6c2b499567abf9b245c42903ec5c98bd10cf780..d290c3c466035d5e2da432db494d263af24218b9 100644 (file)
@@ -468,9 +468,6 @@ struct ProgrammableSink {
     // Writes append to this slice
     pub buffer: Vec<u8>,
 
-    // Flush sets this flag
-    pub flushed: bool,
-
     // If true, writes will always be an error
     pub always_write_error: bool,
 
@@ -520,7 +517,6 @@ fn flush(&mut self) -> io::Result<()> {
         if self.always_flush_error {
             Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error"))
         } else {
-            self.flushed = true;
             Ok(())
         }
     }
index e8466fa06b899470cb213eb6ea295fdc1d6d86b6..4a35d36a9def72f284b48244219b347a9d140e80 100644 (file)
@@ -1611,7 +1611,7 @@ fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
     /// encountered.
     ///
     /// This method is primarily used to interface with the
-    /// [`format_args!()`] macro, but it is rare that this should
+    /// [`format_args!()`] macro, and it is rare that this should
     /// explicitly be called. The [`write!()`] macro should be favored to
     /// invoke this method instead.
     ///
index f4c5a05d1e2cebbd97f717274c5d40c434887b78..694473f52c1a79970e86b1888b737e305db37041 100644 (file)
@@ -16,6 +16,7 @@
 use searcher::get_dbpath_for_term;
 
 /// A parsed terminfo database entry.
+#[allow(unused)]
 #[derive(Debug)]
 pub(crate) struct TermInfo {
     /// Names for the terminal
index a10928a7471770ae520ba86dd2a8396096cce420..444b1cbf3cc45535d01a4f66a67c2ee4df84db76 100644 (file)
@@ -375,7 +375,7 @@ Any reuse of a named label, local or otherwise, can result in a assembler or lin
 
 As a consequence, you should only use GNU assembler **numeric** [local labels] inside inline assembly code. Defining symbols in assembly code may lead to assembler and/or linker errors due to duplicate symbol definitions.
 
-Moreover, on x86 when using the default intel syntax, due to [an llvm bug], you shouldn't use labels exclusively made of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values. Using `option(att_syntax)` will avoid any ambiguity, but that affects the syntax of the _entire_ `asm!` block.
+Moreover, on x86 when using the default intel syntax, due to [an llvm bug], you shouldn't use labels exclusively made of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values. Using `options(att_syntax)` will avoid any ambiguity, but that affects the syntax of the _entire_ `asm!` block.
 
 ```rust,allow_fail
 #![feature(asm)]
index 0c81a5584301355e4d70e84c4b8139751c0d5b6b..78e4e4ec116da2693e430ea058ebe7826a0dae81 100644 (file)
@@ -557,7 +557,6 @@ fn build_macro(
     name: Symbol,
     import_def_id: Option<DefId>,
 ) -> clean::ItemKind {
-    let imported_from = cx.tcx.crate_name(def_id.krate);
     match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
         LoadedMacro::MacroDef(item_def, _) => {
             if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
@@ -569,7 +568,6 @@ fn build_macro(
                         def_id,
                         cx.tcx.visibility(import_def_id.unwrap_or(def_id)),
                     ),
-                    imported_from: Some(imported_from),
                 })
             } else {
                 unreachable!()
index e2ad21bba21b754400031c8bc6283494d0f974e9..7ece2acac7a406ca6e7a2000b3f6931cd57fab18 100644 (file)
@@ -1859,7 +1859,6 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Vec<Item> {
                 }
                 ItemKind::Macro(ref macro_def) => MacroItem(Macro {
                     source: display_macro_source(cx, name, &macro_def, def_id, &item.vis),
-                    imported_from: None,
                 }),
                 ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
                     let items = item_ids
index 5eff56a2200e10d396cfc9eba35c29b37b486859..5f09e6ced96d45f6558f7383d8904c902ef689c7 100644 (file)
@@ -2202,7 +2202,6 @@ impl Import {
 #[derive(Clone, Debug)]
 crate struct Macro {
     crate source: String,
-    crate imported_from: Option<Symbol>,
 }
 
 #[derive(Clone, Debug)]
index 5cd5254f3282d00f6dc4be2d0a37ede3613ed41d..c971e231463cdc56dd1f58c5871e06a7537f9168 100644 (file)
@@ -48,7 +48,7 @@
 mod tests;
 
 /// Options for rendering Markdown in the main body of documentation.
-pub(crate) fn opts() -> Options {
+pub(crate) fn main_body_opts() -> Options {
     Options::ENABLE_TABLES
         | Options::ENABLE_FOOTNOTES
         | Options::ENABLE_STRIKETHROUGH
@@ -56,9 +56,13 @@ pub(crate) fn opts() -> Options {
         | Options::ENABLE_SMART_PUNCTUATION
 }
 
-/// A subset of [`opts()`] used for rendering summaries.
+/// Options for rendering Markdown in summaries (e.g., in search results).
 pub(crate) fn summary_opts() -> Options {
-    Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION | Options::ENABLE_TABLES
+    Options::ENABLE_TABLES
+        | Options::ENABLE_FOOTNOTES
+        | Options::ENABLE_STRIKETHROUGH
+        | Options::ENABLE_TASKLISTS
+        | Options::ENABLE_SMART_PUNCTUATION
 }
 
 /// When `to_string` is called, this struct will emit the HTML corresponding to
@@ -441,6 +445,42 @@ fn next(&mut self) -> Option<Self::Item> {
     }
 }
 
+/// Wrap HTML tables into `<div>` to prevent having the doc blocks width being too big.
+struct TableWrapper<'a, I: Iterator<Item = Event<'a>>> {
+    inner: I,
+    stored_events: VecDeque<Event<'a>>,
+}
+
+impl<'a, I: Iterator<Item = Event<'a>>> TableWrapper<'a, I> {
+    fn new(iter: I) -> Self {
+        Self { inner: iter, stored_events: VecDeque::new() }
+    }
+}
+
+impl<'a, I: Iterator<Item = Event<'a>>> Iterator for TableWrapper<'a, I> {
+    type Item = Event<'a>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if let Some(first) = self.stored_events.pop_front() {
+            return Some(first);
+        }
+
+        let event = self.inner.next()?;
+
+        Some(match event {
+            Event::Start(Tag::Table(t)) => {
+                self.stored_events.push_back(Event::Start(Tag::Table(t)));
+                Event::Html(CowStr::Borrowed("<div>"))
+            }
+            Event::End(Tag::Table(t)) => {
+                self.stored_events.push_back(Event::Html(CowStr::Borrowed("</div>")));
+                Event::End(Tag::Table(t))
+            }
+            e => e,
+        })
+    }
+}
+
 type SpannedEvent<'a> = (Event<'a>, Range<usize>);
 
 /// Make headings links with anchor IDs and build up TOC.
@@ -981,7 +1021,7 @@ pub fn into_string(self) -> String {
             }
         };
 
-        let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
+        let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut replacer));
         let p = p.into_offset_iter();
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
@@ -989,6 +1029,7 @@ pub fn into_string(self) -> String {
         let p = HeadingLinks::new(p, None, &mut ids);
         let p = Footnotes::new(p);
         let p = LinkReplacer::new(p.map(|(ev, _)| ev), links);
+        let p = TableWrapper::new(p);
         let p = CodeBlocks::new(p, codes, edition, playground);
         html::push_html(&mut s, p);
 
@@ -1000,7 +1041,7 @@ impl MarkdownWithToc<'_> {
     crate fn into_string(self) -> String {
         let MarkdownWithToc(md, mut ids, codes, edition, playground) = self;
 
-        let p = Parser::new_ext(md, opts()).into_offset_iter();
+        let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
@@ -1009,7 +1050,8 @@ impl MarkdownWithToc<'_> {
         {
             let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
             let p = Footnotes::new(p);
-            let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
+            let p = TableWrapper::new(p.map(|(ev, _)| ev));
+            let p = CodeBlocks::new(p, codes, edition, playground);
             html::push_html(&mut s, p);
         }
 
@@ -1025,7 +1067,7 @@ impl MarkdownHtml<'_> {
         if md.is_empty() {
             return String::new();
         }
-        let p = Parser::new_ext(md, opts()).into_offset_iter();
+        let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
 
         // Treat inline HTML as plain text.
         let p = p.map(|event| match event.0 {
@@ -1037,7 +1079,8 @@ impl MarkdownHtml<'_> {
 
         let p = HeadingLinks::new(p, None, &mut ids);
         let p = Footnotes::new(p);
-        let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
+        let p = TableWrapper::new(p.map(|(ev, _)| ev));
+        let p = CodeBlocks::new(p, codes, edition, playground);
         html::push_html(&mut s, p);
 
         s
@@ -1099,7 +1142,7 @@ fn markdown_summary_with_limit(
         }
     };
 
-    let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
+    let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer));
     let mut p = LinkReplacer::new(p, link_names);
 
     let mut buf = HtmlWithLimit::new(length_limit);
@@ -1246,7 +1289,8 @@ fn markdown_summary_with_limit(
         });
         None
     };
-    let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push)).into_offset_iter();
+    let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut push))
+        .into_offset_iter();
 
     // There's no need to thread an IdMap through to here because
     // the IDs generated aren't going to be emitted anywhere.
@@ -1285,7 +1329,7 @@ fn markdown_summary_with_limit(
         return code_blocks;
     }
 
-    let mut p = Parser::new_ext(md, opts()).into_offset_iter();
+    let mut p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
 
     while let Some((event, offset)) = p.next() {
         if let Event::Start(Tag::CodeBlock(syntax)) = event {
index 172fe5d164b7afc1f123971b97a2d7fa5b8b4d76..f71660c4b2ab26c96aaa519dbbab0efd7d8e9349 100644 (file)
@@ -224,7 +224,6 @@ struct AllTypes {
     opaque_tys: FxHashSet<ItemEntry>,
     statics: FxHashSet<ItemEntry>,
     constants: FxHashSet<ItemEntry>,
-    keywords: FxHashSet<ItemEntry>,
     attributes: FxHashSet<ItemEntry>,
     derives: FxHashSet<ItemEntry>,
     trait_aliases: FxHashSet<ItemEntry>,
@@ -245,7 +244,6 @@ fn new() -> AllTypes {
             opaque_tys: new_set(100),
             statics: new_set(100),
             constants: new_set(100),
-            keywords: new_set(100),
             attributes: new_set(100),
             derives: new_set(100),
             trait_aliases: new_set(100),
index 470749ef7b3387759cc295e21533a43bab114636..52505f2d634717fa70f06a43f59d0a528a24b0f7 100644 (file)
@@ -256,6 +256,10 @@ fn cmp(
 
     debug!("{:?}", indices);
     let mut curty = None;
+    // See: https://github.com/rust-lang/rust/issues/88545
+    let item_table_block_size = 900usize;
+    let mut item_table_nth_element = 0usize;
+
     for &idx in &indices {
         let myitem = &items[idx];
         if myitem.is_stripped() {
@@ -275,11 +279,13 @@ fn cmp(
             write!(
                 w,
                 "<h2 id=\"{id}\" class=\"section-header\">\
-                       <a href=\"#{id}\">{name}</a></h2>\n{}",
+                    <a href=\"#{id}\">{name}</a>\
+                 </h2>\n{}",
                 ITEM_TABLE_OPEN,
                 id = cx.derive_id(short.to_owned()),
                 name = name
             );
+            item_table_nth_element = 0;
         }
 
         match *myitem.kind {
@@ -386,6 +392,13 @@ fn cmp(
                 );
             }
         }
+
+        item_table_nth_element += 1;
+        if item_table_nth_element > item_table_block_size {
+            w.write_str(ITEM_TABLE_CLOSE);
+            w.write_str(ITEM_TABLE_OPEN);
+            item_table_nth_element = 0;
+        }
     }
 
     if curty.is_some() {
@@ -944,15 +957,15 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
 }
 
 fn print_tuple_struct_fields(w: &mut Buffer, cx: &Context<'_>, s: &[clean::Item]) {
-    for (i, ty) in s
-        .iter()
-        .map(|f| if let clean::StructFieldItem(ref ty) = *f.kind { ty } else { unreachable!() })
-        .enumerate()
-    {
+    for (i, ty) in s.iter().enumerate() {
         if i > 0 {
             w.write_str(",&nbsp;");
         }
-        write!(w, "{}", ty.print(cx));
+        match *ty.kind {
+            clean::StrippedItem(box clean::StructFieldItem(_)) => w.write_str("_"),
+            clean::StructFieldItem(ref ty) => write!(w, "{}", ty.print(cx)),
+            _ => unreachable!(),
+        }
     }
 }
 
@@ -1068,24 +1081,27 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
                     name = variant.name.as_ref().unwrap(),
                 );
                 for field in fields {
-                    use crate::clean::StructFieldItem;
-                    if let StructFieldItem(ref ty) = *field.kind {
-                        let id = cx.derive_id(format!(
-                            "variant.{}.field.{}",
-                            variant.name.as_ref().unwrap(),
-                            field.name.as_ref().unwrap()
-                        ));
-                        write!(
-                            w,
-                            "<span id=\"{id}\" class=\"variant small-section-header\">\
-                                 <a href=\"#{id}\" class=\"anchor field\"></a>\
-                                 <code>{f}:&nbsp;{t}</code>\
-                             </span>",
-                            id = id,
-                            f = field.name.as_ref().unwrap(),
-                            t = ty.print(cx)
-                        );
-                        document(w, cx, field, Some(variant));
+                    match *field.kind {
+                        clean::StrippedItem(box clean::StructFieldItem(_)) => {}
+                        clean::StructFieldItem(ref ty) => {
+                            let id = cx.derive_id(format!(
+                                "variant.{}.field.{}",
+                                variant.name.as_ref().unwrap(),
+                                field.name.as_ref().unwrap()
+                            ));
+                            write!(
+                                w,
+                                "<span id=\"{id}\" class=\"variant small-section-header\">\
+                                    <a href=\"#{id}\" class=\"anchor field\"></a>\
+                                    <code>{f}:&nbsp;{t}</code>\
+                                </span>",
+                                id = id,
+                                f = field.name.as_ref().unwrap(),
+                                t = ty.print(cx)
+                            );
+                            document(w, cx, field, Some(variant));
+                        }
+                        _ => unreachable!(),
                     }
                 }
                 w.write_str("</div></div>");
index 23ca6eeaf3bb969be1af9f6ab6526bdfa12a0171..2d4bfc62af68e94e5fa26c8c14ba306b2953a903 100644 (file)
@@ -522,6 +522,11 @@ nav.sub {
        position: relative;
 }
 
+.docblock > * {
+       max-width: 100%;
+       overflow-x: auto;
+}
+
 .content .out-of-band {
        flex-grow: 0;
        text-align: right;
index 56ef15eb8842017b1320425fb719f4cf8390895c..37faa6742927a2860a543ab97f36f5a42dd92ce7 100644 (file)
@@ -2,7 +2,7 @@
 use crate::clean::*;
 use crate::core::DocContext;
 use crate::fold::DocFolder;
-use crate::html::markdown::opts;
+use crate::html::markdown::main_body_opts;
 use core::ops::Range;
 use pulldown_cmark::{Event, Parser, Tag};
 use regex::Regex;
@@ -83,7 +83,7 @@ fn fold_item(&mut self, item: Item) -> Option<Item> {
                 });
             };
 
-            let mut p = Parser::new_ext(&dox, opts()).into_offset_iter();
+            let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
 
             while let Some((event, range)) = p.next() {
                 match event {
index 92e678e4c024ba9f3f67b8f2f3bba8aa35715570..721af3313d27f6d33d76888b36d25f9fbcc62818 100644 (file)
@@ -4,8 +4,10 @@
 use crate::html::markdown::{find_testable_code, ErrorCodes};
 use crate::passes::doc_test_lints::{should_have_doc_example, Tests};
 use crate::passes::Pass;
+use rustc_hir as hir;
 use rustc_lint::builtin::MISSING_DOCS;
 use rustc_middle::lint::LintLevelSource;
+use rustc_middle::ty::DefIdTree;
 use rustc_session::lint;
 use rustc_span::FileName;
 use serde::Serialize;
@@ -221,10 +223,42 @@ fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
                     .hir()
                     .local_def_id_to_hir_id(i.def_id.expect_def_id().expect_local());
                 let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id);
+
+                // In case we have:
+                //
+                // ```
+                // enum Foo { Bar(u32) }
+                // // or:
+                // struct Bar(u32);
+                // ```
+                //
+                // there is no need to require documentation on the fields of tuple variants and
+                // tuple structs.
+                let should_be_ignored = i
+                    .def_id
+                    .as_def_id()
+                    .and_then(|def_id| self.ctx.tcx.parent(def_id))
+                    .and_then(|def_id| self.ctx.tcx.hir().get_if_local(def_id))
+                    .map(|node| {
+                        matches!(
+                            node,
+                            hir::Node::Variant(hir::Variant {
+                                data: hir::VariantData::Tuple(_, _),
+                                ..
+                            }) | hir::Node::Item(hir::Item {
+                                kind: hir::ItemKind::Struct(hir::VariantData::Tuple(_, _), _),
+                                ..
+                            })
+                        )
+                    })
+                    .unwrap_or(false);
+
                 // `missing_docs` is allow-by-default, so don't treat this as ignoring the item
-                // unless the user had an explicit `allow`
-                let should_have_docs =
-                    level != lint::Level::Allow || matches!(source, LintLevelSource::Default);
+                // unless the user had an explicit `allow`.
+                //
+                let should_have_docs = !should_be_ignored
+                    && (level != lint::Level::Allow || matches!(source, LintLevelSource::Default));
+
                 debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
                 self.items.entry(filename).or_default().count_item(
                     has_docs,
index f29d38e3e078a51251edb7668d72fa0465f0a8ef..a0144a5298eba24b3d2cc94f0e6d562473c00d08 100644 (file)
@@ -2,7 +2,7 @@
 use crate::clean::*;
 use crate::core::DocContext;
 use crate::fold::DocFolder;
-use crate::html::markdown::opts;
+use crate::html::markdown::main_body_opts;
 use core::ops::Range;
 use pulldown_cmark::{Event, Parser, Tag};
 use std::iter::Peekable;
@@ -192,7 +192,7 @@ fn fold_item(&mut self, item: Item) -> Option<Item> {
             let mut is_in_comment = None;
             let mut in_code_block = false;
 
-            let p = Parser::new_ext(&dox, opts()).into_offset_iter();
+            let p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
 
             for (event, range) in p {
                 match event {
index 9ab7cd0fa07b04c4dd2ad746e5380c9884af8e63..10f516d2dae06703003c3a1336ad0da560207867 100644 (file)
@@ -7,3 +7,11 @@ compare-elements-property: (".top-doc .docblock", ".top-doc .docblock > p", ["sc
 assert-property: (".top-doc .docblock", {"scrollWidth": "816"})
 // However, since there is overflow in the <table>, its scroll width is bigger.
 assert-property: (".top-doc .docblock table", {"scrollWidth": "1573"})
+
+// Checking it works on other doc blocks as well...
+
+// Logically, the ".docblock" and the "<p>" should have the same scroll width.
+compare-elements-property: ("#implementations + details .docblock", "#implementations + details .docblock > p", ["scrollWidth"])
+assert-property: ("#implementations + details .docblock", {"scrollWidth": "816"})
+// However, since there is overflow in the <table>, its scroll width is bigger.
+assert-property: ("#implementations + details .docblock table", {"scrollWidth": "1573"})
index cb63a9f60022702881b01a86ac23d0299b5226f0..d5835b78d2fcf17a5d9457c0c9de39a691cd80af 100644 (file)
@@ -67,6 +67,15 @@ pub mod long_table {
     ///
     /// I wanna sqdkfnqds f dsqf qds f dsqf dsq f dsq f qds f qds f qds f dsqq f dsf sqdf dsq fds f dsq f dq f ds fq sd fqds f dsq f sqd fsq df sd fdsqfqsd fdsq f dsq f dsqfd s dfq
     pub struct Foo;
+
+    /// | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two |
+    /// | ----------- | ----------- | ----------- | ----------- |
+    /// | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two |
+    ///
+    /// I wanna sqdkfnqds f dsqf qds f dsqf dsq f dsq f qds f qds f qds f dsqq f dsf sqdf dsq fds f dsq f dq f ds fq sd fqds f dsq f sqd fsq df sd fdsqfqsd fdsq f dsq f dsqfd s dfq
+    impl Foo {
+        pub fn foo(&self) {}
+    }
 }
 
 pub mod summary_table {
diff --git a/src/test/rustdoc-ui/coverage/enum-tuple-documented.rs b/src/test/rustdoc-ui/coverage/enum-tuple-documented.rs
new file mode 100644 (file)
index 0000000..e9c165b
--- /dev/null
@@ -0,0 +1,37 @@
+// compile-flags:-Z unstable-options --show-coverage
+// check-pass
+
+// The point of this test is to ensure that the number of "documented" items
+// is higher than in `enum-tuple.rs`.
+
+//! (remember the crate root is still a module)
+
+/// so check out this enum here
+pub enum ThisEnum {
+    /// VarOne.
+    VarOne(
+        /// hello!
+        String,
+    ),
+    /// Var Two.
+    VarTwo(
+        /// Hello
+        String,
+        /// Bis repetita.
+        String,
+    ),
+}
+
+/// Struct.
+pub struct ThisStruct(
+    /// hello
+    u32,
+);
+
+/// Struct.
+pub struct ThisStruct2(
+    /// hello
+    u32,
+    /// Bis repetita.
+    u8,
+);
diff --git a/src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout b/src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout
new file mode 100644 (file)
index 0000000..82c98f4
--- /dev/null
@@ -0,0 +1,7 @@
++-------------------------------------+------------+------------+------------+------------+
+| File                                | Documented | Percentage |   Examples | Percentage |
++-------------------------------------+------------+------------+------------+------------+
+| ...overage/enum-tuple-documented.rs |          9 |     100.0% |          0 |       0.0% |
++-------------------------------------+------------+------------+------------+------------+
+| Total                               |          9 |     100.0% |          0 |       0.0% |
++-------------------------------------+------------+------------+------------+------------+
diff --git a/src/test/rustdoc-ui/coverage/enum-tuple.rs b/src/test/rustdoc-ui/coverage/enum-tuple.rs
new file mode 100644 (file)
index 0000000..5fb2054
--- /dev/null
@@ -0,0 +1,18 @@
+// compile-flags:-Z unstable-options --show-coverage
+// check-pass
+
+//! (remember the crate root is still a module)
+
+/// so check out this enum here
+pub enum ThisEnum {
+    /// No need to document the field if there is only one in a tuple variant!
+    VarOne(String),
+    /// But if there is more than one... still fine!
+    VarTwo(String, String),
+}
+
+/// Struct.
+pub struct ThisStruct(u32);
+
+/// Struct.
+pub struct ThisStruct2(u32, u8);
diff --git a/src/test/rustdoc-ui/coverage/enum-tuple.stdout b/src/test/rustdoc-ui/coverage/enum-tuple.stdout
new file mode 100644 (file)
index 0000000..a3377d5
--- /dev/null
@@ -0,0 +1,7 @@
++-------------------------------------+------------+------------+------------+------------+
+| File                                | Documented | Percentage |   Examples | Percentage |
++-------------------------------------+------------+------------+------------+------------+
+| ...ustdoc-ui/coverage/enum-tuple.rs |          6 |     100.0% |          0 |       0.0% |
++-------------------------------------+------------+------------+------------+------------+
+| Total                               |          6 |     100.0% |          0 |       0.0% |
++-------------------------------------+------------+------------+------------+------------+
index 414d60c86d3083b80d9558f659823b01d7ec106a..64c012c1f66e3dfea1eea7a743511b78a08e0f5f 100644 (file)
@@ -1,7 +1,7 @@
 +-------------------------------------+------------+------------+------------+------------+
 | File                                | Documented | Percentage |   Examples | Percentage |
 +-------------------------------------+------------+------------+------------+------------+
-| ...est/rustdoc-ui/coverage/enums.rs |          6 |      66.7% |          0 |       0.0% |
+| ...est/rustdoc-ui/coverage/enums.rs |          6 |      75.0% |          0 |       0.0% |
 +-------------------------------------+------------+------------+------------+------------+
-| Total                               |          6 |      66.7% |          0 |       0.0% |
+| Total                               |          6 |      75.0% |          0 |       0.0% |
 +-------------------------------------+------------+------------+------------+------------+
diff --git a/src/test/rustdoc/issue-88600.rs b/src/test/rustdoc/issue-88600.rs
new file mode 100644 (file)
index 0000000..3761805
--- /dev/null
@@ -0,0 +1,34 @@
+// This test ensure that #[doc(hidden)] is applied correctly in enum variant fields.
+
+// Denotes a field which should be hidden.
+pub struct H;
+
+// Denotes a field which should not be hidden (shown).
+pub struct S;
+
+// @has issue_88600/enum.FooEnum.html
+pub enum FooEnum {
+    // @has - '//*[@id="variant.HiddenTupleItem"]//code' 'HiddenTupleItem(_)'
+    // @count - '//*[@id="variant.HiddenTupleItem.field.0"]' 0
+    HiddenTupleItem(#[doc(hidden)] H),
+    // @has - '//*[@id="variant.MultipleHidden"]//code' 'MultipleHidden(_, _)'
+    // @count - '//*[@id="variant.MultipleHidden.field.0"]' 0
+    // @count - '//*[@id="variant.MultipleHidden.field.1"]' 0
+    MultipleHidden(#[doc(hidden)] H, #[doc(hidden)] H),
+    // @has - '//*[@id="variant.MixedHiddenFirst"]//code' 'MixedHiddenFirst(_, S)'
+    // @count - '//*[@id="variant.MixedHiddenFirst.field.0"]' 0
+    // @has - '//*[@id="variant.MixedHiddenFirst.field.1"]' '1: S'
+    MixedHiddenFirst(#[doc(hidden)] H, S),
+    // @has - '//*[@id="variant.MixedHiddenLast"]//code' 'MixedHiddenLast(S, _)'
+    // @has - '//*[@id="variant.MixedHiddenLast.field.0"]' '0: S'
+    // @count - '//*[@id="variant.MixedHiddenLast.field.1"]' 0
+    MixedHiddenLast(S, #[doc(hidden)] H),
+    // @has - '//*[@id="variant.HiddenStruct"]//code' 'HiddenStruct'
+    // @count - '//*[@id="variant.HiddenStruct.field.h"]' 0
+    // @has - '//*[@id="variant.HiddenStruct.field.s"]' 's: S'
+    HiddenStruct {
+        #[doc(hidden)]
+        h: H,
+        s: S,
+    },
+}
diff --git a/src/test/rustdoc/table-in-docblock.rs b/src/test/rustdoc/table-in-docblock.rs
new file mode 100644 (file)
index 0000000..858b589
--- /dev/null
@@ -0,0 +1,16 @@
+#![crate_name = "foo"]
+
+// @has foo/struct.Foo.html
+// @count - '//*[@class="docblock"]/div/table' 2
+// @!has - '//*[@class="docblock"]/table'
+/// | hello | hello2 |
+/// | ----- | ------ |
+/// | data  | data2  |
+pub struct Foo;
+
+impl Foo {
+    /// | hello | hello2 |
+    /// | ----- | ------ |
+    /// | data  | data2  |
+    pub fn foo(&self) {}
+}
index 12236960179e9f57c9fb9b8501031eebfeee7255..4d8022ecba73c5d3744a31d1ffd3f8ed298e1ec3 100644 (file)
@@ -2,6 +2,7 @@
 
 // Test binary_search_by_key lifetime. Issue #34683
 
+#[allow(dead_code)]
 #[derive(Debug)]
 struct Assignment {
     topic: String,
index fd0e346e2b42dee204376dcdd467c13bd0c46037..23ef975cbbca1a8b985f3c2bc77dc27dbd76f9dc 100644 (file)
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(dead_code)]
 #![deny(unused_mut)]
 
 #[derive(Debug)]
index 1cc22fac35282217cf9a121bc11222a220e9fa66..3399bc0018e54526e78acde295f432ab094dcdec 100644 (file)
@@ -3,6 +3,7 @@
 // check-pass
 #![allow(unreachable_code)]
 #![warn(unused)]
+#![allow(dead_code)]
 
 #[derive(Debug)]
 struct Point {
index 4eac5a2d282b07b527e6cbe8f3fe0841e57591e2..74109772724a4ddd7f55f4161d2671378f7c7c0d 100644 (file)
@@ -1,5 +1,5 @@
 warning: value captured by `a` is never read
-  --> $DIR/liveness.rs:23:9
+  --> $DIR/liveness.rs:24:9
    |
 LL |         a = 1;
    |         ^
@@ -13,7 +13,7 @@ LL | #![warn(unused)]
    = help: did you mean to capture by reference instead?
 
 warning: unused variable: `a`
-  --> $DIR/liveness.rs:32:9
+  --> $DIR/liveness.rs:33:9
    |
 LL |         a += 1;
    |         ^
@@ -27,7 +27,7 @@ LL | #![warn(unused)]
    = help: did you mean to capture by reference instead?
 
 warning: value assigned to `a` is never read
-  --> $DIR/liveness.rs:52:9
+  --> $DIR/liveness.rs:53:9
    |
 LL |         a += 1;
    |         ^
@@ -35,7 +35,7 @@ LL |         a += 1;
    = help: maybe it is overwritten before being read?
 
 warning: value assigned to `a` is never read
-  --> $DIR/liveness.rs:76:13
+  --> $DIR/liveness.rs:77:13
    |
 LL |             a = Some("d1");
    |             ^
@@ -43,7 +43,7 @@ LL |             a = Some("d1");
    = help: maybe it is overwritten before being read?
 
 warning: value assigned to `b` is never read
-  --> $DIR/liveness.rs:84:13
+  --> $DIR/liveness.rs:85:13
    |
 LL |             b = Some("e1");
    |             ^
@@ -51,7 +51,7 @@ LL |             b = Some("e1");
    = help: maybe it is overwritten before being read?
 
 warning: value assigned to `b` is never read
-  --> $DIR/liveness.rs:86:13
+  --> $DIR/liveness.rs:87:13
    |
 LL |             b = Some("e2");
    |             ^
@@ -59,7 +59,7 @@ LL |             b = Some("e2");
    = help: maybe it is overwritten before being read?
 
 warning: unused variable: `b`
-  --> $DIR/liveness.rs:84:13
+  --> $DIR/liveness.rs:85:13
    |
 LL |             b = Some("e1");
    |             ^
index 10a7d07a1df99937e38e1a7aa4d05a62862f9e4d..465c9476ba65b1636532ab50c9b3650543242747 100644 (file)
@@ -2,6 +2,7 @@
 
 // check-pass
 #![warn(unused)]
+#![allow(dead_code)]
 
 #[derive(Debug)]
 struct MyStruct {
index f74303e3dd682672d8d13cdba48d6669ee40ad9f..11a440554f759b4a60a9ea096cba8eda9746fdfd 100644 (file)
@@ -1,5 +1,5 @@
 warning: value assigned to `a` is never read
-  --> $DIR/liveness_unintentional_copy.rs:19:9
+  --> $DIR/liveness_unintentional_copy.rs:20:9
    |
 LL |         a = s;
    |         ^
@@ -13,7 +13,7 @@ LL | #![warn(unused)]
    = help: maybe it is overwritten before being read?
 
 warning: unused variable: `a`
-  --> $DIR/liveness_unintentional_copy.rs:19:9
+  --> $DIR/liveness_unintentional_copy.rs:20:9
    |
 LL |         a = s;
    |         ^
@@ -27,7 +27,7 @@ LL | #![warn(unused)]
    = help: did you mean to capture by reference instead?
 
 warning: unused variable: `a`
-  --> $DIR/liveness_unintentional_copy.rs:35:9
+  --> $DIR/liveness_unintentional_copy.rs:36:9
    |
 LL |         a += x;
    |         ^
index 045fe78040a922e330fb926908e33ba64ec74f9a..ed222b3148f410c45433e7aa671e1f526707d1d8 100644 (file)
@@ -1,6 +1,7 @@
 // edition:2021
 //check-pass
 #![warn(unused)]
+#![allow(dead_code)]
 #![feature(rustc_attrs)]
 
 #[derive(Debug, Clone, Copy)]
index 8e4f91c27e224d5c82405b91621700c7193fd917..3f7ddf93f0697c821feeccdb47c6a0eccc4da1eb 100644 (file)
@@ -3,6 +3,8 @@
 
 // Test that we can use raw ptrs when using `capture_disjoint_fields`.
 
+#![allow(dead_code)]
+
 #[derive(Debug)]
 struct S {
     s: String,
index f9e03151374a2190040f8d4d949c09436db6a90b..9d62281178c48c689b5900ebd0c105255b1420a8 100644 (file)
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(dead_code)]
+
 use std::fmt::Debug;
 
 #[derive(Debug)]
diff --git a/src/test/ui/derives/clone-debug-dead-code.rs b/src/test/ui/derives/clone-debug-dead-code.rs
new file mode 100644 (file)
index 0000000..80e9132
--- /dev/null
@@ -0,0 +1,45 @@
+// Checks that derived implementations of Clone and Debug do not
+// contribute to dead code analysis (issue #84647).
+
+#![forbid(dead_code)]
+
+struct A { f: () }
+//~^ ERROR: field is never read: `f`
+
+#[derive(Clone)]
+struct B { f: () }
+//~^ ERROR: field is never read: `f`
+
+#[derive(Debug)]
+struct C { f: () }
+//~^ ERROR: field is never read: `f`
+
+#[derive(Debug,Clone)]
+struct D { f: () }
+//~^ ERROR: field is never read: `f`
+
+struct E { f: () }
+//~^ ERROR: field is never read: `f`
+// Custom impl, still doesn't read f
+impl Clone for E {
+    fn clone(&self) -> Self {
+        Self { f: () }
+    }
+}
+
+struct F { f: () }
+// Custom impl that actually reads f
+impl Clone for F {
+    fn clone(&self) -> Self {
+        Self { f: self.f }
+    }
+}
+
+fn main() {
+    let _ = A { f: () };
+    let _ = B { f: () };
+    let _ = C { f: () };
+    let _ = D { f: () };
+    let _ = E { f: () };
+    let _ = F { f: () };
+}
diff --git a/src/test/ui/derives/clone-debug-dead-code.stderr b/src/test/ui/derives/clone-debug-dead-code.stderr
new file mode 100644 (file)
index 0000000..226007f
--- /dev/null
@@ -0,0 +1,38 @@
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:6:12
+   |
+LL | struct A { f: () }
+   |            ^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/clone-debug-dead-code.rs:4:11
+   |
+LL | #![forbid(dead_code)]
+   |           ^^^^^^^^^
+
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:10:12
+   |
+LL | struct B { f: () }
+   |            ^^^^^
+
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:14:12
+   |
+LL | struct C { f: () }
+   |            ^^^^^
+
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:18:12
+   |
+LL | struct D { f: () }
+   |            ^^^^^
+
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:21:12
+   |
+LL | struct E { f: () }
+   |            ^^^^^
+
+error: aborting due to 5 previous errors
+
index f6e105555fd9d739e88c7931b242216c6bb27c6b..4374d1594e4655272a53e3ffd9c7961fd430d574 100644 (file)
@@ -1,6 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
+#![allow(dead_code)]
+
 #[derive(Clone)]
 struct S<T> {
     foo: (),
index 7b0a1d20260d4565a221c714101386c7a81dfd95..b93cbe5f8b6fd2b15a0a96f9f6467cf315f32af0 100644 (file)
@@ -1,6 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
+#![allow(dead_code)]
+
 #[derive(Clone)]
 struct S {
     _int: isize,
index 166f1be55e02afd2d4f55e2cdacdd8113aa40da8..7ad3f03471324e6b179a29a5629c6b44d49e61c8 100644 (file)
@@ -1,6 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
+#![allow(dead_code)]
+
 #[derive(Clone)]
 struct S((), ());
 
index 8931e94a4f8d2487e06782c341c38b336f5db6a4..07f91d059735623a416b00b41898211089c05bbb 100644 (file)
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(dead_code)]
+
 pub fn main() {
     #[derive(Debug)]
     struct Foo {
diff --git a/src/test/ui/expr/malformed_closure/missing_braces_around_block.fixed b/src/test/ui/expr/malformed_closure/missing_braces_around_block.fixed
new file mode 100644 (file)
index 0000000..c50b9a1
--- /dev/null
@@ -0,0 +1,19 @@
+// This snippet ensures that no attempt to recover on a semicolon instead of
+// comma is made next to a closure body.
+//
+// If this recovery happens, then plenty of errors are emitted. Here, we expect
+// only one error.
+//
+// This is part of issue #88065:
+// https://github.com/rust-lang/rust/issues/88065
+
+// run-rustfix
+
+fn main() {
+    let num = 5;
+    (1..num).reduce(|a, b| {
+        //~^ ERROR: closure bodies that contain statements must be surrounded by braces
+        println!("{}", a);
+        a * b
+    }).unwrap();
+}
diff --git a/src/test/ui/expr/malformed_closure/missing_braces_around_block.rs b/src/test/ui/expr/malformed_closure/missing_braces_around_block.rs
new file mode 100644 (file)
index 0000000..58c81f3
--- /dev/null
@@ -0,0 +1,19 @@
+// This snippet ensures that no attempt to recover on a semicolon instead of
+// comma is made next to a closure body.
+//
+// If this recovery happens, then plenty of errors are emitted. Here, we expect
+// only one error.
+//
+// This is part of issue #88065:
+// https://github.com/rust-lang/rust/issues/88065
+
+// run-rustfix
+
+fn main() {
+    let num = 5;
+    (1..num).reduce(|a, b|
+        //~^ ERROR: closure bodies that contain statements must be surrounded by braces
+        println!("{}", a);
+        a * b
+    ).unwrap();
+}
diff --git a/src/test/ui/expr/malformed_closure/missing_braces_around_block.stderr b/src/test/ui/expr/malformed_closure/missing_braces_around_block.stderr
new file mode 100644 (file)
index 0000000..dac9a8c
--- /dev/null
@@ -0,0 +1,38 @@
+error: closure bodies that contain statements must be surrounded by braces
+  --> $DIR/missing_braces_around_block.rs:14:26
+   |
+LL |     (1..num).reduce(|a, b|
+   |                          ^
+...
+LL |     ).unwrap();
+   |     ^
+   |
+note: statement found outside of a block
+  --> $DIR/missing_braces_around_block.rs:16:26
+   |
+LL |         println!("{}", a);
+   |         -----------------^ this `;` turns the preceding closure into a statement
+   |         |
+   |         this expression is a statement because of the trailing semicolon
+note: the closure body may be incorrectly delimited
+  --> $DIR/missing_braces_around_block.rs:14:21
+   |
+LL |       (1..num).reduce(|a, b|
+   |  _____________________^
+LL | |
+LL | |         println!("{}", a);
+   | |_________________________^ this is the parsed closure...
+LL |           a * b
+LL |       ).unwrap();
+   |       - ...but likely you meant the closure to end here
+help: try adding braces
+   |
+LL ~     (1..num).reduce(|a, b| {
+LL |
+LL |         println!("{}", a);
+LL |         a * b
+LL ~     }).unwrap();
+   |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/expr/malformed_closure/ruby_style_closure.rs b/src/test/ui/expr/malformed_closure/ruby_style_closure.rs
new file mode 100644 (file)
index 0000000..e4341e1
--- /dev/null
@@ -0,0 +1,16 @@
+// Part of issue #27300.
+// The problem here is that ruby-style closures are parsed as blocks whose
+// first statement is a closure. See the issue for more details:
+// https://github.com/rust-lang/rust/issues/27300
+
+// Note: this test represents what the compiler currently emits. The error
+// message will be improved later.
+
+fn main() {
+    let p = Some(45).and_then({
+        //~^ expected a `FnOnce<({integer},)>` closure, found `Option<_>`
+        |x| println!("doubling {}", x);
+        Some(x * 2)
+        //~^ ERROR: cannot find value `x` in this scope
+    });
+}
diff --git a/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr b/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr
new file mode 100644 (file)
index 0000000..99df063
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/ruby_style_closure.rs:13:14
+   |
+LL |         Some(x * 2)
+   |              ^ not found in this scope
+
+error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>`
+  --> $DIR/ruby_style_closure.rs:10:22
+   |
+LL |     let p = Some(45).and_then({
+   |                      ^^^^^^^^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
+   |
+   = help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0425.
+For more information about an error, try `rustc --explain E0277`.
index f66e0a1c07841b6f80ce0767e251abd6a9f42ff2..3970a4155e95c2ec53f4c110a0f347520bc48aed 100644 (file)
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(dead_code)]
+
 trait Trait { fn dummy(&self) { } }
 
 #[derive(Debug)]
index 25a90df45613b9b8e2777a9965c2b1b90c46f045..ce3ab6b599864ded9ba9cf5b66316137b0af37da 100644 (file)
@@ -2,9 +2,12 @@ error[E0277]: the size for values of type `dyn Iterator<Item = &'a mut u8>` cann
   --> $DIR/issue-20605.rs:2:17
    |
 LL |     for item in *things { *item = 0 }
-   |                 ^^^^^^^ doesn't have a size known at compile-time
+   |                 ^^^^^^^
+   |                 |
+   |                 expected an implementor of trait `IntoIterator`
+   |                 help: consider mutably borrowing here: `&mut *things`
    |
-   = help: the trait `Sized` is not implemented for `dyn Iterator<Item = &'a mut u8>`
+   = note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
    = note: required because of the requirements on the impl of `IntoIterator` for `dyn Iterator<Item = &'a mut u8>`
 note: required by `into_iter`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
index 408d8d866d862efdfb7989f471d0be0e00aa6dfb..1809e822c54213d4dbdc222bbac07f17d90fbf4b 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![feature(box_syntax)]
+#![allow(dead_code)]
 
 trait T {
     fn print(&self);
diff --git a/src/test/ui/issues/issue-86865.rs b/src/test/ui/issues/issue-86865.rs
new file mode 100644 (file)
index 0000000..01e0a20
--- /dev/null
@@ -0,0 +1,11 @@
+use std::fmt::Write;
+
+fn main() {
+    println!(b"foo");
+    //~^ ERROR format argument must be a string literal
+    //~| HELP consider removing the leading `b`
+    let mut s = String::new();
+    write!(s, b"foo{}", "bar");
+    //~^ ERROR format argument must be a string literal
+    //~| HELP consider removing the leading `b`
+}
diff --git a/src/test/ui/issues/issue-86865.stderr b/src/test/ui/issues/issue-86865.stderr
new file mode 100644 (file)
index 0000000..eed7553
--- /dev/null
@@ -0,0 +1,18 @@
+error: format argument must be a string literal
+  --> $DIR/issue-86865.rs:4:14
+   |
+LL |     println!(b"foo");
+   |              -^^^^^
+   |              |
+   |              help: consider removing the leading `b`
+
+error: format argument must be a string literal
+  --> $DIR/issue-86865.rs:8:15
+   |
+LL |     write!(s, b"foo{}", "bar");
+   |               -^^^^^^^
+   |               |
+   |               help: consider removing the leading `b`
+
+error: aborting due to 2 previous errors
+
index 637b09fc04e5f38fab90fe70d0670bcd6fee4f7d..a8d8bd1d5fd008ed1785479ba47ca2f7ce8be75c 100644 (file)
@@ -1,6 +1,7 @@
 // run-pass
 
 #![allow(non_upper_case_globals)]
+#![allow(dead_code)]
 /*!
  * On x86_64-linux-gnu and possibly other platforms, structs get 8-byte "preferred" alignment,
  * but their "ABI" alignment (i.e., what actually matters for data layout) is the largest alignment
index 48baead074ac7d5e2442af585c2c0d95e24c0c22..7d3987f65608715ce3147fdbf44295120869b968 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(unused_mut)]
+#![allow(dead_code)]
 #![feature(box_syntax)]
 
 #[derive(Clone)]
index 55b10e057d88cce761e898320d3adc27d6d684d1..d23a852433f4f9b478312061d6a78d16a9eacc5c 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(unused_mut)]
+#![allow(dead_code)]
 #![feature(box_syntax)]
 
 #[derive(Clone)]
index 1ae16d2a7fc66eed75fc62d3836343cbca404223..f48bae55f5f1e820063df9c290b47ef4ce53b5c6 100644 (file)
@@ -1,5 +1,7 @@
 // run-pass
 
+#![allow(dead_code)]
+
 use std::rc::Rc;
 use std::ops::Deref;
 
index 4e2405504f0cb0b65bd4f7b5836dc63eaed15909..0aaaa7d47c3c1eef0bcf8066e2e08218136a495b 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![feature(box_syntax)]
+#![allow(dead_code)]
 
 #[derive(Copy, Clone)]
 struct Foo {
index 55975cbdb5342ee491a78f37fe9d95017b9985f7..ca35a615d214774124cf33a6dd71f41dfe9186ad 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(non_camel_case_types)]
+#![allow(dead_code)]
 
 trait noisy {
   fn speak(&mut self) -> isize;
index c9e98e21b9eb4411316b83cd75866ec8e27f13f2..732aa146ce446ee2e99161d5fa61290c624e75e5 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(non_camel_case_types)]
+#![allow(dead_code)]
 
 trait noisy {
     fn speak(&mut self);
index 51c6b6d7e4ffe236994a6bec788cf33ec883dc7a..68ff73a0805921446b7c3b5ce9788857246218d4 100644 (file)
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(dead_code)]
+
 #[derive(Debug)]
 struct Foo {
     x: isize,
index 87282ddbcca52d863b2275a344d4ff3ba474930c..ce599582378176d32670515d0c20643e644137ad 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(non_camel_case_types)]
+#![allow(dead_code)]
 
 #[derive(Debug)]
 enum a_tag {
diff --git a/src/test/ui/suggestions/slice-issue-87994.rs b/src/test/ui/suggestions/slice-issue-87994.rs
new file mode 100644 (file)
index 0000000..ecb7f54
--- /dev/null
@@ -0,0 +1,16 @@
+fn main() {
+  let v = vec![1i32, 2, 3];
+  for _ in v[1..] {
+    //~^ ERROR [i32]` is not an iterator [E0277]
+    //~^^ ERROR known at compilation time
+  }
+  struct K {
+    n: i32,
+  }
+  let mut v2 = vec![K { n: 1 }, K { n: 1 }, K { n: 1 }];
+  for i2 in v2[1..] {
+    //~^ ERROR [K]` is not an iterator [E0277]
+    //~^^ ERROR known at compilation time
+    i2.n = 2;
+  }
+}
diff --git a/src/test/ui/suggestions/slice-issue-87994.stderr b/src/test/ui/suggestions/slice-issue-87994.stderr
new file mode 100644 (file)
index 0000000..018f62e
--- /dev/null
@@ -0,0 +1,71 @@
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+  --> $DIR/slice-issue-87994.rs:3:12
+   |
+LL |   for _ in v[1..] {
+   |            ^^^^^^
+   |            |
+   |            expected an implementor of trait `IntoIterator`
+   |            help: consider borrowing here: `&v[1..]`
+   |
+   = note: the trait bound `[i32]: IntoIterator` is not satisfied
+   = note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `[i32]` is not an iterator
+  --> $DIR/slice-issue-87994.rs:3:12
+   |
+LL |   for _ in v[1..] {
+   |            ^^^^^^
+   |            |
+   |            expected an implementor of trait `IntoIterator`
+   |            help: consider borrowing here: `&v[1..]`
+   |
+   = note: the trait bound `[i32]: IntoIterator` is not satisfied
+   = note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `[K]` cannot be known at compilation time
+  --> $DIR/slice-issue-87994.rs:11:13
+   |
+LL |   for i2 in v2[1..] {
+   |             ^^^^^^^
+   |             |
+   |             expected an implementor of trait `IntoIterator`
+   |             help: consider borrowing here: `&v2[1..]`
+   |
+   = note: the trait bound `[K]: IntoIterator` is not satisfied
+   = note: required because of the requirements on the impl of `IntoIterator` for `[K]`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `[K]` is not an iterator
+  --> $DIR/slice-issue-87994.rs:11:13
+   |
+LL |   for i2 in v2[1..] {
+   |             ^^^^^^^
+   |             |
+   |             expected an implementor of trait `IntoIterator`
+   |             help: consider borrowing here: `&v2[1..]`
+   |
+   = note: the trait bound `[K]: IntoIterator` is not satisfied
+   = note: required because of the requirements on the impl of `IntoIterator` for `[K]`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
index 7627e0fb28956f3a61a0c8f513d03dad7c29033b..41e6ad12d058923a9af3d1a1b616bd7d650ced23 100644 (file)
     "#[macro_use] is no longer needed"
 }
 
-const BRACKETS: &[char] = &['<', '>'];
-
 #[derive(Clone, Debug, PartialEq, Eq)]
 struct PathAndSpan {
     path: String,
     span: Span,
 }
 
-/// `MacroRefData` includes the name of the macro
-/// and the path from `SourceMap::span_to_filename`.
+/// `MacroRefData` includes the name of the macro.
 #[derive(Debug, Clone)]
 pub struct MacroRefData {
     name: String,
-    path: String,
 }
 
 impl MacroRefData {
-    pub fn new(name: String, callee: Span, cx: &LateContext<'_>) -> Self {
-        let sm = cx.sess().source_map();
-        let mut path = sm.filename_for_diagnostics(&sm.span_to_filename(callee)).to_string();
-
-        // std lib paths are <::std::module::file type>
-        // so remove brackets, space and type.
-        if path.contains('<') {
-            path = path.replace(BRACKETS, "");
-        }
-        if path.contains(' ') {
-            path = path.split(' ').next().unwrap().to_string();
-        }
-        Self { name, path }
+    pub fn new(name: String) -> Self {
+        Self { name }
     }
 }
 
@@ -78,7 +63,7 @@ impl MacroUseImports {
     fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {
         let call_site = span.source_callsite();
         let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
-        if let Some(callee) = span.source_callee() {
+        if let Some(_callee) = span.source_callee() {
             if !self.collected.contains(&call_site) {
                 let name = if name.contains("::") {
                     name.split("::").last().unwrap().to_string()
@@ -86,7 +71,7 @@ fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {
                     name.to_string()
                 };
 
-                self.mac_refs.push(MacroRefData::new(name, callee.def_site, cx));
+                self.mac_refs.push(MacroRefData::new(name));
                 self.collected.insert(call_site);
             }
         }
@@ -95,10 +80,10 @@ fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {
     fn push_unique_macro_pat_ty(&mut self, cx: &LateContext<'_>, span: Span) {
         let call_site = span.source_callsite();
         let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
-        if let Some(callee) = span.source_callee() {
+        if let Some(_callee) = span.source_callee() {
             if !self.collected.contains(&call_site) {
                 self.mac_refs
-                    .push(MacroRefData::new(name.to_string(), callee.def_site, cx));
+                    .push(MacroRefData::new(name.to_string()));
                 self.collected.insert(call_site);
             }
         }
index eab097337306be0e8090451909adff8152effe35..89be7bf844f3a83f637aa27ed823df524e6ea2fc 100644 (file)
@@ -3,8 +3,7 @@
 use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_ast::ast::{LitKind, StrStyle};
-use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::{BorrowKind, Expr, ExprKind, HirId};
+use rustc_hir::{BorrowKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::{BytePos, Span};
 }
 
 #[derive(Clone, Default)]
-pub struct Regex {
-    spans: FxHashSet<Span>,
-    last: Option<HirId>,
-}
+pub struct Regex {}
 
 impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]);
 
index 4c80cabc72305df9371c2854536d7195c7157279..f1f9c123dc842880683a14584d5c63f7bb7aa9c1 100644 (file)
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports,dead_code)]
 #![deny(clippy::default_trait_access)]
 
 use std::default;
index a68b6455c04165f683f4678aae1978a876b4725f..7f3dfc7f01366e0d39b23d59350a2428fe6b0e7c 100644 (file)
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports,dead_code)]
 #![deny(clippy::default_trait_access)]
 
 use std::default;
index a9bc89544d820cd5c0b592fdc9ee4d74c0057ff3..779a1149f413e5fa262104989096379340e91f8c 100644 (file)
@@ -762,7 +762,6 @@ fn rewrite(
 #[derive(Debug, Clone)]
 struct ParsedMacroArg {
     kind: MacroArgKind,
-    span: Span,
 }
 
 impl ParsedMacroArg {
@@ -780,14 +779,10 @@ fn rewrite(
 struct MacroArgParser {
     /// Either a name of the next metavariable, a separator, or junk.
     buf: String,
-    /// The start position on the current buffer.
-    lo: BytePos,
     /// The first token of the current buffer.
     start_tok: Token,
     /// `true` if we are parsing a metavariable or a repeat.
     is_meta_var: bool,
-    /// The position of the last token.
-    hi: BytePos,
     /// The last token parsed.
     last_tok: Token,
     /// Holds the parsed arguments.
@@ -807,8 +802,6 @@ fn last_tok(tt: &TokenTree) -> Token {
 impl MacroArgParser {
     fn new() -> MacroArgParser {
         MacroArgParser {
-            lo: BytePos(0),
-            hi: BytePos(0),
             buf: String::new(),
             is_meta_var: false,
             last_tok: Token {
@@ -824,7 +817,6 @@ fn new() -> MacroArgParser {
     }
 
     fn set_last_tok(&mut self, tok: &TokenTree) {
-        self.hi = tok.span().hi();
         self.last_tok = last_tok(tok);
     }
 
@@ -836,7 +828,6 @@ fn add_separator(&mut self) {
         };
         self.result.push(ParsedMacroArg {
             kind: MacroArgKind::Separator(self.buf.clone(), prefix),
-            span: mk_sp(self.lo, self.hi),
         });
         self.buf.clear();
     }
@@ -849,7 +840,6 @@ fn add_other(&mut self) {
         };
         self.result.push(ParsedMacroArg {
             kind: MacroArgKind::Other(self.buf.clone(), prefix),
-            span: mk_sp(self.lo, self.hi),
         });
         self.buf.clear();
     }
@@ -858,11 +848,10 @@ fn add_meta_variable(&mut self, iter: &mut Cursor) -> Option<()> {
         match iter.next() {
             Some(TokenTree::Token(Token {
                 kind: TokenKind::Ident(name, _),
-                span,
+                ..
             })) => {
                 self.result.push(ParsedMacroArg {
                     kind: MacroArgKind::MetaVariable(name, self.buf.clone()),
-                    span: mk_sp(self.lo, span.hi()),
                 });
 
                 self.buf.clear();
@@ -873,10 +862,9 @@ fn add_meta_variable(&mut self, iter: &mut Cursor) -> Option<()> {
         }
     }
 
-    fn add_delimited(&mut self, inner: Vec<ParsedMacroArg>, delim: DelimToken, span: Span) {
+    fn add_delimited(&mut self, inner: Vec<ParsedMacroArg>, delim: DelimToken) {
         self.result.push(ParsedMacroArg {
             kind: MacroArgKind::Delimited(delim, inner),
-            span,
         });
     }
 
@@ -886,19 +874,15 @@ fn add_repeat(
         inner: Vec<ParsedMacroArg>,
         delim: DelimToken,
         iter: &mut Cursor,
-        span: Span,
     ) -> Option<()> {
         let mut buffer = String::new();
         let mut first = true;
-        let mut lo = span.lo();
-        let mut hi = span.hi();
 
         // Parse '*', '+' or '?.
         for tok in iter {
             self.set_last_tok(&tok);
             if first {
                 first = false;
-                lo = tok.span().lo();
             }
 
             match tok {
@@ -918,7 +902,6 @@ fn add_repeat(
                 }
                 TokenTree::Token(ref t) => {
                     buffer.push_str(&pprust::token_to_string(&t));
-                    hi = t.span.hi();
                 }
                 _ => return None,
             }
@@ -930,20 +913,17 @@ fn add_repeat(
         } else {
             Some(Box::new(ParsedMacroArg {
                 kind: MacroArgKind::Other(buffer, "".to_owned()),
-                span: mk_sp(lo, hi),
             }))
         };
 
         self.result.push(ParsedMacroArg {
             kind: MacroArgKind::Repeat(delim, inner, another, self.last_tok.clone()),
-            span: mk_sp(self.lo, self.hi),
         });
         Some(())
     }
 
     fn update_buffer(&mut self, t: &Token) {
         if self.buf.is_empty() {
-            self.lo = t.span.lo();
             self.start_tok = t.clone();
         } else {
             let needs_space = match next_space(&self.last_tok.kind) {
@@ -999,7 +979,6 @@ fn parse(mut self, tokens: TokenStream) -> Option<Vec<ParsedMacroArg>> {
 
                     // Start keeping the name of this metavariable in the buffer.
                     self.is_meta_var = true;
-                    self.lo = span.lo();
                     self.start_tok = Token {
                         kind: TokenKind::Dollar,
                         span,
@@ -1012,7 +991,7 @@ fn parse(mut self, tokens: TokenStream) -> Option<Vec<ParsedMacroArg>> {
                     self.add_meta_variable(&mut iter)?;
                 }
                 TokenTree::Token(ref t) => self.update_buffer(t),
-                TokenTree::Delimited(delimited_span, delimited, ref tts) => {
+                TokenTree::Delimited(_delimited_span, delimited, ref tts) => {
                     if !self.buf.is_empty() {
                         if next_space(&self.last_tok.kind) == SpaceState::Always {
                             self.add_separator();
@@ -1022,16 +1001,14 @@ fn parse(mut self, tokens: TokenStream) -> Option<Vec<ParsedMacroArg>> {
                     }
 
                     // Parse the stuff inside delimiters.
-                    let mut parser = MacroArgParser::new();
-                    parser.lo = delimited_span.open.lo();
+                    let parser = MacroArgParser::new();
                     let delimited_arg = parser.parse(tts.clone())?;
 
-                    let span = delimited_span.entire();
                     if self.is_meta_var {
-                        self.add_repeat(delimited_arg, delimited, &mut iter, span)?;
+                        self.add_repeat(delimited_arg, delimited, &mut iter)?;
                         self.is_meta_var = false;
                     } else {
-                        self.add_delimited(delimited_arg, delimited, span);
+                        self.add_delimited(delimited_arg, delimited);
                     }
                 }
             }
index 5de0575b5cd66a56a466466608cdf47b9b8600a9..ded34d9032f91f188c11c9437b41691cdcce75b5 100644 (file)
@@ -27,7 +27,6 @@
 pub(crate) struct Module<'a> {
     ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
     pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
-    attrs: Cow<'a, Vec<ast::Attribute>>,
     inner_attr: Vec<ast::Attribute>,
     pub(crate) span: Span,
 }
@@ -46,7 +45,6 @@ pub(crate) fn new(
             .collect();
         Module {
             items: mod_items,
-            attrs: mod_attrs,
             inner_attr,
             span: mod_span,
             ast_mod_kind,