diff options
| author | bors <bors@rust-lang.org> | 2022-12-24 09:41:11 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-12-24 09:41:11 +0000 |
| commit | d23554fae855d884761d549cd6ee6537450b0f3c (patch) | |
| tree | b44bd3e79fa5019f0e8648737e71c432bc784188 /compiler/rustc_lint/src | |
| parent | 245357f61939d2b6d15f8c6b15f7026396f95871 (diff) | |
| parent | e52e0d855799fe651922be4a038fe84fe9009c72 (diff) | |
| download | rust-d23554fae855d884761d549cd6ee6537450b0f3c.tar.gz rust-d23554fae855d884761d549cd6ee6537450b0f3c.zip | |
Auto merge of #2738 - RalfJung:rustup, r=RalfJung
Rustup
Diffstat (limited to 'compiler/rustc_lint/src')
| -rw-r--r-- | compiler/rustc_lint/src/builtin.rs | 76 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/for_loops_over_fallibles.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/levels.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/non_fmt_panic.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/nonstandard_style.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/unused.rs | 2 |
8 files changed, 107 insertions, 17 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 43862570e80..d6de6e70ead 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -25,6 +25,7 @@ use crate::{ types::{transparent_newtype_field, CItemKind}, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext, }; +use hir::IsAsync; use rustc_ast::attr; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::visit::{FnCtxt, FnKind}; @@ -40,7 +41,10 @@ use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, Gate use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; -use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin}; +use rustc_hir::intravisit::FnKind as HirFnKind; +use rustc_hir::{ + Body, FnDecl, ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin, +}; use rustc_index::vec::Idx; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::{LayoutError, LayoutOf}; @@ -270,7 +274,7 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns { |lint| { let suggested_ident = format!("{}{}", binding_annot.prefix_str(), ident); - lint.set_arg("ident", ident.clone()).span_suggestion( + lint.set_arg("ident", ident).span_suggestion( fieldpat.span, fluent::suggestion, suggested_ident, @@ -1371,6 +1375,72 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures { } declare_lint! { + /// The `ungated_async_fn_track_caller` lint warns when the + /// `#[track_caller]` attribute is used on an async function, method, or + /// closure, without enabling the corresponding unstable feature flag. + /// + /// ### Example + /// + /// ```rust + /// #[track_caller] + /// async fn foo() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The attribute must be used in conjunction with the + /// [`closure_track_caller` feature flag]. Otherwise, the `#[track_caller]` + /// annotation will function as as no-op. + /// + /// [`closure_track_caller` feature flag]: https://doc.rust-lang.org/beta/unstable-book/language-features/closure-track-caller.html + UNGATED_ASYNC_FN_TRACK_CALLER, + Warn, + "enabling track_caller on an async fn is a no-op unless the closure_track_caller feature is enabled" +} + +declare_lint_pass!( + /// Explains corresponding feature flag must be enabled for the `#[track_caller] attribute to + /// do anything + UngatedAsyncFnTrackCaller => [UNGATED_ASYNC_FN_TRACK_CALLER] +); + +impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller { + fn check_fn( + &mut self, + cx: &LateContext<'_>, + fn_kind: HirFnKind<'_>, + _: &'tcx FnDecl<'_>, + _: &'tcx Body<'_>, + span: Span, + hir_id: HirId, + ) { + if fn_kind.asyncness() == IsAsync::Async + && !cx.tcx.features().closure_track_caller + && let attrs = cx.tcx.hir().attrs(hir_id) + // Now, check if the function has the `#[track_caller]` attribute + && let Some(attr) = attrs.iter().find(|attr| attr.has_name(sym::track_caller)) + { + cx.struct_span_lint( + UNGATED_ASYNC_FN_TRACK_CALLER, + attr.span, + fluent::lint_ungated_async_fn_track_caller, + |lint| { + lint.span_label(span, fluent::label); + rustc_session::parse::add_feature_diagnostics( + lint, + &cx.tcx.sess.parse_sess, + sym::closure_track_caller, + ); + lint + }, + ); + } + } +} + +declare_lint! { /// The `unreachable_pub` lint triggers for `pub` items not reachable from /// the crate root. /// @@ -2052,7 +2122,7 @@ impl KeywordIdents { ident.span, fluent::lint_builtin_keyword_idents, |lint| { - lint.set_arg("kw", ident.clone()).set_arg("next", next_edition).span_suggestion( + lint.set_arg("kw", ident).set_arg("next", next_edition).span_suggestion( ident.span, fluent::suggestion, format!("r#{}", ident), diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 40b2588388d..3c9ad410663 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -438,18 +438,18 @@ impl LintStore { return CheckLintNameResult::Tool(Ok(&lint_ids)); } }, - Some(&Id(ref id)) => return CheckLintNameResult::Tool(Ok(slice::from_ref(id))), + Some(Id(id)) => return CheckLintNameResult::Tool(Ok(slice::from_ref(id))), // If the lint was registered as removed or renamed by the lint tool, we don't need // to treat tool_lints and rustc lints different and can use the code below. _ => {} } } match self.by_name.get(&complete_name) { - Some(&Renamed(ref new_name, _)) => CheckLintNameResult::Warning( + Some(Renamed(new_name, _)) => CheckLintNameResult::Warning( format!("lint `{}` has been renamed to `{}`", complete_name, new_name), Some(new_name.to_owned()), ), - Some(&Removed(ref reason)) => CheckLintNameResult::Warning( + Some(Removed(reason)) => CheckLintNameResult::Warning( format!("lint `{}` has been removed: {}", complete_name, reason), None, ), @@ -470,7 +470,7 @@ impl LintStore { CheckLintNameResult::Ok(&lint_ids) } }, - Some(&Id(ref id)) => CheckLintNameResult::Ok(slice::from_ref(id)), + Some(Id(id)) => CheckLintNameResult::Ok(slice::from_ref(id)), Some(&Ignored) => CheckLintNameResult::Ok(&[]), } } @@ -483,7 +483,16 @@ impl LintStore { return CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower))); } // ...if not, search for lints with a similar name - let groups = self.lint_groups.keys().copied().map(Symbol::intern); + // Note: find_best_match_for_name depends on the sort order of its input vector. + // To ensure deterministic output, sort elements of the lint_groups hash map. + // Also, never suggest deprecated lint groups. + let mut groups: Vec<_> = self + .lint_groups + .iter() + .filter_map(|(k, LintGroup { depr, .. })| if depr.is_none() { Some(k) } else { None }) + .collect(); + groups.sort(); + let groups = groups.iter().map(|k| Symbol::intern(k)); let lints = self.lints.iter().map(|l| Symbol::intern(&l.name_lower())); let names: Vec<Symbol> = groups.chain(lints).collect(); let suggestion = find_best_match_for_name(&names, Symbol::intern(&name_lower), None); @@ -513,7 +522,7 @@ impl LintStore { CheckLintNameResult::Tool(Err((Some(&lint_ids), complete_name))) } }, - Some(&Id(ref id)) => { + Some(Id(id)) => { CheckLintNameResult::Tool(Err((Some(slice::from_ref(id)), complete_name))) } Some(other) => { diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index 4187850153c..182734fa9fc 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -71,11 +71,11 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { ); } else { lint.multipart_suggestion_verbose( - format!("to check pattern in a loop use `while let`"), + "to check pattern in a loop use `while let`", vec![ // NB can't use `until` here because `expr.span` and `pat.span` have different syntax contexts (expr.span.with_hi(pat.span.lo()), format!("while let {var}(")), - (pat.span.between(arg.span), format!(") = ")), + (pat.span.between(arg.span), ") = ".to_string()), ], Applicability::MaybeIncorrect ); @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { vec![ // NB can't use `until` here because `expr.span` and `pat.span` have different syntax contexts (expr.span.with_hi(pat.span.lo()), format!("if let {var}(")), - (pat.span.between(arg.span), format!(") = ")), + (pat.span.between(arg.span), ") = ".to_string()), ], Applicability::MaybeIncorrect, ) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 847c356b83c..e9d3d44a3f9 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -39,9 +39,9 @@ struct LintLevelSets { } rustc_index::newtype_index! { + #[custom_encodable] // we don't need encoding struct LintStackIndex { - ENCODABLE = custom, // we don't need encoding - const COMMAND_LINE = 0, + const COMMAND_LINE = 0; } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 11022eb80ea..1275d6f223c 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -219,6 +219,7 @@ late_lint_methods!( // May Depend on constants elsewhere UnusedBrokenConst: UnusedBrokenConst, UnstableFeatures: UnstableFeatures, + UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller, ArrayIntoIter: ArrayIntoIter::default(), DropTraitConstraints: DropTraitConstraints, TemporaryCStringAsPtr: TemporaryCStringAsPtr, diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index c1820ac4d1e..8dccfe0046c 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -304,7 +304,7 @@ fn check_panic_str<'tcx>( /// Given the span of `some_macro!(args);`, gives the span of `(` and `)`, /// and the type of (opening) delimiter used. -fn find_delimiters<'tcx>(cx: &LateContext<'tcx>, span: Span) -> Option<(Span, Span, char)> { +fn find_delimiters(cx: &LateContext<'_>, span: Span) -> Option<(Span, Span, char)> { let snippet = cx.sess().parse_sess.source_map().span_to_snippet(span).ok()?; let (open, open_ch) = snippet.char_indices().find(|&(_, c)| "([{".contains(c))?; let close = snippet.rfind(|c| ")]}".contains(c))?; diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 7e50801f80c..91fcd6d690e 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -175,13 +175,23 @@ impl EarlyLintPass for NonCamelCaseTypes { return; } - match it.kind { + match &it.kind { ast::ItemKind::TyAlias(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident), ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident), ast::ItemKind::TraitAlias(..) => self.check_case(cx, "trait alias", &it.ident), + + // N.B. This check is only for inherent associated types, so that we don't lint against + // trait impls where we should have warned for the trait definition already. + ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => { + for it in items { + if let ast::AssocItemKind::Type(..) = it.kind { + self.check_case(cx, "associated type", &it.ident); + } + } + } _ => (), } } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index d628a18dd01..3b8df61a0ea 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1279,7 +1279,7 @@ impl UnusedImportBraces { fn check_use_tree(&self, cx: &EarlyContext<'_>, use_tree: &ast::UseTree, item: &ast::Item) { if let ast::UseTreeKind::Nested(ref items) = use_tree.kind { // Recursively check nested UseTrees - for &(ref tree, _) in items { + for (tree, _) in items { self.check_use_tree(cx, tree, item); } |
