Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b727274
make debug builders with closures impl with cell
connortsui20 Jul 14, 2026
9c81f66
point at method call chain when a return-position `impl Trait` assoc …
Albab-Hasan Jul 16, 2026
e215910
Update global_asm tests for LLVM 23
nikic Jul 13, 2026
d4a24cd
Adjust codegen test for LLVM 23
nikic Jul 13, 2026
283a60b
Update simd mask test for LLVM 23
nikic Jul 13, 2026
61d9ba2
Disable slice is_ascii() test on LLVM 23
nikic Jul 13, 2026
df6afdf
Adjust PGO tests for LLVM 23
nikic Jul 14, 2026
810a7aa
tests: gate `tests/deubinfo/function-call.rs` on min GDB 15.1
jieyouxu Jul 16, 2026
05bebcd
Update books
rustbot Jul 16, 2026
cbd88d9
Fix safety doc in intrinsics::simd
yilin0518 Jul 16, 2026
14713e5
[aarch64][win] Pass oversized c-variadic args indirectly on Arm64EC
dpaoliello Jul 16, 2026
5245634
add a fallback for `fmuladdf*`
folkertdev Jul 16, 2026
71321f5
Manually implement Clone for GrowableBitSet
DaniPopes Jul 16, 2026
403637b
rustdoc: remove old `--emit` types
notriddle Jul 16, 2026
b223838
Rollup merge of #159365 - Albab-Hasan:point-at-chain-in-return-positi…
JonathanBrouwer Jul 17, 2026
c2c019c
Rollup merge of #159402 - yilin0518:fix_simd_2, r=programmerjake
JonathanBrouwer Jul 17, 2026
a30da7d
Rollup merge of #159410 - notriddle:remove-deprecated-emit-types, r=G…
JonathanBrouwer Jul 17, 2026
7677a7c
Rollup merge of #159302 - connortsui20:dyn-debug-helpers, r=hanna-kruppe
JonathanBrouwer Jul 17, 2026
831deeb
Rollup merge of #159386 - folkertdev:fmuladd-fallback, r=RalfJung
JonathanBrouwer Jul 17, 2026
a0fa253
Rollup merge of #159391 - nikic:llvm23-test-updates, r=cuviper
JonathanBrouwer Jul 17, 2026
81d29e7
Rollup merge of #159400 - rustbot:docs-update, r=ehuss
JonathanBrouwer Jul 17, 2026
b56fc8b
Rollup merge of #159401 - jieyouxu:jieyouxu/test/function-call, r=wor…
JonathanBrouwer Jul 17, 2026
875a482
Rollup merge of #159404 - dpaoliello:varargarm64ec, r=folkertdev
JonathanBrouwer Jul 17, 2026
8d649f9
Rollup merge of #159405 - DaniPopes:bitset-clone-from, r=workingjubilee
JonathanBrouwer Jul 17, 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
13 changes: 12 additions & 1 deletion compiler/rustc_index/src/bit_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1287,11 +1287,22 @@ impl<'a, T: Idx> Iterator for MixedBitIter<'a, T> {
///
/// All operations that involve an element will panic if the element is equal
/// to or greater than the domain size.
#[derive(Clone, Debug, PartialEq)]
#[derive(Debug, PartialEq)]
pub struct GrowableBitSet<T: Idx> {
bit_set: DenseBitSet<T>,
}

// Manually implemented to forward `clone_from`, and to avoid the `T: Clone` bound.
impl<T: Idx> Clone for GrowableBitSet<T> {
fn clone(&self) -> Self {
Self { bit_set: self.bit_set.clone() }
}

fn clone_from(&mut self, source: &Self) {
self.bit_set.clone_from(&source.bit_set);
}
}

impl<T: Idx> Default for GrowableBitSet<T> {
fn default() -> Self {
GrowableBitSet::new_empty()
Expand Down
20 changes: 18 additions & 2 deletions compiler/rustc_target/src/callconv/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::iter;
use rustc_abi::{BackendRepr, HasDataLayout, Primitive, TyAbiInterface};

use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
use crate::spec::{HasTargetSpec, RustcAbi, Target};
use crate::spec::{Arch, HasTargetSpec, RustcAbi, Target};

/// Indicates the variant of the AArch64 ABI we are compiling for.
/// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI.
Expand Down Expand Up @@ -166,10 +166,26 @@ where
classify_ret(cx, &mut fn_abi.ret, kind);
}

for arg in fn_abi.args.iter_mut() {
// On Arm64EC the variadic portion of a c-variadic call follows the MS x64 ABI:
// "Any argument that doesn't fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must
// be passed by reference".
let c_variadic = fn_abi.c_variadic;
let fixed_count = fn_abi.fixed_count as usize;
let is_arm64ec = cx.target_spec().arch == Arch::Arm64EC;

for (idx, arg) in fn_abi.args.iter_mut().enumerate() {
if arg.is_ignore() {
continue;
}

if is_arm64ec && c_variadic && idx >= fixed_count {
let size = arg.layout.size.bytes();
if size > 8 || !size.is_power_of_two() {
arg.make_indirect();
continue;
}
}

classify_arg(cx, arg, kind);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4487,6 +4487,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
tcx.disabled_nightly_features(err, [(String::new(), sym::trivial_bounds)]);
}
ObligationCauseCode::OpaqueReturnType(expr_info) => {
// Point at the method call in the returned expression's chain where an
// associated type diverged from what the signature's opaque type expects,
// regardless of how the failed predicate was derived from that expectation.
if let Some(typeck_results) = self.typeck_results.as_deref() {
let chain_expr = match expr_info {
Some((_, hir_id)) => Some(tcx.hir_expect_expr(hir_id)),
None => tcx.hir_node_by_def_id(body_def_id).body_id().and_then(|body_id| {
match tcx.hir_body(body_id).value.kind {
hir::ExprKind::Block(block, _) => block.expr,
_ => None,
}
}),
};
if let Some(chain_expr) = chain_expr {
self.point_at_chain_in_return_position(
body_def_id,
chain_expr,
typeck_results,
param_env,
err,
);
}
}
let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
let expr = tcx.hir_expect_expr(hir_id);
(expr_ty, expr)
Expand Down Expand Up @@ -5438,6 +5461,109 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
assocs_in_this_method
}

/// When a `-> impl Trait<Assoc = Ty>` return type obligation fails, walk the method call
/// chain in the returned expression to point at where the associated type diverged from
/// what the signature expects.
///
/// ```text
/// note: the method call chain might not have had the expected associated types
/// --> $DIR/invalid-iterator-chain-in-return-position.rs:16:18
/// |
/// LL | x.iter_mut().map(foo)
/// | - ---------- ^^^^^^^^ `Iterator::Item` changed to `()` here
/// | | |
/// | | `Iterator::Item` is `&mut Vec<u8>` here
/// | this expression has type `Vec<Vec<u8>>`
/// ```
fn point_at_chain_in_return_position<G: EmissionGuarantee>(
&self,
body_def_id: LocalDefId,
expr: &hir::Expr<'_>,
typeck_results: &TypeckResults<'tcx>,
param_env: ty::ParamEnv<'tcx>,
err: &mut Diag<'_, G>,
) {
let tcx = self.tcx;
if !matches!(tcx.def_kind(body_def_id), DefKind::Fn | DefKind::AssocFn) {
return;
}
let output =
tcx.fn_sig(body_def_id).instantiate_identity().skip_norm_wip().output().skip_binder();
let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id: opaque_def_id }, args, .. }) =
output.kind()
else {
return;
};

// The predicate that reaches here has been rewritten through the impls it was
// derived from (e.g. `Iterator for Map<I, F>` turns `Iterator::Item` requirements
// into requirements on `F`'s return type), so the associated types the user wrote
// in the signature are recovered from the opaque's bounds instead.
let mut probe_diffs = vec![];
for clause in tcx.item_bounds(opaque_def_id).instantiate(tcx, args).skip_norm_wip() {
let Some(proj) = clause.as_projection_clause() else { continue };
let proj = self.instantiate_binder_with_fresh_vars(
expr.span,
BoundRegionConversionTime::FnCall,
proj,
);
let Some(expected_term) = proj.term.as_type() else { continue };
// Only the projection (for its `DefId`) is used when probing the chain; the
// bound's own term is carried in `found` for the divergence check below and
// is replaced with the probed type afterwards.
probe_diffs.push(TypeError::Sorts(ty::error::ExpectedFound {
expected: proj.projection_term.expect_ty().to_ty(tcx, ty::IsRigid::No),
found: expected_term,
}));
}
if probe_diffs.is_empty() {
return;
}

// If the returned expression is a binding, walk the chain that created it instead.
let expr = if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let hir::Path { res: Res::Local(hir_id), .. } = path
&& let hir::Node::Pat(binding) = tcx.hir_node(*hir_id)
&& let hir::Node::LetStmt(local) = tcx.parent_hir_node(binding.hir_id)
&& let Some(binding_expr) = local.init
{
binding_expr
} else {
expr
};

// Resolve what each bound associated type actually is for the returned expression,
// and keep only the ones that diverged from the signature.
let expr_ty = self.resolve_vars_if_possible(
typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)),
);
let assocs = self.probe_assoc_types_at_expr(
&probe_diffs,
expr.span,
expr_ty,
expr.hir_id,
param_env,
);
let mut type_diffs = vec![];
for (probe_diff, assoc) in iter::zip(probe_diffs, assocs) {
let TypeError::Sorts(ty::error::ExpectedFound { expected, found: expected_term }) =
probe_diff
else {
continue;
};
let Some((_, (_, actual_ty))) = assoc else { continue };
if !self.can_eq(param_env, expected_term, actual_ty) {
type_diffs.push(TypeError::Sorts(ty::error::ExpectedFound {
expected,
found: actual_ty,
}));
}
}
if !type_diffs.is_empty() {
self.point_at_chain(expr, typeck_results, type_diffs, param_env, err);
}
}

/// If the type that failed selection is an array or a reference to an array,
/// but the trait is implemented for slices, suggest that the user converts
/// the array into a slice.
Expand Down
Loading
Loading