Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 9 additions & 2 deletions compiler/rustc_next_trait_solver/src/delegate.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::fmt::Debug;
use std::ops::Deref;

use rustc_type_ir::solve::{
Expand Down Expand Up @@ -36,11 +37,17 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
// FIXME: Uplift the leak check into this crate.
fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution>;

fn evaluate_const(
/// Evaluate a const, normalizing the type of the resulting value with `normalize_ty`.
/// Returns `Ok(None)` if the const is too generic, and `Err(_)` only if `normalize_ty`
/// failed.
fn evaluate_const<E: Debug>(
&self,
param_env: <Self::Interner as Interner>::ParamEnv,
alias_const: ty::AliasConst<Self::Interner>,
) -> Option<<Self::Interner as Interner>::Const>;
normalize_ty: impl FnOnce(
ty::Unnormalized<Self::Interner, <Self::Interner as Interner>::Ty>,
) -> Result<<Self::Interner as Interner>::Ty, E>,
) -> Result<Option<<Self::Interner as Interner>::Const>, E>;

// FIXME: This only is here because `wf::obligations` is in `rustc_trait_selection`!
fn well_formed_goals(
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1403,19 +1403,21 @@ where
Ok(())
}

// Try to evaluate a const, or return `None` if the const is too generic.
// This doesn't mean the const isn't evaluatable, though, and should be treated
// as an ambiguity rather than no-solution.
// Try to evaluate a const and normalize the type of the resulting value, or return `None` if
// the const is too generic. This doesn't mean the const isn't evaluatable, though, and should
// be treated as an ambiguity rather than no-solution.
pub(super) fn evaluate_const(
&mut self,
param_env: I::ParamEnv,
alias_const: ty::AliasConst<I>,
) -> Result<Option<I::Const>, RerunNonErased> {
) -> Result<Option<I::Const>, NoSolutionOrRerunNonErased> {
if self.typing_mode().is_erased_not_coherence() {
match self.opaque_accesses.rerun_always(RerunReason::EvaluateConst)? {}
}

Ok(self.delegate.evaluate_const(param_env, alias_const))
self.delegate.evaluate_const(param_env, alias_const, |ty| {
self.normalize(GoalSource::Misc, param_env, ty)
})
}

pub(super) fn evaluate_const_and_instantiate_projection_term(
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,16 @@ pub mod mitigation_coverage;

mod target_modifier_consistency_check {
use super::*;
pub(super) fn sanitizer(l: &TargetModifier, r: Option<&TargetModifier>) -> bool {
let mut lparsed: SanitizerSet = Default::default();
pub(super) fn sanitizer(
sess: &Session,
l: &TargetModifier,
r: Option<&TargetModifier>,
) -> bool {
let mut lparsed: SanitizerSet = sess.target.options.default_sanitizers;
let lval = if l.value_name.is_empty() { None } else { Some(l.value_name.as_str()) };
parse::parse_sanitizers(&mut lparsed, lval);

let mut rparsed: SanitizerSet = Default::default();
let mut rparsed: SanitizerSet = sess.target.options.default_sanitizers;
let rval = r.filter(|v| !v.value_name.is_empty()).map(|v| v.value_name.as_str());
parse::parse_sanitizers(&mut rparsed, rval);

Expand Down Expand Up @@ -166,7 +170,7 @@ impl TargetModifier {
match self.opt {
OptionsTargetModifiers::UnstableOptions(unstable) => match unstable {
UnstableOptionsTargetModifiers::Sanitizer => {
return target_modifier_consistency_check::sanitizer(self, other);
return target_modifier_consistency_check::sanitizer(sess, self, other);
}
UnstableOptionsTargetModifiers::SanitizerCfiNormalizeIntegers => {
return target_modifier_consistency_check::sanitizer_cfi_normalize_integers(
Expand Down
17 changes: 11 additions & 6 deletions compiler/rustc_trait_selection/src/solve/delegate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::hash_map::Entry;
use std::fmt::Debug;
use std::mem;
use std::ops::Deref;

Expand Down Expand Up @@ -319,19 +320,23 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
self.0.leak_check(max_input_universe, None).map_err(|_| NoSolution)
}

fn evaluate_const(
fn evaluate_const<E: Debug>(
&self,
param_env: ty::ParamEnv<'tcx>,
alias_const: ty::AliasConst<'tcx>,
) -> Option<ty::Const<'tcx>> {
normalize_ty: impl FnOnce(ty::Unnormalized<'tcx, Ty<'tcx>>) -> Result<Ty<'tcx>, E>,
) -> Result<Option<ty::Const<'tcx>>, E> {
let ct = ty::Const::new_alias(self.tcx, ty::IsRigid::No, alias_const);

match crate::traits::try_evaluate_const(&self.0, ct, param_env) {
Ok(ct) => Some(ct),
Err(EvaluateConstErr::EvaluationFailure(e)) => Some(ty::Const::new_error(self.tcx, e)),
match crate::traits::try_evaluate_const(&self.0, ct, param_env, normalize_ty) {
Ok(ct) => Ok(Some(ct)),
Err(EvaluateConstErr::EvaluationFailure(e)) => {
Ok(Some(ty::Const::new_error(self.tcx, e)))
}
Err(
EvaluateConstErr::InvalidConstParamTy(_) | EvaluateConstErr::HasGenericsOrInfers,
) => None,
) => Ok(None),
Err(EvaluateConstErr::FailedNormalization(e)) => Err(e),
}
}

Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_trait_selection/src/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -853,8 +853,12 @@ impl<'tcx> AutoTraitFinder<'tcx> {
ty::PredicateKind::ConstEquate(c1, c2) => {
let evaluate = |c: ty::Const<'tcx>| {
if let ty::ConstKind::Alias(_, alias_const) = c.kind() {
let ct =
super::try_evaluate_const(selcx.infcx, c, obligation.param_env);
let ct = super::try_evaluate_const(
selcx.infcx,
c,
obligation.param_env,
|ty| Ok::<_, !>(ty.skip_norm_wip()),
);

if let Err(EvaluateConstErr::InvalidConstParamTy(_)) = ct {
let span = alias_const.kind.def_span(self.tcx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ pub fn is_const_evaluatable<'tcx>(
tcx.dcx().span_bug(span, "evaluating `ConstKind::Expr` is not currently supported");
}
ty::ConstKind::Alias(_, _) => {
match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env) {
match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env, |ty| {
Ok::<_, !>(ty.skip_norm_wip())
}) {
Err(EvaluateConstErr::HasGenericsOrInfers) => {
Err(NotConstEvaluatable::Error(infcx.dcx().span_delayed_bug(
span,
Expand Down Expand Up @@ -98,7 +100,9 @@ pub fn is_const_evaluatable<'tcx>(
_ => bug!("unexpected constkind in `is_const_evalautable: {unexpanded_ct:?}`"),
};

match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env) {
match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env, |ty| {
Ok::<_, !>(ty.skip_norm_wip())
}) {
// If we're evaluating a generic foreign constant, under a nightly compiler while
// the current crate does not enable `feature(generic_const_exprs)`, abort
// compilation with a useful error.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
self.selcx.infcx,
c,
obligation.param_env,
|ty| Ok::<_, !>(ty.skip_norm_wip()),
) {
Ok(val) => Ok(val),
e @ Err(EvaluateConstErr::HasGenericsOrInfers) => {
Expand Down
16 changes: 10 additions & 6 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ pub fn normalize_param_env_or_error<'tcx>(
}

#[derive(Debug)]
pub enum EvaluateConstErr {
pub enum EvaluateConstErr<E> {
/// The constant being evaluated was either a generic parameter or inference variable, *or*,
/// some alias const with either generic parameters or inference variables in its
/// generic arguments.
Expand All @@ -585,6 +585,7 @@ pub enum EvaluateConstErr {
/// CTFE failed to evaluate the constant in some unrecoverable way (e.g. encountered a `panic!`).
/// This is also used when the constant was already tainted by error.
EvaluationFailure(ErrorGuaranteed),
FailedNormalization(E),
}

// FIXME(BoxyUwU): Private this once we `generic_const_exprs` isn't doing its own normalization routine
Expand All @@ -601,7 +602,7 @@ pub fn evaluate_const<'tcx>(
ct: ty::Const<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> ty::Const<'tcx> {
match try_evaluate_const(infcx, ct, param_env) {
match try_evaluate_const(infcx, ct, param_env, |v| Ok::<_, !>(v.skip_norm_wip())) {
Ok(ct) => ct,
Err(EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e)) => {
ty::Const::new_error(infcx.tcx, e)
Expand All @@ -618,12 +619,13 @@ pub fn evaluate_const<'tcx>(
///
/// You should not call this function unless you are implementing normalization itself. Prefer to use
/// `normalize_erasing_regions` or the `normalize` functions on `ObligationCtxt`/`FnCtxt`/`InferCtxt`.
#[instrument(level = "debug", skip(infcx), ret)]
pub fn try_evaluate_const<'tcx>(
#[instrument(level = "debug", skip(infcx, normalize_ty), ret)]
pub fn try_evaluate_const<'tcx, E: Debug>(
infcx: &InferCtxt<'tcx>,
ct: ty::Const<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Result<ty::Const<'tcx>, EvaluateConstErr> {
normalize_ty: impl FnOnce(Unnormalized<'tcx, Ty<'tcx>>) -> Result<Ty<'tcx>, E>,
) -> Result<ty::Const<'tcx>, EvaluateConstErr<E>> {
let tcx = infcx.tcx;
let ct = infcx.resolve_vars_if_possible(ct);
debug!(?ct);
Expand Down Expand Up @@ -762,7 +764,9 @@ pub fn try_evaluate_const<'tcx>(
let span = alias_const.kind.def_span(tcx);
match tcx.const_eval_resolve_for_typeck(typing_env, erased_alias_const, span) {
Ok(Ok(val)) => {
Ok(ty::Const::new_value(tcx, val, alias_const.type_of(tcx).skip_norm_wip()))
let ty = normalize_ty(alias_const.type_of(tcx))
.map_err(EvaluateConstErr::FailedNormalization)?;
Ok(ty::Const::new_value(tcx, val, ty))
}
Ok(Err(_)) => {
let e = tcx.dcx().delayed_bug(
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,11 +921,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {

let evaluate = |c: ty::Const<'tcx>| {
if let ty::ConstKind::Alias(_, _) = c.kind() {
match crate::traits::try_evaluate_const(self.infcx, c, obligation.param_env)
{
Ok(val) => Ok(val),
Err(e) => Err(e),
}
crate::traits::try_evaluate_const(
self.infcx,
c,
obligation.param_env,
|v| Ok::<_, !>(v.skip_norm_wip()),
)
} else {
Ok(c)
}
Expand Down
12 changes: 0 additions & 12 deletions src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,4 @@ if [ "${DIST_TRY_BUILD:-0}" == "0" ]; then
CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist \
gcc-dev \
gcc
# We confirm that the built GCC has support for the `retain` attribute.
# FIXME: Maybe get the path from `.x.py` instead?
gcc_path="./build/$HOSTS/gcc/$HOSTS/install/bin/gcc"
c_code='int x __attribute__((used, retain));'
if echo "$c_code" | "$gcc_path" -S -x c -o - - | grep -i '"a.*R"'; then
echo "retain attribute is supported"
else
echo "retain attribute is not supported"
# We display the generated asm just in case...
echo "$c_code" | "$gcc_path" -S -x c -o - -
exit 1
fi
fi
22 changes: 0 additions & 22 deletions src/ci/docker/scripts/build-gcc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,6 @@ set -eux

source shared.sh

# We have to build our own binutils for the GCC build, because the default CentOS 7 binutils are
# too old, and they do not support `SHF_GNU_RETAIN`.
BINUTILS="2.47"
curl https://ci-mirrors.rust-lang.org/rustc/gcc/binutils-$BINUTILS.tar.xz | xzcat | tar xf -
mkdir binutils-build
cd binutils-build
hide_output ../binutils-$BINUTILS/configure --prefix=/rustroot
hide_output make -j$(nproc)
hide_output make install

cd ..
rm -rf binutils-build binutils-$BINUTILS

if echo '.section .test,"awR",@progbits' | as - -o /dev/null 2>/dev/null; then
echo "binutils assembler supports SHF_GNU_RETAIN"
else
echo "binutils assembler DOES NOT support SHF_GNU_RETAIN"
exit 1
fi


# Note: in the future when bumping to version 10.1.0, also take care of the sed block below.
# This version is specified in the Dockerfile
GCC=$GCC_VERSION
Expand Down Expand Up @@ -57,7 +36,6 @@ sed -i'' 's|ftp://gcc\.gnu\.org/pub/gcc/infrastructure|https://ci-mirrors.rust-l
mkdir ../gcc-build
cd ../gcc-build

export PATH=/rustroot/bin:$PATH
# '-fno-reorder-blocks-and-partition' is required to
# enable BOLT optimization of the C++ standard library,
# which is included in librustc_driver.so
Expand Down
4 changes: 2 additions & 2 deletions src/doc/rustc/src/platform-support/avr-none.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ recommended to always use `--release` to avoid running out of space.
Also, please note that specifying `-C target-cpu`[^1] is required - here's a list of
the possible variants:

https://github.com/llvm/llvm-project/blob/093d4db2f3c874d4683fb01194b00dbb20e5c713/clang/lib/Basic/Targets/AVR.cpp#L32
[https://github.com/llvm/llvm-project/blob/d5a6124259b55789bc49489632efa7c168a4f6cb/clang/lib/Basic/Targets/AVR.cpp#L48](https://github.com/llvm/llvm-project/blob/d5a6124259b55789bc49489632efa7c168a4f6cb/clang/lib/Basic/Targets/AVR.cpp#L48)

Note that devices that have no SRAM are not supported, same as when compiling C/C++ programs with avr-gcc or Clang.

Expand All @@ -86,4 +86,4 @@ $ simavr -m atmega328p ./target/avr-none/release/your-project.elf
```

Alternatively, if you want to write a couple of actual `#[test]`s, you can use
[`avr-tester`](https://github.com/Patryk27/avr-tester).
[`avr-tester`](https://crates.io/crates/avr-tester).
10 changes: 10 additions & 0 deletions tests/ui/target_modifiers/auxiliary/sanitizer_default_explicit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// This represents an rlib where SCS is explicitly provided as a -Zsanitizer flag.

//@ no-prefer-dynamic
//@ compile-flags: --target riscv64gc-unknown-fuchsia -Zsanitizer=shadow-call-stack
//@ needs-llvm-components: riscv
//@ ignore-backends: gcc

#![feature(no_core)]
#![crate_type = "rlib"]
#![no_core]
11 changes: 11 additions & 0 deletions tests/ui/target_modifiers/auxiliary/sanitizer_default_implicit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// This represents an rlib where SCS is not explicitly provided as a -Zsanitizer flag.
// SCS is a default_sanitizer on riscv64gc-unknown-fuchsia.

//@ no-prefer-dynamic
//@ compile-flags: --target riscv64gc-unknown-fuchsia
//@ needs-llvm-components: riscv
//@ ignore-backends: gcc

#![feature(no_core)]
#![crate_type = "rlib"]
#![no_core]
11 changes: 11 additions & 0 deletions tests/ui/target_modifiers/auxiliary/sanitizer_non_default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// This represents an rlib where CFI is explicitly provided as a -Zsanitizer flag.
// CFI is not a default_sanitizer for riscv64gc-unknown-fuchsia.

//@ no-prefer-dynamic
//@ compile-flags: --target riscv64gc-unknown-fuchsia -Zsanitizer=cfi -Clinker-plugin-lto
//@ needs-llvm-components: riscv
//@ ignore-backends: gcc

#![feature(no_core)]
#![crate_type = "rlib"]
#![no_core]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_default`
|
= help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
= note: `-Zsanitizer=shadow-call-stack` in this crate is incompatible with `-Zsanitizer=cfi` in dependency `sanitizer_non_default`
= help: set `-Zsanitizer=cfi` in this crate or `-Zsanitizer=shadow-call-stack` in `sanitizer_non_default`
= help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_default`
|
= help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
= note: `-Zsanitizer` is unset in this crate which is incompatible with `-Zsanitizer=cfi` in dependency `sanitizer_non_default`
= help: set `-Zsanitizer=cfi` in this crate or unset `-Zsanitizer` in `sanitizer_non_default`
= help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error

error: aborting due to 1 previous error

36 changes: 36 additions & 0 deletions tests/ui/target_modifiers/sanitizer_default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Test that we do not get an ABI mismatch error when a default sanitizer is not
// explicitly provided via a -Zsanitizer flag.
//
// riscv64gc-unknown-fuchsia has shadow-call-stack as a default sanitizer.
// Compiling one crate without `-Zsanitizer` and another crate with the target's
// default sanitizer explicitly specified (-Zsanitizer=shadow-call-stack)
// must be accepted.

//@ aux-build:sanitizer_default_implicit.rs
//@ aux-build:sanitizer_default_explicit.rs
//@ aux-build:sanitizer_non_default.rs
//@ compile-flags: --target riscv64gc-unknown-fuchsia
//@ needs-llvm-components: riscv
//@ ignore-backends: gcc

//@ revisions: implicit_default explicit_default implicit_mismatch explicit_mismatch
//@[implicit_default] check-pass
//@[explicit_default] compile-flags: -Zsanitizer=shadow-call-stack
//@[explicit_default] check-pass
//@[explicit_mismatch] compile-flags: -Zsanitizer=shadow-call-stack

#![feature(no_core)]
#![crate_type = "rlib"]
#![no_core]

#[cfg(any(implicit_default, explicit_default))]
extern crate sanitizer_default_implicit;

#[cfg(any(implicit_default, explicit_default))]
extern crate sanitizer_default_explicit;

// We still expect the normal mismatch error with a non-default sanitizer.
#[cfg(any(implicit_mismatch, explicit_mismatch))]
extern crate sanitizer_non_default;
//[implicit_mismatch]~? ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_default`
//[explicit_mismatch]~? ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_default`
Loading
Loading