diff options
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 186 | ||||
-rw-r--r-- | compiler/rustc_passes/src/check_const.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_passes/src/dead.rs | 101 | ||||
-rw-r--r-- | compiler/rustc_passes/src/debugger_visualizer.rs | 8 | ||||
-rw-r--r-- | compiler/rustc_passes/src/diagnostic_items.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_passes/src/entry.rs | 15 | ||||
-rw-r--r-- | compiler/rustc_passes/src/errors.rs | 49 | ||||
-rw-r--r-- | compiler/rustc_passes/src/hir_id_validator.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_passes/src/hir_stats.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_passes/src/layout_test.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_passes/src/lib.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_passes/src/liveness.rs | 9 | ||||
-rw-r--r-- | compiler/rustc_passes/src/naked_functions.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_passes/src/reachable.rs | 10 | ||||
-rw-r--r-- | compiler/rustc_passes/src/stability.rs | 31 |
15 files changed, 204 insertions, 235 deletions
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 |