summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_passes
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_passes')
-rw-r--r--compiler/rustc_passes/Cargo.toml1
-rw-r--r--compiler/rustc_passes/messages.ftl (renamed from compiler/rustc_passes/locales/en-US.ftl)24
-rw-r--r--compiler/rustc_passes/src/check_attr.rs186
-rw-r--r--compiler/rustc_passes/src/check_const.rs4
-rw-r--r--compiler/rustc_passes/src/dead.rs101
-rw-r--r--compiler/rustc_passes/src/debugger_visualizer.rs8
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs7
-rw-r--r--compiler/rustc_passes/src/entry.rs15
-rw-r--r--compiler/rustc_passes/src/errors.rs49
-rw-r--r--compiler/rustc_passes/src/hir_id_validator.rs4
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs4
-rw-r--r--compiler/rustc_passes/src/layout_test.rs2
-rw-r--r--compiler/rustc_passes/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs9
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs7
-rw-r--r--compiler/rustc_passes/src/reachable.rs10
-rw-r--r--compiler/rustc_passes/src/stability.rs31
17 files changed, 206 insertions, 258 deletions
diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml
index faa9c493d..44f991f8c 100644
--- a/compiler/rustc_passes/Cargo.toml
+++ b/compiler/rustc_passes/Cargo.toml
@@ -22,3 +22,4 @@ rustc_span = { path = "../rustc_span" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_feature = { path = "../rustc_feature" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/compiler/rustc_passes/locales/en-US.ftl b/compiler/rustc_passes/messages.ftl
index 3fa78efc2..b354dca7c 100644
--- a/compiler/rustc_passes/locales/en-US.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -148,9 +148,6 @@ passes_doc_test_unknown =
passes_doc_test_takes_list =
`#[doc(test(...)]` takes a list of attributes
-passes_doc_primitive =
- `doc(primitive)` should never have been stable
-
passes_doc_cfg_hide_takes_list =
`#[doc(cfg_hide(...)]` takes a list of attributes
@@ -720,26 +717,7 @@ passes_ignored_derived_impls =
*[other] traits {$trait_list}, but these are
} intentionally ignored during dead code analysis
-passes_proc_macro_typeerror = mismatched {$kind} signature
- .label = found {$found}, expected type `proc_macro::TokenStream`
- .note = {$kind}s must have a signature of `{$expected_signature}`
-
-passes_proc_macro_diff_arg_count = mismatched {$kind} signature
- .label = found unexpected {$count ->
- [one] argument
- *[other] arguments
- }
- .note = {$kind}s must have a signature of `{$expected_signature}`
-
-passes_proc_macro_missing_args = mismatched {$kind} signature
- .label = {$kind} must have {$expected_input_count ->
- [one] one argument
- *[other] two arguments
- } of type `proc_macro::TokenStream`
-
-passes_proc_macro_invalid_abi = proc macro functions may not be `extern "{$abi}"`
-
-passes_proc_macro_unsafe = proc macro functions may not be `unsafe`
+passes_proc_macro_bad_sig = {$kind} has incorrect signature
passes_skipping_const_checks = skipping const checks
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 5ef3e13ef..80a93da2b 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -19,9 +19,10 @@ use rustc_hir::{
use rustc_hir::{MethodKind, Target, Unsafety};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
-use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
+use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{ParamEnv, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
UNUSED_ATTRIBUTES,
@@ -30,6 +31,9 @@ use rustc_session::parse::feature_err;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
+use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
+use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
+use rustc_trait_selection::traits::ObligationCtxt;
use std::cell::Cell;
use std::collections::hash_map::Entry;
@@ -1105,17 +1109,6 @@ impl CheckAttrVisitor<'_> {
}
}
- sym::primitive => {
- if !self.tcx.features().rustdoc_internals {
- self.tcx.emit_spanned_lint(
- INVALID_DOC_ATTRIBUTES,
- hir_id,
- i_meta.span,
- errors::DocPrimitive,
- );
- }
- }
-
_ => {
let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path);
if i_meta.has_name(sym::spotlight) {
@@ -1903,7 +1896,7 @@ impl CheckAttrVisitor<'_> {
match target {
Target::Fn => {
for attr in attrs {
- if self.tcx.sess.is_proc_macro_attr(attr) {
+ if attr.is_proc_macro_attr() {
debug!("Is proc macro attr");
return true;
}
@@ -2188,100 +2181,99 @@ impl CheckAttrVisitor<'_> {
///
/// If this best effort goes wrong, it will just emit a worse error later (see #102923)
fn check_proc_macro(&self, hir_id: HirId, target: Target, kind: ProcMacroKind) {
- let expected_input_count = match kind {
- ProcMacroKind::Attribute => 2,
- ProcMacroKind::Derive | ProcMacroKind::FunctionLike => 1,
- };
-
- let expected_signature = match kind {
- ProcMacroKind::Attribute => "fn(TokenStream, TokenStream) -> TokenStream",
- ProcMacroKind::Derive | ProcMacroKind::FunctionLike => "fn(TokenStream) -> TokenStream",
- };
+ if target != Target::Fn {
+ return;
+ }
let tcx = self.tcx;
- if target == Target::Fn {
- let Some(tokenstream) = tcx.get_diagnostic_item(sym::TokenStream) else {return};
- let tokenstream = tcx.type_of(tokenstream).subst_identity();
-
- let id = hir_id.expect_owner();
- let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id).unwrap();
-
- let sig =
- tcx.liberate_late_bound_regions(id.to_def_id(), tcx.fn_sig(id).subst_identity());
- let sig = tcx.normalize_erasing_regions(ParamEnv::empty(), sig);
-
- // We don't currently require that the function signature is equal to
- // `fn(TokenStream) -> TokenStream`, but instead monomorphizes to
- // `fn(TokenStream) -> TokenStream` after some substitution of generic arguments.
- //
- // Properly checking this means pulling in additional `rustc` crates, so we don't.
- let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::AsInfer };
-
- if sig.abi != Abi::Rust {
- tcx.sess.emit_err(errors::ProcMacroInvalidAbi {
- span: hir_sig.span,
- abi: sig.abi.name(),
- });
- self.abort.set(true);
- }
+ let Some(token_stream_def_id) = tcx.get_diagnostic_item(sym::TokenStream) else { return; };
+ let Some(token_stream) = tcx.type_of(token_stream_def_id).no_bound_vars() else { return; };
- if sig.unsafety == Unsafety::Unsafe {
- tcx.sess.emit_err(errors::ProcMacroUnsafe { span: hir_sig.span });
- self.abort.set(true);
- }
+ let def_id = hir_id.expect_owner().def_id;
+ let param_env = ty::ParamEnv::empty();
- let output = sig.output();
+ let infcx = tcx.infer_ctxt().build();
+ let ocx = ObligationCtxt::new(&infcx);
- // Typecheck the output
- if !drcx.types_may_unify(output, tokenstream) {
- tcx.sess.emit_err(errors::ProcMacroTypeError {
- span: hir_sig.decl.output.span(),
- found: output,
- kind,
- expected_signature,
- });
- self.abort.set(true);
- }
+ let span = tcx.def_span(def_id);
+ let fresh_substs = infcx.fresh_substs_for_item(span, def_id.to_def_id());
+ let sig = tcx.liberate_late_bound_regions(
+ def_id.to_def_id(),
+ tcx.fn_sig(def_id).subst(tcx, fresh_substs),
+ );
- if sig.inputs().len() < expected_input_count {
- tcx.sess.emit_err(errors::ProcMacroMissingArguments {
- expected_input_count,
- span: hir_sig.span,
- kind,
- expected_signature,
- });
- self.abort.set(true);
- }
+ let mut cause = ObligationCause::misc(span, def_id);
+ let sig = ocx.normalize(&cause, param_env, sig);
- // Check that the inputs are correct, if there are enough.
- if sig.inputs().len() >= expected_input_count {
- for (arg, input) in
- sig.inputs().iter().zip(hir_sig.decl.inputs).take(expected_input_count)
- {
- if !drcx.types_may_unify(*arg, tokenstream) {
- tcx.sess.emit_err(errors::ProcMacroTypeError {
- span: input.span,
- found: *arg,
- kind,
- expected_signature,
- });
- self.abort.set(true);
+ // proc macro is not WF.
+ let errors = ocx.select_where_possible();
+ if !errors.is_empty() {
+ return;
+ }
+
+ let expected_sig = tcx.mk_fn_sig(
+ std::iter::repeat(token_stream).take(match kind {
+ ProcMacroKind::Attribute => 2,
+ ProcMacroKind::Derive | ProcMacroKind::FunctionLike => 1,
+ }),
+ token_stream,
+ false,
+ Unsafety::Normal,
+ Abi::Rust,
+ );
+
+ if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) {
+ let mut diag = tcx.sess.create_err(errors::ProcMacroBadSig { span, kind });
+
+ let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id);
+ if let Some(hir_sig) = hir_sig {
+ match terr {
+ TypeError::ArgumentMutability(idx) | TypeError::ArgumentSorts(_, idx) => {
+ if let Some(ty) = hir_sig.decl.inputs.get(idx) {
+ diag.set_span(ty.span);
+ cause.span = ty.span;
+ } else if idx == hir_sig.decl.inputs.len() {
+ let span = hir_sig.decl.output.span();
+ diag.set_span(span);
+ cause.span = span;
+ }
}
+ TypeError::ArgCount => {
+ if let Some(ty) = hir_sig.decl.inputs.get(expected_sig.inputs().len()) {
+ diag.set_span(ty.span);
+ cause.span = ty.span;
+ }
+ }
+ TypeError::UnsafetyMismatch(_) => {
+ // FIXME: Would be nice if we had a span here..
+ }
+ TypeError::AbiMismatch(_) => {
+ // FIXME: Would be nice if we had a span here..
+ }
+ TypeError::VariadicMismatch(_) => {
+ // FIXME: Would be nice if we had a span here..
+ }
+ _ => {}
}
}
- // Check that there are not too many arguments
- let body_id = tcx.hir().body_owned_by(id.def_id);
- let excess = tcx.hir().body(body_id).params.get(expected_input_count..);
- if let Some(excess @ [begin @ end] | excess @ [begin, .., end]) = excess {
- tcx.sess.emit_err(errors::ProcMacroDiffArguments {
- span: begin.span.to(end.span),
- count: excess.len(),
- kind,
- expected_signature,
- });
- self.abort.set(true);
- }
+ infcx.err_ctxt().note_type_err(
+ &mut diag,
+ &cause,
+ None,
+ Some(ValuePairs::Sigs(ExpectedFound { expected: expected_sig, found: sig })),
+ terr,
+ false,
+ false,
+ );
+ diag.emit();
+ self.abort.set(true);
+ }
+
+ let errors = ocx.select_all_or_error();
+ if !errors.is_empty() {
+ infcx.err_ctxt().report_fulfillment_errors(&errors);
+ self.abort.set(true);
}
}
}
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 526b829bf..30dd3e4d0 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -104,9 +104,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
// If this crate is not using stability attributes, or this function is not claiming to be a
// stable `const fn`, that is all that is required.
- if !tcx.features().staged_api
- || tcx.has_attr(def_id.to_def_id(), sym::rustc_const_unstable)
- {
+ if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
return true;
}
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index e2f858a34..5cfe691df 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -2,8 +2,8 @@
// closely. The idea is that all reachable symbols are live, codes called
// from live codes are live, and everything else is dead.
+use hir::def_id::{LocalDefIdMap, LocalDefIdSet};
use itertools::Itertools;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::MultiSpan;
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
@@ -13,9 +13,10 @@ use rustc_hir::{Node, PatKind, TyKind};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::privacy::Level;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, DefIdTree, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{sym, Symbol};
+use rustc_target::abi::FieldIdx;
use std::mem;
use crate::errors::{
@@ -45,17 +46,17 @@ struct MarkSymbolVisitor<'tcx> {
worklist: Vec<LocalDefId>,
tcx: TyCtxt<'tcx>,
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
- live_symbols: FxHashSet<LocalDefId>,
+ live_symbols: LocalDefIdSet,
repr_has_repr_c: bool,
repr_has_repr_simd: bool,
in_pat: bool,
ignore_variant_stack: Vec<DefId>,
// maps from tuple struct constructors to tuple struct items
- struct_constructors: FxHashMap<LocalDefId, LocalDefId>,
+ struct_constructors: LocalDefIdMap<LocalDefId>,
// maps from ADTs to ignored derived traits (e.g. Debug and Clone)
// and the span of their respective impl (i.e., part of the derive
// macro)
- ignored_derived_traits: FxHashMap<LocalDefId, Vec<(DefId, DefId)>>,
+ ignored_derived_traits: LocalDefIdMap<Vec<(DefId, DefId)>>,
}
impl<'tcx> MarkSymbolVisitor<'tcx> {
@@ -232,17 +233,23 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
if let PatKind::Wild = pat.kind {
continue;
}
- self.insert_def_id(variant.fields[idx].did);
+ self.insert_def_id(variant.fields[FieldIdx::from_usize(idx)].did);
}
}
fn mark_live_symbols(&mut self) {
- let mut scanned = FxHashSet::default();
+ let mut scanned = LocalDefIdSet::default();
while let Some(id) = self.worklist.pop() {
if !scanned.insert(id) {
continue;
}
+ // Avoid accessing the HIR for the synthesized associated type generated for RPITITs.
+ if self.tcx.opt_rpitit_info(id.to_def_id()).is_some() {
+ self.live_symbols.insert(id);
+ continue;
+ }
+
// in the case of tuple struct constructors we want to check the item, not the generated
// tuple struct constructor function
let id = self.struct_constructors.get(&id).copied().unwrap_or(id);
@@ -463,9 +470,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
fn has_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
- tcx.has_attr(def_id.to_def_id(), sym::lang)
+ tcx.has_attr(def_id, sym::lang)
// Stable attribute for #[lang = "panic_impl"]
- || tcx.has_attr(def_id.to_def_id(), sym::panic_handler)
+ || tcx.has_attr(def_id, sym::panic_handler)
}
fn has_allow_dead_code(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
@@ -506,7 +513,7 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool
fn check_item<'tcx>(
tcx: TyCtxt<'tcx>,
worklist: &mut Vec<LocalDefId>,
- struct_constructors: &mut FxHashMap<LocalDefId, LocalDefId>,
+ struct_constructors: &mut LocalDefIdMap<LocalDefId>,
id: hir::ItemId,
) {
let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id);
@@ -583,9 +590,7 @@ fn check_foreign_item(tcx: TyCtxt<'_>, worklist: &mut Vec<LocalDefId>, id: hir::
}
}
-fn create_and_seed_worklist(
- tcx: TyCtxt<'_>,
-) -> (Vec<LocalDefId>, FxHashMap<LocalDefId, LocalDefId>) {
+fn create_and_seed_worklist(tcx: TyCtxt<'_>) -> (Vec<LocalDefId>, LocalDefIdMap<LocalDefId>) {
let effective_visibilities = &tcx.effective_visibilities(());
// see `MarkSymbolVisitor::struct_constructors`
let mut struct_constructors = Default::default();
@@ -617,7 +622,7 @@ fn create_and_seed_worklist(
fn live_symbols_and_ignored_derived_traits(
tcx: TyCtxt<'_>,
(): (),
-) -> (FxHashSet<LocalDefId>, FxHashMap<LocalDefId, Vec<(DefId, DefId)>>) {
+) -> (LocalDefIdSet, LocalDefIdMap<Vec<(DefId, DefId)>>) {
let (worklist, struct_constructors) = create_and_seed_worklist(tcx);
let mut symbol_visitor = MarkSymbolVisitor {
worklist,
@@ -629,7 +634,7 @@ fn live_symbols_and_ignored_derived_traits(
in_pat: false,
ignore_variant_stack: vec![],
struct_constructors,
- ignored_derived_traits: FxHashMap::default(),
+ ignored_derived_traits: Default::default(),
};
symbol_visitor.mark_live_symbols();
(symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits)
@@ -643,8 +648,8 @@ struct DeadVariant {
struct DeadVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
- live_symbols: &'tcx FxHashSet<LocalDefId>,
- ignored_derived_traits: &'tcx FxHashMap<LocalDefId, Vec<(DefId, DefId)>>,
+ live_symbols: &'tcx LocalDefIdSet,
+ ignored_derived_traits: &'tcx LocalDefIdMap<Vec<(DefId, DefId)>>,
}
enum ShouldWarnAboutField {
@@ -695,6 +700,13 @@ impl<'tcx> DeadVisitor<'tcx> {
.collect();
let descr = tcx.def_descr(first_id.to_def_id());
+ // `impl` blocks are "batched" and (unlike other batching) might
+ // contain different kinds of associated items.
+ let descr = if dead_codes.iter().any(|did| tcx.def_descr(did.to_def_id()) != descr) {
+ "associated item"
+ } else {
+ descr
+ };
let num = dead_codes.len();
let multiple = num > 6;
let name_list = names.into();
@@ -707,12 +719,12 @@ impl<'tcx> DeadVisitor<'tcx> {
let parent_info = if let Some(parent_item) = parent_item {
let parent_descr = tcx.def_descr(parent_item.to_def_id());
- Some(ParentInfo {
- num,
- descr,
- parent_descr,
- span: tcx.def_ident_span(parent_item).unwrap(),
- })
+ let span = if let DefKind::Impl { .. } = tcx.def_kind(parent_item) {
+ tcx.def_span(parent_item)
+ } else {
+ tcx.def_ident_span(parent_item).unwrap()
+ };
+ Some(ParentInfo { num, descr, parent_descr, span })
} else {
None
};
@@ -795,16 +807,7 @@ impl<'tcx> DeadVisitor<'tcx> {
}
fn check_definition(&mut self, def_id: LocalDefId) {
- if self.live_symbols.contains(&def_id) {
- return;
- }
- if has_allow_dead_code_or_lang_attr(self.tcx, def_id) {
- return;
- }
- let Some(name) = self.tcx.opt_item_name(def_id.to_def_id()) else {
- return
- };
- if name.as_str().starts_with('_') {
+ if self.is_live_code(def_id) {
return;
}
match self.tcx.def_kind(def_id) {
@@ -822,6 +825,18 @@ impl<'tcx> DeadVisitor<'tcx> {
_ => {}
}
}
+
+ fn is_live_code(&self, def_id: LocalDefId) -> bool {
+ // if we cannot get a name for the item, then we just assume that it is
+ // live. I mean, we can't really emit a lint.
+ let Some(name) = self.tcx.opt_item_name(def_id.to_def_id()) else {
+ return true;
+ };
+
+ self.live_symbols.contains(&def_id)
+ || has_allow_dead_code_or_lang_attr(self.tcx, def_id)
+ || name.as_str().starts_with('_')
+ }
}
fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
@@ -831,6 +846,22 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
let module_items = tcx.hir_module_items(module);
for item in module_items.items() {
+ if let hir::ItemKind::Impl(impl_item) = tcx.hir().item(item).kind {
+ let mut dead_items = Vec::new();
+ for item in impl_item.items {
+ let did = item.id.owner_id.def_id;
+ if !visitor.is_live_code(did) {
+ dead_items.push(did)
+ }
+ }
+ visitor.warn_multiple_dead_codes(
+ &dead_items,
+ "used",
+ Some(item.owner_id.def_id),
+ false,
+ );
+ }
+
if !live_symbols.contains(&item.owner_id.def_id) {
let parent = tcx.local_parent(item.owner_id.def_id);
if parent != module && !live_symbols.contains(&parent) {
@@ -895,10 +926,6 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
}
}
- for impl_item in module_items.impl_items() {
- visitor.check_definition(impl_item.owner_id.def_id);
- }
-
for foreign_item in module_items.foreign_items() {
visitor.check_definition(foreign_item.owner_id.def_id);
}
diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs
index aeacbaa67..9dd39a5c9 100644
--- a/compiler/rustc_passes/src/debugger_visualizer.rs
+++ b/compiler/rustc_passes/src/debugger_visualizer.rs
@@ -4,11 +4,9 @@ use hir::CRATE_HIR_ID;
use rustc_data_structures::fx::FxHashSet;
use rustc_expand::base::resolve_path;
use rustc_hir as hir;
-use rustc_hir::def_id::CrateNum;
use rustc_hir::HirId;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
-use rustc_span::def_id::LOCAL_CRATE;
+use rustc_middle::{query::LocalCrate, ty::query::Providers};
use rustc_span::{sym, DebuggerVisualizerFile, DebuggerVisualizerType};
use std::sync::Arc;
@@ -69,9 +67,7 @@ fn check_for_debugger_visualizer(
}
/// Traverses and collects the debugger visualizers for a specific crate.
-fn debugger_visualizers(tcx: TyCtxt<'_>, cnum: CrateNum) -> Vec<DebuggerVisualizerFile> {
- assert_eq!(cnum, LOCAL_CRATE);
-
+fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec<DebuggerVisualizerFile> {
// Initialize the collector.
let mut debugger_visualizers = FxHashSet::default();
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index 110eb210d..eb6ea673c 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -12,9 +12,10 @@
use rustc_ast as ast;
use rustc_hir::diagnostic_items::DiagnosticItems;
use rustc_hir::OwnerId;
+use rustc_middle::query::LocalCrate;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
-use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::{sym, Symbol};
use crate::errors::DuplicateDiagnosticItemInCrate;
@@ -62,9 +63,7 @@ fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
}
/// Traverse and collect the diagnostic items in the current
-fn diagnostic_items(tcx: TyCtxt<'_>, cnum: CrateNum) -> DiagnosticItems {
- assert_eq!(cnum, LOCAL_CRATE);
-
+fn diagnostic_items(tcx: TyCtxt<'_>, _: LocalCrate) -> DiagnosticItems {
// Initialize the collector.
let mut diagnostic_items = DiagnosticItems::default();
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index b327ba633..e3e4b73ef 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -1,10 +1,11 @@
+use rustc_ast::attr;
use rustc_ast::entry::EntryPointType;
use rustc_errors::error_code;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::{ItemId, Node, CRATE_HIR_ID};
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{DefIdTree, TyCtxt};
+use rustc_middle::ty::TyCtxt;
use rustc_session::config::{sigpipe, CrateType, EntryFnType};
use rustc_session::parse::feature_err;
use rustc_span::symbol::sym;
@@ -37,7 +38,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
}
// If the user wants no main function at all, then stop here.
- if tcx.sess.contains_name(&tcx.hir().attrs(CRATE_HIR_ID), sym::no_main) {
+ if attr::contains_name(&tcx.hir().attrs(CRATE_HIR_ID), sym::no_main) {
return None;
}
@@ -57,9 +58,9 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
// An equivalent optimization was not applied to the duplicated code in test_harness.rs.
fn entry_point_type(ctxt: &EntryContext<'_>, id: ItemId, at_root: bool) -> EntryPointType {
let attrs = ctxt.tcx.hir().attrs(id.hir_id());
- if ctxt.tcx.sess.contains_name(attrs, sym::start) {
+ if attr::contains_name(attrs, sym::start) {
EntryPointType::Start
- } else if ctxt.tcx.sess.contains_name(attrs, sym::rustc_main) {
+ } else if attr::contains_name(attrs, sym::rustc_main) {
EntryPointType::RustcMainAttr
} else {
if let Some(name) = ctxt.tcx.opt_item_name(id.owner_id.to_def_id())
@@ -78,7 +79,7 @@ fn entry_point_type(ctxt: &EntryContext<'_>, id: ItemId, at_root: bool) -> Entry
fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Option<Span> {
let attrs = ctxt.tcx.hir().attrs(id.hir_id());
- ctxt.tcx.sess.find_by_name(attrs, sym).map(|attr| attr.span)
+ attr::find_by_name(attrs, sym).map(|attr| attr.span)
}
fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
@@ -186,7 +187,7 @@ fn sigpipe(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
let sp = tcx.def_span(CRATE_DEF_ID);
- if *tcx.sess.parse_sess.reached_eof.borrow() {
+ if tcx.sess.parse_sess.reached_eof.load(rustc_data_structures::sync::Ordering::Relaxed) {
// There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about
// the missing `fn main()` then as it might have been hidden inside an unclosed block.
tcx.sess.delay_span_bug(sp, "`main` not found, but expected unclosed brace error");
@@ -205,7 +206,7 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
// The file may be empty, which leads to the diagnostic machinery not emitting this
// note. This is a relatively simple way to detect that case and emit a span-less
// note instead.
- let file_empty = !tcx.sess.source_map().lookup_line(sp.hi()).is_ok();
+ let file_empty = tcx.sess.source_map().lookup_line(sp.hi()).is_err();
tcx.sess.emit_err(NoMainErr {
sp,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 9f1c0b5a0..139ba8c96 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -289,10 +289,6 @@ pub struct DocTestTakesList;
pub struct DocCfgHideTakesList;
#[derive(LintDiagnostic)]
-#[diag(passes_doc_primitive)]
-pub struct DocPrimitive;
-
-#[derive(LintDiagnostic)]
#[diag(passes_doc_test_unknown_any)]
pub struct DocTestUnknownAny {
pub path: String,
@@ -1546,52 +1542,11 @@ pub struct ChangeFieldsToBeOfUnitType {
}
#[derive(Diagnostic)]
-#[diag(passes_proc_macro_typeerror)]
-#[note]
-pub(crate) struct ProcMacroTypeError<'tcx> {
- #[primary_span]
- #[label]
- pub span: Span,
- pub found: Ty<'tcx>,
- pub kind: ProcMacroKind,
- pub expected_signature: &'static str,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_proc_macro_diff_arg_count)]
-pub(crate) struct ProcMacroDiffArguments {
- #[primary_span]
- #[label]
- pub span: Span,
- pub count: usize,
- pub kind: ProcMacroKind,
- pub expected_signature: &'static str,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_proc_macro_missing_args)]
-pub(crate) struct ProcMacroMissingArguments {
+#[diag(passes_proc_macro_bad_sig)]
+pub(crate) struct ProcMacroBadSig {
#[primary_span]
- #[label]
pub span: Span,
- pub expected_input_count: usize,
pub kind: ProcMacroKind,
- pub expected_signature: &'static str,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_proc_macro_invalid_abi)]
-pub(crate) struct ProcMacroInvalidAbi {
- #[primary_span]
- pub span: Span,
- pub abi: &'static str,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_proc_macro_unsafe)]
-pub(crate) struct ProcMacroUnsafe {
- #[primary_span]
- pub span: Span,
}
#[derive(Diagnostic)]
diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs
index de0e50a65..3942a73be 100644
--- a/compiler/rustc_passes/src/hir_id_validator.rs
+++ b/compiler/rustc_passes/src/hir_id_validator.rs
@@ -5,11 +5,9 @@ use rustc_hir::intravisit;
use rustc_hir::{HirId, ItemLocalId};
use rustc_index::bit_set::GrowableBitSet;
use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::{DefIdTree, TyCtxt};
+use rustc_middle::ty::TyCtxt;
pub fn check_crate(tcx: TyCtxt<'_>) {
- tcx.dep_graph.assert_ignored();
-
if tcx.sess.opts.unstable_opts.hir_stats {
crate::hir_stats::print_hir_stats(tcx);
}
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 5e2d2d3e5..47e032758 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -300,7 +300,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
record_variants!(
(self, e, e.kind, Id::Node(e.hir_id), hir, Expr, ExprKind),
[
- Box, ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type,
+ ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type,
DropTemps, Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index,
Path, AddrOf, Break, Continue, Ret, InlineAsm, Struct, Repeat, Yield, Err
]
@@ -565,7 +565,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
record_variants!(
(self, e, e.kind, Id::None, ast, Expr, ExprKind),
[
- Box, Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let,
+ Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let,
If, While, ForLoop, Loop, Match, Closure, Block, Async, Await, TryBlock, Assign,
AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret,
InlineAsm, FormatArgs, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, IncludedBytes, Err
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index 047b9b525..5a1ae808e 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -18,7 +18,7 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
tcx.def_kind(id.owner_id),
DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union
) {
- for attr in tcx.get_attrs(id.owner_id.to_def_id(), sym::rustc_layout) {
+ for attr in tcx.get_attrs(id.owner_id, sym::rustc_layout) {
dump_layout_of(tcx, id.owner_id.def_id, attr);
}
}
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 0cb842408..b7e07aff4 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -42,7 +42,7 @@ pub mod stability;
mod upvars;
mod weak_lang_items;
-fluent_messages! { "../locales/en-US.ftl" }
+fluent_messages! { "../messages.ftl" }
pub fn provide(providers: &mut Providers) {
check_attr::provide(providers);
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index df5c8f53e..a8471ce3b 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -95,7 +95,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet};
use rustc_index::vec::IndexVec;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, DefIdTree, RootVariableMinCaptureList, Ty, TyCtxt};
+use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{BytePos, Span};
@@ -146,7 +146,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) {
// Don't run unused pass for #[derive()]
let parent = tcx.local_parent(local_def_id);
if let DefKind::Impl { .. } = tcx.def_kind(parent)
- && tcx.has_attr(parent.to_def_id(), sym::automatically_derived)
+ && tcx.has_attr(parent, sym::automatically_derived)
{
return;
}
@@ -473,7 +473,6 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
| hir::ExprKind::Struct(..)
| hir::ExprKind::Repeat(..)
| hir::ExprKind::InlineAsm(..)
- | hir::ExprKind::Box(..)
| hir::ExprKind::Type(..)
| hir::ExprKind::Err(_)
| hir::ExprKind::Path(hir::QPath::TypeRelative(..))
@@ -1059,8 +1058,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&l, r_succ)
}
- hir::ExprKind::Box(ref e)
- | hir::ExprKind::AddrOf(_, _, ref e)
+ hir::ExprKind::AddrOf(_, _, ref e)
| hir::ExprKind::Cast(ref e, _)
| hir::ExprKind::Type(ref e, _)
| hir::ExprKind::DropTemps(ref e)
@@ -1425,7 +1423,6 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
| hir::ExprKind::Closure { .. }
| hir::ExprKind::Path(_)
| hir::ExprKind::Yield(..)
- | hir::ExprKind::Box(..)
| hir::ExprKind::Type(..)
| hir::ExprKind::Err(_) => {}
}
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index c5b5cf7f5..c398467f0 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -30,7 +30,7 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
continue;
}
- let naked = tcx.has_attr(def_id.to_def_id(), sym::naked);
+ let naked = tcx.has_attr(def_id, sym::naked);
if !naked {
continue;
}
@@ -59,7 +59,7 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
/// Check that the function isn't inlined.
fn check_inline(tcx: TyCtxt<'_>, def_id: LocalDefId) {
- let attrs = tcx.get_attrs(def_id.to_def_id(), sym::inline);
+ let attrs = tcx.get_attrs(def_id, sym::inline);
for attr in attrs {
tcx.sess.emit_err(CannotInlineNakedFunction { span: attr.span });
}
@@ -179,8 +179,7 @@ enum ItemKind {
impl<'tcx> CheckInlineAssembly<'tcx> {
fn check_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, span: Span) {
match expr.kind {
- ExprKind::Box(..)
- | ExprKind::ConstBlock(..)
+ ExprKind::ConstBlock(..)
| ExprKind::Array(..)
| ExprKind::Call(..)
| ExprKind::MethodCall(..)
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 051100c56..a5f7b07fe 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -5,7 +5,7 @@
// makes all other generics or inline functions that it references
// reachable as well.
-use rustc_data_structures::fx::FxHashSet;
+use hir::def_id::LocalDefIdSet;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -14,7 +14,7 @@ use rustc_hir::Node;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::middle::privacy::{self, Level};
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, DefIdTree, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
use rustc_session::config::CrateType;
use rustc_target::spec::abi::Abi;
@@ -63,7 +63,7 @@ struct ReachableContext<'tcx> {
tcx: TyCtxt<'tcx>,
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
// The set of items which must be exported in the linkage sense.
- reachable_symbols: FxHashSet<LocalDefId>,
+ reachable_symbols: LocalDefIdSet,
// A worklist of item IDs. Each item ID in this worklist will be inlined
// and will be scanned for further references.
// FIXME(eddyb) benchmark if this would be faster as a `VecDeque`.
@@ -175,7 +175,7 @@ impl<'tcx> ReachableContext<'tcx> {
// Step 2: Mark all symbols that the symbols on the worklist touch.
fn propagate(&mut self) {
- let mut scanned = FxHashSet::default();
+ let mut scanned = LocalDefIdSet::default();
while let Some(search_item) = self.worklist.pop() {
if !scanned.insert(search_item) {
continue;
@@ -361,7 +361,7 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
}
-fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> FxHashSet<LocalDefId> {
+fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet {
let effective_visibilities = &tcx.effective_visibilities(());
let any_library =
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 16194a6f1..4a35c6794 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -159,7 +159,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
return;
}
- let (stab, const_stab, body_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
+ let stab = attr::find_stability(&self.tcx.sess, attrs, item_sp);
+ let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item_sp);
+ let body_stab = attr::find_body_stability(&self.tcx.sess, attrs);
let mut const_span = None;
let const_stab = const_stab.map(|(const_stab, const_span_node)| {
@@ -265,6 +267,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
self.index.implications.insert(implied_by, feature);
}
+ if let Some(ConstStability {
+ level: Unstable { implied_by: Some(implied_by), .. },
+ feature,
+ ..
+ }) = const_stab
+ {
+ self.index.implications.insert(implied_by, feature);
+ }
+
self.index.stab_map.insert(def_id, stab);
stab
});
@@ -519,7 +530,7 @@ struct MissingStabilityAnnotations<'tcx> {
impl<'tcx> MissingStabilityAnnotations<'tcx> {
fn check_missing_stability(&self, def_id: LocalDefId, span: Span) {
let stab = self.tcx.stability().local_stability(def_id);
- if !self.tcx.sess.opts.test
+ if !self.tcx.sess.is_test_crate()
&& stab.is_none()
&& self.effective_visibilities.is_reachable(def_id)
{
@@ -682,14 +693,10 @@ pub(crate) fn provide(providers: &mut Providers) {
check_mod_unstable_api_usage,
stability_index,
stability_implications: |tcx, _| tcx.stability().implications.clone(),
- lookup_stability: |tcx, id| tcx.stability().local_stability(id.expect_local()),
- lookup_const_stability: |tcx, id| tcx.stability().local_const_stability(id.expect_local()),
- lookup_default_body_stability: |tcx, id| {
- tcx.stability().local_default_body_stability(id.expect_local())
- },
- lookup_deprecation_entry: |tcx, id| {
- tcx.stability().local_deprecation_entry(id.expect_local())
- },
+ lookup_stability: |tcx, id| tcx.stability().local_stability(id),
+ lookup_const_stability: |tcx, id| tcx.stability().local_const_stability(id),
+ lookup_default_body_stability: |tcx, id| tcx.stability().local_default_body_stability(id),
+ lookup_deprecation_entry: |tcx, id| tcx.stability().local_deprecation_entry(id),
..*providers
};
}
@@ -737,8 +744,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
let features = self.tcx.features();
if features.staged_api {
let attrs = self.tcx.hir().attrs(item.hir_id());
- let (stab, const_stab, _) =
- attr::find_stability(&self.tcx.sess, attrs, item.span);
+ let stab = attr::find_stability(&self.tcx.sess, attrs, item.span);
+ let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item.span);
// If this impl block has an #[unstable] attribute, give an
// error if all involved types and traits are stable, because