about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-05 16:07:23 -0700
committerGitHub <noreply@github.com>2020-07-05 16:07:23 -0700
commitfed20132a6a7bbedb87c7bde6abfa0e58d8743d4 (patch)
tree06ab74a1e68b3d91cf38e6ccc6d7d46c981f5f52
parente2ae88d4a60ea226500f52e89e02732c55213a3a (diff)
parent394b8cdfb7734a6dcb10b392c5b83e1b3d9521d3 (diff)
downloadrust-fed20132a6a7bbedb87c7bde6abfa0e58d8743d4.tar.gz
rust-fed20132a6a7bbedb87c7bde6abfa0e58d8743d4.zip
Rollup merge of #73834 - oli-obk:safe_intrinsics, r=ecstatic-morse
Some refactoring around intrinsic type checking

So... This PR went a bit overboard. I wanted to make the `rustc_peek` intrinsic safe (cc @ecstatic-morse ), and remembered a long-standing itch of mine. So I made that huge `&str` match for the intrinsic name a match on `Symbol`s (so basically `u32`s). This is unlikely to have a positive perf effect, even if it likely has better codegen (intrinsics are used rarely, mostly once in their wrapper), so it's mostly a consistency thing since other places actually match on the symbol name of the intrinsics.
-rw-r--r--src/librustc_span/symbol.rs79
-rw-r--r--src/librustc_typeck/check/intrinsic.rs263
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/test/ui/mir-dataflow/def-inits-1.rs18
-rw-r--r--src/test/ui/mir-dataflow/def-inits-1.stderr24
-rw-r--r--src/test/ui/mir-dataflow/indirect-mutation-offset.rs2
-rw-r--r--src/test/ui/mir-dataflow/indirect-mutation-offset.stderr6
-rw-r--r--src/test/ui/mir-dataflow/inits-1.rs18
-rw-r--r--src/test/ui/mir-dataflow/inits-1.stderr18
-rw-r--r--src/test/ui/mir-dataflow/liveness-ptr.rs6
-rw-r--r--src/test/ui/mir-dataflow/liveness-ptr.stderr6
-rw-r--r--src/test/ui/mir-dataflow/uninits-1.rs18
-rw-r--r--src/test/ui/mir-dataflow/uninits-1.stderr30
-rw-r--r--src/test/ui/mir-dataflow/uninits-2.rs4
-rw-r--r--src/test/ui/mir-dataflow/uninits-2.stderr6
15 files changed, 307 insertions, 193 deletions
diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index acc2a50abe8..c34da8b1cf3 100644
--- a/src/librustc_span/symbol.rs
+++ b/src/librustc_span/symbol.rs
@@ -152,10 +152,14 @@ symbols! {
         arm_target_feature,
         asm,
         assert,
+        assert_inhabited,
+        assert_uninit_valid,
+        assert_zero_valid,
         associated_consts,
         associated_type_bounds,
         associated_type_defaults,
         associated_types,
+        assume,
         assume_init,
         async_await,
         async_closure,
@@ -181,11 +185,14 @@ symbols! {
         box_patterns,
         box_syntax,
         braced_empty_structs,
+        breakpoint,
         bswap,
         bitreverse,
         C,
         caller_location,
         cdylib,
+        ceilf32,
+        ceilf64,
         cfg,
         cfg_accessible,
         cfg_attr,
@@ -239,8 +246,14 @@ symbols! {
         convert,
         Copy,
         copy_closures,
+        copy,
+        copy_nonoverlapping,
+        copysignf32,
+        copysignf64,
         core,
         core_intrinsics,
+        cosf32,
+        cosf64,
         count_code_region,
         coverage_counter_add,
         coverage_counter_subtract,
@@ -299,6 +312,7 @@ symbols! {
         dropck_eyepatch,
         dropck_parametricity,
         drop_types_in_const,
+        drop_in_place,
         dylib,
         dyn_trait,
         eh_personality,
@@ -311,11 +325,16 @@ symbols! {
         Eq,
         Equal,
         enclosing_scope,
+        exact_div,
         except,
         exclusive_range_pattern,
         exhaustive_integer_patterns,
         exhaustive_patterns,
         existential_type,
+        expf32,
+        expf64,
+        exp2f32,
+        exp2f64,
         expected,
         export_name,
         expr,
@@ -329,6 +348,10 @@ symbols! {
         f16c_target_feature,
         f32,
         f64,
+        fadd_fast,
+        fabsf32,
+        fabsf64,
+        fdiv_fast,
         feature,
         ffi_const,
         ffi_pure,
@@ -336,13 +359,21 @@ symbols! {
         field,
         field_init_shorthand,
         file,
+        float_to_int_unchecked,
+        floorf64,
+        floorf32,
+        fmaf32,
+        fmaf64,
         fmt,
         fmt_internals,
+        fmul_fast,
         fn_must_use,
         forbid,
+        forget,
         format_args,
         format_args_nl,
         format_args_capture,
+        frem_fast,
         from,
         From,
         from_desugaring,
@@ -352,6 +383,7 @@ symbols! {
         from_ok,
         from_usize,
         from_trait,
+        fsub_fast,
         fundamental,
         future,
         Future,
@@ -448,6 +480,12 @@ symbols! {
         llvm_asm,
         local_inner_macros,
         log_syntax,
+        logf32,
+        logf64,
+        log10f32,
+        log10f64,
+        log2f32,
+        log2f64,
         loop_break_value,
         macro_at_most_once_rep,
         macro_escape,
@@ -475,10 +513,16 @@ symbols! {
         message,
         meta,
         min_align_of,
+        min_align_of_val,
         min_const_fn,
         min_const_unsafe_fn,
         min_specialization,
+        minnumf32,
+        minnumf64,
+        maxnumf32,
+        maxnumf64,
         mips_target_feature,
+        miri_start_panic,
         mmx_target_feature,
         module,
         module_path,
@@ -491,6 +535,8 @@ symbols! {
         naked,
         naked_functions,
         name,
+        nearbyintf32,
+        nearbyintf64,
         needs_allocator,
         needs_drop,
         needs_panic_runtime,
@@ -518,6 +564,7 @@ symbols! {
         None,
         non_exhaustive,
         non_modrs_mods,
+        nontemporal_store,
         nontrapping_fptoint: "nontrapping-fptoint",
         noreturn,
         no_niche,
@@ -577,8 +624,16 @@ symbols! {
         poll,
         Poll,
         powerpc_target_feature,
+        powf32,
+        powf64,
+        powif32,
+        powif64,
         precise_pointer_size_matching,
         pref_align_of,
+        prefetch_read_data,
+        prefetch_read_instruction,
+        prefetch_write_data,
+        prefetch_write_instruction,
         prelude,
         prelude_import,
         preserves_flags,
@@ -640,10 +695,14 @@ symbols! {
         Result,
         Return,
         rhs,
+        rintf32,
+        rintf64,
         riscv_target_feature,
         rlib,
         rotate_left,
         rotate_right,
+        roundf32,
+        roundf64,
         rt,
         rtm_target_feature,
         rust,
@@ -726,14 +785,19 @@ symbols! {
         simd_ffi,
         simd_insert,
         since,
+        sinf32,
+        sinf64,
         size,
         size_of,
+        size_of_val,
         slice_patterns,
         slicing_syntax,
         soft,
         Some,
         specialization,
         speed,
+        sqrtf32,
+        sqrtf64,
         sse4a_target_feature,
         stable,
         staged_api,
@@ -787,6 +851,8 @@ symbols! {
         transparent_enums,
         transparent_unions,
         trivial_bounds,
+        truncf32,
+        truncf64,
         Try,
         try_blocks,
         try_trait,
@@ -809,6 +875,8 @@ symbols! {
         u32,
         u64,
         u8,
+        unaligned_volatile_load,
+        unaligned_volatile_store,
         unboxed_closures,
         unchecked_add,
         unchecked_div,
@@ -824,6 +892,7 @@ symbols! {
         universal_impl_trait,
         unlikely,
         unmarked_api,
+        unreachable,
         unreachable_code,
         unrestricted_attribute_tokens,
         unsafe_block_in_unsafe_fn,
@@ -843,12 +912,21 @@ symbols! {
         val,
         var,
         variant_count,
+        va_arg,
+        va_copy,
+        va_end,
+        va_start,
         vec,
         Vec,
         version,
         vis,
         visible_private_types,
         volatile,
+        volatile_copy_memory,
+        volatile_copy_nonoverlapping_memory,
+        volatile_load,
+        volatile_set_memory,
+        volatile_store,
         warn,
         wasm_import_module,
         wasm_target_feature,
@@ -858,6 +936,7 @@ symbols! {
         wrapping_add,
         wrapping_sub,
         wrapping_mul,
+        write_bytes,
         Yield,
     }
 }
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 6205088adad..9b3b4a67650 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -5,10 +5,11 @@ use crate::require_same_types;
 
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_target::spec::abi::Abi;
 
 use std::iter;
@@ -16,14 +17,13 @@ use std::iter;
 fn equate_intrinsic_type<'tcx>(
     tcx: TyCtxt<'tcx>,
     it: &hir::ForeignItem<'_>,
+    def_id: DefId,
     n_tps: usize,
     abi: Abi,
     safety: hir::Unsafety,
     inputs: Vec<Ty<'tcx>>,
     output: Ty<'tcx>,
 ) {
-    let def_id = tcx.hir().local_def_id(it.hir_id);
-
     match it.kind {
         hir::ForeignItemKind::Fn(..) => {}
         _ => {
@@ -67,15 +67,43 @@ fn equate_intrinsic_type<'tcx>(
 }
 
 /// Returns `true` if the given intrinsic is unsafe to call or not.
-pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
+pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
     match intrinsic {
-        "abort" | "size_of" | "min_align_of" | "needs_drop" | "caller_location" | "size_of_val"
-        | "min_align_of_val" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow"
-        | "wrapping_add" | "wrapping_sub" | "wrapping_mul" | "saturating_add"
-        | "saturating_sub" | "rotate_left" | "rotate_right" | "ctpop" | "ctlz" | "cttz"
-        | "bswap" | "bitreverse" | "discriminant_value" | "type_id" | "likely" | "unlikely"
-        | "ptr_guaranteed_eq" | "ptr_guaranteed_ne" | "minnumf32" | "minnumf64" | "maxnumf32"
-        | "maxnumf64" | "type_name" | "variant_count" => hir::Unsafety::Normal,
+        sym::abort
+        | sym::size_of
+        | sym::min_align_of
+        | sym::needs_drop
+        | sym::caller_location
+        | sym::size_of_val
+        | sym::min_align_of_val
+        | sym::add_with_overflow
+        | sym::sub_with_overflow
+        | sym::mul_with_overflow
+        | sym::wrapping_add
+        | sym::wrapping_sub
+        | sym::wrapping_mul
+        | sym::saturating_add
+        | sym::saturating_sub
+        | sym::rotate_left
+        | sym::rotate_right
+        | sym::ctpop
+        | sym::ctlz
+        | sym::cttz
+        | sym::bswap
+        | sym::bitreverse
+        | sym::discriminant_value
+        | sym::type_id
+        | sym::likely
+        | sym::unlikely
+        | sym::ptr_guaranteed_eq
+        | sym::ptr_guaranteed_ne
+        | sym::minnumf32
+        | sym::minnumf64
+        | sym::maxnumf32
+        | sym::rustc_peek
+        | sym::maxnumf64
+        | sym::type_name
+        | sym::variant_count => hir::Unsafety::Normal,
         _ => hir::Unsafety::Unsafe,
     }
 }
@@ -84,7 +112,9 @@ pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
 /// and in libcore/intrinsics.rs
 pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
-    let name = it.ident.as_str();
+    let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id();
+    let intrinsic_name = tcx.item_name(def_id);
+    let name_str = intrinsic_name.as_str();
 
     let mk_va_list_ty = |mutbl| {
         tcx.lang_items().va_list().map(|did| {
@@ -98,8 +128,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
         })
     };
 
-    let (n_tps, inputs, output, unsafety) = if name.starts_with("atomic_") {
-        let split: Vec<&str> = name.split('_').collect();
+    let (n_tps, inputs, output, unsafety) = if name_str.starts_with("atomic_") {
+        let split: Vec<&str> = name_str.split('_').collect();
         assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
 
         //We only care about the operation here
@@ -129,32 +159,30 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             }
         };
         (n_tps, inputs, output, hir::Unsafety::Unsafe)
-    } else if &name[..] == "abort" {
-        (0, Vec::new(), tcx.types.never, hir::Unsafety::Normal)
-    } else if &name[..] == "unreachable" {
-        (0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe)
     } else {
-        let unsafety = intrinsic_operation_unsafety(&name[..]);
-        let (n_tps, inputs, output) = match &name[..] {
-            "breakpoint" => (0, Vec::new(), tcx.mk_unit()),
-            "size_of" | "pref_align_of" | "min_align_of" | "variant_count" => {
+        let unsafety = intrinsic_operation_unsafety(intrinsic_name);
+        let (n_tps, inputs, output) = match intrinsic_name {
+            sym::abort => (0, Vec::new(), tcx.types.never),
+            sym::unreachable => (0, Vec::new(), tcx.types.never),
+            sym::breakpoint => (0, Vec::new(), tcx.mk_unit()),
+            sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => {
                 (1, Vec::new(), tcx.types.usize)
             }
-            "size_of_val" | "min_align_of_val" => {
+            sym::size_of_val | sym::min_align_of_val => {
                 (1, vec![tcx.mk_imm_ptr(param(0))], tcx.types.usize)
             }
-            "rustc_peek" => (1, vec![param(0)], param(0)),
-            "caller_location" => (0, vec![], tcx.caller_location_ty()),
-            "assert_inhabited" | "assert_zero_valid" | "assert_uninit_valid" => {
+            sym::rustc_peek => (1, vec![param(0)], param(0)),
+            sym::caller_location => (0, vec![], tcx.caller_location_ty()),
+            sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
                 (1, Vec::new(), tcx.mk_unit())
             }
-            "forget" => (1, vec![param(0)], tcx.mk_unit()),
-            "transmute" => (2, vec![param(0)], param(1)),
-            "move_val_init" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
-            "prefetch_read_data"
-            | "prefetch_write_data"
-            | "prefetch_read_instruction"
-            | "prefetch_write_instruction" => (
+            sym::forget => (1, vec![param(0)], tcx.mk_unit()),
+            sym::transmute => (2, vec![param(0)], param(1)),
+            sym::move_val_init => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
+            sym::prefetch_read_data
+            | sym::prefetch_write_data
+            | sym::prefetch_read_instruction
+            | sym::prefetch_write_instruction => (
                 1,
                 vec![
                     tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
@@ -162,12 +190,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 ],
                 tcx.mk_unit(),
             ),
-            "drop_in_place" => (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_unit()),
-            "needs_drop" => (1, Vec::new(), tcx.types.bool),
+            sym::drop_in_place => (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_unit()),
+            sym::needs_drop => (1, Vec::new(), tcx.types.bool),
 
-            "type_name" => (1, Vec::new(), tcx.mk_static_str()),
-            "type_id" => (1, Vec::new(), tcx.types.u64),
-            "offset" | "arith_offset" => (
+            sym::type_name => (1, Vec::new(), tcx.mk_static_str()),
+            sym::type_id => (1, Vec::new(), tcx.types.u64),
+            sym::offset | sym::arith_offset => (
                 1,
                 vec![
                     tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
@@ -175,7 +203,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 ],
                 tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
             ),
-            "copy" | "copy_nonoverlapping" => (
+            sym::copy | sym::copy_nonoverlapping => (
                 1,
                 vec![
                     tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
@@ -184,7 +212,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 ],
                 tcx.mk_unit(),
             ),
-            "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => (
+            sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => (
                 1,
                 vec![
                     tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
@@ -193,7 +221,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 ],
                 tcx.mk_unit(),
             ),
-            "write_bytes" | "volatile_set_memory" => (
+            sym::write_bytes | sym::volatile_set_memory => (
                 1,
                 vec![
                     tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
@@ -202,93 +230,98 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 ],
                 tcx.mk_unit(),
             ),
-            "sqrtf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "sqrtf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "powif32" => (0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32),
-            "powif64" => (0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64),
-            "sinf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "sinf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "cosf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "cosf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "powf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            "powf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            "expf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "expf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "exp2f32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "exp2f64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "logf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "logf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "log10f32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "log10f64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "log2f32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "log2f64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "fmaf32" => (0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            "fmaf64" => (0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            "fabsf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "fabsf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "minnumf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            "minnumf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            "maxnumf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            "maxnumf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            "copysignf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            "copysignf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            "floorf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "floorf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "ceilf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "ceilf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "truncf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "truncf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "rintf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "rintf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "nearbyintf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "nearbyintf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-            "roundf32" => (0, vec![tcx.types.f32], tcx.types.f32),
-            "roundf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-
-            "volatile_load" | "unaligned_volatile_load" => {
+            sym::sqrtf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::sqrtf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::powif32 => (0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32),
+            sym::powif64 => (0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64),
+            sym::sinf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::sinf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::cosf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::cosf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::powf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::powf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::expf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::expf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::exp2f32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::exp2f64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::logf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::logf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::log10f32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::log10f64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::log2f32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::log2f64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::fmaf32 => (0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::fmaf64 => (0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::fabsf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::fabsf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::minnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::minnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::maxnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::maxnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::copysignf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::copysignf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::floorf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::floorf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::ceilf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::ceilf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::truncf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::truncf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::rintf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::rintf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::nearbyintf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::nearbyintf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+            sym::roundf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+            sym::roundf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+
+            sym::volatile_load | sym::unaligned_volatile_load => {
                 (1, vec![tcx.mk_imm_ptr(param(0))], param(0))
             }
-            "volatile_store" | "unaligned_volatile_store" => {
+            sym::volatile_store | sym::unaligned_volatile_store => {
                 (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit())
             }
 
-            "ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "bswap"
-            | "bitreverse" => (1, vec![param(0)], param(0)),
+            sym::ctpop
+            | sym::ctlz
+            | sym::ctlz_nonzero
+            | sym::cttz
+            | sym::cttz_nonzero
+            | sym::bswap
+            | sym::bitreverse => (1, vec![param(0)], param(0)),
 
-            "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => {
+            sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
                 (1, vec![param(0), param(0)], tcx.intern_tup(&[param(0), tcx.types.bool]))
             }
 
-            "ptr_guaranteed_eq" | "ptr_guaranteed_ne" => {
+            sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
                 (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.bool)
             }
 
-            "ptr_offset_from" => {
+            sym::ptr_offset_from => {
                 (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)
             }
-            "unchecked_div" | "unchecked_rem" | "exact_div" => {
+            sym::unchecked_div | sym::unchecked_rem | sym::exact_div => {
                 (1, vec![param(0), param(0)], param(0))
             }
-            "unchecked_shl" | "unchecked_shr" | "rotate_left" | "rotate_right" => {
+            sym::unchecked_shl | sym::unchecked_shr | sym::rotate_left | sym::rotate_right => {
                 (1, vec![param(0), param(0)], param(0))
             }
-            "unchecked_add" | "unchecked_sub" | "unchecked_mul" => {
+            sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => {
                 (1, vec![param(0), param(0)], param(0))
             }
-            "wrapping_add" | "wrapping_sub" | "wrapping_mul" => {
+            sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => {
                 (1, vec![param(0), param(0)], param(0))
             }
-            "saturating_add" | "saturating_sub" => (1, vec![param(0), param(0)], param(0)),
-            "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
+            sym::saturating_add | sym::saturating_sub => (1, vec![param(0), param(0)], param(0)),
+            sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => {
                 (1, vec![param(0), param(0)], param(0))
             }
-            "float_to_int_unchecked" => (2, vec![param(0)], param(1)),
+            sym::float_to_int_unchecked => (2, vec![param(0)], param(1)),
 
-            "assume" => (0, vec![tcx.types.bool], tcx.mk_unit()),
-            "likely" => (0, vec![tcx.types.bool], tcx.types.bool),
-            "unlikely" => (0, vec![tcx.types.bool], tcx.types.bool),
+            sym::assume => (0, vec![tcx.types.bool], tcx.mk_unit()),
+            sym::likely => (0, vec![tcx.types.bool], tcx.types.bool),
+            sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool),
 
-            "discriminant_value" => {
+            sym::discriminant_value => {
                 let assoc_items =
                     tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
                 let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
@@ -303,7 +336,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 )
             }
 
-            "try" => {
+            kw::Try => {
                 let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
                 let try_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(
                     iter::once(mut_u8),
@@ -326,12 +359,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 )
             }
 
-            "va_start" | "va_end" => match mk_va_list_ty(hir::Mutability::Mut) {
+            sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) {
                 Some((va_list_ref_ty, _)) => (0, vec![va_list_ref_ty], tcx.mk_unit()),
                 None => bug!("`va_list` language item needed for C-variadic intrinsics"),
             },
 
-            "va_copy" => match mk_va_list_ty(hir::Mutability::Not) {
+            sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) {
                 Some((va_list_ref_ty, va_list_ty)) => {
                     let va_list_ptr_ty = tcx.mk_mut_ptr(va_list_ty);
                     (0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.mk_unit())
@@ -339,38 +372,38 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 None => bug!("`va_list` language item needed for C-variadic intrinsics"),
             },
 
-            "va_arg" => match mk_va_list_ty(hir::Mutability::Mut) {
+            sym::va_arg => match mk_va_list_ty(hir::Mutability::Mut) {
                 Some((va_list_ref_ty, _)) => (1, vec![va_list_ref_ty], param(0)),
                 None => bug!("`va_list` language item needed for C-variadic intrinsics"),
             },
 
-            "nontemporal_store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
+            sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
 
-            "miri_start_panic" => {
+            sym::miri_start_panic => {
                 // FIXME - the relevant types aren't lang items,
                 // so it's not trivial to check this
                 return;
             }
 
-            "count_code_region" => {
+            sym::count_code_region => {
                 (0, vec![tcx.types.u32, tcx.types.u32, tcx.types.u32], tcx.mk_unit())
             }
 
-            "coverage_counter_add" | "coverage_counter_subtract" => (
+            sym::coverage_counter_add | sym::coverage_counter_subtract => (
                 0,
                 vec![tcx.types.u32, tcx.types.u32, tcx.types.u32, tcx.types.u32, tcx.types.u32],
                 tcx.mk_unit(),
             ),
 
-            "coverage_unreachable" => (0, vec![tcx.types.u32, tcx.types.u32], tcx.mk_unit()),
+            sym::coverage_unreachable => (0, vec![tcx.types.u32, tcx.types.u32], tcx.mk_unit()),
 
-            ref other => {
+            other => {
                 struct_span_err!(
                     tcx.sess,
                     it.span,
                     E0093,
                     "unrecognized intrinsic function: `{}`",
-                    *other
+                    other,
                 )
                 .span_label(it.span, "unrecognized intrinsic")
                 .emit();
@@ -379,7 +412,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
         };
         (n_tps, inputs, output, unsafety)
     };
-    equate_intrinsic_type(tcx, it, n_tps, Abi::RustIntrinsic, unsafety, inputs, output)
+    equate_intrinsic_type(tcx, it, def_id, n_tps, Abi::RustIntrinsic, unsafety, inputs, output)
 }
 
 /// Type-check `extern "platform-intrinsic" { ... }` functions.
@@ -389,6 +422,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         tcx.mk_ty_param(n, name)
     };
 
+    let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id();
     let name = it.ident.as_str();
 
     let (n_tps, inputs, output) = match &*name {
@@ -463,6 +497,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
     equate_intrinsic_type(
         tcx,
         it,
+        def_id,
         n_tps,
         Abi::PlatformIntrinsic,
         hir::Unsafety::Unsafe,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 8920203e6af..cc491c527db 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -2063,7 +2063,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     ident: Ident,
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
-        intrinsic_operation_unsafety(&tcx.item_name(def_id).as_str())
+        intrinsic_operation_unsafety(tcx.item_name(def_id))
     } else {
         hir::Unsafety::Unsafe
     };
diff --git a/src/test/ui/mir-dataflow/def-inits-1.rs b/src/test/ui/mir-dataflow/def-inits-1.rs
index 91d41e9b579..30460824a16 100644
--- a/src/test/ui/mir-dataflow/def-inits-1.rs
+++ b/src/test/ui/mir-dataflow/def-inits-1.rs
@@ -11,13 +11,13 @@ struct S(i32);
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
     // `ret` starts off uninitialized
-    unsafe { rustc_peek(&ret); }  //~ ERROR rustc_peek: bit not set
+    rustc_peek(&ret);  //~ ERROR rustc_peek: bit not set
 
     // All function formal parameters start off initialized.
 
-    unsafe { rustc_peek(&x) };
-    unsafe { rustc_peek(&y) };
-    unsafe { rustc_peek(&z) };
+    rustc_peek(&x);
+    rustc_peek(&y);
+    rustc_peek(&z);
 
     ret = if test {
         ::std::mem::replace(x, y)
@@ -27,21 +27,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     };
 
     // `z` may be uninitialized here.
-    unsafe { rustc_peek(&z); } //~ ERROR rustc_peek: bit not set
+    rustc_peek(&z); //~ ERROR rustc_peek: bit not set
 
     // `y` is definitely uninitialized here.
-    unsafe { rustc_peek(&y); } //~ ERROR rustc_peek: bit not set
+    rustc_peek(&y); //~ ERROR rustc_peek: bit not set
 
     // `x` is still (definitely) initialized (replace above is a reborrow).
-    unsafe { rustc_peek(&x); }
+    rustc_peek(&x);
 
     ::std::mem::drop(x);
 
     // `x` is *definitely* uninitialized here
-    unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set
+    rustc_peek(&x); //~ ERROR rustc_peek: bit not set
 
     // `ret` is now definitely initialized (via `if` above).
-    unsafe { rustc_peek(&ret); }
+    rustc_peek(&ret);
 
     ret
 }
diff --git a/src/test/ui/mir-dataflow/def-inits-1.stderr b/src/test/ui/mir-dataflow/def-inits-1.stderr
index 48d84504894..e2bddb54d9b 100644
--- a/src/test/ui/mir-dataflow/def-inits-1.stderr
+++ b/src/test/ui/mir-dataflow/def-inits-1.stderr
@@ -1,26 +1,26 @@
 error: rustc_peek: bit not set
-  --> $DIR/def-inits-1.rs:14:14
+  --> $DIR/def-inits-1.rs:14:5
    |
-LL |     unsafe { rustc_peek(&ret); }
-   |              ^^^^^^^^^^^^^^^^
+LL |     rustc_peek(&ret);
+   |     ^^^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/def-inits-1.rs:30:14
+  --> $DIR/def-inits-1.rs:30:5
    |
-LL |     unsafe { rustc_peek(&z); }
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&z);
+   |     ^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/def-inits-1.rs:33:14
+  --> $DIR/def-inits-1.rs:33:5
    |
-LL |     unsafe { rustc_peek(&y); }
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&y);
+   |     ^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/def-inits-1.rs:41:14
+  --> $DIR/def-inits-1.rs:41:5
    |
-LL |     unsafe { rustc_peek(&x); }
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&x);
+   |     ^^^^^^^^^^^^^^
 
 error: stop_after_dataflow ended compilation
 
diff --git a/src/test/ui/mir-dataflow/indirect-mutation-offset.rs b/src/test/ui/mir-dataflow/indirect-mutation-offset.rs
index caa307e269f..374a9f75a13 100644
--- a/src/test/ui/mir-dataflow/indirect-mutation-offset.rs
+++ b/src/test/ui/mir-dataflow/indirect-mutation-offset.rs
@@ -38,7 +38,7 @@ const BOO: i32 = {
 
     *rmut_cell = 42;  // Mutates `x` indirectly even though `x` is not marked indirectly mutable!!!
     let val = *rmut_cell;
-    unsafe { rustc_peek(x) }; //~ ERROR rustc_peek: bit not set
+    rustc_peek(x); //~ ERROR rustc_peek: bit not set
 
     val
 };
diff --git a/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr b/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr
index 8d3548ececd..1d5287c15ab 100644
--- a/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr
+++ b/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr
@@ -1,8 +1,8 @@
 error: rustc_peek: bit not set
-  --> $DIR/indirect-mutation-offset.rs:41:14
+  --> $DIR/indirect-mutation-offset.rs:41:5
    |
-LL |     unsafe { rustc_peek(x) };
-   |              ^^^^^^^^^^^^^
+LL |     rustc_peek(x);
+   |     ^^^^^^^^^^^^^
 
 error: stop_after_dataflow ended compilation
 
diff --git a/src/test/ui/mir-dataflow/inits-1.rs b/src/test/ui/mir-dataflow/inits-1.rs
index 4a4786a2a73..8fb1d4bc736 100644
--- a/src/test/ui/mir-dataflow/inits-1.rs
+++ b/src/test/ui/mir-dataflow/inits-1.rs
@@ -11,13 +11,13 @@ struct S(i32);
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
     // `ret` starts off uninitialized, so we get an error report here.
-    unsafe { rustc_peek(&ret); }  //~ ERROR rustc_peek: bit not set
+    rustc_peek(&ret);  //~ ERROR rustc_peek: bit not set
 
     // All function formal parameters start off initialized.
 
-    unsafe { rustc_peek(&x) };
-    unsafe { rustc_peek(&y) };
-    unsafe { rustc_peek(&z) };
+    rustc_peek(&x);
+    rustc_peek(&y);
+    rustc_peek(&z);
 
     ret = if test {
         ::std::mem::replace(x, y)
@@ -28,21 +28,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
 
 
     // `z` may be initialized here.
-    unsafe { rustc_peek(&z); }
+    rustc_peek(&z);
 
     // `y` is definitely uninitialized here.
-    unsafe { rustc_peek(&y); }  //~ ERROR rustc_peek: bit not set
+    rustc_peek(&y);  //~ ERROR rustc_peek: bit not set
 
     // `x` is still (definitely) initialized (replace above is a reborrow).
-    unsafe { rustc_peek(&x); }
+    rustc_peek(&x);
 
     ::std::mem::drop(x);
 
     // `x` is *definitely* uninitialized here
-    unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set
+    rustc_peek(&x); //~ ERROR rustc_peek: bit not set
 
     // `ret` is now definitely initialized (via `if` above).
-    unsafe { rustc_peek(&ret); }
+    rustc_peek(&ret);
 
     ret
 }
diff --git a/src/test/ui/mir-dataflow/inits-1.stderr b/src/test/ui/mir-dataflow/inits-1.stderr
index 23d0679cb1a..7a00a70af6f 100644
--- a/src/test/ui/mir-dataflow/inits-1.stderr
+++ b/src/test/ui/mir-dataflow/inits-1.stderr
@@ -1,20 +1,20 @@
 error: rustc_peek: bit not set
-  --> $DIR/inits-1.rs:14:14
+  --> $DIR/inits-1.rs:14:5
    |
-LL |     unsafe { rustc_peek(&ret); }
-   |              ^^^^^^^^^^^^^^^^
+LL |     rustc_peek(&ret);
+   |     ^^^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/inits-1.rs:34:14
+  --> $DIR/inits-1.rs:34:5
    |
-LL |     unsafe { rustc_peek(&y); }
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&y);
+   |     ^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/inits-1.rs:42:14
+  --> $DIR/inits-1.rs:42:5
    |
-LL |     unsafe { rustc_peek(&x); }
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&x);
+   |     ^^^^^^^^^^^^^^
 
 error: stop_after_dataflow ended compilation
 
diff --git a/src/test/ui/mir-dataflow/liveness-ptr.rs b/src/test/ui/mir-dataflow/liveness-ptr.rs
index 34097d7526a..786da523a33 100644
--- a/src/test/ui/mir-dataflow/liveness-ptr.rs
+++ b/src/test/ui/mir-dataflow/liveness-ptr.rs
@@ -10,17 +10,17 @@ fn foo() -> i32 {
     x = 0;
 
     // `x` is live here since it is used in the next statement...
-    unsafe { rustc_peek(x); }
+    rustc_peek(x);
 
     p = &x;
 
     // ... but not here, even while it can be accessed through `p`.
-    unsafe { rustc_peek(x); } //~ ERROR rustc_peek: bit not set
+    rustc_peek(x); //~ ERROR rustc_peek: bit not set
     let tmp = unsafe { *p };
 
     x = tmp + 1;
 
-    unsafe { rustc_peek(x); }
+    rustc_peek(x);
 
     x
 }
diff --git a/src/test/ui/mir-dataflow/liveness-ptr.stderr b/src/test/ui/mir-dataflow/liveness-ptr.stderr
index 3397d0c5a12..858cdbac3d3 100644
--- a/src/test/ui/mir-dataflow/liveness-ptr.stderr
+++ b/src/test/ui/mir-dataflow/liveness-ptr.stderr
@@ -1,8 +1,8 @@
 error: rustc_peek: bit not set
-  --> $DIR/liveness-ptr.rs:18:14
+  --> $DIR/liveness-ptr.rs:18:5
    |
-LL |     unsafe { rustc_peek(x); }
-   |              ^^^^^^^^^^^^^
+LL |     rustc_peek(x);
+   |     ^^^^^^^^^^^^^
 
 error: stop_after_dataflow ended compilation
 
diff --git a/src/test/ui/mir-dataflow/uninits-1.rs b/src/test/ui/mir-dataflow/uninits-1.rs
index 66b3f458a51..c2b4284a7b4 100644
--- a/src/test/ui/mir-dataflow/uninits-1.rs
+++ b/src/test/ui/mir-dataflow/uninits-1.rs
@@ -11,13 +11,13 @@ struct S(i32);
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
     // `ret` starts off uninitialized
-    unsafe { rustc_peek(&ret); }
+    rustc_peek(&ret);
 
     // All function formal parameters start off initialized.
 
-    unsafe { rustc_peek(&x) }; //~ ERROR rustc_peek: bit not set
-    unsafe { rustc_peek(&y) }; //~ ERROR rustc_peek: bit not set
-    unsafe { rustc_peek(&z) }; //~ ERROR rustc_peek: bit not set
+    rustc_peek(&x); //~ ERROR rustc_peek: bit not set
+    rustc_peek(&y); //~ ERROR rustc_peek: bit not set
+    rustc_peek(&z); //~ ERROR rustc_peek: bit not set
 
     ret = if test {
         ::std::mem::replace(x, y)
@@ -27,21 +27,21 @@ fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     };
 
     // `z` may be uninitialized here.
-    unsafe { rustc_peek(&z); }
+    rustc_peek(&z);
 
     // `y` is definitely uninitialized here.
-    unsafe { rustc_peek(&y); }
+    rustc_peek(&y);
 
     // `x` is still (definitely) initialized (replace above is a reborrow).
-    unsafe { rustc_peek(&x); } //~ ERROR rustc_peek: bit not set
+    rustc_peek(&x); //~ ERROR rustc_peek: bit not set
 
     ::std::mem::drop(x);
 
     // `x` is *definitely* uninitialized here
-    unsafe { rustc_peek(&x); }
+    rustc_peek(&x);
 
     // `ret` is now definitely initialized (via `if` above).
-    unsafe { rustc_peek(&ret); } //~ ERROR rustc_peek: bit not set
+    rustc_peek(&ret); //~ ERROR rustc_peek: bit not set
 
     ret
 }
diff --git a/src/test/ui/mir-dataflow/uninits-1.stderr b/src/test/ui/mir-dataflow/uninits-1.stderr
index 5f6dbde212d..c52f5ac7bd9 100644
--- a/src/test/ui/mir-dataflow/uninits-1.stderr
+++ b/src/test/ui/mir-dataflow/uninits-1.stderr
@@ -1,32 +1,32 @@
 error: rustc_peek: bit not set
-  --> $DIR/uninits-1.rs:18:14
+  --> $DIR/uninits-1.rs:18:5
    |
-LL |     unsafe { rustc_peek(&x) };
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&x);
+   |     ^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/uninits-1.rs:19:14
+  --> $DIR/uninits-1.rs:19:5
    |
-LL |     unsafe { rustc_peek(&y) };
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&y);
+   |     ^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/uninits-1.rs:20:14
+  --> $DIR/uninits-1.rs:20:5
    |
-LL |     unsafe { rustc_peek(&z) };
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&z);
+   |     ^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/uninits-1.rs:36:14
+  --> $DIR/uninits-1.rs:36:5
    |
-LL |     unsafe { rustc_peek(&x); }
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&x);
+   |     ^^^^^^^^^^^^^^
 
 error: rustc_peek: bit not set
-  --> $DIR/uninits-1.rs:44:14
+  --> $DIR/uninits-1.rs:44:5
    |
-LL |     unsafe { rustc_peek(&ret); }
-   |              ^^^^^^^^^^^^^^^^
+LL |     rustc_peek(&ret);
+   |     ^^^^^^^^^^^^^^^^
 
 error: stop_after_dataflow ended compilation
 
diff --git a/src/test/ui/mir-dataflow/uninits-2.rs b/src/test/ui/mir-dataflow/uninits-2.rs
index 2ccf1c7f9d6..c584ee74afb 100644
--- a/src/test/ui/mir-dataflow/uninits-2.rs
+++ b/src/test/ui/mir-dataflow/uninits-2.rs
@@ -11,12 +11,12 @@ struct S(i32);
 fn foo(x: &mut S) {
     // `x` is initialized here, so maybe-uninit bit is 0.
 
-    unsafe { rustc_peek(&x) }; //~ ERROR rustc_peek: bit not set
+    rustc_peek(&x); //~ ERROR rustc_peek: bit not set
 
     ::std::mem::drop(x);
 
     // `x` definitely uninitialized here, so maybe-uninit bit is 1.
-    unsafe { rustc_peek(&x) };
+    rustc_peek(&x);
 }
 fn main() {
     foo(&mut S(13));
diff --git a/src/test/ui/mir-dataflow/uninits-2.stderr b/src/test/ui/mir-dataflow/uninits-2.stderr
index dcb61371994..0ef954e35a4 100644
--- a/src/test/ui/mir-dataflow/uninits-2.stderr
+++ b/src/test/ui/mir-dataflow/uninits-2.stderr
@@ -1,8 +1,8 @@
 error: rustc_peek: bit not set
-  --> $DIR/uninits-2.rs:14:14
+  --> $DIR/uninits-2.rs:14:5
    |
-LL |     unsafe { rustc_peek(&x) };
-   |              ^^^^^^^^^^^^^^
+LL |     rustc_peek(&x);
+   |     ^^^^^^^^^^^^^^
 
 error: stop_after_dataflow ended compilation