Skip to content

Commit

Permalink
Auto merge of rust-lang#132997 - GuillaumeGomez:rollup-8j97gl3, r=Gui…
Browse files Browse the repository at this point in the history
…llaumeGomez

Rollup of 5 pull requests

Successful merges:

 - rust-lang#132709 (optimize char::to_digit and assert radix is at least 2)
 - rust-lang#132842 (ABI checks: add support for tier2 arches)
 - rust-lang#132965 (allow CFGuard on windows-gnullvm)
 - rust-lang#132967 (fix REGISTRY_USERNAME to reuse cache between auto and pr jobs)
 - rust-lang#132971 (Handle infer vars in anon consts on stable)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Nov 13, 2024
2 parents a00df61 + b6074c0 commit d0d5602
Show file tree
Hide file tree
Showing 17 changed files with 252 additions and 66 deletions.
8 changes: 6 additions & 2 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,12 @@ pub(crate) unsafe fn create_module<'ll>(
}
}

// Control Flow Guard is currently only supported by the MSVC linker on Windows.
if sess.target.is_like_msvc {
// Control Flow Guard is currently only supported by MSVC and LLVM on Windows.
if sess.target.is_like_msvc
|| (sess.target.options.os == "windows"
&& sess.target.options.env == "gnu"
&& sess.target.options.abi == "llvm")
{
match sess.opts.cg.control_flow_guard {
CFGuard::Disabled => {}
CFGuard::NoChecks => {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/mir/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ impl<'tcx> Const<'tcx> {

match c.kind() {
ConstKind::Value(ty, val) => Ok(tcx.valtree_to_const_val((ty, val))),
ConstKind::Expr(_) => {
bug!("Normalization of `ty::ConstKind::Expr` is unimplemented")
}
_ => Err(tcx.dcx().delayed_bug("Unevaluated `ty::Const` in MIR body").into()),
}
}
Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_monomorphize/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
monomorphize_abi_error_disabled_vector_type_call =
ABI error: this function call uses a vector type that requires the `{$required_feature}` target feature, which is not enabled in the caller
this function call uses a SIMD vector type that (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled in the caller
.label = function called here
.help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`)
monomorphize_abi_error_disabled_vector_type_def =
ABI error: this function definition uses a vector type that requires the `{$required_feature}` target feature, which is not enabled
this function definition uses a SIMD vector type that (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled
.label = function defined here
.help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`)
monomorphize_abi_error_unsupported_vector_type_call =
this function call uses a SIMD vector type that is not currently supported with the chosen ABI
.label = function called here
monomorphize_abi_error_unsupported_vector_type_def =
this function definition uses a SIMD vector type that is not currently supported with the chosen ABI
.label = function defined here
monomorphize_couldnt_dump_mono_stats =
unexpected error occurred while dumping monomorphization stats: {$error}
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_monomorphize/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,17 @@ pub(crate) struct AbiErrorDisabledVectorTypeCall<'a> {
pub span: Span,
pub required_feature: &'a str,
}

#[derive(LintDiagnostic)]
#[diag(monomorphize_abi_error_unsupported_vector_type_def)]
pub(crate) struct AbiErrorUnsupportedVectorTypeDef {
#[label]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(monomorphize_abi_error_unsupported_vector_type_call)]
pub(crate) struct AbiErrorUnsupportedVectorTypeCall {
#[label]
pub span: Span,
}
57 changes: 41 additions & 16 deletions compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use rustc_span::{DUMMY_SP, Span, Symbol};
use rustc_target::abi::call::{FnAbi, PassMode};
use rustc_target::abi::{BackendRepr, RegKind};

use crate::errors::{AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef};
use crate::errors::{
AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef,
AbiErrorUnsupportedVectorTypeCall, AbiErrorUnsupportedVectorTypeDef,
};

fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool {
match mode {
Expand All @@ -23,11 +26,15 @@ fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool {
}
}

/// Checks whether a certain function ABI is compatible with the target features currently enabled
/// for a certain function.
/// If not, `emit_err` is called, with `Some(feature)` if a certain feature should be enabled and
/// with `None` if no feature is known that would make the ABI compatible.
fn do_check_abi<'tcx>(
tcx: TyCtxt<'tcx>,
abi: &FnAbi<'tcx, Ty<'tcx>>,
target_feature_def: DefId,
mut emit_err: impl FnMut(&'static str),
mut emit_err: impl FnMut(Option<&'static str>),
) {
let Some(feature_def) = tcx.sess.target.features_for_correct_vector_abi() else {
return;
Expand All @@ -40,15 +47,15 @@ fn do_check_abi<'tcx>(
let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) {
Some((_, feature)) => feature,
None => {
emit_err("<no available feature for this size>");
emit_err(None);
continue;
}
};
let feature_sym = Symbol::intern(feature);
if !tcx.sess.unstable_target_features.contains(&feature_sym)
&& !codegen_attrs.target_features.iter().any(|x| x.name == feature_sym)
{
emit_err(feature);
emit_err(Some(&feature));
}
}
}
Expand All @@ -65,12 +72,21 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
};
do_check_abi(tcx, abi, instance.def_id(), |required_feature| {
let span = tcx.def_span(instance.def_id());
tcx.emit_node_span_lint(
ABI_UNSUPPORTED_VECTOR_TYPES,
CRATE_HIR_ID,
span,
AbiErrorDisabledVectorTypeDef { span, required_feature },
);
if let Some(required_feature) = required_feature {
tcx.emit_node_span_lint(
ABI_UNSUPPORTED_VECTOR_TYPES,
CRATE_HIR_ID,
span,
AbiErrorDisabledVectorTypeDef { span, required_feature },
);
} else {
tcx.emit_node_span_lint(
ABI_UNSUPPORTED_VECTOR_TYPES,
CRATE_HIR_ID,
span,
AbiErrorUnsupportedVectorTypeDef { span },
);
}
})
}

Expand Down Expand Up @@ -109,12 +125,21 @@ fn check_call_site_abi<'tcx>(
return;
};
do_check_abi(tcx, callee_abi, caller.def_id(), |required_feature| {
tcx.emit_node_span_lint(
ABI_UNSUPPORTED_VECTOR_TYPES,
CRATE_HIR_ID,
span,
AbiErrorDisabledVectorTypeCall { span, required_feature },
);
if let Some(required_feature) = required_feature {
tcx.emit_node_span_lint(
ABI_UNSUPPORTED_VECTOR_TYPES,
CRATE_HIR_ID,
span,
AbiErrorDisabledVectorTypeCall { span, required_feature },
);
} else {
tcx.emit_node_span_lint(
ABI_UNSUPPORTED_VECTOR_TYPES,
CRATE_HIR_ID,
span,
AbiErrorUnsupportedVectorTypeCall { span },
);
}
});
}

Expand Down
24 changes: 21 additions & 3 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,9 +586,20 @@ pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
// certain size to have their "proper" ABI on each architecture.
// Note that they must be kept sorted by vector size.
const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
&[(128, "sse"), (256, "avx"), (512, "avx512f")];
&[(128, "sse"), (256, "avx"), (512, "avx512f")]; // FIXME: might need changes for AVX10.
const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];

