diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index ce1e7c14b1ff6..f4cbbb60b053a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -218,7 +218,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); 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 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { 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)) = diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 652165fb9b60b..693114e378664 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -510,7 +510,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option template_part, Err(err) => { - if let Some(mut err) = err { + if let Some((mut err, _)) = err { err.emit(); } return None; diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 8508b3b7ae6ed..c7626dec4d7c0 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -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); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 35df8aae4babb..6a135dd4f1f6a 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -10,7 +10,7 @@ use rustc_ast::{self as ast, AstLike, Attribute, Item, NodeId, PatKind}; 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 @@ impl<'a> ExtCtxt<'a> { } /// 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, err_msg: &str, -) -> Result<(Symbol, ast::StrStyle, Span), Option>> { +) -> 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, @@ -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(); }) }) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 55700f7b0d495..02d92e7c90a0d 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -758,6 +758,12 @@ impl server::Span for Rustc<'_> { 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 { let self_loc = self.sess.source_map().lookup_char_pos(first.lo()); let other_loc = self.sess.source_map().lookup_char_pos(second.lo()); diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 725f8b8763af1..61e27d2e4cd41 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -16,7 +16,6 @@ macro_rules! declare_features { since: $ver, issue: to_nonzero($issue), edition: None, - description: concat!($($doc,)*), } ),+ ]; diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index a3807a2bb9fde..366ed715434ed 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -37,7 +37,6 @@ macro_rules! declare_features { since: $ver, issue: to_nonzero($issue), edition: $edition, - description: concat!($($doc,)*), } ),+]; diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index e2aa54a59b202..f74ea0e0c4d27 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -453,6 +453,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // 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: diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index cf102aa16e057..b25aab21e491a 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -51,7 +51,6 @@ pub struct Feature { pub since: &'static str, issue: Option, pub edition: Option, - description: &'static str, } #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index efab0200ff502..7b9b68268eacd 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -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,)*), } ),+ ]; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 4f07a0c67c13f..9850f395a0f65 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -203,56 +203,57 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { report_fatal_error("bad AttributeKind"); } +template 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(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(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(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(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(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(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(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(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(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(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(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(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); } diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index 1351b4950f143..082948eba416d 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -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, diff --git a/compiler/rustc_middle/src/ich/hcx.rs b/compiler/rustc_middle/src/ich/hcx.rs index 32ccdafaeb48c..1c7e022673d95 100644 --- a/compiler/rustc_middle/src/ich/hcx.rs +++ b/compiler/rustc_middle/src/ich/hcx.rs @@ -28,7 +28,6 @@ fn compute_ignored_attr_names() -> FxHashSet { /// 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 @@ impl<'a> StableHashingContext<'a> { !always_ignore_spans && !sess.opts.debugging_opts.incremental_ignore_spans; StableHashingContext { - sess, body_resolver: BodyResolver(krate), definitions, cstore, diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index ba94e15444a19..0ff3fc60995bf 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -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, } diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 1feb8b0d7a06d..4ce26cc8dff46 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -176,17 +176,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { 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, }); } diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index bd8d14fcd012c..b74208edafea6 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -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 @@ impl<'tcx> Scopes<'tcx> { 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, diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 6043606c37957..b9e3c058ad7ec 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -263,7 +263,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { } 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 diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 05156745105a1..dc80dab8c6c5f 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -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> { + self.current_closure.take(); + self.parse_expr_res(Restrictions::empty(), None) } @@ -1736,7 +1741,7 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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. diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index c4419e995edac..5c701fefd17de 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -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, +} + +/// 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 @@ impl<'a> Parser<'a> { replace_ranges: Vec::new(), inner_attr_ranges: Default::default(), }, + current_closure: None, }; // Make parser point to the first token. @@ -761,8 +773,11 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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. diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 25ad00aaf1f75..0a3093757166a 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -239,7 +239,69 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } } + /// 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; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 24023163cc30e..c816d06045681 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1134,6 +1134,7 @@ symbols! { rustc_synthetic, rustc_test_marker, rustc_then_this_would_need, + rustc_trivial_field_reads, rustc_unsafe_specialization_marker, rustc_variance, rustdoc, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 0d3fd748645ed..9371ff3405eb0 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::{ 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 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); // 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 { diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 19faf9cddac6f..b02333b028850 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -105,6 +105,7 @@ #[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. /// diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 0a29843c9cf27..166a8e3f28a41 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -582,6 +582,7 @@ impl Display for Arguments<'_> { )] #[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. /// diff --git a/library/core/tests/fmt/builders.rs b/library/core/tests/fmt/builders.rs index 7580010a28b4a..9567479c8137b 100644 --- a/library/core/tests/fmt/builders.rs +++ b/library/core/tests/fmt/builders.rs @@ -653,6 +653,7 @@ mod debug_list { fn test_formatting_parameters_are_forwarded() { use std::collections::{BTreeMap, BTreeSet}; #[derive(Debug)] + #[allow(dead_code)] struct Foo { bar: u32, baz: u32, diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 7001e827ad845..bb05506defd07 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -162,6 +162,8 @@ macro_rules! with_api { 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; diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 243922b18b565..e21a1507a62e2 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -357,6 +357,18 @@ impl Span { 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. diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs index 130bb5cb2b3c2..71645aadb1d88 100644 --- a/library/std/src/collections/mod.rs +++ b/library/std/src/collections/mod.rs @@ -239,7 +239,7 @@ //! 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. //! diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index f6c2b499567ab..d290c3c466035 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs @@ -468,9 +468,6 @@ struct ProgrammableSink { // Writes append to this slice pub buffer: Vec, - // Flush sets this flag - pub flushed: bool, - // If true, writes will always be an error pub always_write_error: bool, @@ -520,7 +517,6 @@ impl Write for ProgrammableSink { if self.always_flush_error { Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error")) } else { - self.flushed = true; Ok(()) } } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index e8466fa06b899..4a35d36a9def7 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1611,7 +1611,7 @@ pub trait Write { /// 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. /// diff --git a/library/test/src/term/terminfo/mod.rs b/library/test/src/term/terminfo/mod.rs index f4c5a05d1e2ce..694473f52c1a7 100644 --- a/library/test/src/term/terminfo/mod.rs +++ b/library/test/src/term/terminfo/mod.rs @@ -16,6 +16,7 @@ use parser::compiled::{msys_terminfo, parse}; use searcher::get_dbpath_for_term; /// A parsed terminfo database entry. +#[allow(unused)] #[derive(Debug)] pub(crate) struct TermInfo { /// Names for the terminal diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index a10928a747177..444b1cbf3cc45 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -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)] diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 0c81a55843013..78e4e4ec116da 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -557,7 +557,6 @@ fn build_macro( name: Symbol, import_def_id: Option, ) -> 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!() diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e2ad21bba21b7..7ece2acac7a40 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1859,7 +1859,6 @@ impl Clean> for (&hir::Item<'_>, Option) { } ItemKind::Macro(ref macro_def) => MacroItem(Macro { source: display_macro_source(cx, name, ¯o_def, def_id, &item.vis), - imported_from: None, }), ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => { let items = item_ids diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5eff56a2200e1..5f09e6ced96d4 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2202,7 +2202,6 @@ crate struct ImportSource { #[derive(Clone, Debug)] crate struct Macro { crate source: String, - crate imported_from: Option, } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5cd5254f3282d..c971e231463cd 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -48,7 +48,7 @@ use pulldown_cmark::{ 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 @@ impl<'a, I: Iterator>> Iterator for LinkReplacer<'a, I> { } } +/// Wrap HTML tables into `
` to prevent having the doc blocks width being too big. +struct TableWrapper<'a, I: Iterator>> { + inner: I, + stored_events: VecDeque>, +} + +impl<'a, I: Iterator>> TableWrapper<'a, I> { + fn new(iter: I) -> Self { + Self { inner: iter, stored_events: VecDeque::new() } + } +} + +impl<'a, I: Iterator>> Iterator for TableWrapper<'a, I> { + type Item = Event<'a>; + + fn next(&mut self) -> Option { + 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("
")) + } + Event::End(Tag::Table(t)) => { + self.stored_events.push_back(Event::Html(CowStr::Borrowed("
"))); + Event::End(Tag::Table(t)) + } + e => e, + }) + } +} + type SpannedEvent<'a> = (Event<'a>, Range); /// Make headings links with anchor IDs and build up TOC. @@ -981,7 +1021,7 @@ impl Markdown<'_> { } }; - 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 @@ impl Markdown<'_> { 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 @@ crate fn markdown_links(md: &str) -> Vec { }); 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 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec, statics: FxHashSet, constants: FxHashSet, - keywords: FxHashSet, attributes: FxHashSet, derives: FxHashSet, trait_aliases: FxHashSet, @@ -245,7 +244,6 @@ impl 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), diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 470749ef7b338..52505f2d63471 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -256,6 +256,10 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl 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 item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl write!( w, "

\ - {name}

\n{}", + {name}\ + \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 item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl ); } } + + 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(", "); } - 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, - "\ - \ - {f}: {t}\ - ", - 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, + "\ + \ + {f}: {t}\ + ", + id = id, + f = field.name.as_ref().unwrap(), + t = ty.print(cx) + ); + document(w, cx, field, Some(variant)); + } + _ => unreachable!(), } } w.write_str("
"); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 23ca6eeaf3bb9..2d4bfc62af68e 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -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; diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs index 56ef15eb88420..37faa6742927a 100644 --- a/src/librustdoc/passes/bare_urls.rs +++ b/src/librustdoc/passes/bare_urls.rs @@ -2,7 +2,7 @@ use super::Pass; 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 @@ impl<'a, 'tcx> DocFolder for BareUrlsLinter<'a, 'tcx> { }); }; - 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 { diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 92e678e4c024b..721af3313d27f 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -4,8 +4,10 @@ use crate::fold::{self, DocFolder}; 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 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { .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, diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs index f29d38e3e078a..a0144a5298eba 100644 --- a/src/librustdoc/passes/html_tags.rs +++ b/src/librustdoc/passes/html_tags.rs @@ -2,7 +2,7 @@ use super::Pass; 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 @@ impl<'a, 'tcx> DocFolder for InvalidHtmlTagsLinter<'a, 'tcx> { 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 { diff --git a/src/test/rustdoc-gui/docblock-table-overflow.goml b/src/test/rustdoc-gui/docblock-table-overflow.goml index 9ab7cd0fa07b0..10f516d2dae06 100644 --- a/src/test/rustdoc-gui/docblock-table-overflow.goml +++ b/src/test/rustdoc-gui/docblock-table-overflow.goml @@ -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 , 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 "

" 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

, its scroll width is bigger. +assert-property: ("#implementations + details .docblock table", {"scrollWidth": "1573"}) diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs index cb63a9f600227..d5835b78d2fcf 100644 --- a/src/test/rustdoc-gui/src/lib2/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/lib.rs @@ -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 index 0000000000000..e9c165b1916e2 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/enum-tuple-documented.rs @@ -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 index 0000000000000..82c98f43f3dd0 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout @@ -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 index 0000000000000..5fb205450755b --- /dev/null +++ b/src/test/rustdoc-ui/coverage/enum-tuple.rs @@ -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 index 0000000000000..a3377d59c073a --- /dev/null +++ b/src/test/rustdoc-ui/coverage/enum-tuple.stdout @@ -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% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/enums.stdout b/src/test/rustdoc-ui/coverage/enums.stdout index 414d60c86d308..64c012c1f66e3 100644 --- a/src/test/rustdoc-ui/coverage/enums.stdout +++ b/src/test/rustdoc-ui/coverage/enums.stdout @@ -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 index 0000000000000..3761805b48b71 --- /dev/null +++ b/src/test/rustdoc/issue-88600.rs @@ -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 index 0000000000000..858b589196e72 --- /dev/null +++ b/src/test/rustdoc/table-in-docblock.rs @@ -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) {} +} diff --git a/src/test/ui/array-slice-vec/slice_binary_search.rs b/src/test/ui/array-slice-vec/slice_binary_search.rs index 12236960179e9..4d8022ecba73c 100644 --- a/src/test/ui/array-slice-vec/slice_binary_search.rs +++ b/src/test/ui/array-slice-vec/slice_binary_search.rs @@ -2,6 +2,7 @@ // Test binary_search_by_key lifetime. Issue #34683 +#[allow(dead_code)] #[derive(Debug)] struct Assignment { topic: String, diff --git a/src/test/ui/borrowck/borrowck-unused-mut-locals.rs b/src/test/ui/borrowck/borrowck-unused-mut-locals.rs index fd0e346e2b42d..23ef975cbbca1 100644 --- a/src/test/ui/borrowck/borrowck-unused-mut-locals.rs +++ b/src/test/ui/borrowck/borrowck-unused-mut-locals.rs @@ -1,4 +1,5 @@ // run-pass +#![allow(dead_code)] #![deny(unused_mut)] #[derive(Debug)] diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs index 1cc22fac35282..3399bc0018e54 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs @@ -3,6 +3,7 @@ // check-pass #![allow(unreachable_code)] #![warn(unused)] +#![allow(dead_code)] #[derive(Debug)] struct Point { diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr index 4eac5a2d282b0..74109772724a4 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr @@ -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"); | ^ diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs index 10a7d07a1df99..465c9476ba65b 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs @@ -2,6 +2,7 @@ // check-pass #![warn(unused)] +#![allow(dead_code)] #[derive(Debug)] struct MyStruct { diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr index f74303e3dd682..11a440554f759 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr @@ -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; | ^ diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs index 045fe78040a92..ed222b3148f41 100644 --- a/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs @@ -1,6 +1,7 @@ // edition:2021 //check-pass #![warn(unused)] +#![allow(dead_code)] #![feature(rustc_attrs)] #[derive(Debug, Clone, Copy)] diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs index 8e4f91c27e224..3f7ddf93f0697 100644 --- a/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs @@ -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, diff --git a/src/test/ui/const-generics/broken-mir-2.rs b/src/test/ui/const-generics/broken-mir-2.rs index f9e03151374a2..9d62281178c48 100644 --- a/src/test/ui/const-generics/broken-mir-2.rs +++ b/src/test/ui/const-generics/broken-mir-2.rs @@ -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 index 0000000000000..80e9132093944 --- /dev/null +++ b/src/test/ui/derives/clone-debug-dead-code.rs @@ -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 index 0000000000000..226007f3647b1 --- /dev/null +++ b/src/test/ui/derives/clone-debug-dead-code.stderr @@ -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 + diff --git a/src/test/ui/deriving/deriving-clone-generic-struct.rs b/src/test/ui/deriving/deriving-clone-generic-struct.rs index f6e105555fd9d..4374d1594e465 100644 --- a/src/test/ui/deriving/deriving-clone-generic-struct.rs +++ b/src/test/ui/deriving/deriving-clone-generic-struct.rs @@ -1,6 +1,8 @@ // run-pass // pretty-expanded FIXME #23616 +#![allow(dead_code)] + #[derive(Clone)] struct S { foo: (), diff --git a/src/test/ui/deriving/deriving-clone-struct.rs b/src/test/ui/deriving/deriving-clone-struct.rs index 7b0a1d20260d4..b93cbe5f8b6fd 100644 --- a/src/test/ui/deriving/deriving-clone-struct.rs +++ b/src/test/ui/deriving/deriving-clone-struct.rs @@ -1,6 +1,8 @@ // run-pass // pretty-expanded FIXME #23616 +#![allow(dead_code)] + #[derive(Clone)] struct S { _int: isize, diff --git a/src/test/ui/deriving/deriving-clone-tuple-struct.rs b/src/test/ui/deriving/deriving-clone-tuple-struct.rs index 166f1be55e02a..7ad3f03471324 100644 --- a/src/test/ui/deriving/deriving-clone-tuple-struct.rs +++ b/src/test/ui/deriving/deriving-clone-tuple-struct.rs @@ -1,6 +1,8 @@ // run-pass // pretty-expanded FIXME #23616 +#![allow(dead_code)] + #[derive(Clone)] struct S((), ()); diff --git a/src/test/ui/deriving/deriving-in-fn.rs b/src/test/ui/deriving/deriving-in-fn.rs index 8931e94a4f8d2..07f91d0597356 100644 --- a/src/test/ui/deriving/deriving-in-fn.rs +++ b/src/test/ui/deriving/deriving-in-fn.rs @@ -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 index 0000000000000..c50b9a12b6d44 --- /dev/null +++ b/src/test/ui/expr/malformed_closure/missing_braces_around_block.fixed @@ -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 index 0000000000000..58c81f3a6e2a9 --- /dev/null +++ b/src/test/ui/expr/malformed_closure/missing_braces_around_block.rs @@ -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 index 0000000000000..dac9a8cfc69d4 --- /dev/null +++ b/src/test/ui/expr/malformed_closure/missing_braces_around_block.stderr @@ -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 index 0000000000000..e4341e196877b --- /dev/null +++ b/src/test/ui/expr/malformed_closure/ruby_style_closure.rs @@ -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 index 0000000000000..99df0632b4c33 --- /dev/null +++ b/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr @@ -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`. diff --git a/src/test/ui/issues/issue-19358.rs b/src/test/ui/issues/issue-19358.rs index f66e0a1c07841..3970a4155e95c 100644 --- a/src/test/ui/issues/issue-19358.rs +++ b/src/test/ui/issues/issue-19358.rs @@ -1,4 +1,7 @@ // run-pass + +#![allow(dead_code)] + trait Trait { fn dummy(&self) { } } #[derive(Debug)] diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr index 25a90df45613b..ce3ab6b599864 100644 --- a/src/test/ui/issues/issue-20605.stderr +++ b/src/test/ui/issues/issue-20605.stderr @@ -2,9 +2,12 @@ error[E0277]: the size for values of type `dyn Iterator` 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` + = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied = note: required because of the requirements on the impl of `IntoIterator` for `dyn Iterator` note: required by `into_iter` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL diff --git a/src/test/ui/issues/issue-3794.rs b/src/test/ui/issues/issue-3794.rs index 408d8d866d862..1809e822c5421 100644 --- a/src/test/ui/issues/issue-3794.rs +++ b/src/test/ui/issues/issue-3794.rs @@ -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 index 0000000000000..01e0a20a5115c --- /dev/null +++ b/src/test/ui/issues/issue-86865.rs @@ -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 index 0000000000000..eed755366311b --- /dev/null +++ b/src/test/ui/issues/issue-86865.stderr @@ -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 + diff --git a/src/test/ui/monomorphize-abi-alignment.rs b/src/test/ui/monomorphize-abi-alignment.rs index 637b09fc04e5f..a8d8bd1d5fd00 100644 --- a/src/test/ui/monomorphize-abi-alignment.rs +++ b/src/test/ui/monomorphize-abi-alignment.rs @@ -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 diff --git a/src/test/ui/moves/move-1-unique.rs b/src/test/ui/moves/move-1-unique.rs index 48baead074ac7..7d3987f656087 100644 --- a/src/test/ui/moves/move-1-unique.rs +++ b/src/test/ui/moves/move-1-unique.rs @@ -1,5 +1,6 @@ // run-pass #![allow(unused_mut)] +#![allow(dead_code)] #![feature(box_syntax)] #[derive(Clone)] diff --git a/src/test/ui/moves/move-3-unique.rs b/src/test/ui/moves/move-3-unique.rs index 55b10e057d88c..d23a852433f4f 100644 --- a/src/test/ui/moves/move-3-unique.rs +++ b/src/test/ui/moves/move-3-unique.rs @@ -1,5 +1,6 @@ // run-pass #![allow(unused_mut)] +#![allow(dead_code)] #![feature(box_syntax)] #[derive(Clone)] diff --git a/src/test/ui/overloaded/overloaded-autoderef-order.rs b/src/test/ui/overloaded/overloaded-autoderef-order.rs index 1ae16d2a7fc66..f48bae55f5f1e 100644 --- a/src/test/ui/overloaded/overloaded-autoderef-order.rs +++ b/src/test/ui/overloaded/overloaded-autoderef-order.rs @@ -1,5 +1,7 @@ // run-pass +#![allow(dead_code)] + use std::rc::Rc; use std::ops::Deref; diff --git a/src/test/ui/self/ufcs-explicit-self.rs b/src/test/ui/self/ufcs-explicit-self.rs index 4e2405504f0cb..0aaaa7d47c3c1 100644 --- a/src/test/ui/self/ufcs-explicit-self.rs +++ b/src/test/ui/self/ufcs-explicit-self.rs @@ -1,5 +1,6 @@ // run-pass #![feature(box_syntax)] +#![allow(dead_code)] #[derive(Copy, Clone)] struct Foo { diff --git a/src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs b/src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs index 55975cbdb5342..ca35a615d2147 100644 --- a/src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs +++ b/src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs @@ -1,5 +1,6 @@ // run-pass #![allow(non_camel_case_types)] +#![allow(dead_code)] trait noisy { fn speak(&mut self) -> isize; diff --git a/src/test/ui/structs-enums/class-implement-traits.rs b/src/test/ui/structs-enums/class-implement-traits.rs index c9e98e21b9eb4..732aa146ce446 100644 --- a/src/test/ui/structs-enums/class-implement-traits.rs +++ b/src/test/ui/structs-enums/class-implement-traits.rs @@ -1,5 +1,6 @@ // run-pass #![allow(non_camel_case_types)] +#![allow(dead_code)] trait noisy { fn speak(&mut self); diff --git a/src/test/ui/structs-enums/functional-struct-upd.rs b/src/test/ui/structs-enums/functional-struct-upd.rs index 51c6b6d7e4ffe..68ff73a080592 100644 --- a/src/test/ui/structs-enums/functional-struct-upd.rs +++ b/src/test/ui/structs-enums/functional-struct-upd.rs @@ -1,4 +1,7 @@ // run-pass + +#![allow(dead_code)] + #[derive(Debug)] struct Foo { x: isize, diff --git a/src/test/ui/structs-enums/tag-align-shape.rs b/src/test/ui/structs-enums/tag-align-shape.rs index 87282ddbcca52..ce59958237817 100644 --- a/src/test/ui/structs-enums/tag-align-shape.rs +++ b/src/test/ui/structs-enums/tag-align-shape.rs @@ -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 index 0000000000000..ecb7f54ea250a --- /dev/null +++ b/src/test/ui/suggestions/slice-issue-87994.rs @@ -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 index 0000000000000..018f62e783daf --- /dev/null +++ b/src/test/ui/suggestions/slice-issue-87994.stderr @@ -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`. diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 7627e0fb28956..41e6ad12d0589 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -29,36 +29,21 @@ declare_clippy_lint! { "#[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 @@ impl MacroUseImports { 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 @@ impl MacroUseImports { 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); } } diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs index eab097337306b..89be7bf844f3a 100644 --- a/src/tools/clippy/clippy_lints/src/regex.rs +++ b/src/tools/clippy/clippy_lints/src/regex.rs @@ -3,8 +3,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; 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}; @@ -53,10 +52,7 @@ declare_clippy_lint! { } #[derive(Clone, Default)] -pub struct Regex { - spans: FxHashSet, - last: Option, -} +pub struct Regex {} impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]); diff --git a/src/tools/clippy/tests/ui/default_trait_access.fixed b/src/tools/clippy/tests/ui/default_trait_access.fixed index 4c80cabc72305..f1f9c123dc842 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.fixed +++ b/src/tools/clippy/tests/ui/default_trait_access.fixed @@ -1,6 +1,6 @@ // run-rustfix -#![allow(unused_imports)] +#![allow(unused_imports,dead_code)] #![deny(clippy::default_trait_access)] use std::default; diff --git a/src/tools/clippy/tests/ui/default_trait_access.rs b/src/tools/clippy/tests/ui/default_trait_access.rs index a68b6455c0416..7f3dfc7f01366 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.rs +++ b/src/tools/clippy/tests/ui/default_trait_access.rs @@ -1,6 +1,6 @@ // run-rustfix -#![allow(unused_imports)] +#![allow(unused_imports,dead_code)] #![deny(clippy::default_trait_access)] use std::default; diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index a9bc89544d820..779a1149f413e 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -762,7 +762,6 @@ impl MacroArgKind { #[derive(Debug, Clone)] struct ParsedMacroArg { kind: MacroArgKind, - span: Span, } impl ParsedMacroArg { @@ -780,14 +779,10 @@ impl ParsedMacroArg { 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 @@ impl MacroArgParser { } fn set_last_tok(&mut self, tok: &TokenTree) { - self.hi = tok.span().hi(); self.last_tok = last_tok(tok); } @@ -836,7 +828,6 @@ impl MacroArgParser { }; 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 @@ impl MacroArgParser { }; 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 @@ impl MacroArgParser { 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 @@ impl MacroArgParser { } } - fn add_delimited(&mut self, inner: Vec, delim: DelimToken, span: Span) { + fn add_delimited(&mut self, inner: Vec, delim: DelimToken) { self.result.push(ParsedMacroArg { kind: MacroArgKind::Delimited(delim, inner), - span, }); } @@ -886,19 +874,15 @@ impl MacroArgParser { inner: Vec, 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 @@ impl MacroArgParser { } TokenTree::Token(ref t) => { buffer.push_str(&pprust::token_to_string(&t)); - hi = t.span.hi(); } _ => return None, } @@ -930,20 +913,17 @@ impl MacroArgParser { } 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 @@ impl MacroArgParser { // 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 @@ impl MacroArgParser { 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 @@ impl MacroArgParser { } // 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); } } } diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs index 5de0575b5cd66..ded34d9032f91 100644 --- a/src/tools/rustfmt/src/modules.rs +++ b/src/tools/rustfmt/src/modules.rs @@ -27,7 +27,6 @@ type FileModMap<'ast> = BTreeMap>; pub(crate) struct Module<'a> { ast_mod_kind: Option>, pub(crate) items: Cow<'a, Vec>>, - attrs: Cow<'a, Vec>, inner_attr: Vec, pub(crate) span: Span, } @@ -46,7 +45,6 @@ impl<'a> Module<'a> { .collect(); Module { items: mod_items, - attrs: mod_attrs, inner_attr, span: mod_span, ast_mod_kind,