diff options
Diffstat (limited to 'compiler/rustc_lint/src/builtin.rs')
-rw-r--r-- | compiler/rustc_lint/src/builtin.rs | 105 |
1 files changed, 48 insertions, 57 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 6b387df78..85141836e 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -22,7 +22,7 @@ use crate::fluent_generated as fluent; use crate::{ - errors::BuiltinEllpisisInclusiveRangePatterns, + errors::BuiltinEllipsisInclusiveRangePatterns, lints::{ BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinClashingExtern, BuiltinClashingExternSub, BuiltinConstNoMangle, BuiltinDeprecatedAttrLink, @@ -62,7 +62,9 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef}; +use rustc_session::config::ExpectedValues; use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; @@ -116,8 +118,7 @@ impl EarlyLintPass for WhileTrue { #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { if let ast::ExprKind::While(cond, _, label) = &e.kind - && let cond = pierce_parens(cond) - && let ast::ExprKind::Lit(token_lit) = cond.kind + && let ast::ExprKind::Lit(token_lit) = pierce_parens(cond).kind && let token::Lit { kind: token::Bool, symbol: kw::True, .. } = token_lit && !cond.span.from_expansion() { @@ -166,10 +167,8 @@ declare_lint_pass!(BoxPointers => [BOX_POINTERS]); impl BoxPointers { fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) { for leaf in ty.walk() { - if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { - if leaf_ty.is_box() { - cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); - } + if let GenericArgKind::Type(leaf_ty) = leaf.unpack() && leaf_ty.is_box() { + cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); } } } @@ -548,32 +547,17 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - match it.kind { - hir::ItemKind::Trait(..) => { - // Issue #11592: traits are always considered exported, even when private. - if cx.tcx.visibility(it.owner_id) - == ty::Visibility::Restricted( - cx.tcx.parent_module_from_def_id(it.owner_id.def_id).to_def_id(), - ) - { - return; - } - } - hir::ItemKind::TyAlias(..) - | hir::ItemKind::Fn(..) - | hir::ItemKind::Macro(..) - | hir::ItemKind::Mod(..) - | hir::ItemKind::Enum(..) - | hir::ItemKind::Struct(..) - | hir::ItemKind::Union(..) - | hir::ItemKind::Const(..) - | hir::ItemKind::Static(..) => {} - - _ => return, - }; + // Previously the Impl and Use types have been excluded from missing docs, + // so we will continue to exclude them for compatibility. + // + // The documentation on `ExternCrate` is not used at the moment so no need to warn for it. + if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(_) = + it.kind + { + return; + } let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id()); - self.check_missing_docs_attrs(cx, it.owner_id.def_id, article, desc); } @@ -631,7 +615,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { declare_lint! { /// The `missing_copy_implementations` lint detects potentially-forgotten - /// implementations of [`Copy`]. + /// implementations of [`Copy`] for public types. /// /// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html /// @@ -667,7 +651,9 @@ declare_lint_pass!(MissingCopyImplementations => [MISSING_COPY_IMPLEMENTATIONS]) impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { - if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) { + if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id) + && cx.tcx.local_visibility(item.owner_id.def_id).is_public()) + { return; } let (def, ty) = match item.kind { @@ -747,7 +733,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { declare_lint! { /// The `missing_debug_implementations` lint detects missing - /// implementations of [`fmt::Debug`]. + /// implementations of [`fmt::Debug`] for public types. /// /// [`fmt::Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html /// @@ -786,7 +772,9 @@ impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]); impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { - if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) { + if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id) + && cx.tcx.local_visibility(item.owner_id.def_id).is_public()) + { return; } @@ -977,7 +965,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: & Some(sugared_span.map_or(attr.span, |span| span.with_hi(attr.span.hi()))); } - if attrs.peek().map_or(false, |next_attr| next_attr.is_doc_comment()) { + if attrs.peek().is_some_and(|next_attr| next_attr.is_doc_comment()) { continue; } @@ -1463,6 +1451,10 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { // Bounds are respected for `type X = impl Trait` return; } + if cx.tcx.type_of(item.owner_id).skip_binder().has_inherent_projections() { + // Bounds are respected for `type X = … Type::Inherent …` + return; + } // There must not be a where clause if type_alias_generics.predicates.is_empty() { return; @@ -1582,7 +1574,6 @@ declare_lint_pass!( impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { - use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::Clause; use rustc_middle::ty::PredicateKind::*; @@ -1711,13 +1702,13 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { } } - let (parenthesise, endpoints) = match &pat.kind { + let (parentheses, endpoints) = match &pat.kind { PatKind::Ref(subpat, _) => (true, matches_ellipsis_pat(&subpat)), _ => (false, matches_ellipsis_pat(pat)), }; if let Some((start, end, join)) = endpoints { - if parenthesise { + if parentheses { self.node_id = Some(pat.id); let end = expr_to_string(&end); let replace = match start { @@ -1725,7 +1716,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { None => format!("&(..={})", end), }; if join.edition() >= Edition::Edition2021 { - cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns { + cx.sess().emit_err(BuiltinEllipsisInclusiveRangePatterns { span: pat.span, suggestion: pat.span, replace, @@ -1743,7 +1734,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { } else { let replace = "..="; if join.edition() >= Edition::Edition2021 { - cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns { + cx.sess().emit_err(BuiltinEllipsisInclusiveRangePatterns { span: pat.span, suggestion: join, replace: replace.to_string(), @@ -1899,8 +1890,8 @@ declare_lint_pass!( struct UnderMacro(bool); impl KeywordIdents { - fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: TokenStream) { - for tt in tokens.into_trees() { + fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: &TokenStream) { + for tt in tokens.trees() { match tt { // Only report non-raw idents. TokenTree::Token(token, _) => { @@ -1961,10 +1952,10 @@ impl KeywordIdents { impl EarlyLintPass for KeywordIdents { fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) { - self.check_tokens(cx, mac_def.body.tokens.clone()); + self.check_tokens(cx, &mac_def.body.tokens); } fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) { - self.check_tokens(cx, mac.args.tokens.clone()); + self.check_tokens(cx, &mac.args.tokens); } fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) { self.check_ident_token(cx, UnderMacro(false), ident); @@ -2560,7 +2551,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { .subst(cx.tcx, substs) .apply_any_module(cx.tcx, cx.param_env) { - // Entirely skip uninhbaited variants. + // Entirely skip uninhabited variants. Some(false) => return None, // Forward the others, but remember which ones are definitely inhabited. Some(true) => true, @@ -2628,7 +2619,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { if let Some(err) = with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init)) { let msg = match init { InitKind::Zeroed => fluent::lint_builtin_unpermitted_type_init_zeroed, - InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_unint, + InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_uninit, }; let sub = BuiltinUnpermittedTypeInitSub { err }; cx.emit_spanned_lint( @@ -2919,6 +2910,7 @@ impl ClashingExternDeclarations { | (Generator(..), Generator(..)) | (GeneratorWitness(..), GeneratorWitness(..)) | (Alias(ty::Projection, ..), Alias(ty::Projection, ..)) + | (Alias(ty::Inherent, ..), Alias(ty::Inherent, ..)) | (Alias(ty::Opaque, ..), Alias(ty::Opaque, ..)) => false, // These definitely should have been caught above. @@ -3308,16 +3300,15 @@ impl EarlyLintPass for UnexpectedCfgs { let cfg = &cx.sess().parse_sess.config; let check_cfg = &cx.sess().parse_sess.check_config; for &(name, value) in cfg { - if let Some(names_valid) = &check_cfg.names_valid && !names_valid.contains(&name){ - cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigName { - name, - }); - } - if let Some(value) = value && let Some(values) = check_cfg.values_valid.get(&name) && !values.contains(&value) { - cx.emit_lint( - UNEXPECTED_CFGS, - BuiltinUnexpectedCliConfigValue { name, value }, - ); + match check_cfg.expecteds.get(&name) { + Some(ExpectedValues::Some(values)) if !values.contains(&value) => { + let value = value.unwrap_or(kw::Empty); + cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigValue { name, value }); + } + None if check_cfg.exhaustive_names => { + cx.emit_lint(UNEXPECTED_CFGS, BuiltinUnexpectedCliConfigName { name }); + } + _ => { /* expected */ } } } } |