// We might want to add "helium" too.
const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];

const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
&[/*(64, "zvl64b"), */ (128, "v")];
// Always warn on SPARC, as the necessary target features cannot be enabled in Rust at the moment.
const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(128, "vis")*/];

impl super::spec::Target {
pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
match &*self.arch {
Expand All @@ -613,8 +624,15 @@ impl super::spec::Target {
pub fn features_for_correct_vector_abi(&self) -> Option<&'static [(u64, &'static str)]> {
match &*self.arch {
"x86" | "x86_64" => Some(X86_FEATURES_FOR_CORRECT_VECTOR_ABI),
"aarch64" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
// FIXME: add support for non-tier1 architectures
"aarch64" | "arm64ec" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
"arm" => Some(ARM_FEATURES_FOR_CORRECT_VECTOR_ABI),
"powerpc" | "powerpc64" => Some(POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI),
"loongarch64" => Some(&[]), // on-stack ABI, so we complain about all by-val vectors
"riscv32" | "riscv64" => Some(RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI),
"wasm32" | "wasm64" => Some(WASM_FEATURES_FOR_CORRECT_VECTOR_ABI),
"s390x" => Some(S390X_FEATURES_FOR_CORRECT_VECTOR_ABI),
"sparc" | "sparc64" => Some(SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI),
// FIXME: add support for non-tier2 architectures
_ => None,
}
}
Expand Down
30 changes: 21 additions & 9 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,16 +578,28 @@ pub fn try_evaluate_const<'tcx>(
(args, param_env)
}
}
} else {
// FIXME: We don't check anything on stable as the only way we can wind up with
// an unevaluated constant containing generic parameters is through array repeat
// expression counts which have a future compat lint for usage of generic parameters
// instead of a hard error.
} else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
// FIXME: remove this when `const_evaluatable_unchecked` is a hard error.
//
// Diagnostics will sometimes replace the identity args of anon consts in
// array repeat expr counts with inference variables so we have to handle this
// even though it is not something we should ever actually encounter.
//
// This codepath is however also reachable by `generic_const_exprs` and some other
// feature gates which allow constants in the type system to use generic parameters.
// In theory we should be checking for generic parameters here and returning an error
// in such cases.
// Array repeat expr counts are allowed to syntactically use generic parameters
// but must not actually depend on them in order to evalaute succesfully. This means
// that it is actually fine to evalaute them in their own environment rather than with
// the actually provided generic arguments.
tcx.dcx().delayed_bug(
"Encountered anon const with inference variable args but no error reported",
);

