Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f3ed0a5
Ensure inferred let pattern types are well-formed
s7tya Jun 13, 2026
c1ee079
Normalize next-gen region constraints
Dnreikronos Jun 25, 2026
cece6fd
Add regression test for object candidates
Dnreikronos Jun 25, 2026
3ad430d
Preserve normalized solver region constraints
Dnreikronos Jul 21, 2026
6d216c7
Normalize eagerly handled region constraints
Dnreikronos Jul 21, 2026
9b4184b
Ignore query cycle test under parallel frontend
Dnreikronos Jul 26, 2026
26fba41
Fix inaccurate description for crate and pathroot
bb1yd Aug 4, 2026
47fb4b9
Do not eagerly download rustfmt when parsing the config
Kobzol Aug 6, 2026
83c82b5
Explictily pass rustfmt path to the `format` function
Kobzol Aug 6, 2026
5e42830
Simplify `maybe_download_rustfmt`
Kobzol Aug 6, 2026
0226819
MaybeDangling: ensure references fit inside the address space
RalfJung Aug 8, 2026
5395227
use recognizer functions for enums and tuple structs
Walnut356 Aug 9, 2026
57e48b0
Fix references to unsupported on sys::paths::unix
pheki Aug 10, 2026
86a16af
Clarify `InternalRustfmt` comment
Kobzol Aug 10, 2026
1bf4fba
Download stage 0 rustfmt after running `x setup`
Kobzol Aug 10, 2026
a923550
mir: prohibit projection into scalable vec
davidtwco Aug 6, 2026
f6d18c6
Use `remove_dir_all` for `./x clean`
ChrisDenton Aug 10, 2026
102e608
Rollup merge of #158404 - Dnreikronos:trait_solver/canonicalize_next_…
JonathanBrouwer Aug 10, 2026
8240909
Rollup merge of #160631 - Kobzol:bootstrap-rustfmt, r=jieyouxu
JonathanBrouwer Aug 10, 2026
e0b202e
Rollup merge of #160642 - davidtwco:sve-field-projection, r=folkertdev
JonathanBrouwer Aug 10, 2026
e888c61
Rollup merge of #160749 - RalfJung:maybe-dangling-address-space, r=Wa…
JonathanBrouwer Aug 10, 2026
7d5bd35
Rollup merge of #160791 - Walnut356:enum_recog, r=Kobzol
JonathanBrouwer Aug 10, 2026
1a36d49
Rollup merge of #157841 - Kivooeo:fix-let-pat-inferred-wf, r=lcnr
JonathanBrouwer Aug 10, 2026
4028468
Rollup merge of #160500 - bb1yd:same-message-for-crate-and-pathroot, …
JonathanBrouwer Aug 10, 2026
3366a3a
Rollup merge of #160825 - vita-rust:fix-references-unsupported-vita, …
JonathanBrouwer Aug 10, 2026
cd6c365
Rollup merge of #160852 - ChrisDenton:rmdirall, r=jieyouxu
JonathanBrouwer Aug 10, 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
48 changes: 34 additions & 14 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,25 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
None
}
} else {
// We are not checking dereferenceability, but we still want to ensure that the pointer
// *could* be dereferenceable in *some* memory: we have to be able to compute the
// address at the end of this range without overflowing..
let scalar = Scalar::from_maybe_pointer(place.ptr(), self.ecx);
// Skip this if we don't know the absolute address (during CTFE).
if let Ok(addr) = scalar.try_to_scalar_int() {
// Try to compute the end address.
let addr = Size::from_bytes(addr.to_target_usize(*self.ecx.tcx));
if addr.checked_add(size, self.ecx).is_none() {
throw_validation_failure!(
self.path,
format!(
"encountered a {ptr_kind} that is too close to the end of the address space for a pointee of {} bytes",
size.bytes(),
)
)
}
}

// Pointer remains unchanged.
None
};
Expand All @@ -658,20 +677,6 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
self.reset_pointer_provenance(value, &ptr)?;
}

