about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2020-09-20 15:52:04 +0200
committerGitHub <noreply@github.com>2020-09-20 15:52:04 +0200
commit7ff17c13bc26e2cf20beea35a5757f8c548ac5f2 (patch)
tree693af2525d95518a7eef9a332fda44b0b4627fd1
parent9567b5a9f52f35f1bb127f626a1b14062d735751 (diff)
parentbfa2030ccbbabc4944b719c9194e190e1726fc8c (diff)
downloadrust-7ff17c13bc26e2cf20beea35a5757f8c548ac5f2.tar.gz
rust-7ff17c13bc26e2cf20beea35a5757f8c548ac5f2.zip
Rollup merge of #76910 - lcnr:foreign-item-like, r=oli-obk
transmute: use diagnostic item

closes #66075, we now have no remaining uses of `match_def_path`  in the compiler while some uses still remain in `clippy`.

cc @RalfJung
-rw-r--r--compiler/rustc_lint/src/builtin.rs9
-rw-r--r--compiler/rustc_lint/src/context.rs4
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs14
-rw-r--r--library/core/src/intrinsics.rs1
4 files changed, 19 insertions, 9 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 32107d621dd..c35b6a9aaf4 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<InitKind> {
-            // `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 f0342b69c92..0265fc323b3 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 df0f9f157ae..94592935c7f 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<Symbol, DefId> {
 
     // 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 dd9af2d07e7..abb9bfec127 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<T, U>(e: T) -> U;
 
     /// Returns `true` if the actual type given as `T` requires drop