Skip to content

Commit ce0bf0b

Browse files
committed
Auto merge of #152639 - jhpratt:rollup-sIUYGho, r=jhpratt
Rollup of 9 pull requests Successful merges: - #150424 (diagnostics: add note when param-env shadows global impl) - #152132 (implement `carryless_mul`) - #152508 (Improve write! and writeln! error when called without destination) - #152534 (Test(lib/win/net): Skip UDS tests when under Win7) - #152578 (ci: Lock cross toolchain version and update docs) - #152188 (Include `library/stdarch` for `CURRENT_RUSTC_VERSION` updates) - #152402 (Add regression test for #141738) - #152472 (unwind/wasm: fix compile error by wrapping wasm_throw in unsafe block) - #152610 (Exchange js_lint message between bless and non-bless)
2 parents 75b9d89 + 12755aa commit ce0bf0b

59 files changed

Lines changed: 2278 additions & 1278 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,27 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
387387
let pair = self.insert_value(pair, high, 1);
388388
pair
389389
}
390+
391+
// FIXME move into the branch below when LLVM 22 is the lowest version we support.
392+
sym::carryless_mul if crate::llvm_util::get_version() >= (22, 0, 0) => {
393+
let ty = args[0].layout.ty;
394+
if !ty.is_integral() {
395+
tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
396+
span,
397+
name,
398+
ty,
399+
});
400+
return Ok(());
401+
}
402+
let (size, _) = ty.int_size_and_signed(self.tcx);
403+
let width = size.bits();
404+
let llty = self.type_ix(width);
405+
406+
let lhs = args[0].immediate();
407+
let rhs = args[1].immediate();
408+
self.call_intrinsic("llvm.clmul", &[llty], &[lhs, rhs])
409+
}
410+
390411
sym::ctlz
391412
| sym::ctlz_nonzero
392413
| sym::cttz
@@ -2784,6 +2805,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
27842805
| sym::simd_ctlz
27852806
| sym::simd_ctpop
27862807
| sym::simd_cttz
2808+
| sym::simd_carryless_mul
27872809
| sym::simd_funnel_shl
27882810
| sym::simd_funnel_shr
27892811
) {
@@ -2808,6 +2830,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
28082830
sym::simd_cttz => "llvm.cttz",
28092831
sym::simd_funnel_shl => "llvm.fshl",
28102832
sym::simd_funnel_shr => "llvm.fshr",
2833+
sym::simd_carryless_mul => "llvm.clmul",
28112834
_ => unreachable!(),
28122835
};
28132836
let int_size = in_elem.int_size_and_signed(bx.tcx()).0.bits();
@@ -2833,6 +2856,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
28332856
&[vec_ty],
28342857
&[args[0].immediate(), args[1].immediate(), args[2].immediate()],
28352858
)),
2859+
sym::simd_carryless_mul => {
2860+
if crate::llvm_util::get_version() >= (22, 0, 0) {
2861+
Ok(bx.call_intrinsic(
2862+
llvm_intrinsic,
2863+
&[vec_ty],
2864+
&[args[0].immediate(), args[1].immediate()],
2865+
))
2866+
} else {
2867+
span_bug!(span, "`simd_carryless_mul` needs LLVM 22 or higher");
2868+
}
2869+
}
28362870
_ => unreachable!(),
28372871
};
28382872
}

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,14 @@ impl CodegenBackend for LlvmCodegenBackend {
354354
}
355355

356356
fn replaced_intrinsics(&self) -> Vec<Symbol> {
357-
vec![sym::unchecked_funnel_shl, sym::unchecked_funnel_shr, sym::carrying_mul_add]
357+
let mut will_not_use_fallback =
358+
vec![sym::unchecked_funnel_shl, sym::unchecked_funnel_shr, sym::carrying_mul_add];
359+
360+
if llvm_util::get_version() >= (22, 0, 0) {
361+
will_not_use_fallback.push(sym::carryless_mul);
362+
}
363+
364+
will_not_use_fallback
358365
}
359366

