diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 32107d621dd6d..c35b6a9aaf4e9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2350,13 +2350,6 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { /// Determine if this expression is a "dangerous initialization". fn is_dangerous_init(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { - // `transmute` is inside an anonymous module (the `extern` block?); - // `Invalid` represents the empty string and matches that. - // FIXME(#66075): use diagnostic items. Somehow, that does not seem to work - // on intrinsics right now. - const TRANSMUTE_PATH: &[Symbol] = - &[sym::core, sym::intrinsics, kw::Invalid, sym::transmute]; - if let hir::ExprKind::Call(ref path_expr, ref args) = expr.kind { // Find calls to `mem::{uninitialized,zeroed}` methods. if let hir::ExprKind::Path(ref qpath) = path_expr.kind { @@ -2366,7 +2359,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { return Some(InitKind::Zeroed); } else if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, def_id) { return Some(InitKind::Uninit); - } else if cx.match_def_path(def_id, TRANSMUTE_PATH) { + } else if cx.tcx.is_diagnostic_item(sym::transmute, def_id) { if is_zero(&args[0]) { return Some(InitKind::Zeroed); } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index f0342b69c9261..0265fc323b3b3 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -720,6 +720,10 @@ impl<'tcx> LateContext<'tcx> { /// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`; /// inherent `impl` blocks are matched with the name of the type. /// + /// Instead of using this method, it is often preferable to instead use + /// `rustc_diagnostic_item` or a `lang_item`. This is less prone to errors + /// as paths get invalidated if the target definition moves. + /// /// # Examples /// /// ```rust,ignore (no context or def id available) diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index df0f9f157aedf..94592935c7f91 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -12,11 +12,11 @@ use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::Session; +use rustc_span::def_id::{DefId, LOCAL_CRATE}; use rustc_span::symbol::{sym, Symbol}; struct DiagnosticItemCollector<'tcx> { @@ -100,6 +100,18 @@ fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> FxHashMap { // Collect diagnostic items in this crate. tcx.hir().krate().visit_all_item_likes(&mut collector); + // FIXME(visit_all_item_likes): Foreign items are not visited + // here, so we have to manually look at them for now. + for foreign_module in tcx.foreign_modules(LOCAL_CRATE) { + for &foreign_item in foreign_module.foreign_items.iter() { + match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(foreign_item.expect_local())) { + hir::Node::ForeignItem(item) => { + collector.observe_item(item.attrs, item.hir_id); + } + item => bug!("unexpected foreign item {:?}", item), + } + } + } collector.items } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index dd9af2d07e770..abb9bfec127be 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1071,6 +1071,7 @@ extern "rust-intrinsic" { // NOTE: While this makes the intrinsic const stable, we have some custom code in const fn // checks that prevent its use within `const fn`. #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "transmute")] pub fn transmute(e: T) -> U; /// Returns `true` if the actual type given as `T` requires drop