let args = GenericArgs::identity_for_item(tcx, uv.def);
let param_env = tcx.param_env(uv.def);
(args, param_env)
} else {
// FIXME: This codepath is reachable under `associated_const_equality` and in the
// future will be reachable by `min_generic_const_args`. We should handle inference
// variables and generic parameters properly instead of doing nothing.
(uv.args, param_env)
};
let uv = ty::UnevaluatedConst::new(uv.def, args);
Expand Down
44 changes: 31 additions & 13 deletions library/core/src/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ impl char {
///
/// # Panics
///
/// Panics if given a radix larger than 36.
/// Panics if given a radix smaller than 2 or larger than 36.
///
/// # Examples
///
Expand All @@ -319,6 +319,13 @@ impl char {
/// // this panics
/// '1'.is_digit(37);
/// ```
///
/// Passing a small radix, causing a panic:
///
/// ```should_panic
/// // this panics
/// '1'.is_digit(1);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_char_classify", issue = "132241")]
#[inline]
Expand All @@ -345,7 +352,7 @@ impl char {
///
/// # Panics
///
/// Panics if given a radix larger than 36.
/// Panics if given a radix smaller than 2 or larger than 36.
///
/// # Examples
///
Expand All @@ -369,24 +376,35 @@ impl char {
/// // this panics
/// let _ = '1'.to_digit(37);
/// ```
/// Passing a small radix, causing a panic:
///
/// ```should_panic
/// // this panics
/// let _ = '1'.to_digit(1);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn to_digit(self, radix: u32) -> Option<u32> {
// If not a digit, a number greater than radix will be created.
let mut digit = (self as u32).wrapping_sub('0' as u32);
if radix > 10 {
assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
if digit < 10 {
return Some(digit);
}
// Force the 6th bit to be set to ensure ascii is lower case.
digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
}
assert!(
radix >= 2 && radix <= 36,
"to_digit: invalid radix -- radix must be in the range 2 to 36 inclusive"
);
// check radix to remove letter handling code when radix is a known constant
let value = if self > '9' && radix > 10 {
// convert ASCII letters to lowercase
let lower = self as u32 | 0x20;
// convert an ASCII letter to the corresponding value,
// non-letters convert to values > 36
lower.wrapping_sub('a' as u32) as u64 + 10
} else {
// convert digit to value, non-digits wrap to values > 36
(self as u32).wrapping_sub('0' as u32) as u64
};
// FIXME(const-hack): once then_some is const fn, use it here
if digit < radix { Some(digit) } else { None }
if value < radix as u64 { Some(value as u32) } else { None }
}

/// Returns an iterator that yields the hexadecimal Unicode escape of a
Expand Down
4 changes: 3 additions & 1 deletion src/ci/docker/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
docker --version

REGISTRY=ghcr.io
REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER:-rust-lang-ci}
# Hardcode username to reuse cache between auto and pr jobs
# FIXME: should be changed after move from rust-lang-ci
REGISTRY_USERNAME=rust-lang-ci
# Tag used to push the final Docker image, so that it can be pulled by e.g. rustup
IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum}
# Tag used to cache the Docker build
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Regression test for #132955 checking that we handle anon consts with
// inference variables in their generic arguments correctly.
//
// This arose via diagnostics where we would have some failing goal such
// as `[u8; AnonConst<Self>]: PartialEq<Self::A>`, then as part of diagnostics
// we would replace all generic parameters with inference vars which would yield
// a self type of `[u8; AnonConst<?x>]` and then attempt to normalize `AnonConst<?x>`.

pub trait T {
type A;
const P: Self::A;

fn a() {
[0u8; std::mem::size_of::<Self::A>()] == Self::P;
//~^ ERROR: can't compare
//~| ERROR: constant expression depends on a generic parameter
//~| ERROR: constant expression depends on a generic parameter
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
error: constant expression depends on a generic parameter
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:15
|
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes

error: constant expression depends on a generic parameter
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47
|
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
| ^^
|
= note: this may fail depending on what value the parameter takes

error[E0277]: can't compare `[u8; std::mem::size_of::<Self::A>()]` with `<Self as T>::A`
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47
|
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
| ^^ no implementation for `[u8; std::mem::size_of::<Self::A>()] == <Self as T>::A`
|
= help: the trait `PartialEq<<Self as T>::A>` is not implemented for `[u8; std::mem::size_of::<Self::A>()]`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub trait T where [u8; std::mem::size_of::<Self::A>()]: PartialEq<<Self as T>::A> {
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
Loading

0 comments on commit d0d5602

Please sign in to comment.