Skip to content

Commit

Permalink
Rollup merge of #98657 - compiler-errors:rustc-const-eval-session-dia…
Browse files Browse the repository at this point in the history
…gnostic-1, r=davidtwco

Migrate some diagnostics from `rustc_const_eval` to `SessionDiagnostic`

I'm still trying to get the hang of this, so it doesn't migrate _all_ of `rustc_const_eval`. Working on that later.

r? `@davidtwco`
  • Loading branch information
Dylan-DPC authored Jul 8, 2022
2 parents fe87923 + 2058333 commit dbae830
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 89 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3813,6 +3813,7 @@ dependencies = [
"atty",
"rustc_data_structures",
"rustc_error_messages",
"rustc_hir",
"rustc_lint_defs",
"rustc_macros",
"rustc_serialize",
Expand Down
89 changes: 89 additions & 0 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use rustc_hir::ConstContext;
use rustc_macros::SessionDiagnostic;
use rustc_span::Span;

#[derive(SessionDiagnostic)]
#[error(const_eval::unstable_in_stable)]
pub(crate) struct UnstableInStable {
pub gate: String,
#[primary_span]
pub span: Span,
#[suggestion(
const_eval::unstable_sugg,
code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
applicability = "has-placeholders"
)]
#[suggestion(
const_eval::bypass_sugg,
code = "#[rustc_allow_const_fn_unstable({gate})]\n",
applicability = "has-placeholders"
)]
pub attr_span: Span,
}

#[derive(SessionDiagnostic)]
#[error(const_eval::thread_local_access, code = "E0625")]
pub(crate) struct NonConstOpErr {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[error(const_eval::static_access, code = "E0013")]
#[help]
pub(crate) struct StaticAccessErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
#[note(const_eval::teach_note)]
#[help(const_eval::teach_help)]
pub teach: Option<()>,
}

#[derive(SessionDiagnostic)]
#[error(const_eval::raw_ptr_to_int)]
#[note]
#[note(const_eval::note2)]
pub(crate) struct RawPtrToIntErr {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[error(const_eval::raw_ptr_comparison)]
#[note]
pub(crate) struct RawPtrComparisonErr {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[error(const_eval::panic_non_str)]
pub(crate) struct PanicNonStrErr {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[error(const_eval::mut_deref, code = "E0658")]
pub(crate) struct MutDerefErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}

#[derive(SessionDiagnostic)]
#[error(const_eval::transient_mut_borrow, code = "E0658")]
pub(crate) struct TransientMutBorrowErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}

#[derive(SessionDiagnostic)]
#[error(const_eval::transient_mut_borrow_raw, code = "E0658")]
pub(crate) struct TransientMutBorrowErrRaw {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ extern crate tracing;
extern crate rustc_middle;

pub mod const_eval;
mod errors;
pub mod interpret;
pub mod transform;
pub mod util;
Expand Down
23 changes: 3 additions & 20 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.

use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed};
use rustc_errors::{Diagnostic, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::bit_set::BitSet;
Expand All @@ -24,6 +24,7 @@ use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop, NeedsNonConstDro
use super::resolver::FlowSensitiveAnalysis;
use super::{ConstCx, Qualif};
use crate::const_eval::is_unstable_const_fn;
use crate::errors::UnstableInStable;

type QualifResults<'mir, 'tcx, Q> =
rustc_mir_dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'mir, 'mir, 'tcx, Q>>;
Expand Down Expand Up @@ -1026,23 +1027,5 @@ fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) {
let attr_span = ccx.tcx.def_span(ccx.def_id()).shrink_to_lo();

ccx.tcx
.sess
.struct_span_err(
span,
&format!("const-stable function cannot use `#[feature({})]`", gate.as_str()),
)
.span_suggestion(
attr_span,
"if it is not part of the public API, make this function unstably const",
concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n'),
Applicability::HasPlaceholders,
)
.span_suggestion(
attr_span,
"otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks",
format!("#[rustc_allow_const_fn_unstable({})]\n", gate),
Applicability::MaybeIncorrect,
)
.emit();
ccx.tcx.sess.emit_err(UnstableInStable { gate: gate.to_string(), span, attr_span });
}
93 changes: 29 additions & 64 deletions compiler/rustc_const_eval/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Concrete error types for all operations which may be invalid in a certain const context.

use hir::def_id::LocalDefId;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
use rustc_errors::{
error_code, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
Expand All @@ -20,6 +22,10 @@ use rustc_span::{BytePos, Pos, Span, Symbol};
use rustc_trait_selection::traits::SelectionContext;

use super::ConstCx;
use crate::errors::{
MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrComparisonErr, RawPtrToIntErr,
StaticAccessErr, TransientMutBorrowErr, TransientMutBorrowErrRaw,
};
use crate::util::{call_kind, CallDesugaringKind, CallKind};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -590,17 +596,17 @@ impl<'tcx> NonConstOp<'tcx> for TransientMutBorrow {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let raw = match self.0 {
hir::BorrowKind::Raw => "raw ",
hir::BorrowKind::Ref => "",
};

feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
span,
&format!("{}mutable references are not allowed in {}s", raw, ccx.const_kind()),
)
let kind = ccx.const_kind();
match self.0 {
hir::BorrowKind::Raw => ccx
.tcx
.sess
.create_feature_err(TransientMutBorrowErrRaw { span, kind }, sym::const_mut_refs),
hir::BorrowKind::Ref => ccx
.tcx
.sess
.create_feature_err(TransientMutBorrowErr { span, kind }, sym::const_mut_refs),
}
}
}