360367
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
8282
| sym::bswap
8383
| sym::caller_location
8484
| sym::carrying_mul_add
85+
| sym::carryless_mul
8586
| sym::ceilf16
8687
| sym::ceilf32
8788
| sym::ceilf64
@@ -564,6 +565,7 @@ pub(crate) fn check_intrinsic_type(
564565
(1, 0, vec![param(0), param(0)], param(0))
565566
}
566567
sym::saturating_add | sym::saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
568+
sym::carryless_mul => (1, 0, vec![param(0), param(0)], param(0)),
567569
sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => {
568570
(1, 0, vec![param(0), param(0)], param(0))
569571
}
@@ -711,7 +713,8 @@ pub(crate) fn check_intrinsic_type(
711713
| sym::simd_fmin
712714
| sym::simd_fmax
713715
| sym::simd_saturating_add
714-
| sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
716+
| sym::simd_saturating_sub
717+
| sym::simd_carryless_mul => (1, 0, vec![param(0), param(0)], param(0)),
715718
sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)),
716719
sym::simd_neg
717720
| sym::simd_bswap

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ symbols! {
648648
caller_location,
649649
capture_disjoint_fields,
650650
carrying_mul_add,
651+
carryless_mul,
651652
catch_unwind,
652653
cause,
653654
cdylib,
@@ -2093,6 +2094,7 @@ symbols! {
20932094
simd_bitmask,
20942095
simd_bitreverse,
20952096
simd_bswap,
2097+
simd_carryless_mul,
20962098
simd_cast,
20972099
simd_cast_ptr,
20982100
simd_ceil,

compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ use rustc_hir::def_id::DefId;
5858
use rustc_hir::intravisit::Visitor;
5959
use rustc_hir::lang_items::LangItem;
6060
use rustc_hir::{self as hir};
61+
use rustc_infer::infer::DefineOpaqueTypes;
6162
use rustc_macros::extension;
6263
use rustc_middle::bug;
6364
use rustc_middle::dep_graph::DepContext;
@@ -72,12 +73,17 @@ use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym};
7273
use tracing::{debug, instrument};
7374

7475
use crate::error_reporting::TypeErrCtxt;
76+
use crate::error_reporting::traits::ambiguity::{
77+
CandidateSource, compute_applicable_impls_for_diagnostics,
78+
};
7579
use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
7680
use crate::infer;
7781
use crate::infer::relate::{self, RelateResult, TypeRelation};
7882
use crate::infer::{InferCtxt, InferCtxtExt as _, TypeTrace, ValuePairs};
7983
use crate::solve::deeply_normalize_for_diagnostics;
80-
use crate::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
84+
use crate::traits::{
85+
MatchExpressionArmCause, Obligation, ObligationCause, ObligationCauseCode, specialization_graph,
86+
};
8187

8288
mod note_and_explain;
8389
mod suggest;
@@ -149,11 +155,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
149155
actual: Ty<'tcx>,
150156
err: TypeError<'tcx>,
151157
) -> Diag<'a> {
152-
self.report_and_explain_type_error(
158+
let mut diag = self.report_and_explain_type_error(
153159
TypeTrace::types(cause, expected, actual),
154160
param_env,
155161
err,
156-
)
162+
);
163+
164+
self.suggest_param_env_shadowing(&mut diag, expected, actual, param_env);
165+
166+
diag
157167
}
158168

159169
pub fn report_mismatched_consts(
@@ -240,6 +250,76 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
240250
false
241251
}
242252

