Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rustc lint, warning when iterating over hashmaps #89558

Merged
merged 4 commits into from
Oct 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#![feature(box_patterns)]
#![feature(iter_zip)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

use rustc_ast::node_id::NodeMap;
use rustc_ast::token::{self, Token};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#![feature(iter_is_partitioned)]
#![feature(box_patterns)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

pub mod ast_validation;
pub mod feature_gate;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#![feature(trusted_step)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate rustc_middle;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

extern crate proc_macro;

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#![feature(iter_zip)]
#![feature(nll)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

use back::write::{create_informational_target_machine, create_target_machine};

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#![feature(nll)]
#![feature(associated_type_bounds)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

//! This crate contains codegen code that is used by all codegen backends (LLVM and others).
//! The backend-agnostic functions of this crate use functions defined in various traits that
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Rust MIR: a lowered representation of Rust.
#![feature(trusted_step)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate tracing;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#![feature(thread_id_value)]
#![allow(rustc::default_hash_types)]
#![deny(unaligned_references)]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate tracing;
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#![feature(nll)]
#![feature(once_cell)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate tracing;
Expand Down Expand Up @@ -846,7 +847,7 @@ Available lint options:
let builtin = sort_lints(sess, builtin);

let (plugin_groups, builtin_groups): (Vec<_>, _) =
lint_store.get_lint_groups().iter().cloned().partition(|&(.., p)| p);
lint_store.get_lint_groups().partition(|&(.., p)| p);
let plugin_groups = sort_lint_groups(plugin_groups);
let builtin_groups = sort_lint_groups(builtin_groups);

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![feature(format_args_capture)]
#![feature(iter_zip)]
#![feature(nll)]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate rustc_macros;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_expand/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![feature(proc_macro_span)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate rustc_macros;
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// 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),
// Used by the `rustc::potential_query_instability` lint to warn methods which
// might not be stable during incremental compilation.
rustc_attr!(rustc_lint_query_instability, Normal, template!(Word), INTERNAL_UNSTABLE),

// ==========================================================================
// Internal attributes, Const related:
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_incremental/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate rustc_middle;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#![feature(min_specialization)]
#![feature(label_break_value)]
#![recursion_limit = "512"] // For rustdoc
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate rustc_macros;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#![feature(nll)]
#![feature(once_cell)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

mod callbacks;
pub mod interface;
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,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, .. })| {
Expand All @@ -154,7 +158,6 @@ impl LintStore {
.map(|(k, LintGroup { lint_ids, from_plugin, .. })| {
(*k, lint_ids.clone(), *from_plugin)
})
.collect()
}

pub fn register_early_pass(
Expand Down
59 changes: 55 additions & 4 deletions compiler/rustc_lint/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +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, MutTy, Mutability, 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};
Expand Down Expand Up @@ -51,6 +48,60 @@ 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 (def_id, span) = match expr.kind {
ExprKind::Path(ref path) if let Some(def_id) = cx.qpath_res(path, expr.hir_id).opt_def_id() => {
(def_id, expr.span)
}
ExprKind::MethodCall(_, span, _, _) if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => {
(def_id, span)
},
_ => return,
};

let substs = cx.typeck_results().node_substs(expr.hir_id);
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,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
#![feature(box_patterns)]
#![feature(crate_visibility_modifier)]
#![feature(format_args_capture)]
#![feature(if_let_guard)]
#![feature(iter_order_by)]
#![feature(iter_zip)]
#![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;
Expand Down Expand Up @@ -484,6 +486,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());
Expand All @@ -494,6 +498,7 @@ fn register_internals(store: &mut LintStore) {
None,
vec![
LintId::of(DEFAULT_HASH_TYPES),
LintId::of(POTENTIAL_QUERY_INSTABILITY),
LintId::of(USAGE_OF_TY_TYKIND),
LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
LintId::of(TY_PASS_BY_REFERENCE),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![feature(try_blocks)]
#![feature(never_type)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

extern crate proc_macro;

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#![feature(try_reserve_kind)]
#![feature(nonzero_ops)]
#![recursion_limit = "512"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate bitflags;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![feature(once_cell)]
#![feature(min_specialization)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate tracing;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#![feature(trusted_step)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate tracing;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_monomorphize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#![feature(control_flow_enum)]
#![feature(in_band_lifetimes)]
#![recursion_limit = "256"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]

#[macro_use]
extern crate tracing;
Expand Down
Loading