Expand All @@ -621,12 +627,9 @@ impl<'tcx> NonConstOp<'tcx> for MutDeref {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
span,
&format!("mutation through a reference is not allowed in {}s", ccx.const_kind()),
)
ccx.tcx
.sess
.create_feature_err(MutDerefErr { span, kind: ccx.const_kind() }, sym::const_mut_refs)
}
}

Expand All @@ -639,10 +642,7 @@ impl<'tcx> NonConstOp<'tcx> for PanicNonStr {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.struct_span_err(
span,
"argument to `panic!()` in a const context must have type `&str`",
)
ccx.tcx.sess.create_err(PanicNonStrErr { span })
}
}

Expand All @@ -657,15 +657,7 @@ impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let mut err = ccx
.tcx
.sess
.struct_span_err(span, "pointers cannot be reliably compared during const eval");
err.note(
"see issue #53020 <https://github.com/rust-lang/rust/issues/53020> \
for more information",
);
err
ccx.tcx.sess.create_err(RawPtrComparisonErr { span })
}
}

Expand Down Expand Up @@ -701,15 +693,7 @@ impl<'tcx> NonConstOp<'tcx> for RawPtrToIntCast {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let mut err = ccx
.tcx
.sess
.struct_span_err(span, "pointers cannot be cast to integers during const eval");
err.note("at compile-time, pointers do not have an integer value");
err.note(
"avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior",
);
err
ccx.tcx.sess.create_err(RawPtrToIntErr { span })
}
}

Expand All @@ -730,24 +714,11 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let mut err = struct_span_err!(
ccx.tcx.sess,
ccx.tcx.sess.create_err(StaticAccessErr {
span,
E0013,
"{}s cannot refer to statics",
ccx.const_kind()
);
err.help(
"consider extracting the value of the `static` to a `const`, and referring to that",
);
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"`static` and `const` variables can refer to other `const` variables. \
A `const` variable, however, cannot refer to a `static` variable.",
);
err.help("To fix this, the value can be extracted to a `const` and then used.");
}
err
kind: ccx.const_kind(),
teach: ccx.tcx.sess.teach(&error_code!(E0013)).then_some(()),
})
}
}

Expand All @@ -760,13 +731,7 @@ impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
struct_span_err!(
ccx.tcx.sess,
span,
E0625,
"thread-local statics cannot be \
accessed at compile-time"
)
ccx.tcx.sess.create_err(NonConstOpErr { span })
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
builtin_macros-requires-cfg-pattern =
builtin-macros-requires-cfg-pattern =
macro requires a cfg-pattern as an argument
.label = cfg-pattern required
builtin_macros-expected-one-cfg-pattern = expected 1 cfg-pattern
builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern
31 changes: 31 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/const_eval.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const-eval-unstable-in-stable =
const-stable function cannot use `#[feature({$gate})]`
.unstable-sugg = if it is not part of the public API, make this function unstably const
.bypass-sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
const-eval-thread-local-access =
thread-local statics cannot be accessed at compile-time
const-eval-static-access =
{$kind}s cannot refer to statics
.help = consider extracting the value of the `static` to a `const`, and referring to that
.teach-note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
.teach-help = To fix this, the value can be extracted to a `const` and then used.
const-eval-raw-ptr-to-int =
pointers cannot be cast to integers during const eval
.note = at compile-time, pointers do not have an integer value
.note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
const-eval-raw-ptr-comparison =
pointers cannot be reliably compared during const eval
.note = see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
const-eval-panic-non-str = argument to `panic!()` in a const context must have type `&str`
const-eval-mut-deref =
mutation through a reference is not allowed in {$kind}s
const-eval-transient-mut-borrow = mutable references are not allowed in {$kind}s
const-eval-transient-mut-borrow-raw = raw mutable references are not allowed in {$kind}s
1 change: 1 addition & 0 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ fluent_messages! {
parser => "../locales/en-US/parser.ftl",
privacy => "../locales/en-US/privacy.ftl",
typeck => "../locales/en-US/typeck.ftl",
const_eval => "../locales/en-US/const_eval.ftl",
}

pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
rustc_macros = { path = "../rustc_macros" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_hir = { path = "../rustc_hir" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
unicode-width = "0.1.4"
atty = "0.2"
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
};
use rustc_data_structures::stable_map::FxHashMap;
use rustc_error_messages::FluentValue;
use rustc_hir as hir;
use rustc_lint_defs::{Applicability, LintExpectationId};
use rustc_span::edition::LATEST_STABLE_EDITION;
use rustc_span::symbol::{Ident, Symbol};
Expand Down Expand Up @@ -160,6 +161,16 @@ impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
}
}

impl IntoDiagnosticArg for hir::ConstContext {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::Borrowed(match self {
hir::ConstContext::ConstFn => "constant function",
hir::ConstContext::Static(_) => "static",
hir::ConstContext::Const => "constant",
}))
}
}

/// Trait implemented by error types. This should not be implemented manually. Instead, use
/// `#[derive(SessionSubdiagnostic)]` -- see [rustc_macros::SessionSubdiagnostic].
#[rustc_diagnostic_item = "AddSubdiagnostic"]
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,9 @@ impl fmt::Display for ConstContext {
}
}

// NOTE: `IntoDiagnosticArg` impl for `ConstContext` lives in `rustc_errors`
// due to a cyclical dependency between hir that crate.

/// A literal.
pub type Lit = Spanned<LitKind>;

Expand Down
Loading

0 comments on commit dbae830

Please sign in to comment.