Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ec3de4b
Replace `stdarch` version placeholders with 1.94
cuviper Feb 5, 2026
dd322a0
Include library/stdarch for CURRENT_RUSTC_VERSION updates
cuviper Feb 5, 2026
001d710
Replace a stale clippy `CURRENT_RUSTC_VERSION`
cuviper Feb 6, 2026
78dc744
unwind/wasm: fix compile error by wrapping wasm_throw in unsafe block
lizan Feb 10, 2026
5b1070b
Add note for param-env shadowing
xonx4l Dec 27, 2025
a873a3f
add suggested changes
xonx4l Jan 11, 2026
c576dc5
delete middle check.
xonx4l Jan 16, 2026
071d0cd
rewording note and refer issue
xonx4l Feb 10, 2026
6b3c425
update tests
xonx4l Feb 10, 2026
0bcec37
Improve write! and writeln! error when called without destination
arferreira Feb 12, 2026
1eddc17
fix GATs logic
xonx4l Feb 12, 2026
7a2f2fe
fix tidy
xonx4l Feb 12, 2026
7a7d48e
add tests
xonx4l Feb 13, 2026
c0c3c59
ci: Drop outdated toolchain configuration: aarch64-linux-gnu.defconfig
heiher Feb 13, 2026
e37374b
ci: dist-arm-linux: Cleanup unused crosstool-ng
heiher Feb 13, 2026
df798ad
ci: Lock cross toolchain version and update docs
heiher Feb 13, 2026
34981bf
add comments to tests
xonx4l Feb 13, 2026
c22301b
Test(lib/win/net): Skip UDS tests when under Win7
PaulDance Feb 12, 2026
98975ff
exchange js_lint message between bless and non-bless
Shunpoco Feb 14, 2026
8d96e26
Add regression test for struct ctor used as array repeat count under …
AprilNEA Feb 14, 2026
b935f37
implement `carryless_mul`
folkertdev Feb 4, 2026
1be4164
move and add comment
xonx4l Feb 14, 2026
79adcd1
Rollup merge of #150424 - xonx4l:suggest_param_env_shadowing, r=lcnr
jhpratt Feb 15, 2026
f065c9d
Rollup merge of #152132 - folkertdev:carryless-mul, r=Mark-Simulacrum
jhpratt Feb 15, 2026
8075b89
Rollup merge of #152508 - arferreira:improve-write-macro-diagnostic, …
jhpratt Feb 15, 2026
3ce7fb6
Rollup merge of #152534 - PaulDance:patches/remove-win7-uds, r=Mark-S…
jhpratt Feb 15, 2026
9f0b29b
Rollup merge of #152578 - heiher:ci-crosstool, r=Mark-Simulacrum
jhpratt Feb 15, 2026
ef776c6
Rollup merge of #152188 - cuviper:placeholder-stdarch, r=Mark-Simulacrum
jhpratt Feb 15, 2026
9369cff
Rollup merge of #152402 - AprilNEA:test/issue-141738-struct-ctor-arra…
jhpratt Feb 15, 2026
5d2a033
Rollup merge of #152472 - lizan:wasm, r=Mark-Simulacrum
jhpratt Feb 15, 2026
12755aa
Rollup merge of #152610 - Shunpoco:fix-js-lint-bless-message, r=clubb…
jhpratt Feb 15, 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
34 changes: 34 additions & 0 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,27 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
let pair = self.insert_value(pair, high, 1);
pair
}

// FIXME move into the branch below when LLVM 22 is the lowest version we support.
sym::carryless_mul if crate::llvm_util::get_version() >= (22, 0, 0) => {
let ty = args[0].layout.ty;
if !ty.is_integral() {
tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
span,
name,
ty,
});
return Ok(());
}
let (size, _) = ty.int_size_and_signed(self.tcx);
let width = size.bits();
let llty = self.type_ix(width);

let lhs = args[0].immediate();
let rhs = args[1].immediate();
self.call_intrinsic("llvm.clmul", &[llty], &[lhs, rhs])
}

sym::ctlz
| sym::ctlz_nonzero
| sym::cttz
Expand Down Expand Up @@ -2784,6 +2805,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
| sym::simd_ctlz
| sym::simd_ctpop
| sym::simd_cttz
| sym::simd_carryless_mul
| sym::simd_funnel_shl
| sym::simd_funnel_shr
) {
Expand All @@ -2808,6 +2830,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
sym::simd_cttz => "llvm.cttz",
sym::simd_funnel_shl => "llvm.fshl",
sym::simd_funnel_shr => "llvm.fshr",
sym::simd_carryless_mul => "llvm.clmul",
_ => unreachable!(),
};
let int_size = in_elem.int_size_and_signed(bx.tcx()).0.bits();
Expand All @@ -2833,6 +2856,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
&[vec_ty],
&[args[0].immediate(), args[1].immediate(), args[2].immediate()],
)),
sym::simd_carryless_mul => {
if crate::llvm_util::get_version() >= (22, 0, 0) {
Ok(bx.call_intrinsic(
llvm_intrinsic,
&[vec_ty],
&[args[0].immediate(), args[1].immediate()],
))
} else {
span_bug!(span, "`simd_carryless_mul` needs LLVM 22 or higher");
}
}
_ => unreachable!(),
};
}
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,14 @@ impl CodegenBackend for LlvmCodegenBackend {
}

