Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
63a02ac
Fix LegacyKeyValueFormat report from docker build: i686
homersimpsons Mar 7, 2026
5064056
interpreter error reporting: remove arguments that are always the same
RalfJung Mar 9, 2026
46e3c4d
further cleanup and deduplication
RalfJung Mar 11, 2026
b9cd592
Replace `truncate(0)` with `clear()`
xtqqczze Mar 18, 2026
4a439b6
Inline and remove `DepGraphData::try_mark_parent_green`.
nnethercote Mar 20, 2026
b25a2d5
Prevent no_threads RwLock's write() impl from setting mode to -1 when…
asder8215 Mar 21, 2026
1af153c
Tweak incorrect assoc item note
JohnTitor Feb 20, 2026
a1d397e
Emit pre-expansion feature gate warning for `box`'ed struct field pats
fmease Mar 27, 2026
a7ad9ac
Clearly exercise all soft feature gates
fmease Mar 27, 2026
531631c
Make messages more generic
JohnTitor Mar 8, 2026
767d71f
EnumSizeOpt test: show actual bytes of new allocation
RalfJung Mar 28, 2026
1dfbb89
use Allocation::write_scalar instead of manual endianess logic
RalfJung Mar 28, 2026
29be059
Use the normal arg-parsing machinery for `-Zassert-incr-state`
Zalathar Mar 27, 2026
10d29ee
Extract `-Zassert-incr-state` into a separate helper function
Zalathar Mar 27, 2026
ad298d5
interpret: ensure that untupled arguments are actually tuples
RalfJung Mar 28, 2026
d10baae
Normalize rustc path prefix when testing `-Z track-diagnostics`
aDotInTheVoid Mar 25, 2026
7881a31
Rollup merge of #152880 - JohnTitor:tweak-assoc-item-note, r=fmease
RalfJung Mar 28, 2026
ca39636
Rollup merge of #153526 - homersimpsons:chore/fix-LegacyKeyValueForma…
RalfJung Mar 28, 2026
f50103e
Rollup merge of #153613 - RalfJung:interpret-report, r=oli-obk
RalfJung Mar 28, 2026
d289cc4
Rollup merge of #154029 - xtqqczze:clear, r=joboet
RalfJung Mar 28, 2026
b3196a0
Rollup merge of #154125 - nnethercote:rm-try_mark_parent_green, r=oli…
RalfJung Mar 28, 2026
54b4b99
Rollup merge of #154185 - asder8215:no_threads_write_impl, r=joboet
RalfJung Mar 28, 2026
d400f17
Rollup merge of #154394 - aDotInTheVoid:in-one-word-he-told-me-secret…
RalfJung Mar 28, 2026
effcc70
Rollup merge of #154450 - Zalathar:assert-incr-state, r=fmease
RalfJung Mar 28, 2026
7ee19eb
Rollup merge of #154475 - fmease:soft-gate-box-struct-field-pat, r=Ki…
RalfJung Mar 28, 2026
2645f0d
Rollup merge of #154500 - RalfJung:enum-opt-endianess, r=oli-obk
RalfJung Mar 28, 2026
c47e0e1
Rollup merge of #154502 - RalfJung:interpret-untuple-check, r=oli-obk
RalfJung Mar 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 11 additions & 17 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use std::{fmt, mem};

use rustc_errors::Diag;
use rustc_errors::{Diag, E0080};
use rustc_middle::mir::AssertKind;
use rustc_middle::mir::interpret::{
AllocId, Provenance, ReportedErrorInfo, UndefinedBehaviorInfo, UnsupportedOpInfo,
};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::ConstInt;
use rustc_middle::ty::layout::LayoutError;
use rustc_span::{Span, Symbol};
use rustc_span::{DUMMY_SP, Span, Symbol};