// Check alignment after dereferenceable (if both are violated, trigger the error above).
try_validation!(
self.ecx.check_ptr_align(
place.ptr(),
align,
),
self.path,
Ub(AlignmentCheckFailed(Misalignment { required, has }, _msg)) => format!(
"encountered an unaligned {ptr_kind} (required {required_bytes} byte alignment but found {found_bytes})",
required_bytes = required.bytes(),
found_bytes = has.bytes()
),
);

// Make sure this is non-null. This is obviously needed when `may_dangle` is set,
// but even if we did check dereferenceability above that would still allow null
// pointers if `size` is zero.
Expand All @@ -686,6 +691,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
)
)
}

// Do not allow references to uninhabited types.
if !place.layout.ty.is_opsem_inhabited(*self.ecx.tcx, self.ecx.typing_env) {
let ty = place.layout.ty;
Expand All @@ -695,6 +701,20 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
)
}

// Check alignment after dereferenceable (if both are violated, trigger the error above).
try_validation!(
self.ecx.check_ptr_align(
place.ptr(),
align,
),
self.path,
Ub(AlignmentCheckFailed(Misalignment { required, has }, _msg)) => format!(
"encountered an unaligned {ptr_kind} (required {required_bytes} byte alignment but found {found_bytes})",
required_bytes = required.bytes(),
found_bytes = has.bytes()
),
);

// Recursive checking (but not inside `MaybeDangling` of course).
if let Some(ref_tracking) = self.ref_tracking.as_deref_mut()
&& !self.may_dangle
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Type check the pattern. Override if necessary to avoid knock-on errors.
self.check_pat_top(decl.pat, decl_ty, ty_span, origin_expr, Some(decl.origin));
let pat_ty = self.node_ty(decl.pat.hir_id);
if decl.ty.is_none()
&& decl.init.is_none()
&& !matches!(decl.pat.kind, hir::PatKind::Binding(.., None) | hir::PatKind::Wild)
{
self.register_wf_obligation(
decl_ty.into(),
decl.pat.span,
ObligationCauseCode::WellFormed(None),
);
}
self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, pat_ty);

if let Some(blk) = decl.origin.try_get_else() {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/infer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
use rustc_data_structures::undo_log::UndoLogs;

use crate::infer::UndoLog;
inner.undo_log.push(UndoLog::PushSolverRegionConstraint);
let previous_was_and = inner.solver_region_constraint_storage.is_and();
inner.undo_log.push(UndoLog::PushSolverRegionConstraint { previous_was_and });
inner.solver_region_constraint_storage.push(c);
}

Expand Down
32 changes: 18 additions & 14 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1895,12 +1895,21 @@ impl<'tcx> SolverRegionConstraintStorage<'tcx> {
self.0.clone()
}

fn pop(&mut self) -> Option<SolverRegionConstraint<'tcx>> {
fn is_and(&self) -> bool {
self.0.is_and()
}

