]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/transform/check_unsafety.rs
Various minor/cosmetic improvements to code
[rust.git] / src / librustc_mir / transform / check_unsafety.rs
index 25dbd160d19f4cb95b8e4d0eb6dd619a7d54836f..6af29b74c1c4fab1e535a8b8ee492e47202b66ad 100644 (file)
@@ -351,19 +351,22 @@ fn register_violations(&mut self,
                 }
                 // only some unsafety is allowed in const fn
                 if self.min_const_fn {
+                    let min_const_unsafe_fn = self.tcx.features().min_const_unsafe_fn;
                     for violation in violations {
                         match violation.kind {
-                            // these are allowed
-                            UnsafetyViolationKind::GatedConstFnCall => {
+                            UnsafetyViolationKind::GatedConstFnCall if min_const_unsafe_fn => {
+                                // these function calls to unsafe functions are allowed
                                 // if `#![feature(min_const_unsafe_fn)]` is active
-                                if !self.tcx.sess.features_untracked().min_const_unsafe_fn {
-                                    if !self.violations.contains(&violation) {
-                                        self.violations.push(violation.clone())
-                                    }
+                            },
+                            UnsafetyViolationKind::GatedConstFnCall => {
+                                // without the feature gate, we report errors
+                                if !self.violations.contains(&violation) {
+                                    self.violations.push(violation.clone())
                                 }
                             }
                             // these unsafe things are stable in const fn
                             UnsafetyViolationKind::GeneralAndConstFn => {},
+                            // these things are forbidden in const fns
                             UnsafetyViolationKind::General |
                             UnsafetyViolationKind::BorrowPacked(_) |
                             UnsafetyViolationKind::ExternStatic(_) => {
@@ -470,8 +473,8 @@ fn check_unused_unsafe<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  unsafe_blocks: &'a mut Vec<(ast::NodeId, bool)>)
 {
     let body_id =
-        tcx.hir.as_local_node_id(def_id).and_then(|node_id| {
-            tcx.hir.maybe_body_owned_by(node_id)
+        tcx.hir().as_local_node_id(def_id).and_then(|node_id| {
+            tcx.hir().maybe_body_owned_by(node_id)
         });
 
     let body_id = match body_id {
@@ -481,7 +484,7 @@ fn check_unused_unsafe<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             return
         }
     };
-    let body = tcx.hir.body(body_id);
+    let body = tcx.hir().body(body_id);
     debug!("check_unused_unsafe({:?}, body={:?}, used_unsafe={:?})",
            def_id, body, used_unsafe);
 
@@ -494,7 +497,7 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
 {
     debug!("unsafety_violations({:?})", def_id);
 
-    // NB: this borrow is valid because all the consumers of
+    // N.B., this borrow is valid because all the consumers of
     // `mir_built` force this.
     let mir = &tcx.mir_built(def_id).borrow();
 
@@ -511,7 +514,7 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
 
     let param_env = tcx.param_env(def_id);
     let mut checker = UnsafetyChecker::new(
-        tcx.is_const_fn(def_id) && tcx.is_min_const_fn(def_id),
+        tcx.is_min_const_fn(def_id),
         mir, source_scope_local_data, tcx, param_env);
     checker.visit_mir(mir);
 
@@ -523,7 +526,7 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
 }
 
 fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
-    let lint_node_id = match tcx.hir.as_local_node_id(def_id) {
+    let lint_node_id = match tcx.hir().as_local_node_id(def_id) {
         Some(node_id) => node_id,
         None => bug!("checking unsafety for non-local def id {:?}", def_id)
     };
@@ -547,14 +550,14 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D
 fn is_enclosed(tcx: TyCtxt,
                used_unsafe: &FxHashSet<ast::NodeId>,
                id: ast::NodeId) -> Option<(String, ast::NodeId)> {
-    let parent_id = tcx.hir.get_parent_node(id);
+    let parent_id = tcx.hir().get_parent_node(id);
     if parent_id != id {
         if used_unsafe.contains(&parent_id) {
             Some(("block".to_string(), parent_id))
         } else if let Some(Node::Item(&hir::Item {
             node: hir::ItemKind::Fn(_, header, _, _),
             ..
-        })) = tcx.hir.find(parent_id) {
+        })) = tcx.hir().find(parent_id) {
             match header.unsafety {
                 hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)),
                 hir::Unsafety::Normal => None,
@@ -568,12 +571,12 @@ fn is_enclosed(tcx: TyCtxt,
 }
 
 fn report_unused_unsafe(tcx: TyCtxt, used_unsafe: &FxHashSet<ast::NodeId>, id: ast::NodeId) {
-    let span = tcx.sess.source_map().def_span(tcx.hir.span(id));
+    let span = tcx.sess.source_map().def_span(tcx.hir().span(id));
     let msg = "unnecessary `unsafe` block";
     let mut db = tcx.struct_span_lint_node(UNUSED_UNSAFE, id, span, msg);
     db.span_label(span, msg);
     if let Some((kind, id)) = is_enclosed(tcx, used_unsafe, id) {
-        db.span_label(tcx.sess.source_map().def_span(tcx.hir.span(id)),
+        db.span_label(tcx.sess.source_map().def_span(tcx.hir().span(id)),
                       format!("because it's nested under this `unsafe` {}", kind));
     }
     db.emit();
@@ -614,13 +617,19 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
         // Report an error.
         match kind {
             UnsafetyViolationKind::General if tcx.is_min_const_fn(def_id) => {
-                tcx.sess.struct_span_err(
+                let mut err = tcx.sess.struct_span_err(
                     source_info.span,
                     &format!("{} is unsafe and unsafe operations \
-                            are not allowed in const fn", description))
-                    .span_label(source_info.span, &description.as_str()[..])
-                    .note(&details.as_str()[..])
-                    .emit();
+                            are not allowed in const fn", description));
+                err.span_label(source_info.span, &description.as_str()[..])
+                    .note(&details.as_str()[..]);
+                if tcx.fn_sig(def_id).unsafety() == hir::Unsafety::Unsafe {
+                    err.note(
+                        "unsafe action within a `const unsafe fn` still require an `unsafe` \
+                        block in contrast to regular `unsafe fn`."
+                    );
+                }
+                err.emit();
             }
             UnsafetyViolationKind::GeneralAndConstFn |
             UnsafetyViolationKind::General => {