use super::CompileTimeMachine;
use crate::errors::{self, FrameNote};
Expand Down Expand Up @@ -164,36 +164,30 @@ pub fn get_span_and_frames<'tcx>(
/// This will use the `mk` function for adding more information to the error.
/// You can use it to add a stacktrace of current execution according to
/// `get_span_and_frames` or just give context on where the const eval error happened.
pub(super) fn report<'tcx, C, F>(
pub(super) fn report<'tcx>(
ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
error: InterpErrorKind<'tcx>,
span: Span,
get_span_and_frames: C,
mk: F,
) -> ErrorHandled
where
C: FnOnce() -> (Span, Vec<FrameNote>),
F: FnOnce(&mut Diag<'_>, Span, Vec<FrameNote>),
{
mk: impl FnOnce(&mut Diag<'_>, Span, Vec<FrameNote>),
) -> ErrorHandled {
let tcx = ecx.tcx.tcx;
// Special handling for certain errors
match error {
// Don't emit a new diagnostic for these errors, they are already reported elsewhere or
// should remain silent.
err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span),
err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, DUMMY_SP),
err_inval!(Layout(LayoutError::TooGeneric(_))) | err_inval!(TooGeneric) => {
ErrorHandled::TooGeneric(span)
ErrorHandled::TooGeneric(DUMMY_SP)
}
err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
// This can occur in infallible promoteds e.g. when a non-existent type or field is
// encountered.
ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), span)
ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), DUMMY_SP)
}
// Report remaining errors.
_ => {
let (our_span, frames) = get_span_and_frames();
let span = span.substitute_dummy(our_span);
let mut err = tcx.dcx().struct_span_err(our_span, error.to_string());
let (span, frames) = super::get_span_and_frames(ecx.tcx, ecx.stack());
let mut err = tcx.dcx().struct_span_err(span, error.to_string());
err.code(E0080);
if matches!(
error,
InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError {
Expand Down
65 changes: 21 additions & 44 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::sync::atomic::Ordering::Relaxed;

use either::{Left, Right};
use rustc_abi::{self as abi, BackendRepr};
use rustc_errors::{E0080, msg};
use rustc_hir::def::DefKind;
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo, ReportedErrorInfo};
use rustc_middle::mir::{self, ConstAlloc, ConstValue};
Expand All @@ -11,8 +10,8 @@ use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, throw_inval};
use rustc_span::Span;
use rustc_span::def_id::LocalDefId;
use rustc_span::{DUMMY_SP, Span};
use tracing::{debug, instrument, trace};

use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
Expand Down Expand Up @@ -458,32 +457,20 @@ fn report_eval_error<'tcx>(
let (error, backtrace) = error.into_parts();
backtrace.print_backtrace();

super::report(
ecx,
error,
DUMMY_SP,
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
|diag, span, frames| {
let num_frames = frames.len();
// FIXME(oli-obk): figure out how to use structured diagnostics again.
diag.code(E0080);
diag.span_label(
span,
msg!(
"evaluation of `{$instance}` failed {$num_frames ->
[0] here
*[other] inside this call
}"
),
);
for frame in frames {
diag.subdiagnostic(frame);
}
// Add after the frame rendering above, as it adds its own `instance` args.
diag.arg("instance", with_no_trimmed_paths!(cid.instance.to_string()));
diag.arg("num_frames", num_frames);
},
)
super::report(ecx, error, |diag, span, frames| {
let num_frames = frames.len();
diag.span_label(
span,
format!(
"evaluation of `{instance}` failed {where_}",
instance = with_no_trimmed_paths!(cid.instance.to_string()),
where_ = if num_frames == 0 { "here" } else { "inside this call" },
),
);
for frame in frames {
diag.subdiagnostic(frame);
}
})
}

#[inline(never)]
Expand All @@ -506,20 +493,10 @@ fn report_validation_error<'tcx>(
let raw_bytes =
errors::RawBytesNote { size: info.size.bytes(), align: info.align.bytes(), bytes };

crate::const_eval::report(
ecx,
error,
DUMMY_SP,
|| crate::const_eval::get_span_and_frames(ecx.tcx, ecx.stack()),
move |diag, span, frames| {
// FIXME(oli-obk): figure out how to use structured diagnostics again.
diag.code(E0080);
diag.span_label(span, "it is undefined behavior to use this value");
diag.note("the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.");
for frame in frames {
diag.subdiagnostic(frame);
}
diag.subdiagnostic(raw_bytes);
},
)
crate::const_eval::report(ecx, error, move |diag, span, frames| {
diag.span_label(span, "it is undefined behavior to use this value");
diag.note("the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.");
assert!(frames.is_empty()); // we just report validation errors for the final const here
diag.subdiagnostic(raw_bytes);
})
}
11 changes: 8 additions & 3 deletions compiler/rustc_const_eval/src/interpret/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}

