From 4debbdc6b9cfe35295ba0e245b0aad8f8079ec8a Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 19 Sep 2020 10:57:13 +0200 Subject: [PATCH 1/4] transmute: use diagnostic item --- compiler/rustc_lint/src/builtin.rs | 9 +-------- compiler/rustc_lint/src/context.rs | 2 ++ compiler/rustc_passes/src/diagnostic_items.rs | 14 +++++++++++++- library/core/src/intrinsics.rs | 1 + 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 5b5dbcf192ca1..6cbcbc3173b07 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..ec275dda1f4b7 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -720,6 +720,8 @@ 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. /// + /// If possible, consider using a `rustc_diagnostic_item` instead. + /// /// # 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..f3f0a2f02c57d 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")] + #[rustc_diagnostic_item = "transmute"] pub fn transmute(e: T) -> U; /// Returns `true` if the actual type given as `T` requires drop From 39f125918d05176d711ef9da3c0bbd4c861bb14e Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 19 Sep 2020 11:17:44 +0200 Subject: [PATCH 2/4] cfg bootstrap --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index f3f0a2f02c57d..abb9bfec127be 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1071,7 +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")] - #[rustc_diagnostic_item = "transmute"] + #[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 From 0eecbd4f9731d3dc574691344997b640dd023315 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 19 Sep 2020 11:32:55 +0200 Subject: [PATCH 3/4] wording --- compiler/rustc_lint/src/context.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index ec275dda1f4b7..f4f25752e3f5a 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -720,7 +720,8 @@ 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. /// - /// If possible, consider using a `rustc_diagnostic_item` instead. + /// Instead of using this method, it is often preferable to instead use + /// `rustc_diagnostic_item` or a `lang_item`, which is less prone to errors. /// /// # Examples /// From bfa2030ccbbabc4944b719c9194e190e1726fc8c Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 19 Sep 2020 15:36:53 +0200 Subject: [PATCH 4/4] update docs --- compiler/rustc_lint/src/context.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index f4f25752e3f5a..0265fc323b3b3 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -721,7 +721,8 @@ impl<'tcx> LateContext<'tcx> { /// 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`, which is less prone to errors. + /// `rustc_diagnostic_item` or a `lang_item`. This is less prone to errors + /// as paths get invalidated if the target definition moves. /// /// # Examples ///