fn pop(&mut self, previous_was_and: bool) -> Option<SolverRegionConstraint<'tcx>> {
match &mut self.0 {
SolverRegionConstraint::And(and) => {
let mut and = core::mem::take(and).into_iter().collect::<Vec<_>>();
let popped = and.pop()?;
self.0 = SolverRegionConstraint::And(and.into_boxed_slice());
if previous_was_and {
self.0 = SolverRegionConstraint::And(and.into_boxed_slice());
} else {
assert_eq!(and.len(), 1);
self.0 = and.pop().unwrap();
}
Some(popped)
}
_ => unreachable!(),
Expand All @@ -1909,26 +1918,21 @@ impl<'tcx> SolverRegionConstraintStorage<'tcx> {

#[instrument(level = "debug")]
fn push(&mut self, constraint: SolverRegionConstraint<'tcx>) {
match &mut self.0 {
match core::mem::replace(&mut self.0, SolverRegionConstraint::new_true()) {
SolverRegionConstraint::And(and) => {
let and = core::mem::take(and)
.into_iter()
.chain([constraint])
.collect::<Vec<_>>()
.into_boxed_slice();
let and =
and.into_iter().chain([constraint]).collect::<Vec<_>>().into_boxed_slice();
self.0 = SolverRegionConstraint::And(and);
}
_ => unreachable!(),
previous => {
self.0 = SolverRegionConstraint::And(Box::new([previous, constraint]));
}
}
}

#[instrument(level = "debug", skip(self))]
fn overwrite_solver_region_constraint(&mut self, constraint: SolverRegionConstraint<'tcx>) {
if !constraint.is_and() {
self.0 = SolverRegionConstraint::And(vec![constraint].into_boxed_slice())
} else {
self.0 = constraint;
}
self.0 = constraint;
}
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_infer/src/infer/snapshot/undo_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub(crate) enum UndoLog<'tcx> {
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
ProjectionCache(traits::UndoLog<'tcx>),
PushTypeOutlivesConstraint,
PushSolverRegionConstraint,
PushSolverRegionConstraint { previous_was_and: bool },
OverwriteSolverRegionConstraint { old_constraint: SolverRegionConstraint<'tcx> },
PushRegionAssumption,
PushHirTypeckPotentiallyRegionDependentGoal,
Expand Down Expand Up @@ -79,8 +79,8 @@ impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
self.region_constraint_storage.as_mut().unwrap().unification_table.reverse(undo)
}
UndoLog::ProjectionCache(undo) => self.projection_cache.reverse(undo),
UndoLog::PushSolverRegionConstraint => {
let popped = self.solver_region_constraint_storage.pop();
UndoLog::PushSolverRegionConstraint { previous_was_and } => {
let popped = self.solver_region_constraint_storage.pop(previous_was_and);
assert_matches!(
popped,
Some(_),
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir_transform/src/sroa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ fn escaping_locals<'tcx>(
return true;
}
if let ty::Adt(def, _args) = ty.kind()
&& (def.repr().simd() || tcx.is_lang_item(def.did(), LangItem::DynMetadata))
&& (def.repr().simd()
|| def.repr().scalable()
|| tcx.is_lang_item(def.did(), LangItem::DynMetadata))
{
// Exclude #[repr(simd)] types so that they are not de-optimized into an array
// (MCP#838 banned projections into SIMD types, but if the value is unused
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
);
}

if adt_def.repr().simd() {
if adt_def.repr().simd() || adt_def.repr().scalable() {
self.fail(
location,
format!(
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::ops::ControlFlow;
use rustc_macros::StableHash;
use rustc_type_ir::data_structures::HashSet;
use rustc_type_ir::inherent::*;
use rustc_type_ir::region_constraint::RegionConstraint;
use rustc_type_ir::region_constraint::{RegionConstraint, evaluate_solver_constraint};
use rustc_type_ir::relate::Relate;
use rustc_type_ir::relate::solver_relating::RelateExt;
use rustc_type_ir::search_graph::{CandidateHeadUsages, LowerAvailableDepth, PathKind};
Expand Down Expand Up @@ -1656,7 +1656,12 @@ where
// `tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.rs`.
let region_constraints = if self.cx().assumptions_on_binders() {
ExternalRegionConstraints::NextGen(if let Certainty::Yes = certainty {
self.delegate.get_solver_region_constraint()
let constraint = self.delegate.get_solver_region_constraint();
debug_assert_eq!(
constraint,
evaluate_solver_constraint(&constraint.clone().canonical_form())
);
constraint
} else {
RegionConstraint::new_true()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rustc_type_ir::outlives::{Component, push_outlives_components};
use rustc_type_ir::region_constraint::TransitiveRelationBuilder;
use rustc_type_ir::region_constraint::{
Assumptions, RegionConstraint, eagerly_handle_placeholders_in_universe,
evaluate_solver_constraint,
};
use rustc_type_ir::{
AliasTy, Binder, ClauseKind, InferCtxtLike, Interner, OutlivesClause, Region, TypeVisitable,
Expand Down Expand Up @@ -136,6 +137,7 @@ where
.fold(constraint, |constraint, u| {
eagerly_handle_placeholders_in_universe(&**self.delegate, constraint, u)
});
let constraint = evaluate_solver_constraint(&constraint.canonical_form());

self.delegate.overwrite_solver_region_constraint(constraint.clone());

Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_resolve/src/diagnostics/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2973,7 +2973,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
};
let scope = match &path[..failed_segment_idx] {
[.., prev] => {
if prev.ident.name == kw::PathRoot {
if prev.ident.name == kw::PathRoot && self.tcx.sess.edition() > Edition::Edition2015
{
format!("the list of imported crates")
} else if prev.ident.name == kw::PathRoot || prev.ident.name == kw::Crate {
format!("the crate root")
} else {
format!("`{}`", prev.ident)
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_type_ir/src/region_constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,11 @@ impl<I: Interner> RegionConstraint<I> {
[or1, rest_ors @ ..] => {
let mut choices = vec![];
for choice in or1 {
choices.extend(permutations(rest_ors).into_iter().map(|mut and| {
and.push(choice.clone());
and
}));
choices.extend(
permutations(rest_ors)
.into_iter()
.map(|and| std::iter::once(choice.clone()).chain(and).collect()),
);
}
choices
}
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/paths/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub fn getcwd() -> io::Result<PathBuf> {

#[cfg(target_os = "espidf")]
pub fn chdir(_p: &path::Path) -> io::Result<()> {
crate::sys::pal::unsupported::unsupported()
crate::sys::pal::unsupported()
}

#[cfg(not(target_os = "espidf"))]
Expand Down Expand Up @@ -385,7 +385,7 @@ pub fn current_exe() -> io::Result<PathBuf> {

#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
pub fn current_exe() -> io::Result<PathBuf> {
crate::sys::pal::unsupported::unsupported()
crate::sys::pal::unsupported()
}

#[cfg(target_os = "fuchsia")]
Expand Down
8 changes: 4 additions & 4 deletions library/stdarch/crates/core_arch/src/aarch64/sve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl<T> SveInto<T> for T {
macro_rules! impl_sve_type {
($(($v:vis, $elem_type:ty, $name:ident, $elt:literal))*) => ($(
#[doc = concat!("Scalable vector of type ", stringify!($elem_type))]
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy)]
#[rustc_scalable_vector($elt)]
#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
$v struct $name($elem_type);
Expand All @@ -52,21 +52,21 @@ macro_rules! impl_sve_tuple_type {
)*);
(@ ($v:vis, $vec_type:ty, 2, $name:ident)) => (
#[doc = concat!("Two-element tuple of scalable vectors of type ", stringify!($vec_type))]
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy)]
#[rustc_scalable_vector]
#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
$v struct $name($vec_type, $vec_type);
);
(@ ($v:vis, $vec_type:ty, 3, $name:ident)) => (
#[doc = concat!("Three-element tuple of scalable vectors of type ", stringify!($vec_type))]
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy)]
#[rustc_scalable_vector]
#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
$v struct $name($vec_type, $vec_type, $vec_type);
);
(@ ($v:vis, $vec_type:ty, 4, $name:ident)) => (
#[doc = concat!("Four-element tuple of scalable vectors of type ", stringify!($vec_type))]
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy)]
#[rustc_scalable_vector]
#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
$v struct $name($vec_type, $vec_type, $vec_type, $vec_type);
Expand Down
12 changes: 11 additions & 1 deletion src/bootstrap/src/core/build_steps/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,16 @@ fn clean_default(build: &Build) {
}

fn rm_rf(path: &Path) {
match fs::remove_dir_all(path) {
Ok(()) => return,
// Already deleted, nothing for us to do.
Err(e) if e.kind() == ErrorKind::NotFound => return,
_ => {}
}

// If remove_dir_all fails then retry.
// We do so manually so we can provide better diagnostics,
// e.g. pointing to the exact file that failed.
match path.symlink_metadata() {
Err(e) => {
if e.kind() == ErrorKind::NotFound {
Expand Down Expand Up @@ -235,7 +245,7 @@ where
t!(fs::set_permissions(path, p));
f(path).unwrap_or_else(|e| {
// Delete symlinked directories on Windows
if m.file_type().is_symlink() && path.is_dir() && fs::remove_dir(path).is_ok() {
if fs::remove_dir(path).is_ok() {
return;
}
panic!("failed to {} {}: {}", desc, path.display(), e);
Expand Down
Loading
Loading