Skip to content

Commit 80fe0bb

Browse files
committed
add a rustc::query_stability lint
1 parent 7f79153 commit 80fe0bb

File tree

11 files changed

+246
-65
lines changed

11 files changed

+246
-65
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+3
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
460460
// Prevents field reads in the marked trait or method to be considered
461461
// during dead code analysis.
462462
rustc_attr!(rustc_trivial_field_reads, Normal, template!(Word), INTERNAL_UNSTABLE),
463+
// Used by the `rustc::potential_query_instability` lint to warn methods which
464+
// might not be stable during incremental compilation.
465+
rustc_attr!(rustc_lint_query_instability, Normal, template!(Word), INTERNAL_UNSTABLE),
463466

464467
// ==========================================================================
465468
// Internal attributes, Const related:

compiler/rustc_lint/src/internal.rs

+40-4
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}
55
use rustc_ast as ast;
66
use rustc_errors::Applicability;
77
use rustc_hir::def::Res;
8-
use rustc_hir::{
9-
GenericArg, HirId, Item, ItemKind, MutTy, Mutability, Node, Path, PathSegment, QPath, Ty,
10-
TyKind,
11-
};
8+
use rustc_hir::*;
129
use rustc_middle::ty;
1310
use rustc_session::{declare_lint_pass, declare_tool_lint};
1411
use rustc_span::hygiene::{ExpnKind, MacroKind};
@@ -51,6 +48,45 @@ impl LateLintPass<'_> for DefaultHashTypes {
5148
}
5249
}
5350

51+
declare_tool_lint! {
52+
pub rustc::POTENTIAL_QUERY_INSTABILITY,
53+
Allow,
54+
"require explicit opt-in when using potentially unstable methods or functions",
55+
report_in_external_macro: true
56+
}
57+
58+
declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY]);
59+
60+
impl LateLintPass<'_> for QueryStability {
61+
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
62+
let (def_id, span) = match expr.kind {
63+
ExprKind::Path(ref path) if let Some(def_id) = cx.qpath_res(path, expr.hir_id).opt_def_id() => {
64+
(def_id, expr.span)
65+
}
66+
ExprKind::MethodCall(_, span, _, _) if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => {
67+
(def_id, span)
68+
},
69+
_ => return,
70+
};
71+
72+
let substs = cx.typeck_results().node_substs(expr.hir_id);
73+
if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs) {
74+
let def_id = instance.def_id();
75+
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
76+
cx.struct_span_lint(POTENTIAL_QUERY_INSTABILITY, span, |lint| {
77+
let msg = format!(
78+
"using `{}` can result in unstable query results",
79+
cx.tcx.item_name(def_id)
80+
);
81+
lint.build(&msg)
82+
.note("if you believe this case to be fine, allow this lint and add a comment explaining your rationale")
83+
.emit();
84+
})
85+
}
86+
}
87+
}
88+
}
89+
5490
declare_tool_lint! {
5591
pub rustc::USAGE_OF_TY_TYKIND,
5692
Allow,

compiler/rustc_lint/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#![feature(box_patterns)]
3232
#![feature(crate_visibility_modifier)]
3333
#![feature(format_args_capture)]
34+
#![feature(if_let_guard)]
3435
#![feature(iter_order_by)]
3536
#![feature(iter_zip)]
3637
#![feature(never_type)]
@@ -484,6 +485,8 @@ fn register_internals(store: &mut LintStore) {
484485
store.register_early_pass(|| Box::new(LintPassImpl));
485486
store.register_lints(&DefaultHashTypes::get_lints());
486487
store.register_late_pass(|| Box::new(DefaultHashTypes));
488+
store.register_lints(&QueryStability::get_lints());
489+
store.register_late_pass(|| Box::new(QueryStability));
487490
store.register_lints(&ExistingDocKeyword::get_lints());
488491
store.register_late_pass(|| Box::new(ExistingDocKeyword));
489492
store.register_lints(&TyTyKind::get_lints());
@@ -494,6 +497,7 @@ fn register_internals(store: &mut LintStore) {
494497
None,
495498
vec![
496499
LintId::of(DEFAULT_HASH_TYPES),
500+
LintId::of(POTENTIAL_QUERY_INSTABILITY),
497501
LintId::of(USAGE_OF_TY_TYKIND),
498502
LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
499503
LintId::of(TY_PASS_BY_REFERENCE),

0 commit comments

Comments
 (0)