fn replaced_intrinsics(&self) -> Vec<Symbol> {
vec![sym::unchecked_funnel_shl, sym::unchecked_funnel_shr, sym::carrying_mul_add]
let mut will_not_use_fallback =
vec![sym::unchecked_funnel_shl, sym::unchecked_funnel_shr, sym::carrying_mul_add];

if llvm_util::get_version() >= (22, 0, 0) {
will_not_use_fallback.push(sym::carryless_mul);
}

will_not_use_fallback
}

fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::bswap
| sym::caller_location
| sym::carrying_mul_add
| sym::carryless_mul
| sym::ceilf16
| sym::ceilf32
| sym::ceilf64
Expand Down Expand Up @@ -564,6 +565,7 @@ pub(crate) fn check_intrinsic_type(
(1, 0, vec![param(0), param(0)], param(0))
}
sym::saturating_add | sym::saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
sym::carryless_mul => (1, 0, vec![param(0), param(0)], param(0)),
sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => {
(1, 0, vec![param(0), param(0)], param(0))
}
Expand Down Expand Up @@ -711,7 +713,8 @@ pub(crate) fn check_intrinsic_type(
| sym::simd_fmin
| sym::simd_fmax
| sym::simd_saturating_add
| sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
| sym::simd_saturating_sub
| sym::simd_carryless_mul => (1, 0, vec![param(0), param(0)], param(0)),
sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)),
sym::simd_neg
| sym::simd_bswap
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ symbols! {
caller_location,
capture_disjoint_fields,
carrying_mul_add,
carryless_mul,
catch_unwind,
cause,
cdylib,
Expand Down Expand Up @@ -2093,6 +2094,7 @@ symbols! {
simd_bitmask,
simd_bitreverse,
simd_bswap,
simd_carryless_mul,
simd_cast,
simd_cast_ptr,
simd_ceil,
Expand Down
86 changes: 83 additions & 3 deletions compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{self as hir};
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_macros::extension;
use rustc_middle::bug;
use rustc_middle::dep_graph::DepContext;
Expand All @@ -72,12 +73,17 @@ use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym};
use tracing::{debug, instrument};

use crate::error_reporting::TypeErrCtxt;
use crate::error_reporting::traits::ambiguity::{
CandidateSource, compute_applicable_impls_for_diagnostics,
};
use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
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, ObligationCause, ObligationCauseCode};
use crate::traits::{
MatchExpressionArmCause, Obligation, ObligationCause, ObligationCauseCode, specialization_graph,
};

mod note_and_explain;
mod suggest;
Expand Down Expand Up @@ -149,11 +155,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
actual: Ty<'tcx>,
err: TypeError<'tcx>,
) -> Diag<'a> {
self.report_and_explain_type_error(
let mut diag = self.report_and_explain_type_error(
TypeTrace::types(cause, expected, actual),
param_env,
err,
)
);

self.suggest_param_env_shadowing(&mut diag, expected, actual, param_env);

diag
}

pub fn report_mismatched_consts(
Expand Down Expand Up @@ -240,6 +250,76 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
false
}

fn suggest_param_env_shadowing(
&self,
diag: &mut Diag<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) {
let (alias, concrete) = match (expected.kind(), found.kind()) {
(ty::Alias(ty::Projection, proj), _) => (proj, found),
(_, ty::Alias(ty::Projection, proj)) => (proj, expected),
_ => return,
};

let tcx = self.tcx;

let trait_ref = alias.trait_ref(tcx);
let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, ty::Binder::dummy(trait_ref));

let applicable_impls = compute_applicable_impls_for_diagnostics(self.infcx, &obligation);

for candidate in applicable_impls {
let impl_def_id = match candidate {
CandidateSource::DefId(did) => did,
CandidateSource::ParamEnv(_) => continue,
};

let is_shadowed = self.infcx.probe(|_| {
let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs);

let expected_trait_ref = alias.trait_ref(tcx);

if let Err(_) = self.infcx.at(&ObligationCause::dummy(), param_env).eq(
DefineOpaqueTypes::No,
expected_trait_ref,
impl_trait_ref,
) {
return false;
}

let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, alias.def_id)
{
Ok(leaf) => leaf,
Err(_) => return false,
};

let trait_def_id = alias.trait_def_id(tcx);
let rebased_args = alias.args.rebase_onto(tcx, trait_def_id, impl_substs);

let impl_item_def_id = leaf_def.item.def_id;
let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, rebased_args);