253+
fn suggest_param_env_shadowing(
254+
&self,
255+
diag: &mut Diag<'_>,
256+
expected: Ty<'tcx>,
257+
found: Ty<'tcx>,
258+
param_env: ty::ParamEnv<'tcx>,
259+
) {
260+
let (alias, concrete) = match (expected.kind(), found.kind()) {
261+
(ty::Alias(ty::Projection, proj), _) => (proj, found),
262+
(_, ty::Alias(ty::Projection, proj)) => (proj, expected),
263+
_ => return,
264+
};
265+
266+
let tcx = self.tcx;
267+
268+
let trait_ref = alias.trait_ref(tcx);
269+
let obligation =
270+
Obligation::new(tcx, ObligationCause::dummy(), param_env, ty::Binder::dummy(trait_ref));
271+
272+
let applicable_impls = compute_applicable_impls_for_diagnostics(self.infcx, &obligation);
273+
274+
for candidate in applicable_impls {
275+
let impl_def_id = match candidate {
276+
CandidateSource::DefId(did) => did,
277+
CandidateSource::ParamEnv(_) => continue,
278+
};
279+
280+
let is_shadowed = self.infcx.probe(|_| {
281+
let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
282+
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs);
283+
284+
let expected_trait_ref = alias.trait_ref(tcx);
285+
286+
if let Err(_) = self.infcx.at(&ObligationCause::dummy(), param_env).eq(
287+
DefineOpaqueTypes::No,
288+
expected_trait_ref,
289+
impl_trait_ref,
290+
) {
291+
return false;
292+
}
293+
294+
let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, alias.def_id)
295+
{
296+
Ok(leaf) => leaf,
297+
Err(_) => return false,
298+
};
299+
300+
let trait_def_id = alias.trait_def_id(tcx);
301+
let rebased_args = alias.args.rebase_onto(tcx, trait_def_id, impl_substs);
302+
303+
let impl_item_def_id = leaf_def.item.def_id;
304+
let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, rebased_args);
305+
306+
self.infcx.can_eq(param_env, impl_assoc_ty, concrete)
307+
});
308+
309+
if is_shadowed {
310+
diag.note(format!(
311+
"the associated type `{}` is defined as `{}` in the implementation, \
312+
but the where-bound `{}` shadows this definition\n\
313+
see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information",
314+
self.ty_to_string(tcx.mk_ty_from_kind(ty::Alias(ty::Projection, *alias))),
315+
self.ty_to_string(concrete),
316+
self.ty_to_string(alias.self_ty())
317+
));
318+
return;
319+
}
320+
}
321+
}
322+
243323
fn note_error_origin(
244324
&self,
245325
err: &mut Diag<'_>,

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub mod project;
1616
pub mod query;
1717
#[allow(hidden_glob_reexports)]
1818
mod select;
19-
mod specialize;
19+
pub mod specialize;
2020
mod structural_normalize;
2121
#[allow(hidden_glob_reexports)]
2222
mod util;

library/core/src/intrinsics/fallback.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,38 @@ macro_rules! impl_funnel_shifts {
218218
impl_funnel_shifts! {
219219
u8, u16, u32, u64, u128, usize
220220
}
221+
222+
#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
223+
pub const trait CarrylessMul: Copy + 'static {
224+
/// See [`super::carryless_mul`]; we just need the trait indirection to handle
225+
/// different types since calling intrinsics with generics doesn't work.
226+
fn carryless_mul(self, rhs: Self) -> Self;
227+
}
228+
229+
macro_rules! impl_carryless_mul{
230+
($($type:ident),*) => {$(
231+
#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
232+
impl const CarrylessMul for $type {
233+
#[inline]
234+
fn carryless_mul(self, rhs: Self) -> Self {
235+
let mut result = 0;
236+
let mut i = 0;
237+
238+
while i < $type::BITS {
239+
// If the i-th bit in rhs is set.
240+
if (rhs >> i) & 1 != 0 {
241+
// Then xor the result with `self` shifted to the left by i positions.
242+
result ^= self << i;
243+
}
244+
i += 1;
245+
}
246+
247+
result
248+
}
249+
}
250+
)*};
251+
}
252+
253+
impl_carryless_mul! {
254+
u8, u16, u32, u64, u128, usize
255+
}

library/core/src/intrinsics/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,6 +2178,19 @@ pub const unsafe fn unchecked_funnel_shr<T: [const] fallback::FunnelShift>(
21782178
unsafe { a.unchecked_funnel_shr(b, shift) }
21792179
}
21802180

2181+
/// Carryless multiply.
2182+
///
2183+
/// Safe versions of this intrinsic are available on the integer primitives
2184+
/// via the `carryless_mul` method. For example, [`u32::carryless_mul`].
2185+
#[rustc_intrinsic]
2186+
#[rustc_nounwind]
2187+
#[rustc_const_unstable(feature = "uint_carryless_mul", issue = "152080")]
2188+
#[unstable(feature = "uint_carryless_mul", issue = "152080")]
2189+
#[miri::intrinsic_fallback_is_spec]
2190+
pub const fn carryless_mul<T: [const] fallback::CarrylessMul>(a: T, b: T) -> T {
2191+
a.carryless_mul(b)
2192+
}
2193+
21812194
/// This is an implementation detail of [`crate::ptr::read`] and should
21822195
/// not be used anywhere else. See its comments for why this exists.
21832196
///

library/core/src/intrinsics/simd.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ pub const unsafe fn simd_funnel_shl<T>(a: T, b: T, shift: T) -> T;
162162
#[rustc_nounwind]
163163
pub const unsafe fn simd_funnel_shr<T>(a: T, b: T, shift: T) -> T;
164164

165+
/// Compute the carry-less product.
166+
///
167+
/// This is similar to long multiplication except that the carry is discarded.
168+
///
169+
/// This operation can be used to model multiplication in `GF(2)[X]`, the polynomial
170+
/// ring over `GF(2)`.
171+
///
172+
/// `T` must be a vector of integers.
173+
#[rustc_intrinsic]
174+
#[rustc_nounwind]
175+
pub unsafe fn simd_carryless_mul<T>(a: T, b: T) -> T;
176+
165177
/// "And"s vectors elementwise.
166178
///
167179
/// `T` must be a vector of integers.

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@
170170
#![feature(trait_alias)]
171171
#![feature(transparent_unions)]
172172
#![feature(try_blocks)]
173+
#![feature(uint_carryless_mul)]
173174
#![feature(unboxed_closures)]
174175
#![feature(unsized_fn_params)]
175176
#![feature(with_negative_coherence)]

0 commit comments

Comments
 (0)