Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4ba73c3
test: add regression cases for valtree hashing ICE
Dushyanthyadav Dec 31, 2025
6453a17
add `vpdpbusd` avx512 intrinsic
folkertdev Dec 18, 2025
e4a8675
Merge pull request #4776 from folkertdev/vpdpbusd
RalfJung Jan 2, 2026
9f1066b
Basic support for FFI callbacks
weiznich Nov 27, 2025
c7f6d78
minor cleanup
RalfJung Jan 2, 2026
6feaf1d
Merge pull request #4728 from weiznich/ffi_callbacks
RalfJung Jan 2, 2026
1f32c2a
bump libffi
RalfJung Jan 2, 2026
604cf92
avoid aliasing trouble around libffi closures
RalfJung Jan 2, 2026
9a170fe
make specialization of Vec::extend and VecDeque::extend_front work fo…
antonilol Jan 2, 2026
4d2ce7d
use a single generic codepath for all return types
RalfJung Jan 2, 2026
e811227
Merge pull request #4798 from RalfJung/native-lib-uniform-ret
RalfJung Jan 2, 2026
296ab7c
android: get the entire test suite to pass
RalfJung Jan 2, 2026
2db68ef
Merge pull request #4799 from RalfJung/android
RalfJung Jan 2, 2026
9a675c0
alloc: Move Cow impl to existing ones
cvengler Jan 2, 2026
b80a3ea
Prepare for merging from rust-lang/rust
Jan 3, 2026
0b22248
Merge ref 'e8f3cfc0de70' from rust-lang/rust
Jan 3, 2026
efdd313
Merge pull request #4801 from rust-lang/rustup-2026-01-03
oli-obk Jan 3, 2026
aec6b9b
Refactor libc pipe tests to use utility functions for error handling …
hulxv Dec 17, 2025
b692fcb
minor tweaks
RalfJung Jan 3, 2026
cb36523
Merge pull request #4768 from hulxv/refactor/simplify-libc-tests/libc…
RalfJung Jan 3, 2026
de37724
Prefer to pass HIR nodes instead of loose types/spans
Zalathar Jan 4, 2026
9302232
Prepare for merging from rust-lang/rust
Jan 4, 2026
bd26cf7
Merge ref 'f57b9e6f565a' from rust-lang/rust
Jan 4, 2026
f65c581
Merge pull request #4802 from rust-lang/rustup-2026-01-04
RalfJung Jan 4, 2026
0557c75
add check_only feature for faster check builds
RalfJung Jan 4, 2026
dbf2ef7
Merge pull request #4803 from RalfJung/check_only
RalfJung Jan 4, 2026
ff2acf0
update lockfile
RalfJung Jan 4, 2026
2270553
Rollup merge of #150554 - Dushyanthyadav:ice-issue-150409-regression-…
matthiaskrgr Jan 4, 2026
9dd3b23
Rollup merge of #150597 - antonilol:extend-from-vec-any-allocator, r=…
matthiaskrgr Jan 4, 2026
18910b7
Rollup merge of #150619 - cvengler:move-cow-impl, r=Mark-Simulacrum
matthiaskrgr Jan 4, 2026
cdddb85
Rollup merge of #150660 - Zalathar:pass-nodes, r=davidtwco
matthiaskrgr Jan 4, 2026
eeb4431
Rollup merge of #150671 - RalfJung:miri, r=RalfJung
matthiaskrgr Jan 4, 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
19 changes: 9 additions & 10 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -445,22 +445,21 @@ dependencies = [

[[package]]
name = "capstone"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "015ef5d5ca1743e3f94af9509ba6bd2886523cfee46e48d15c2ef5216fd4ac9a"
checksum = "f442ae0f2f3f1b923334b4a5386c95c69c1cfa072bafa23d6fae6d9682eb1dd4"
dependencies = [
"capstone-sys",
"libc",
"static_assertions",
]

[[package]]
name = "capstone-sys"
version = "0.17.0"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2267cb8d16a1e4197863ec4284ffd1aec26fe7e57c58af46b02590a0235809a0"
checksum = "a4e8087cab6731295f5a2a2bd82989ba4f41d3a428aab2e7c98d8f4db38aac05"
dependencies = [
"cc",
"libc",
]

[[package]]
Expand Down Expand Up @@ -2232,19 +2231,19 @@ dependencies = [

[[package]]
name = "libffi"
version = "5.0.0"
version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0444124f3ffd67e1b0b0c661a7f81a278a135eb54aaad4078e79fbc8be50c8a5"
checksum = "0498fe5655f857803e156523e644dcdcdc3b3c7edda42ea2afdae2e09b2db87b"
dependencies = [
"libc",
"libffi-sys",
]

[[package]]
name = "libffi-sys"
version = "4.0.0"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d722da8817ea580d0669da6babe2262d7b86a1af1103da24102b8bb9c101ce7"
checksum = "71d4f1d4ce15091955144350b75db16a96d4a63728500122706fb4d29a26afbb"
dependencies = [
"cc",
]
Expand Down
91 changes: 62 additions & 29 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod check_match;
mod const_to_pat;
mod migration;

use std::assert_matches::assert_matches;
use std::cmp::Ordering;
use std::sync::Arc;

Expand All @@ -21,7 +22,7 @@ use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_span::{ErrorGuaranteed, Span};
use rustc_span::ErrorGuaranteed;
use tracing::{debug, instrument};

pub(crate) use self::check_match::check_match;
Expand Down Expand Up @@ -129,15 +130,20 @@ impl<'tcx> PatCtxt<'tcx> {

fn lower_pattern_range_endpoint(
&mut self,
pat: &'tcx hir::Pat<'tcx>, // Range pattern containing the endpoint
expr: Option<&'tcx hir::PatExpr<'tcx>>,
// Out-parameter collecting extra data to be reapplied by the caller
ascriptions: &mut Vec<Ascription<'tcx>>,
) -> Result<Option<PatRangeBoundary<'tcx>>, ErrorGuaranteed> {
assert_matches!(pat.kind, hir::PatKind::Range(..));

// For partly-bounded ranges like `X..` or `..X`, an endpoint will be absent.
// Return None in that case; the caller will use NegInfinity or PosInfinity instead.
let Some(expr) = expr else { return Ok(None) };

// Lower the endpoint into a temporary `PatKind` that will then be
// deconstructed to obtain the constant value and other data.
let mut kind: PatKind<'tcx> = self.lower_pat_expr(expr, None);
let mut kind: PatKind<'tcx> = self.lower_pat_expr(pat, expr);

// Unpeel any ascription or inline-const wrapper nodes.
loop {
Expand Down Expand Up @@ -214,20 +220,23 @@ impl<'tcx> PatCtxt<'tcx> {

fn lower_pattern_range(
&mut self,
pat: &'tcx hir::Pat<'tcx>,
lo_expr: Option<&'tcx hir::PatExpr<'tcx>>,
hi_expr: Option<&'tcx hir::PatExpr<'tcx>>,
end: RangeEnd,
ty: Ty<'tcx>,
span: Span,
) -> Result<PatKind<'tcx>, ErrorGuaranteed> {
let ty = self.typeck_results.node_type(pat.hir_id);
let span = pat.span;

if lo_expr.is_none() && hi_expr.is_none() {
let msg = "found twice-open range pattern (`..`) outside of error recovery";
self.tcx.dcx().span_bug(span, msg);
}

// Collect extra data while lowering the endpoints, to be reapplied later.
let mut ascriptions = vec![];
let mut lower_endpoint = |expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions);
let mut lower_endpoint =
|expr| self.lower_pattern_range_endpoint(pat, expr, &mut ascriptions);

let lo = lower_endpoint(lo_expr)?.unwrap_or(PatRangeBoundary::NegInfinity);
let hi = lower_endpoint(hi_expr)?.unwrap_or(PatRangeBoundary::PosInfinity);
Expand Down Expand Up @@ -299,12 +308,10 @@ impl<'tcx> PatCtxt<'tcx> {

hir::PatKind::Never => PatKind::Never,

hir::PatKind::Expr(value) => self.lower_pat_expr(value, Some(ty)),
hir::PatKind::Expr(value) => self.lower_pat_expr(pat, value),

hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => {
let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref());
self.lower_pattern_range(lo_expr, hi_expr, end, ty, span)
.unwrap_or_else(PatKind::Error)
hir::PatKind::Range(lo_expr, hi_expr, end) => {
self.lower_pattern_range(pat, lo_expr, hi_expr, end).unwrap_or_else(PatKind::Error)
}

hir::PatKind::Deref(subpattern) => {
Expand All @@ -327,7 +334,7 @@ impl<'tcx> PatCtxt<'tcx> {
},

hir::PatKind::Slice(prefix, slice, suffix) => {
self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix)
self.slice_or_array_pattern(pat, prefix, slice, suffix)
}

hir::PatKind::Tuple(pats, ddpos) => {
Expand Down Expand Up @@ -389,7 +396,7 @@ impl<'tcx> PatCtxt<'tcx> {
};
let variant_def = adt_def.variant_of_res(res);
let subpatterns = self.lower_tuple_subpats(pats, variant_def.fields.len(), ddpos);
self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns)
self.lower_variant_or_leaf(pat, None, res, subpatterns)
}

hir::PatKind::Struct(ref qpath, fields, _) => {
Expand All @@ -406,7 +413,7 @@ impl<'tcx> PatCtxt<'tcx> {
})
.collect();

self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns)
self.lower_variant_or_leaf(pat, None, res, subpatterns)
}

hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) },
Expand Down Expand Up @@ -445,12 +452,13 @@ impl<'tcx> PatCtxt<'tcx> {

fn slice_or_array_pattern(
&mut self,
span: Span,
ty: Ty<'tcx>,
pat: &'tcx hir::Pat<'tcx>,
prefix: &'tcx [hir::Pat<'tcx>],
slice: Option<&'tcx hir::Pat<'tcx>>,
suffix: &'tcx [hir::Pat<'tcx>],
) -> PatKind<'tcx> {
let ty = self.typeck_results.node_type(pat.hir_id);

