diff options
Diffstat (limited to 'compiler/rustc_lint/src')
| -rw-r--r-- | compiler/rustc_lint/src/context.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/internal.rs | 54 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 5 |
3 files changed, 63 insertions, 3 deletions
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index cb08e952586..5da77b9f946 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -143,7 +143,11 @@ impl LintStore { &self.lints } - pub fn get_lint_groups<'t>(&'t self) -> Vec<(&'static str, Vec<LintId>, bool)> { + pub fn get_lint_groups<'t>( + &'t self, + ) -> impl Iterator<Item = (&'static str, Vec<LintId>, bool)> + 't { + // This function is not used in a way which observes the order of lints. + #[cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))] self.lint_groups .iter() .filter(|(_, LintGroup { depr, .. })| { @@ -153,7 +157,6 @@ impl LintStore { .map(|(k, LintGroup { lint_ids, from_plugin, .. })| { (*k, lint_ids.clone(), *from_plugin) }) - .collect() } pub fn register_early_pass( diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index d8e1162890c..b4b75bf64c9 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -5,7 +5,7 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext} use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::{GenericArg, HirId, Item, ItemKind, Node, Path, PathSegment, QPath, Ty, TyKind}; +use rustc_hir::*; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::{ExpnKind, MacroKind}; @@ -49,6 +49,58 @@ impl LateLintPass<'_> for DefaultHashTypes { } declare_tool_lint! { + pub rustc::POTENTIAL_QUERY_INSTABILITY, + Allow, + "require explicit opt-in when using potentially unstable methods or functions", + report_in_external_macro: true +} + +declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY]); + +impl LateLintPass<'_> for QueryStability { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + // FIXME(rustdoc): This lint uses typecheck results, causing rustdoc to + // error if there are resolution failures. + // + // As internal lints are currently always run if there are `unstable_options`, + // they are added to the lint store of rustdoc. Internal lints are also + // not used via the `lint_mod` query. Crate lints run outside of a query + // so rustdoc currently doesn't disable them. + // + // Instead of relying on this, either change crate lints to a query disabled by + // rustdoc, only run internal lints if the user is explicitly opting in + // or figure out a different way to avoid running lints for rustdoc. + if cx.tcx.sess.opts.actually_rustdoc { + return; + } + + let (span, def_id, substs) = match expr.kind { + ExprKind::MethodCall(_, span, _, _) if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => { + (span, def_id, cx.typeck_results().node_substs(expr.hir_id)) + }, + _ => { + let &ty::FnDef(def_id, substs) = cx.typeck_results().node_type(expr.hir_id).kind() else { return }; + (expr.span, def_id, substs) + } + }; + if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs) { + let def_id = instance.def_id(); + if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { + cx.struct_span_lint(POTENTIAL_QUERY_INSTABILITY, span, |lint| { + let msg = format!( + "using `{}` can result in unstable query results", + cx.tcx.item_name(def_id) + ); + lint.build(&msg) + .note("if you believe this case to be fine, allow this lint and add a comment explaining your rationale") + .emit(); + }) + } + } + } +} + +declare_tool_lint! { pub rustc::USAGE_OF_TY_TYKIND, Allow, "usage of `ty::TyKind` outside of the `ty::sty` module", diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a87f2b2768d..69863b5ff82 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -30,12 +30,14 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(crate_visibility_modifier)] +#![feature(if_let_guard)] #![feature(iter_order_by)] #![feature(let_else)] #![feature(never_type)] #![feature(nll)] #![feature(control_flow_enum)] #![recursion_limit = "256"] +#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))] #[macro_use] extern crate rustc_middle; @@ -493,6 +495,8 @@ fn register_internals(store: &mut LintStore) { store.register_early_pass(|| Box::new(LintPassImpl)); store.register_lints(&DefaultHashTypes::get_lints()); store.register_late_pass(|| Box::new(DefaultHashTypes)); + store.register_lints(&QueryStability::get_lints()); + store.register_late_pass(|| Box::new(QueryStability)); store.register_lints(&ExistingDocKeyword::get_lints()); store.register_late_pass(|| Box::new(ExistingDocKeyword)); store.register_lints(&TyTyKind::get_lints()); @@ -505,6 +509,7 @@ fn register_internals(store: &mut LintStore) { None, vec