/// Helper function for argument untupling.
pub(super) fn fn_arg_field(
fn fn_arg_project_field(
&self,
arg: &FnArg<'tcx, M::Provenance>,
field: FieldIdx,
Expand Down Expand Up @@ -655,12 +655,17 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
if caller_abi == ExternAbi::RustCall && !args.is_empty() {
// Untuple
let (untuple_arg, args) = args.split_last().unwrap();
let ty::Tuple(untuple_fields) = untuple_arg.layout().ty.kind() else {
span_bug!(self.cur_span(), "untuple argument must be a tuple")
};
trace!("init_fn_call: Will pass last argument by untupling");
Cow::from(
args.iter()
// The regular arguments.
.map(|a| interp_ok(a.clone()))
.chain((0..untuple_arg.layout().fields.count()).map(|i| {
self.fn_arg_field(untuple_arg, FieldIdx::from_usize(i))
// The fields of the untupled argument.
.chain((0..untuple_fields.len()).map(|i| {
self.fn_arg_project_field(untuple_arg, FieldIdx::from_usize(i))
}))
.collect::<InterpResult<'_, Vec<_>>>()?,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ impl<O: ForestObligation> ObligationForest<O> {
self.apply_rewrites(&node_rewrites);
}

node_rewrites.truncate(0);
node_rewrites.clear();
self.reused_node_vec = node_rewrites;
}

Expand Down
11 changes: 3 additions & 8 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1177,15 +1177,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let is_method = mode == Mode::MethodCall;
let item_kind = if is_method {
"method"
} else if rcvr_ty.is_enum() {
"variant or associated item"
} else if rcvr_ty.is_enum() || rcvr_ty.is_fresh_ty() {
"variant, associated function, or constant"
} else {
match (item_ident.as_str().chars().next(), rcvr_ty.is_fresh_ty()) {
(Some(name), false) if name.is_lowercase() => "function or associated item",
(Some(_), false) => "associated item",
(Some(_), true) | (None, false) => "variant or associated item",
(None, true) => "variant",
}
"associated function or constant"
};

if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var(
Expand Down
41 changes: 28 additions & 13 deletions compiler/rustc_incremental/src/persist/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,8 @@ pub enum LoadResult<T> {
impl<T: Default> LoadResult<T> {
/// Accesses the data returned in [`LoadResult::Ok`].
pub fn open(self, sess: &Session) -> T {
// Check for errors when using `-Zassert-incremental-state`
match (sess.opts.assert_incr_state, &self) {
(Some(IncrementalStateAssertion::NotLoaded), LoadResult::Ok { .. }) => {
sess.dcx().emit_fatal(errors::AssertNotLoaded);
}
(
Some(IncrementalStateAssertion::Loaded),
LoadResult::LoadDepGraph(..) | LoadResult::DataOutOfDate,
) => {
sess.dcx().emit_fatal(errors::AssertLoaded);
}
_ => {}
};
// Emit a fatal error if `-Zassert-incr-state` is present and unsatisfied.
maybe_assert_incr_state(sess, &self);

match self {
LoadResult::LoadDepGraph(path, err) => {
Expand Down Expand Up @@ -188,6 +177,32 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache> {
}
}

/// Emits a fatal error if the assertion in `-Zassert-incr-state` doesn't match
/// the outcome of trying to load previous-session state.
fn maybe_assert_incr_state(sess: &Session, load_result: &LoadResult<impl Sized>) {
// Return immediately if there's nothing to assert.
let Some(assertion) = sess.opts.unstable_opts.assert_incr_state else { return };

// Match exhaustively to make sure we don't miss any cases.
let loaded = match load_result {
LoadResult::Ok { .. } => true,
LoadResult::DataOutOfDate | LoadResult::LoadDepGraph(..) => false,
};

match assertion {
IncrementalStateAssertion::Loaded => {
if !loaded {
sess.dcx().emit_fatal(errors::AssertLoaded);
}
}
IncrementalStateAssertion::NotLoaded => {
if loaded {
sess.dcx().emit_fatal(errors::AssertNotLoaded)
}
}
}
}

/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
/// new graph to an incremental session directory.
pub fn setup_dep_graph(
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ use rustc_hir::attrs::{CollapseMacroDebuginfo, NativeLibKind};
use rustc_session::config::{
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CoverageLevel, CoverageOptions,
DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs,
FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay,
LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig,
Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes,
PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options,
rustc_optgroups,
FmtDebug, FunctionReturn, IncrementalStateAssertion, InliningThreshold, Input,
InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli,
MirIncludeSpans, NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes,
PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip,
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration,
build_session_options, rustc_optgroups,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
Expand Down Expand Up @@ -686,7 +686,7 @@ fn test_unstable_options_tracking_hash() {

// Make sure that changing an [UNTRACKED] option leaves the hash unchanged.
// tidy-alphabetical-start
untracked!(assert_incr_state, Some(String::from("loaded")));
untracked!(assert_incr_state, Some(IncrementalStateAssertion::Loaded));
untracked!(codegen_source_order, true);
untracked!(deduplicate_diagnostics, false);
untracked!(dump_dep_graph, true);
Expand Down
Loading
Loading