let prefix = self.lower_patterns(prefix);
let slice = self.lower_opt_pattern(slice);
let suffix = self.lower_patterns(suffix);
Expand All @@ -465,18 +473,32 @@ impl<'tcx> PatCtxt<'tcx> {
assert!(len >= prefix.len() as u64 + suffix.len() as u64);
PatKind::Array { prefix, slice, suffix }
}
_ => span_bug!(span, "bad slice pattern type {:?}", ty),
_ => span_bug!(pat.span, "bad slice pattern type {ty:?}"),
}
}

fn lower_variant_or_leaf(
&mut self,
pat: &'tcx hir::Pat<'tcx>,
expr: Option<&'tcx hir::PatExpr<'tcx>>,
res: Res,
hir_id: hir::HirId,
span: Span,
ty: Ty<'tcx>,
subpatterns: Vec<FieldPat<'tcx>>,
) -> PatKind<'tcx> {
// Check whether the caller should have provided an `expr` for this pattern kind.
assert_matches!(
(pat.kind, expr),
(hir::PatKind::Expr(..) | hir::PatKind::Range(..), Some(_))
| (hir::PatKind::Struct(..) | hir::PatKind::TupleStruct(..), None)
);

// Use the id/span of the `hir::PatExpr`, if provided.
// Otherwise, use the id/span of the `hir::Pat`.
let (hir_id, span) = match expr {
Some(expr) => (expr.hir_id, expr.span),
None => (pat.hir_id, pat.span),
};
let ty = self.typeck_results.node_type(hir_id);

