Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d48bdef
implement `Add` and `Sub` for `Complex`
folkertdev Aug 17, 2026
dd4b00d
make target feature ABI check a hard error on ARM
RalfJung Aug 18, 2026
8c4486b
fix[154166]: closure debug capture print
joseph-isaacs Sep 1, 2026
e7e2b01
fix supposedly unreachable `bug!` being reachable
khyperia Sep 2, 2026
aea4dd4
remove outdated next-solver FIXMEs
lcnr Sep 2, 2026
07c0090
core: mark float `ClampBounds` methods as `#[inline]`
ojeda Sep 2, 2026
75ff1f5
docs(time): clarify exact seconds for week and day
sorairolake Sep 2, 2026
cf0c54c
docs(time): clarify exact seconds for hour and minute
sorairolake Sep 2, 2026
9c3dad9
Decide the effective DefId in `extract_hir_info` without recursion
Zalathar Sep 3, 2026
2a3529c
Use let-chains to simplify a deep HIR pattern
Zalathar Sep 3, 2026
68fcd1b
Bless bootstrap tests
Kobzol Jul 30, 2026
d44c98f
Generalize `MirOptPanicAbortSyntheticTarget` to `SyntheticTargetWithP…
Kobzol Aug 7, 2026
fccffee
Create targets for `mir-opt` tests explicitly and use the minimal set…
Kobzol Aug 7, 2026
d07e492
Fix host normalization
Kobzol Aug 7, 2026
00f0834
Bless at most four individual targets
Kobzol Aug 7, 2026
506a085
Do not call `configure_linker` for synthetic targets
Kobzol Aug 10, 2026
99158cd
Add `needs-deterministic-layouts` flag
Kobzol Aug 20, 2026
98f5ad8
Add comments
Kobzol Sep 1, 2026
a983fe5
Bless test
Kobzol Sep 1, 2026
3ba9f00
Do not normalize host in mir-opt bootstrap test to fix it on i686-pc-…
Kobzol Sep 3, 2026
c5c326b
Pass -Z merge-functions=disabled in tests/codegen-llvm/intrinsics/unc…
zmodem Sep 3, 2026
1e10424
Windows: add fallback if canonicalize fails
ChrisDenton Aug 28, 2026
29776c0
Fix tidy directive in windows bindings
ChrisDenton Aug 28, 2026
73c958b
Rollup merge of #160200 - Kobzol:mir-opt-panic-abort-on-ci, r=jieyouxu
JonathanBrouwer Sep 3, 2026
3189e8c
Rollup merge of #161227 - folkertdev:complex-add-sub, r=nia-e
JonathanBrouwer Sep 3, 2026
5574e51
Rollup merge of #161280 - RalfJung:abi-required-target-feature-arm, r…
JonathanBrouwer Sep 3, 2026
33bbf29
Rollup merge of #162154 - joseph-isaacs:ji/issue-154166-mir-closure-d…
JonathanBrouwer Sep 3, 2026
67b0acd
Rollup merge of #161951 - ChrisDenton:canonicalize-boogaloo, r=clarfo…
JonathanBrouwer Sep 3, 2026
dd92494
Rollup merge of #162173 - khyperia:fix-unreachable, r=BoxyUwU
JonathanBrouwer Sep 3, 2026
9768aee
Rollup merge of #162180 - lcnr:next-solver-fixmes, r=adwinwhite
JonathanBrouwer Sep 3, 2026
ede349f
Rollup merge of #162191 - ojeda:clamp-inline, r=clarfonthey
JonathanBrouwer Sep 3, 2026
b73ed19
Rollup merge of #162195 - sorairolake:clarify-week-day-seconds, r=jhp…
JonathanBrouwer Sep 3, 2026
abf7f19
Rollup merge of #162199 - sorairolake:clarify-hour-minute-seconds, r=…
JonathanBrouwer Sep 3, 2026
95c07e4
Rollup merge of #162222 - Zalathar:extract-hir-info, r=nnethercote
JonathanBrouwer Sep 3, 2026
3a58739
Rollup merge of #162230 - zmodem:unchecked_math, r=nikic
JonathanBrouwer Sep 3, 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
22 changes: 0 additions & 22 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2184,28 +2184,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
}

// See <https://github.com/rust-lang/trait-system-refactor-initiative/issues/134>.
//
// In the new solver, check the well-formedness of the return type.
// This emulates, in a way, the predicates that fall out of
// normalizing the return type in the old solver.
//
// FIXME(-Znext-solver): We alternatively could check the predicates of
// the method itself hold, but we intentionally do not do this in the old
// solver b/c of cycles, and doing it in the new solver would be stronger.
// This should be fixed in the future, since it likely leads to much better
// method winnowing.
if let Some(xform_ret_ty) = xform_ret_ty
&& self.infcx.next_trait_solver()
{
ocx.register_obligation(traits::Obligation::new(
self.tcx,
cause.clone(),
self.param_env,
ty::ClauseKind::WellFormed(xform_ret_ty.into()),
));
}

// Evaluate those obligations to see if they might possibly hold.
for error in ocx.try_evaluate_obligations() {
result = ProbeResult::NoMatch;
Expand Down
11 changes: 7 additions & 4 deletions compiler/rustc_interface/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,16 @@ pub(crate) struct MultipleOutputTypesToStdout;
#[diag(
"target feature `{$feature}` must be {$enabled} to ensure that the ABI of the current target can be implemented correctly"
)]
#[note(
"this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
)]
#[note("for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>")]
pub(crate) struct AbiRequiredTargetFeature<'a> {
pub feature: &'a str,
pub enabled: &'a str,
#[note(
"this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
)]
#[note(
"for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>"
)]
pub fcw: bool,
}

#[derive(Diagnostic)]
Expand Down
30 changes: 25 additions & 5 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use rustc_span::edition::Edition;
use rustc_span::source_map::SourceMapInputs;
use rustc_span::{SessionGlobals, Symbol, sym};
use rustc_structures::CrateType;
use rustc_target::spec::Target;
use rustc_target::spec::{Arch, Target};
use tracing::info;

use crate::diagnostics;
Expand Down Expand Up @@ -102,16 +102,36 @@ pub(crate) fn check_abi_required_features(sess: &Session) {
);
}

// Make this a hard error on ARM since starting with LLVM24, the backend will otherwise
// emit a (less friendly) hard error.
let hard_error = matches!(sess.target.arch, Arch::Arm);

for feature in abi_feature_constraints.required {
if !sess.internal_target_features.contains(&Symbol::intern(feature)) {
sess.dcx()
.emit_warn(diagnostics::AbiRequiredTargetFeature { feature, enabled: "enabled" });
let diag = diagnostics::AbiRequiredTargetFeature {
feature,
enabled: "enabled",
fcw: !hard_error,
};
if hard_error {
sess.dcx().emit_err(diag);
} else {
sess.dcx().emit_warn(diag);
}
}
}
for feature in abi_feature_constraints.incompatible {
if sess.internal_target_features.contains(&Symbol::intern(feature)) {
sess.dcx()
.emit_warn(diagnostics::AbiRequiredTargetFeature { feature, enabled: "disabled" });
let diag = diagnostics::AbiRequiredTargetFeature {
feature,
enabled: "disabled",
fcw: !hard_error,
};
if hard_error {
sess.dcx().emit_err(diag);
} else {
sess.dcx().emit_warn(diag);
}
}
}
}
Expand Down
24 changes: 10 additions & 14 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1256,13 +1256,11 @@ impl<'tcx> Debug for Rvalue<'tcx> {
};
let mut struct_fmt = fmt.debug_struct(&name);

// FIXME(project-rfc-2229#48): This should be a list of capture names/places
if let Some(def_id) = def_id.as_local()
&& let Some(upvars) = tcx.upvars_mentioned(def_id)
{
for (&var_id, place) in iter::zip(upvars.keys(), places) {
let var_name = tcx.hir_name(var_id);
struct_fmt.field(var_name.as_str(), place);
if let Some(def_id) = def_id.as_local() {
let captures = tcx.closure_captures(def_id);
assert_eq!(captures.len(), places.len());
for (&capture, place) in iter::zip(captures, places) {
struct_fmt.field(capture.to_symbol().as_str(), place);
}
} else {
for (index, place) in places.iter().enumerate() {
Expand All @@ -1277,13 +1275,11 @@ impl<'tcx> Debug for Rvalue<'tcx> {
let name = format!("{{coroutine@{:?}}}", tcx.def_span(def_id));
let mut struct_fmt = fmt.debug_struct(&name);

// FIXME(project-rfc-2229#48): This should be a list of capture names/places
if let Some(def_id) = def_id.as_local()
&& let Some(upvars) = tcx.upvars_mentioned(def_id)
{
for (&var_id, place) in iter::zip(upvars.keys(), places) {
let var_name = tcx.hir_name(var_id);
struct_fmt.field(var_name.as_str(), place);
if let Some(def_id) = def_id.as_local() {
let captures = tcx.closure_captures(def_id);
assert_eq!(captures.len(), places.len());
for (&capture, place) in iter::zip(captures, places) {
struct_fmt.field(capture.to_symbol().as_str(), place);
}
} else {
for (index, place) in places.iter().enumerate() {
Expand Down
41 changes: 23 additions & 18 deletions compiler/rustc_mir_transform/src/coverage/hir_info.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_hir as hir;
use rustc_hir::intravisit::{Visitor, walk_expr};
use rustc_middle::hir::nested_filter;
use rustc_middle::mir;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::Span;
use rustc_span::def_id::LocalDefId;
Expand All @@ -20,21 +21,24 @@ pub(crate) struct ExtractedHirInfo {
pub(crate) hole_spans: Vec<Span>,
}

pub(crate) fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHirInfo {
// FIXME(#79625): Consider improving MIR to provide the information needed, to avoid going back
// to HIR for it.

// Synthetic by-move coroutine bodies don't have useful HIR of their own.
// Use the original coroutine body instead. These synthetic bodies are
// created with a coroutine type, so we can inspect that type as-is.
if tcx.is_synthetic_mir(def_id) {
let effective_def_id =
pub(crate) fn extract_hir_info<'tcx>(
tcx: TyCtxt<'tcx>,
mir_body: &mir::Body<'tcx>,
) -> ExtractedHirInfo {
let def_id: LocalDefId = {
let mut def_id = mir_body.source.def_id().expect_local();

// Synthetic by-move coroutine bodies don't have useful HIR of their own.
// Use the original coroutine body instead. These synthetic bodies are
// created with a coroutine type, so we can inspect that type as-is.
if tcx.is_synthetic_mir(def_id) {
match *tcx.type_of(def_id).instantiate_identity().skip_normalization().kind() {
ty::Coroutine(coroutine_def_id, _) => coroutine_def_id.expect_local(),
_ => tcx.local_parent(def_id),
};
return extract_hir_info(tcx, effective_def_id);
}
ty::Coroutine(coroutine_def_id, _) => def_id = coroutine_def_id.expect_local(),
_ => def_id = tcx.local_parent(def_id),
}
}
def_id
};

let hir_node = tcx.hir_node_by_def_id(def_id);
let fn_body_id = hir_node.body_id().expect("HIR node is a function with body");
Expand All @@ -45,14 +49,15 @@ pub(crate) fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> E

let mut body_span = hir_body.value.span;

use hir::{Closure, Expr, ExprKind, Node};
// Unexpand a closure's body span back to the context of its declaration.
// This helps with closure bodies that consist of just a single bang-macro,
// and also with closure bodies produced by async desugaring.
if let Node::Expr(&Expr { kind: ExprKind::Closure(&Closure { fn_decl_span, .. }), .. }) =
hir_node
if let hir::Node::Expr(expr) = hir_node
&& let hir::ExprKind::Closure(closure) = expr.kind
&& let Some(effective_body_span) =
body_span.find_ancestor_in_same_ctxt(closure.fn_decl_span)
{
body_span = body_span.find_ancestor_in_same_ctxt(fn_decl_span).unwrap_or(body_span);
body_span = effective_body_span;
}

// The actual signature span is only used if it has the same context and
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir_transform/src/coverage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ impl<'tcx> crate::MirPass<'tcx> for InstrumentCoverage {
}

fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) {
let def_id = mir_body.source.def_id();
let _span = debug_span!("instrument_function_for_coverage", ?def_id).entered();
let _span = debug_span!("instrument_function_for_coverage", def_id = ?mir_body.source.def_id())
.entered();

let hir_info = hir_info::extract_hir_info(tcx, def_id.expect_local());
let hir_info = hir_info::extract_hir_info(tcx, mir_body);

// Build the coverage graph, which is a simplified view of the MIR control-flow
// graph that ignores some details not relevant to coverage instrumentation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ use crate::error_reporting::traits::ambiguity::{
use crate::infer;
use crate::infer::relate::{self, RelateResult, TypeRelation};
use crate::infer::{InferCtxt, InferCtxtExt as _, TypeTrace, ValuePairs};
use crate::solve::deeply_normalize_for_diagnostics;
use crate::traits::{
MatchExpressionArmCause, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt,
specialization_graph,
Expand Down Expand Up @@ -1577,10 +1576,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let (expected_found, exp_found, is_simple_error, values, param_env) = match values {
None => (None, Mismatch::Fixed("type"), false, None, None),
Some(ty::ParamEnvAnd { param_env, value: values }) => {
let mut values = self.resolve_vars_if_possible(values);
if self.next_trait_solver() {
values = deeply_normalize_for_diagnostics(self, param_env, values);
}
let values = self.resolve_vars_if_possible(values);
let (is_simple_error, exp_found) = match values {
ValuePairs::Terms(ExpectedFound { expected, found }) => {
match (expected.kind(), found.kind()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1669,8 +1669,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
bound_predicate.rebind(data),
);
let unnormalized_term = data.projection_term.to_term(self.tcx, ty::IsRigid::No);
// FIXME(-Znext-solver): For diagnostic purposes, it would be nice
// to deeply normalize this type.
let normalized_term = ocx.normalize(
&obligation.cause,
obligation.param_env,
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,16 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// (*) The predicates of an inherent associated type include the
// predicates of the impl that it's contained in.

if !data.self_ty().has_escaping_bound_vars() {
// In an ideal world, there are no escaping bound vars here. However, WF is jank, and
// sometimes there are. We can only `compute_inherent_assoc_term_args` if the Self ty in the
// args has no escaping bound vars. If we already have impl format args, though,
// `compute_inherent_assoc_term_args` is a no-op (and we have no Self type), so no need to
// check for escaping bound vars.
let can_compute_impl_args =
matches!(data.kind, ty::AliasTermKind::InherentConstImpl { .. })
|| !data.self_ty().has_escaping_bound_vars();

if can_compute_impl_args {
// FIXME(inherent_associated_types): Should this happen inside of a snapshot?
// FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm!
let args = traits::project::compute_inherent_assoc_term_args(
Expand Down Expand Up @@ -1099,10 +1108,12 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
self.add_wf_preds_for_inherent_projection(alias_const.into());
return; // Subtree is handled by above function
}
// please ping khyperia and/or BoxyUwU if this `bug!` fires
ty::AliasConstKind::InherentImpl { .. } => bug!(
"This ought to be unreachable, the entrypoints of WF should still have InherentSelf-form alias consts."
),
// FIXME: This should be unreachable but isn't because we normalize in item
// wfck before computing wf requirements
ty::AliasConstKind::InherentImpl { .. } => {
self.add_wf_preds_for_inherent_projection(alias_const.into());
return;
}
ty::AliasConstKind::Projection { def_id }
| ty::AliasConstKind::Free { def_id }
| ty::AliasConstKind::Anon { def_id } => {
Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_type_ir/src/term_kind.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::debug_assert_matches;

use derive_where::derive_where;
#[cfg(feature = "nightly")]
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
Expand Down Expand Up @@ -265,11 +267,25 @@ impl<I: Interner> AliasTerm<I> {
/// The following methods work only with (trait) associated term projections.
// FIXME: Replace by an impl on Alias<ProjectionAliasTermKind>
impl<I: Interner> AliasTerm<I> {
fn debug_assert_has_self(self) {
// InherentConstImpl is deliberately omitted here, it is not self-format args
debug_assert_matches!(
self.kind,
AliasTermKind::ProjectionTy { .. }
| AliasTermKind::ProjectionConst { .. }
| AliasTermKind::InherentTy { .. }
| AliasTermKind::InherentConstSelf { .. },
"AliasTerm::self_ty is only valid on projection and inherent aliases"
);
}

pub fn self_ty(self) -> I::Ty {
self.debug_assert_has_self();
self.args.type_at(0)
}

pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
self.debug_assert_has_self();
AliasTerm::new(
interner,
self.kind,
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/cmp/clamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ macro impl_for_float($t:ty) {
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl ClampBounds<$t> for RangeFrom<$t> {
#[inline]
fn clamp(self, value: $t) -> $t {
assert!(!self.start.is_nan(), "start was NaN");
value.max(self.start)
Expand All @@ -75,6 +76,7 @@ macro impl_for_float($t:ty) {
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl ClampBounds<$t> for RangeToInclusive<$t> {
#[inline]
fn clamp(self, value: $t) -> $t {
assert!(!self.end.is_nan(), "end was NaN");
value.min(self.end)
Expand All @@ -88,6 +90,7 @@ macro impl_for_float($t:ty) {
clippy::neg_cmp_op_on_partial_ord,
reason = "NaN check is intentionally included in comparison"
)]
#[inline]
fn clamp(self, value: $t) -> $t {
let (start, end) = self.into_inner();
assert!(start <= end, "start > end, or either was NaN");
Expand Down
40 changes: 39 additions & 1 deletion library/core/src/num/complex.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::ops::{Add, Sub};

/// A complex number.
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[unstable(feature = "complex_numbers", issue = "154023")]
#[repr(C)]
#[lang = "complex"]
Expand All @@ -18,3 +20,39 @@ impl<T> Complex<T> {
Complex { re, im }
}
}

#[unstable(feature = "complex_numbers", issue = "154023")]
impl<T: Add> Add<Self> for Complex<T> {
type Output = Complex<T::Output>;

fn add(self, rhs: Self) -> Self::Output {
Complex::new(self.re + rhs.re, self.im + rhs.im)
}
}

#[unstable(feature = "complex_numbers", issue = "154023")]
impl<T: Add<Output = T>> Add<T> for Complex<T> {
type Output = Complex<T::Output>;

fn add(self, rhs: T) -> Self::Output {
Complex::new(self.re + rhs, self.im)
}
}

#[unstable(feature = "complex_numbers", issue = "154023")]
impl<T: Sub> Sub<Self> for Complex<T> {
type Output = Complex<T::Output>;

fn sub(self, rhs: Self) -> Self::Output {
Complex::new(self.re - rhs.re, self.im - rhs.im)
}
}

#[unstable(feature = "complex_numbers", issue = "154023")]
impl<T: Sub<Output = T>> Sub<T> for Complex<T> {
type Output = Complex<T::Output>;

fn sub(self, rhs: T) -> Self::Output {
Complex::new(self.re - rhs, self.im)
}
}
Loading
Loading