self.infcx.can_eq(param_env, impl_assoc_ty, concrete)
});

if is_shadowed {
diag.note(format!(
"the associated type `{}` is defined as `{}` in the implementation, \
but the where-bound `{}` shadows this definition\n\
see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information",
self.ty_to_string(tcx.mk_ty_from_kind(ty::Alias(ty::Projection, *alias))),
self.ty_to_string(concrete),
self.ty_to_string(alias.self_ty())
));
return;
}
}
}

fn note_error_origin(
&self,
err: &mut Diag<'_>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub mod project;
pub mod query;
#[allow(hidden_glob_reexports)]
mod select;
mod specialize;
pub mod specialize;
mod structural_normalize;
#[allow(hidden_glob_reexports)]
mod util;
Expand Down
35 changes: 35 additions & 0 deletions library/core/src/intrinsics/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,38 @@ macro_rules! impl_funnel_shifts {
impl_funnel_shifts! {
u8, u16, u32, u64, u128, usize
}

#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
pub const trait CarrylessMul: Copy + 'static {
/// See [`super::carryless_mul`]; we just need the trait indirection to handle
/// different types since calling intrinsics with generics doesn't work.
fn carryless_mul(self, rhs: Self) -> Self;
}

macro_rules! impl_carryless_mul{
($($type:ident),*) => {$(
#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
impl const CarrylessMul for $type {
#[inline]
fn carryless_mul(self, rhs: Self) -> Self {
let mut result = 0;
let mut i = 0;

while i < $type::BITS {
// If the i-th bit in rhs is set.
if (rhs >> i) & 1 != 0 {
// Then xor the result with `self` shifted to the left by i positions.
result ^= self << i;
}
i += 1;
}

result
}
}
)*};
}

impl_carryless_mul! {
u8, u16, u32, u64, u128, usize
}
13 changes: 13 additions & 0 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2178,6 +2178,19 @@ pub const unsafe fn unchecked_funnel_shr<T: [const] fallback::FunnelShift>(
unsafe { a.unchecked_funnel_shr(b, shift) }
}

/// Carryless multiply.
///
/// Safe versions of this intrinsic are available on the integer primitives
/// via the `carryless_mul` method. For example, [`u32::carryless_mul`].
#[rustc_intrinsic]
#[rustc_nounwind]
#[rustc_const_unstable(feature = "uint_carryless_mul", issue = "152080")]
#[unstable(feature = "uint_carryless_mul", issue = "152080")]
#[miri::intrinsic_fallback_is_spec]
pub const fn carryless_mul<T: [const] fallback::CarrylessMul>(a: T, b: T) -> T {
a.carryless_mul(b)
}

/// This is an implementation detail of [`crate::ptr::read`] and should
/// not be used anywhere else. See its comments for why this exists.
///
Expand Down
12 changes: 12 additions & 0 deletions library/core/src/intrinsics/simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,18 @@ pub const unsafe fn simd_funnel_shl<T>(a: T, b: T, shift: T) -> T;
#[rustc_nounwind]
pub const unsafe fn simd_funnel_shr<T>(a: T, b: T, shift: T) -> T;

/// Compute the carry-less product.
///
/// This is similar to long multiplication except that the carry is discarded.
///
/// This operation can be used to model multiplication in `GF(2)[X]`, the polynomial
/// ring over `GF(2)`.
///
/// `T` must be a vector of integers.
#[rustc_intrinsic]
#[rustc_nounwind]
pub unsafe fn simd_carryless_mul<T>(a: T, b: T) -> T;

/// "And"s vectors elementwise.
///
/// `T` must be a vector of integers.
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
#![feature(trait_alias)]
#![feature(transparent_unions)]
#![feature(try_blocks)]
#![feature(uint_carryless_mul)]
#![feature(unboxed_closures)]
#![feature(unsized_fn_params)]
#![feature(with_negative_coherence)]
Expand Down
6 changes: 6 additions & 0 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,9 @@ macro_rules! write {
($dst:expr, $($arg:tt)*) => {
$dst.write_fmt($crate::format_args!($($arg)*))
};
($($arg:tt)*) => {
compile_error!("requires a destination and format arguments, like `write!(dest, \"format string\", args...)`")
};
}

/// Writes formatted data into a buffer, with a newline appended.
Expand Down Expand Up @@ -645,6 +648,9 @@ macro_rules! writeln {
($dst:expr, $($arg:tt)*) => {
$dst.write_fmt($crate::format_args_nl!($($arg)*))
};
($($arg:tt)*) => {
compile_error!("requires a destination and format arguments, like `writeln!(dest, \"format string\", args...)`")
};
}

/// Indicates unreachable code.
Expand Down
Loading
Loading