let res = match res {
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
let variant_id = self.tcx.parent(variant_ctor_id);
Expand Down Expand Up @@ -563,7 +585,16 @@ impl<'tcx> PatCtxt<'tcx> {
/// it to `const_to_pat`. Any other path (like enum variants without fields)
/// is converted to the corresponding pattern via `lower_variant_or_leaf`.
#[instrument(skip(self), level = "debug")]
fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) -> Box<Pat<'tcx>> {
fn lower_path(
&mut self,
pat: &'tcx hir::Pat<'tcx>, // Pattern that directly contains `expr`
expr: &'tcx hir::PatExpr<'tcx>,
qpath: &hir::QPath<'_>,
) -> Box<Pat<'tcx>> {
assert_matches!(pat.kind, hir::PatKind::Expr(..) | hir::PatKind::Range(..));

let id = expr.hir_id;
let span = expr.span;
let ty = self.typeck_results.node_type(id);
let res = self.typeck_results.qpath_res(qpath, id);

Expand All @@ -575,7 +606,7 @@ impl<'tcx> PatCtxt<'tcx> {
_ => {
// The path isn't the name of a constant, so it must actually
// be a unit struct or unit variant (e.g. `Option::None`).
let kind = self.lower_variant_or_leaf(res, id, span, ty, vec![]);
let kind = self.lower_variant_or_leaf(pat, Some(expr), res, vec![]);
return Box::new(Pat { span, ty, kind });
}
};
Expand Down Expand Up @@ -615,24 +646,26 @@ impl<'tcx> PatCtxt<'tcx> {
/// - Literals, possibly negated (e.g. `-128u8`, `"hello"`)
fn lower_pat_expr(
&mut self,
pat: &'tcx hir::Pat<'tcx>, // Pattern that directly contains `expr`
expr: &'tcx hir::PatExpr<'tcx>,
pat_ty: Option<Ty<'tcx>>,
) -> PatKind<'tcx> {
assert_matches!(pat.kind, hir::PatKind::Expr(..) | hir::PatKind::Range(..));
match &expr.kind {
hir::PatExprKind::Path(qpath) => self.lower_path(qpath, expr.hir_id, expr.span).kind,
hir::PatExprKind::Path(qpath) => self.lower_path(pat, expr, qpath).kind,
hir::PatExprKind::Lit { lit, negated } => {
// We handle byte string literal patterns by using the pattern's type instead of the
// literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference,
// the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the
// pattern's type means we'll properly translate it to a slice reference pattern. This works
// because slices and arrays have the same valtree representation.
let ct_ty = match pat_ty {
Some(pat_ty) => pat_ty,
None => self.typeck_results.node_type(expr.hir_id),
};
let lit_input = LitToConstInput { lit: lit.node, ty: ct_ty, neg: *negated };
//
// Under `feature(deref_patterns)`, this adjustment can also convert string literal
// patterns to `str`, and byte-string literal patterns to `[u8; N]` or `[u8]`.

let pat_ty = self.typeck_results.node_type(pat.hir_id);
let lit_input = LitToConstInput { lit: lit.node, ty: pat_ty, neg: *negated };
let constant = self.tcx.at(expr.span).lit_to_const(lit_input);
self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
self.const_to_pat(constant, pat_ty, expr.hir_id, lit.span).kind
}
}
}
Expand Down
26 changes: 13 additions & 13 deletions library/alloc/src/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,6 @@ use crate::fmt;
#[cfg(not(no_global_oom_handling))]
use crate::string::String;

// FIXME(inference): const bounds removed due to inference regressions found by crater;
// see https://github.com/rust-lang/rust/issues/147964
// #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized + ToOwned> Borrow<B> for Cow<'a, B>
// where
// B::Owned: [const] Borrow<B>,
{
fn borrow(&self) -> &B {
&**self
}
}

/// A generalization of `Clone` to borrowed data.
///
/// Some types make it possible to go from borrowed to owned, usually by
Expand Down Expand Up @@ -192,6 +179,19 @@ where
Owned(#[stable(feature = "rust1", since = "1.0.0")] <B as ToOwned>::Owned),
}

// FIXME(inference): const bounds removed due to inference regressions found by crater;
// see https://github.com/rust-lang/rust/issues/147964
// #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized + ToOwned> Borrow<B> for Cow<'a, B>
// where
// B::Owned: [const] Borrow<B>,
{
fn borrow(&self) -> &B {
&**self
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<B: ?Sized + ToOwned> Clone for Cow<'_, B> {
fn clone(&self) -> Self {
Expand Down
14 changes: 8 additions & 6 deletions library/alloc/src/collections/vec_deque/spec_extend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ where
}

#[cfg(not(test))]
impl<T, A: Allocator> SpecExtend<T, vec::IntoIter<T>> for VecDeque<T, A> {
fn spec_extend(&mut self, mut iterator: vec::IntoIter<T>) {
impl<T, A1: Allocator, A2: Allocator> SpecExtend<T, vec::IntoIter<T, A2>> for VecDeque<T, A1> {
fn spec_extend(&mut self, mut iterator: vec::IntoIter<T, A2>) {
let slice = iterator.as_slice();
self.reserve(slice.len());

Expand Down Expand Up @@ -153,9 +153,9 @@ where
}

#[cfg(not(test))]
impl<T, A: Allocator> SpecExtendFront<T, vec::IntoIter<T>> for VecDeque<T, A> {
impl<T, A1: Allocator, A2: Allocator> SpecExtendFront<T, vec::IntoIter<T, A2>> for VecDeque<T, A1> {
#[track_caller]
fn spec_extend_front(&mut self, mut iterator: vec::IntoIter<T>) {
fn spec_extend_front(&mut self, mut iterator: vec::IntoIter<T, A2>) {
let slice = iterator.as_slice();
self.reserve(slice.len());
// SAFETY: `slice.len()` space was just reserved and elements in the slice are forgotten after this call
Expand All @@ -165,9 +165,11 @@ impl<T, A: Allocator> SpecExtendFront<T, vec::IntoIter<T>> for VecDeque<T, A> {
}

#[cfg(not(test))]
impl<T, A: Allocator> SpecExtendFront<T, Rev<vec::IntoIter<T>>> for VecDeque<T, A> {
impl<T, A1: Allocator, A2: Allocator> SpecExtendFront<T, Rev<vec::IntoIter<T, A2>>>
for VecDeque<T, A1>
{
#[track_caller]
fn spec_extend_front(&mut self, iterator: Rev<vec::IntoIter<T>>) {
fn spec_extend_front(&mut self, iterator: Rev<vec::IntoIter<T, A2>>) {
let mut iterator = iterator.into_inner();
let slice = iterator.as_slice();
self.reserve(slice.len());
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/vec/spec_extend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ where
}
}

impl<T, A: Allocator> SpecExtend<T, IntoIter<T>> for Vec<T, A> {
fn spec_extend(&mut self, mut iterator: IntoIter<T>) {
impl<T, A1: Allocator, A2: Allocator> SpecExtend<T, IntoIter<T, A2>> for Vec<T, A1> {
fn spec_extend(&mut self, mut iterator: IntoIter<T, A2>) {
unsafe {
self.append_elements(iterator.as_slice() as _);
}
Expand Down
Loading
Loading