Skip to content

Commit

Permalink
don't point at const usage site for resolution-time errors
Browse files Browse the repository at this point in the history
also share the code that emits the actual error
  • Loading branch information
RalfJung committed Sep 14, 2023
1 parent 89ac57d commit 9ac8b36
Show file tree
Hide file tree
Showing 47 changed files with 133 additions and 171 deletions.
25 changes: 9 additions & 16 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use rustc_ast::InlineAsmOptions;
use rustc_index::IndexVec;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
Expand Down Expand Up @@ -251,21 +250,15 @@ pub(crate) fn verify_func(
}

fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
match fx.mir.post_mono_checks(fx.tcx, ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c))) {
Ok(()) => {}
Err(ErrorHandled::TooGeneric(span)) => {
span_bug!(span, "codegen encountered polymorphic constant");
}
Err(ErrorHandled::Reported(info, span)) => {
if !info.is_tainted_by_errors() {
fx.tcx.sess.span_err(span, "erroneous constant encountered");
}
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
// compilation should have been aborted
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
return;
}
if let Err(err) =
fx.mir.post_mono_checks(fx.tcx, ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c)))
{
err.emit_err(fx.tcx);
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
// compilation should have been aborted
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
return;
}

let arg_uninhabited = fx
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$e
codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
codegen_ssa_erroneous_constant = erroneous constant encountered
codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)`
Expand Down Expand Up @@ -174,8 +172,6 @@ codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc
codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric
codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
.note = {$output}
Expand Down
14 changes: 0 additions & 14 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,20 +595,6 @@ pub struct InvalidWindowsSubsystem {
pub subsystem: Symbol,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_erroneous_constant)]
pub struct ErroneousConstant {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_polymorphic_constant_too_generic)]
pub struct PolymorphicConstantTooGeneric {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_shuffle_indices_evaluation)]
pub struct ShuffleIndicesEvaluation {
Expand Down
24 changes: 8 additions & 16 deletions compiler/rustc_codegen_ssa/src/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use crate::base;
use crate::errors;
use crate::traits::*;
use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec;
use rustc_middle::mir;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::mir::traversal;
use rustc_middle::mir::UnwindTerminateReason;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
Expand Down Expand Up @@ -214,20 +212,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);

// Rust post-monomorphization checks; we later rely on them.
match mir.post_mono_checks(cx.tcx(), ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c))) {
Ok(()) => {}
Err(ErrorHandled::TooGeneric(span)) => {
cx.tcx().sess.diagnostic().emit_bug(errors::PolymorphicConstantTooGeneric { span });
}
Err(ErrorHandled::Reported(info, span)) => {
if !info.is_tainted_by_errors() {
cx.tcx().sess.emit_err(errors::ErroneousConstant { span });
}
// This IR shouldn't ever be emitted, but let's try to guard against any of this code
// ever running.
start_bx.abort();
return;
}
if let Err(err) =
mir.post_mono_checks(cx.tcx(), ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c)))
{
err.emit_err(cx.tcx());
// This IR shouldn't ever be emitted, but let's try to guard against any of this code
// ever running.
start_bx.abort();
return;
}

let memory_locals = analyze::non_ssa_locals(&fx);
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ const_eval_dyn_call_vtable_mismatch =
const_eval_dyn_star_call_vtable_mismatch =
`dyn*` call on a pointer whose vtable does not match its type
const_eval_erroneous_constant =
erroneous constant used
const_eval_error = {$error_kind ->
[static] could not evaluate static initializer
[const] evaluation of constant value failed
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,6 @@ pub struct LongRunningWarn {
pub item_span: Span,
}

#[derive(Diagnostic)]
#[diag(const_eval_erroneous_constant)]
pub(crate) struct ErroneousConstUsed {
#[primary_span]
pub span: Span,
}

#[derive(Subdiagnostic)]
#[note(const_eval_non_const_impl)]
pub(crate) struct NonConstImplNote {
Expand Down
14 changes: 2 additions & 12 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use super::{
MemPlaceMeta, Memory, MemoryKind, OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic,
Projectable, Provenance, Scalar, StackPopJump,
};
use crate::errors::{self, ErroneousConstUsed};
use crate::errors;
use crate::util;
use crate::{fluent_generated as fluent, ReportErrorExt};

Expand Down Expand Up @@ -1063,17 +1063,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> Result<T, ErrorHandled> {
// Use a precise span for better cycle errors.
query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| {
match err {
ErrorHandled::Reported(err, reported_span) => {
// We trust the provided span more than the one that came out of the query.
let span = span.unwrap_or(reported_span);
if !err.is_tainted_by_errors() {
// To make it easier to figure out where this error comes from, also add a note at the current location.
self.tcx.sess.emit_note(ErroneousConstUsed { span });
}
}
ErrorHandled::TooGeneric(_) => {}
}
err.emit_note(*self.tcx);
err
})
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ middle_drop_check_overflow =
overflow while adding drop-check rules for {$ty}
.note = overflowed on {$overflow_ty}
middle_erroneous_constant = erroneous constant encountered
middle_layout_references_error =
the type has an unknown layout
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,12 @@ pub struct UnsupportedFnAbi {
pub abi: &'static str,
}

#[derive(Diagnostic)]
#[diag(middle_erroneous_constant)]
pub struct ErroneousConstant {
#[primary_span]
pub span: Span,
}

/// Used by `rustc_const_eval`
pub use crate::fluent_generated::middle_adjust_for_foreign_abi_error;
35 changes: 28 additions & 7 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar};

use crate::error;
use crate::mir::interpret::ConstValue;
use crate::query::TyCtxtAt;
use crate::ty::{layout, tls, Ty, ValTree};
use crate::ty::{layout, tls, Ty, TyCtxt, ValTree};

use rustc_data_structures::sync::Lock;
use rustc_errors::{
Expand Down Expand Up @@ -41,6 +42,32 @@ impl ErrorHandled {
ErrorHandled::TooGeneric(_span) => ErrorHandled::TooGeneric(span),
}
}

pub fn emit_err(&self, tcx: TyCtxt<'_>) -> ErrorGuaranteed {
match self {
&ErrorHandled::Reported(err, span) => {
if !err.is_tainted_by_errors && !span.is_dummy() {
tcx.sess.emit_err(error::ErroneousConstant { span });
}
err.error
}
&ErrorHandled::TooGeneric(span) => tcx.sess.delay_span_bug(
span,
"encountered TooGeneric error when monomorphic data was expected",
),
}
}

pub fn emit_note(&self, tcx: TyCtxt<'_>) {
match self {
&ErrorHandled::Reported(err, span) => {
if !err.is_tainted_by_errors && !span.is_dummy() {
tcx.sess.emit_note(error::ErroneousConstant { span });
}
}
&ErrorHandled::TooGeneric(_) => {}
}
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
Expand All @@ -54,12 +81,6 @@ impl ReportedErrorInfo {
pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo {
ReportedErrorInfo { is_tainted_by_errors: true, error }
}

/// Returns true if evaluation failed because MIR was tainted by errors.
#[inline]
pub fn is_tainted_by_errors(self) -> bool {
self.is_tainted_by_errors
}
}

impl From<ErrorGuaranteed> for ReportedErrorInfo {
Expand Down
18 changes: 12 additions & 6 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ impl<'tcx> TyCtxt<'tcx> {
let cid = GlobalId { instance, promoted: ct.promoted };
self.const_eval_global_id(param_env, cid, span)
}
Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))),
Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(DUMMY_SP))),
// For errors during resolution, we deliberately do not point at the usage site of the constant,
// since for these errors the place the constant is used shouldn't matter.
Ok(None) => Err(ErrorHandled::TooGeneric(DUMMY_SP)),
Err(err) => Err(ErrorHandled::Reported(err.into(), DUMMY_SP)),
}
}

Expand Down Expand Up @@ -117,8 +119,10 @@ impl<'tcx> TyCtxt<'tcx> {
}
})
}
Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))),
Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(DUMMY_SP))),
// For errors during resolution, we deliberately do not point at the usage site of the constant,
// since for these errors the place the constant is used shouldn't matter.
Ok(None) => Err(ErrorHandled::TooGeneric(DUMMY_SP)),
Err(err) => Err(ErrorHandled::Reported(err.into(), DUMMY_SP)),
}
}

Expand All @@ -143,7 +147,8 @@ impl<'tcx> TyCtxt<'tcx> {
// improve caching of queries.
let inputs = self.erase_regions(param_env.and(cid));
if let Some(span) = span {
self.at(span).eval_to_const_value_raw(inputs)
// The query doesn't know where it is being invoked, so we need to fix the span.
self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span))
} else {
self.eval_to_const_value_raw(inputs)
}
Expand All @@ -162,7 +167,8 @@ impl<'tcx> TyCtxt<'tcx> {
let inputs = self.erase_regions(param_env.and(cid));
debug!(?inputs);
if let Some(span) = span {
self.at(span).eval_to_valtree(inputs)
// The query doesn't know where it is being invoked, so we need to fix the span.
self.at(span).eval_to_valtree(inputs).map_err(|e| e.with_span(span))
} else {
self.eval_to_valtree(inputs)
}
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,10 +588,7 @@ impl<'tcx> Body<'tcx> {
// the body successfully evaluate.
for &const_ in &self.required_consts {
let c = normalize_const(const_.literal)?;
c.eval(tcx, param_env, Some(const_.span)).map_err(|e| {
// The query results don't always have the span we want.
e.with_span(const_.span)
})?;
c.eval(tcx, param_env, Some(const_.span))?;
}

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0080]: evaluation of `main::{constant#3}` failed
LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/test.rs:37:5
|
LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/indexing_slicing_index.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ error[E0080]: evaluation of `main::{constant#3}` failed
LL | const { &ARR[idx4()] };
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/indexing_slicing_index.rs:48:5
|
LL | const { &ARR[idx4()] };
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/const-ub-checks.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed
LL | ptr.read();
| ^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/const-ub-checks.rs:LL:CC
|
LL | let _x = UNALIGNED_READ;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/erroneous_const.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LL | const VOID: ! = panic!();
|
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/erroneous_const.rs:LL:CC
|
LL | let _ = PrintName::<T>::VOID;
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/tests/fail/erroneous_const2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ error[E0080]: evaluation of constant value failed
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
| ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/erroneous_const2.rs:LL:CC
|
LL | println!("{}", FOO);
| ^^^

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/erroneous_const2.rs:LL:CC
|
LL | println!("{}", FOO);
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/associated-consts/defaults-not-assumed-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ error[E0080]: evaluation of `<() as Tr>::B` failed
LL | const B: u8 = Self::A + 1;
| ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/defaults-not-assumed-fail.rs:33:16
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/defaults-not-assumed-fail.rs:33:5
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/defaults-not-assumed-fail.rs:33:5
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/issue-81899.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
note: erroneous constant encountered
--> $DIR/issue-81899.rs:4:23
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
Expand Down
Loading

0 comments on commit 9ac8b36

Please sign in to comment.