diff options
| author | Dylan MacKenzie <ecstaticmorse@gmail.com> | 2020-09-30 09:48:18 -0700 |
|---|---|---|
| committer | Dylan MacKenzie <ecstaticmorse@gmail.com> | 2020-09-30 11:29:16 -0700 |
| commit | 0c26144b1ac75267c679bad6a4e2c4e7bc7957d3 (patch) | |
| tree | 9a865db00ff13ff99caa3b1f599ac1ef9666ac7d | |
| parent | 7c6d685551604dcb86f8239d09b21eeca5988f67 (diff) | |
| download | rust-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.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/validation.rs | 20 |
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(); |
