about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2020-09-30 09:48:18 -0700
committerDylan MacKenzie <ecstaticmorse@gmail.com>2020-09-30 11:29:16 -0700
commit0c26144b1ac75267c679bad6a4e2c4e7bc7957d3 (patch)
tree9a865db00ff13ff99caa3b1f599ac1ef9666ac7d
parent7c6d685551604dcb86f8239d09b21eeca5988f67 (diff)
downloadrust-0c26144b1ac75267c679bad6a4e2c4e7bc7957d3.tar.gz
rust-0c26144b1ac75267c679bad6a4e2c4e7bc7957d3.zip
Better span for attribute suggestions
`def_span` has the same issues as `body.span`, so do it this way instead.
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/mod.rs10
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs20
2 files changed, 19 insertions, 11 deletions
diff --git a/compiler/rustc_mir/src/transform/check_consts/mod.rs b/compiler/rustc_mir/src/transform/check_consts/mod.rs
index 8d4efd8ae80..8df134860a5 100644
--- a/compiler/rustc_mir/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/mod.rs
@@ -57,6 +57,16 @@ impl ConstCx<'mir, 'tcx> {
             && self.tcx.features().staged_api
             && is_const_stable_const_fn(self.tcx, self.def_id.to_def_id())
     }
+
+    /// Returns the function signature of the item being const-checked if it is a `fn` or `const fn`.
+    pub fn fn_sig(&self) -> Option<&'tcx hir::FnSig<'tcx>> {
+        // Get this from the HIR map instead of a query to avoid cycle errors.
+        //
+        // FIXME: Is this still an issue?
+        let hir_map = self.tcx.hir();
+        let hir_id = hir_map.local_def_id_to_hir_id(self.def_id);
+        hir_map.fn_sig_by_hir_id(hir_id)
+    }
 }
 
 /// Returns `true` if this `DefId` points to one of the official `panic` lang items.
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index 7588c01ed3c..ab63fd03a33 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -1,7 +1,7 @@
 //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
 
 use rustc_errors::{struct_span_err, Applicability, Diagnostic};
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, HirId, LangItem};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
@@ -209,7 +209,7 @@ impl Validator<'mir, 'tcx> {
 
         // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
         // no need to emit duplicate errors here.
-        if is_async_fn(tcx, def_id) || body.generator_kind.is_some() {
+        if is_async_fn(self.ccx) || body.generator_kind.is_some() {
             tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`");
             return;
         }
@@ -929,15 +929,13 @@ fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
     ty.is_bool() || ty.is_integral() || ty.is_char()
 }
 
-fn is_async_fn(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
-    let hir_map = tcx.hir();
-    let hir_id = hir_map.local_def_id_to_hir_id(def_id);
-    hir_map
-        .fn_sig_by_hir_id(hir_id)
-        .map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async)
+fn is_async_fn(ccx: &ConstCx<'_, '_>) -> bool {
+    ccx.fn_sig().map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async)
 }
 
 fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) {
+    let attr_span = ccx.fn_sig().map_or(ccx.body.span, |sig| sig.span.shrink_to_lo());
+
     ccx.tcx
         .sess
         .struct_span_err(
@@ -945,15 +943,15 @@ fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol
             &format!("const-stable function cannot use `#[feature({})]`", gate.as_str()),
         )
         .span_suggestion(
-            ccx.body.span,
+            attr_span,
             "if it is not part of the public API, make this function unstably const",
             concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(),
             Applicability::HasPlaceholders,
         )
         .span_suggestion(
-            ccx.body.span,
+            attr_span,
             "otherwise `#[allow_internal_unstable]` can be used to bypass stability checks",
-            format!("#[allow_internal_unstable({})]", gate),
+            format!("#[allow_internal_unstable({})]\n", gate),
             Applicability::MaybeIncorrect,
         )
         .emit();