Skip to content

Rollup of 7 pull requests #119760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
Jan 9, 2024
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ab716d0
Use assert_unsafe_precondition for char::from_u32_unchecked
ChrisDenton Dec 15, 2023
12784c3
Add -Zuse-sync-unwind
quininer Nov 9, 2023
4c4c6a6
Preparing for merge from rustc
Jan 5, 2024
d11a2bd
Merge from rustc
Jan 5, 2024
39c714b
Auto merge of #3252 - rust-lang:rustup-2024-01-05, r=RalfJung
bors Jan 5, 2024
a10b3cd
Fix broken build for ESP IDF due to #119026
ivmarkov Jan 5, 2024
80ee0c0
remove redundant clone
matthiaskrgr Jan 5, 2024
d334a4b
Auto merge of #3253 - matthiaskrgr:noclone, r=RalfJung
bors Jan 5, 2024
7e4e9ad
Preparing for merge from rustc
Jan 6, 2024
078f228
Merge from rustc
Jan 6, 2024
46f53c8
fmt
Jan 6, 2024
1c98b78
implement the rounding intrinsics using apfloat rounding
RalfJung Jan 6, 2024
58c80a0
merge intrinsics-math into float tests
RalfJung Jan 6, 2024
ac4526d
these should be exact
RalfJung Jan 6, 2024
0814a56
Auto merge of #3254 - rust-lang:rustup-2024-01-06, r=saethlin
bors Jan 6, 2024
643e7f0
./miri build: also build tests, to avoid rebuilds later
RalfJung Jan 6, 2024
66b15ae
cargo update
RalfJung Jan 6, 2024
b8209e2
use jemalloc as global allocator
RalfJung Jan 7, 2024
c4a11ea
only use jemalloc on Unix
RalfJung Jan 7, 2024
d93ca6e
Auto merge of #3259 - RalfJung:jemalloc, r=RalfJung
bors Jan 7, 2024
8675aa1
Auto merge of #3256 - RalfJung:rounding, r=RalfJung
bors Jan 7, 2024
6f017d2
Auto merge of #3257 - RalfJung:build-tests, r=RalfJung
bors Jan 7, 2024
5b30586
Adding alignment to the list of cases to test for specific error mess…
madsravn Jan 7, 2024
7d5de70
Check if tier 2 targets build in the nightly cron job
saethlin Jan 7, 2024
d475e62
Auto merge of #3260 - saethlin:build-all-tier-2, r=RalfJung
bors Jan 7, 2024
56ff1b8
only use jemalloc on Linux and macOS
RalfJung Jan 8, 2024
8d4a5c7
Auto merge of #3261 - RalfJung:jemalloc, r=RalfJung
bors Jan 8, 2024
0ddccf9
update lockfile
RalfJung Jan 8, 2024
8aa7dd0
enable RUSTC_BOOTSTRAP on panic=abort mir-opt test
onur-ozkan Jan 5, 2024
26c71cb
detect user-specified custom targets in compiletest
onur-ozkan Jan 5, 2024
b888e2f
fix the incorrect target on stage1 ui-fulldeps tests
onur-ozkan Jan 7, 2024
8abf133
Make inductive cycles in coherence ambiguous always
compiler-errors Dec 5, 2023
506c066
Removing redudant note from parse error
madsravn Jan 8, 2024
9e4843e
Rollup merge of #117744 - quininer:add-z-sync-uw, r=bjorn3
matthiaskrgr Jan 9, 2024
1974f5c
Rollup merge of #118649 - compiler-errors:coherence-ambig, r=lcnr
matthiaskrgr Jan 9, 2024
b0c492c
Rollup merge of #118979 - ChrisDenton:unwrap-const, r=Nilstrieb,dtolnay
matthiaskrgr Jan 9, 2024
985b2ce
Rollup merge of #119619 - onur-ozkan:panic-abort-mir-opt, r=oli-obk
matthiaskrgr Jan 9, 2024
50982bd
Rollup merge of #119632 - ivmarkov:master, r=Nilstrieb,dtolnay
matthiaskrgr Jan 9, 2024
deb504b
Rollup merge of #119712 - madsravn:parsing-errors, r=estebank
matthiaskrgr Jan 9, 2024
91fcc17
Rollup merge of #119734 - RalfJung:miri, r=RalfJung
matthiaskrgr Jan 9, 2024
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
6 changes: 3 additions & 3 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -2465,6 +2465,7 @@ dependencies = [
"ctrlc",
"env_logger",
"getrandom",
"jemalloc-sys",
"lazy_static",
"libc",
"libffi",
@@ -2474,7 +2475,6 @@ dependencies = [
"rand",
"regex",
"rustc_version",
"serde",
"smallvec",
"ui_test",
]
@@ -3280,9 +3280,9 @@ dependencies = [

[[package]]
name = "rustc-build-sysroot"
version = "0.4.2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ed2a90dfa5232ed5ff21d53d4df655f315ab316ea06fc508f1c74bcedb1ce6c"
checksum = "39dcf8d82b1f79a179bdb284dc44db440a9666eefa5a6df5ef282d6db930d544"
dependencies = [
"anyhow",
"rustc_version",
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_llvm/src/allocator.rs
Original file line number Diff line number Diff line change
@@ -134,7 +134,8 @@ fn create_wrapper_function(
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
if tcx.sess.must_emit_unwind_tables() {
let uwtable = attributes::uwtable_attr(llcx);
let uwtable =
attributes::uwtable_attr(llcx, tcx.sess.opts.unstable_opts.use_sync_unwind);
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
}

7 changes: 4 additions & 3 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
@@ -95,11 +95,12 @@ pub fn sanitize_attrs<'ll>(

/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
#[inline]
pub fn uwtable_attr(llcx: &llvm::Context) -> &Attribute {
pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Attribute {
// NOTE: We should determine if we even need async unwind tables, as they
// take have more overhead and if we can use sync unwind tables we
// probably should.
llvm::CreateUWTableAttr(llcx, true)
let async_unwind = !use_sync_unwind.unwrap_or(false);
llvm::CreateUWTableAttr(llcx, async_unwind)
}

pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
@@ -333,7 +334,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
// You can also find more info on why Windows always requires uwtables here:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1302078
if cx.sess().must_emit_unwind_tables() {
to_add.push(uwtable_attr(cx.llcx));
to_add.push(uwtable_attr(cx.llcx, cx.sess().opts.unstable_opts.use_sync_unwind));
}

if cx.sess().opts.unstable_opts.profile_sample_use.is_some() {
5 changes: 5 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
@@ -513,6 +513,11 @@ fn register_builtins(store: &mut LintStore) {
"converted into hard error, see PR #117984 \
<https://github.com/rust-lang/rust/pull/117984> for more information",
);
store.register_removed(
"coinductive_overlap_in_coherence",
"converted into hard error, see PR #118649 \
<https://github.com/rust-lang/rust/pull/118649> for more information",
);
}

fn register_internals(store: &mut LintStore) {
40 changes: 0 additions & 40 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -26,7 +26,6 @@ declare_lint_pass! {
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
CENUM_IMPL_DROP_CAST,
COHERENCE_LEAK_CHECK,
COINDUCTIVE_OVERLAP_IN_COHERENCE,
CONFLICTING_REPR_HINTS,
CONST_EVALUATABLE_UNCHECKED,
CONST_ITEM_MUTATION,
@@ -4367,45 +4366,6 @@ declare_lint! {
@feature_gate = sym::type_privacy_lints;
}

declare_lint! {
/// The `coinductive_overlap_in_coherence` lint detects impls which are currently
/// considered not overlapping, but may be considered to overlap if support for
/// coinduction is added to the trait solver.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(coinductive_overlap_in_coherence)]
///
/// trait CyclicTrait {}
/// impl<T: CyclicTrait> CyclicTrait for T {}
///
/// trait Trait {}
/// impl<T: CyclicTrait> Trait for T {}
/// // conflicting impl with the above
/// impl Trait for u8 {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// We have two choices for impl which satisfy `u8: Trait`: the blanket impl
/// for generic `T`, and the direct impl for `u8`. These two impls nominally
/// overlap, since we can infer `T = u8` in the former impl, but since the where
/// clause `u8: CyclicTrait` would end up resulting in a cycle (since it depends
/// on itself), the blanket impl is not considered to hold for `u8`. This will
/// change in a future release.
pub COINDUCTIVE_OVERLAP_IN_COHERENCE,
Deny,
"impls that are not considered to overlap may be considered to \
overlap in the future",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
reference: "issue #114040 <https://github.com/rust-lang/rust/issues/114040>",
};
}

declare_lint! {
/// The `unknown_or_malformed_diagnostic_attributes` lint detects unrecognized or otherwise malformed
/// diagnostic attributes.
28 changes: 22 additions & 6 deletions compiler/rustc_parse_format/src/lib.rs
Original file line number Diff line number Diff line change
@@ -289,10 +289,10 @@ impl<'a> Iterator for Parser<'a> {
}
} else {
if let Some(&(_, maybe)) = self.cur.peek() {
if maybe == '?' {
self.suggest_format();
} else {
self.suggest_positional_arg_instead_of_captured_arg(arg);
match maybe {
'?' => self.suggest_format_debug(),
'<' | '^' | '>' => self.suggest_format_align(maybe),
_ => self.suggest_positional_arg_instead_of_captured_arg(arg),
}
}
}
@@ -868,10 +868,9 @@ impl<'a> Parser<'a> {
found.then_some(cur)
}

fn suggest_format(&mut self) {
fn suggest_format_debug(&mut self) {
if let (Some(pos), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
let word = self.word();
let _end = self.current_pos();
let pos = self.to_span_index(pos);
self.errors.insert(
0,
@@ -887,6 +886,23 @@ impl<'a> Parser<'a> {
}
}

fn suggest_format_align(&mut self, alignment: char) {
if let Some(pos) = self.consume_pos(alignment) {
let pos = self.to_span_index(pos);
self.errors.insert(
0,
ParseError {
description: "expected format parameter to occur after `:`".to_owned(),
note: None,
label: format!("expected `{}` to occur after `:`", alignment).to_owned(),
span: pos.to(pos),
secondary_label: None,
suggestion: Suggestion::None,
},
);
}
}

fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) {
if let Some(end) = self.consume_pos('.') {
let byte_pos = self.to_span_index(end);
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
@@ -1960,6 +1960,8 @@ written to standard error output)"),
"adds unstable command line options to rustc interface (default: no)"),
use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED],
"use legacy .ctors section for initializers rather than .init_array"),
use_sync_unwind: Option<bool> = (None, parse_opt_bool, [TRACKED],
"Generate sync unwind tables instead of async unwind tables (default: no)"),
validate_mir: bool = (false, parse_bool, [UNTRACKED],
"validate MIR after each transformation"),
#[rustc_lint_opt_deny_field_access("use `Session::verbose_internals` instead of this field")]
64 changes: 6 additions & 58 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor
use crate::solve::{deeply_normalize_for_diagnostics, inspect};
use crate::traits::engine::TraitEngineExt;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::select::{IntercrateAmbiguityCause, TreatInductiveCycleAs};
use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::structural_normalize::StructurallyNormalizeExt;
use crate::traits::NormalizeExt;
use crate::traits::SkipLeakCheck;
@@ -31,7 +31,6 @@ use rustc_middle::traits::DefiningAnchor;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_session::lint::builtin::COINDUCTIVE_OVERLAP_IN_COHERENCE;
use rustc_span::symbol::sym;
use rustc_span::DUMMY_SP;
use std::fmt::Debug;
@@ -197,7 +196,7 @@ fn overlap<'tcx>(
.intercrate(true)
.with_next_trait_solver(tcx.next_trait_solver_in_coherence())
.build();
let selcx = &mut SelectionContext::new(&infcx);
let selcx = &mut SelectionContext::with_treat_inductive_cycle_as_ambig(&infcx);
if track_ambiguity_causes.is_yes() {
selcx.enable_tracking_intercrate_ambiguity_causes();
}
@@ -224,61 +223,10 @@ fn overlap<'tcx>(
);

if overlap_mode.use_implicit_negative() {
for mode in [TreatInductiveCycleAs::Ambig, TreatInductiveCycleAs::Recur] {
if let Some(failing_obligation) = selcx.with_treat_inductive_cycle_as(mode, |selcx| {
impl_intersection_has_impossible_obligation(selcx, &obligations)
}) {
if matches!(mode, TreatInductiveCycleAs::Recur) {
let first_local_impl = impl1_header
.impl_def_id
.as_local()
.or(impl2_header.impl_def_id.as_local())
.expect("expected one of the impls to be local");
infcx.tcx.struct_span_lint_hir(
COINDUCTIVE_OVERLAP_IN_COHERENCE,
infcx.tcx.local_def_id_to_hir_id(first_local_impl),
infcx.tcx.def_span(first_local_impl),
format!(
"implementations {} will conflict in the future",
match impl1_header.trait_ref {
Some(trait_ref) => {
let trait_ref = infcx.resolve_vars_if_possible(trait_ref);
format!(
"of `{}` for `{}`",
trait_ref.print_trait_sugared(),
trait_ref.self_ty()
)
}
None => format!(
"for `{}`",
infcx.resolve_vars_if_possible(impl1_header.self_ty)
),
},
),
|lint| {
lint.note(
"impls that are not considered to overlap may be considered to \
overlap in the future",
)
.span_label(
infcx.tcx.def_span(impl1_header.impl_def_id),
"the first impl is here",
)
.span_label(
infcx.tcx.def_span(impl2_header.impl_def_id),
"the second impl is here",
);
lint.note(format!(
"`{}` may be considered to hold in future releases, \
causing the impls to overlap",
infcx.resolve_vars_if_possible(failing_obligation.predicate)
));
},
);
}

return None;
}
if let Some(_failing_obligation) =
impl_intersection_has_impossible_obligation(selcx, &obligations)
{
return None;
}
}

20 changes: 8 additions & 12 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
@@ -239,20 +239,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}

// Sets the `TreatInductiveCycleAs` mode temporarily in the selection context
pub fn with_treat_inductive_cycle_as<T>(
&mut self,
treat_inductive_cycle: TreatInductiveCycleAs,
f: impl FnOnce(&mut Self) -> T,
) -> T {
pub fn with_treat_inductive_cycle_as_ambig(
infcx: &'cx InferCtxt<'tcx>,
) -> SelectionContext<'cx, 'tcx> {
// Should be executed in a context where caching is disabled,
// otherwise the cache is poisoned with the temporary result.
assert!(self.is_intercrate());
let treat_inductive_cycle =
std::mem::replace(&mut self.treat_inductive_cycle, treat_inductive_cycle);
let value = f(self);
self.treat_inductive_cycle = treat_inductive_cycle;
value
assert!(infcx.intercrate);
SelectionContext {
treat_inductive_cycle: TreatInductiveCycleAs::Ambig,
..SelectionContext::new(infcx)
}
}

pub fn with_query_mode(
9 changes: 8 additions & 1 deletion library/core/src/char/convert.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ use crate::char::TryFromCharError;
use crate::convert::TryFrom;
use crate::error::Error;
use crate::fmt;
use crate::intrinsics::assert_unsafe_precondition;
use crate::mem::transmute;
use crate::str::FromStr;

@@ -23,7 +24,13 @@ pub(super) const fn from_u32(i: u32) -> Option<char> {
#[must_use]
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
// SAFETY: the caller must guarantee that `i` is a valid char value.
if cfg!(debug_assertions) { char::from_u32(i).unwrap() } else { unsafe { transmute(i) } }
unsafe {
assert_unsafe_precondition!(
"invalid value for `char`",
(i: u32) => char_try_from_u32(i).is_ok()
);
transmute(i)
}
}

#[stable(feature = "char_convert", since = "1.13.0")]
5 changes: 3 additions & 2 deletions library/std/src/os/unix/net/listener.rs
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ impl UnixListener {
unsafe {
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
let (addr, len) = sockaddr_un(path.as_ref())?;
#[cfg(any(target_os = "windows", target_os = "redox"))]
#[cfg(any(target_os = "windows", target_os = "redox", target_os = "espidf"))]
const backlog: libc::c_int = 128;
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))]
const backlog: libc::c_int = -1;
@@ -82,7 +82,8 @@ impl UnixListener {
target_os = "redox",
target_os = "linux",
target_os = "freebsd",
target_os = "openbsd"
target_os = "openbsd",
target_os = "espidf"
)))]
const backlog: libc::c_int = libc::SOMAXCONN;

5 changes: 5 additions & 0 deletions src/bootstrap/src/core/build_steps/synthetic_targets.rs
Original file line number Diff line number Diff line change
@@ -59,6 +59,11 @@ fn create_synthetic_target(
let mut cmd = Command::new(builder.rustc(compiler));
cmd.arg("--target").arg(base.rustc_target_arg());
cmd.args(["-Zunstable-options", "--print", "target-spec-json"]);

// If `rust.channel` is set to either beta or stable, rustc will complain that
// we cannot use nightly features. So `RUSTC_BOOTSTRAP` is needed here.
cmd.env("RUSTC_BOOTSTRAP", "1");

cmd.stdout(Stdio::piped());

let output = cmd.spawn().unwrap().wait_with_output().unwrap();
9 changes: 7 additions & 2 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
@@ -1596,8 +1596,13 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
// NOTE: Only stage 1 is special cased because we need the rustc_private artifacts to match the
// running compiler in stage 2 when plugins run.
let stage_id = if suite == "ui-fulldeps" && compiler.stage == 1 {
compiler = builder.compiler(compiler.stage - 1, target);
format!("stage{}-{}", compiler.stage + 1, target)
// At stage 0 (stage - 1) we are using the beta compiler. Using `self.target` can lead finding
// an incorrect compiler path on cross-targets, as the stage 0 beta compiler is always equal
// to `build.build` in the configuration.
let build = builder.build.build;

compiler = builder.compiler(compiler.stage - 1, build);
format!("stage{}-{}", compiler.stage + 1, build)
} else {
format!("stage{}-{}", compiler.stage, target)
};
45 changes: 33 additions & 12 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
@@ -483,6 +483,7 @@ impl TargetCfgs {
let mut targets: HashMap<String, TargetCfg> = serde_json::from_str(&rustc_output(
config,
&["--print=all-target-specs-json", "-Zunstable-options"],
Default::default(),
))
.unwrap();

@@ -495,16 +496,33 @@ impl TargetCfgs {
let mut all_families = HashSet::new();
let mut all_pointer_widths = HashSet::new();

// Handle custom target specs, which are not included in `--print=all-target-specs-json`.
if config.target.ends_with(".json") {
targets.insert(
config.target.clone(),
serde_json::from_str(&rustc_output(
config,
&["--print=target-spec-json", "-Zunstable-options", "--target", &config.target],
))
.unwrap(),
);
// If current target is not included in the `--print=all-target-specs-json` output,
// we check whether it is a custom target from the user or a synthetic target from bootstrap.
if !targets.contains_key(&config.target) {
let mut envs: HashMap<String, String> = HashMap::new();

if let Ok(t) = std::env::var("RUST_TARGET_PATH") {
envs.insert("RUST_TARGET_PATH".into(), t);
}

// This returns false only when the target is neither a synthetic target
// nor a custom target from the user, indicating it is most likely invalid.
if config.target.ends_with(".json") || !envs.is_empty() {
targets.insert(
config.target.clone(),
serde_json::from_str(&rustc_output(
config,
&[
"--print=target-spec-json",
"-Zunstable-options",
"--target",
&config.target,
],
envs,
))
.unwrap(),
);
}
}

for (target, cfg) in targets.iter() {
@@ -549,7 +567,9 @@ impl TargetCfgs {
// code below extracts them from `--print=cfg`: make sure to only override fields that can
// actually be changed with `-C` flags.
for config in
rustc_output(config, &["--print=cfg", "--target", &config.target]).trim().lines()
rustc_output(config, &["--print=cfg", "--target", &config.target], Default::default())
.trim()
.lines()
{
let (name, value) = config
.split_once("=\"")
@@ -628,11 +648,12 @@ pub enum Endian {
Big,
}

fn rustc_output(config: &Config, args: &[&str]) -> String {
fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
let mut command = Command::new(&config.rustc_path);
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
command.args(&config.target_rustcflags).args(args);
command.env("RUSTC_BOOTSTRAP", "1");
command.envs(envs);

let output = match command.output() {
Ok(output) => output,
4 changes: 2 additions & 2 deletions src/tools/miri/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ jobs:
cargo -V
- name: Test
run: ./ci.sh
run: ./ci/ci.sh

style:
name: style checks
@@ -169,7 +169,7 @@ jobs:
--message 'Dear @*T-miri*,
It would appear that the [Miri cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed.
This likely means that rustc changed the miri directory and
we now need to do a [`./miri rustc-pull`](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#importing-changes-from-the-rustc-repo).
49 changes: 49 additions & 0 deletions src/tools/miri/.github/workflows/sysroots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Tier 2 sysroots

on: push
# schedule:
# - cron: '44 4 * * *' # At 4:44 UTC every day.

defaults:
run:
shell: bash

jobs:
sysroots:
name: Build the sysroots
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the sysroots
run: |
cargo install -f rustup-toolchain-install-master
./miri toolchain -c rust-docs # Docs are the only place targets are separated by tier
./miri install
python3 -m pip install beautifulsoup4
./ci/build-all-targets.sh
sysroots-cron-fail-notify:
name: sysroots cronjob failure notification
runs-on: ubuntu-latest
needs: [sysroots]
if: failure() || cancelled()
steps:
# Send a Zulip notification
- name: Install zulip-send
run: pip3 install zulip
- name: Send Zulip notification
env:
ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }}
ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
run: |
~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \
--stream miri --subject "Cron Job Failure (miri, $(date -u +%Y-%m))" \
--message 'Dear @*T-miri*,
It would appear that the [Miri sysroots cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed.
Would you mind investigating this issue?
Thanks in advance!
Sincerely,
The Miri Cronjobs Bot'
322 changes: 187 additions & 135 deletions src/tools/miri/Cargo.lock

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions src/tools/miri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -24,10 +24,16 @@ log = "0.4"
rand = "0.8"
smallvec = "1.7"
aes = { version = "0.8.3", features = ["hazmat"] }

measureme = "10.0.0"
ctrlc = "3.2.5"

# Copied from `compiler/rustc/Cargo.toml`.
# But only for some targets, it fails for others. Rustc configures this in its CI, but we can't
# easily use that since we support of-tree builds.
[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies.jemalloc-sys]
version = "0.5.0"
features = ['unprefixed_malloc_on_supported_platforms']

[target.'cfg(unix)'.dependencies]
libc = "0.2"

@@ -39,11 +45,8 @@ libloading = "0.8"
colored = "2"
ui_test = "0.21.1"
rustc_version = "0.4"
# Features chosen to match those required by env_logger, to avoid rebuilds
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
regex = "1.5.5"
lazy_static = "1.4.0"
# Require a version of serde without intransparent unreproducible binary blobs.
serde = { version = "1.0.185", features = ["derive"] }

[package.metadata.rust-analyzer]
# This crate uses #[feature(rustc_private)].
232 changes: 140 additions & 92 deletions src/tools/miri/cargo-miri/Cargo.lock

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions src/tools/miri/ci/build-all-targets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

set -eu
set -o pipefail

FAILS_DIR=failures

rm -rf $FAILS_DIR
mkdir $FAILS_DIR

PLATFORM_SUPPORT_FILE=$(rustc +miri --print sysroot)/share/doc/rust/html/rustc/platform-support.html

for target in $(python3 ci/scrape-targets.py $PLATFORM_SUPPORT_FILE); do
# Wipe the cache before every build to minimize disk usage
rm -rf ~/.cache/miri
if cargo +miri miri setup --target $target 2>&1 | tee failures/$target; then
# If the build succeeds, delete its output. If we have output, a build failed.
rm $FAILS_DIR/$target
fi
done

# If the sysroot for any target fails to build, we will have a file in FAILS_DIR.
if [[ $(ls failures | wc -l) -ne 0 ]]; then
echo "Sysroots for the following targets failed to build:"
ls $FAILS_DIR
exit 1
fi
File renamed without changes.
15 changes: 15 additions & 0 deletions src/tools/miri/ci/scrape-targets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import sys
from bs4 import BeautifulSoup

html = open(sys.argv[1], 'r').read()
soup = BeautifulSoup(html, features="html.parser")
# The tables are:
# Tier 1 <-- this is already checked by main CI, so we ignore it here
# Tier 2 with host tools <-- we want this one
# Tier 2 without host tools <-- and also this
# Tier 3
for table in soup.find_all("table")[1:3]:
for row in table.find_all('tr'):
code = row.find('code')
if code is not None:
print(code.text)
193 changes: 125 additions & 68 deletions src/tools/miri/miri-script/Cargo.lock
4 changes: 3 additions & 1 deletion src/tools/miri/miri-script/src/util.rs
Original file line number Diff line number Diff line change
@@ -111,9 +111,11 @@ impl MiriEnv {
) -> Result<()> {
let MiriEnv { toolchain, cargo_extra_flags, .. } = self;
let quiet_flag = if quiet { Some("--quiet") } else { None };
// We build the tests as well, (a) to avoid having rebuilds when building the tests later
// and (b) to have more parallelism during the build of Miri and its tests.
let mut cmd = cmd!(
self.sh,
"cargo +{toolchain} build {cargo_extra_flags...} --manifest-path {manifest_path} {quiet_flag...} {args...}"
"cargo +{toolchain} build --bins --tests {cargo_extra_flags...} --manifest-path {manifest_path} {quiet_flag...} {args...}"
);
cmd.set_quiet(quiet);
cmd.run()?;
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2271c26e4a8e062bb00d709d0ccb5846e0c341b9
5bcd86d89b2b7b6a490f7e075dd4eb346deb5f98
40 changes: 39 additions & 1 deletion src/tools/miri/src/bin/miri.rs
Original file line number Diff line number Diff line change
@@ -293,13 +293,51 @@ fn run_compiler(
}

/// Parses a comma separated list of `T` from the given string:
///
/// `<value1>,<value2>,<value3>,...`
fn parse_comma_list<T: FromStr>(input: &str) -> Result<Vec<T>, T::Err> {
input.split(',').map(str::parse::<T>).collect()
}

#[cfg(any(target_os = "linux", target_os = "macos"))]
fn jemalloc_magic() {
// These magic runes are copied from
// <https://github.com/rust-lang/rust/blob/e89bd9428f621545c979c0ec686addc6563a394e/compiler/rustc/src/main.rs#L39>.
// See there for further comments.
use std::os::raw::{c_int, c_void};

#[used]
static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc;
#[used]
static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int =
jemalloc_sys::posix_memalign;
#[used]
static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc;
#[used]
static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc;
#[used]
static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc;
#[used]
static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free;

// On OSX, jemalloc doesn't directly override malloc/free, but instead
// registers itself with the allocator's zone APIs in a ctor. However,
// the linker doesn't seem to consider ctors as "used" when statically
// linking, so we need to explicitly depend on the function.
#[cfg(target_os = "macos")]
{
extern "C" {
fn _rjem_je_zone_register();
}

#[used]
static _F7: unsafe extern "C" fn() = _rjem_je_zone_register;
}
}

fn main() {
#[cfg(any(target_os = "linux", target_os = "macos"))]
jemalloc_magic();

let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());

// Snapshot a copy of the environment before `rustc` starts messing with it.
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
Original file line number Diff line number Diff line change
@@ -612,7 +612,7 @@ impl<'tcx> Tree {
is_foreign: rel_pos.is_foreign(),
access_cause,
access_range,
transition_range: perms_range.clone(),
transition_range: perms_range,
span,
});
}
52 changes: 30 additions & 22 deletions src/tools/miri/src/shims/intrinsics/mod.rs
Original file line number Diff line number Diff line change
@@ -145,17 +145,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"fabsf32" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f32()?;
// Can be implemented in soft-floats.
// This is a "bitwise" operation, so there's no NaN non-determinism.
this.write_scalar(Scalar::from_f32(f.abs()), dest)?;
}
"fabsf64" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f64()?;
// Can be implemented in soft-floats.
// This is a "bitwise" operation, so there's no NaN non-determinism.
this.write_scalar(Scalar::from_f64(f.abs()), dest)?;
}
"floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f32()?;
let mode = match intrinsic_name {
"floorf32" => Round::TowardNegative,
"ceilf32" => Round::TowardPositive,
"truncf32" => Round::TowardZero,
"roundf32" => Round::NearestTiesToAway,
"rintf32" => Round::NearestTiesToEven,
_ => bug!(),
};
let res = f.round_to_integral(mode).value;
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}
#[rustfmt::skip]
| "sinf32"
| "cosf32"
@@ -165,11 +178,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
| "logf32"
| "log10f32"
| "log2f32"
| "floorf32"
| "ceilf32"
| "truncf32"
| "roundf32"
| "rintf32"
=> {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f32()?;
@@ -184,18 +192,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"logf32" => f_host.ln(),
"log10f32" => f_host.log10(),
"log2f32" => f_host.log2(),
"floorf32" => f_host.floor(),
"ceilf32" => f_host.ceil(),
"truncf32" => f_host.trunc(),
"roundf32" => f_host.round(),
"rintf32" => f_host.round_ties_even(),
_ => bug!(),
};
let res = res.to_soft();
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}

"floorf64" | "ceilf64" | "truncf64" | "roundf64" | "rintf64" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f64()?;
let mode = match intrinsic_name {
"floorf64" => Round::TowardNegative,
"ceilf64" => Round::TowardPositive,
"truncf64" => Round::TowardZero,
"roundf64" => Round::NearestTiesToAway,
"rintf64" => Round::NearestTiesToEven,
_ => bug!(),
};
let res = f.round_to_integral(mode).value;
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}
#[rustfmt::skip]
| "sinf64"
| "cosf64"
@@ -205,11 +223,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
| "logf64"
| "log10f64"
| "log2f64"
| "floorf64"
| "ceilf64"
| "truncf64"
| "roundf64"
| "rintf64"
=> {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f64()?;
@@ -224,11 +237,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"logf64" => f_host.ln(),
"log10f64" => f_host.log10(),
"log2f64" => f_host.log2(),
"floorf64" => f_host.floor(),
"ceilf64" => f_host.ceil(),
"truncf64" => f_host.trunc(),
"roundf64" => f_host.round(),
"rintf64" => f_host.round_ties_even(),
_ => bug!(),
};
let res = res.to_soft();
117 changes: 54 additions & 63 deletions src/tools/miri/test_dependencies/Cargo.lock
Original file line number Diff line number Diff line change
@@ -3,7 +3,12 @@
// Some targets treat arrays and structs very differently. We would probably catch that on those
// targets since we check the `PassMode`; here we ensure that we catch it on *all* targets
// (in particular, on x86-64 the pass mode is `Indirect` for both of these).
struct S(#[allow(dead_code)] i32, #[allow(dead_code)] i32, #[allow(dead_code)] i32, #[allow(dead_code)] i32);
struct S(
#[allow(dead_code)] i32,
#[allow(dead_code)] i32,
#[allow(dead_code)] i32,
#[allow(dead_code)] i32,
);
type A = [i32; 4];

fn main() {
163 changes: 161 additions & 2 deletions src/tools/miri/tests/pass/float.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
#![feature(stmt_expr_attributes)]
#![feature(round_ties_even)]
#![feature(float_gamma)]
#![allow(arithmetic_overflow)]

use std::fmt::Debug;
use std::hint::black_box;
use std::{f32, f64};

macro_rules! assert_approx_eq {
($a:expr, $b:expr) => {{
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b);
}};
}

fn main() {
basic();
@@ -11,6 +21,8 @@ fn main() {
ops();
nan_casts();
rounding();
mul_add();
libm();
}

// Helper function to avoid promotion so that this tests "run-time" casts, not CTFE.
@@ -148,8 +160,6 @@ fn basic() {
assert_ne!({ 5.0_f32 / 0.0 }, { -5.0_f32 / 0.0 });
assert!((5.0_f64 / 0.0).is_infinite());
assert_ne!({ 5.0_f64 / 0.0 }, { 5.0_f64 / -0.0 });
assert!((-5.0_f32).sqrt().is_nan());
assert!((-5.0_f64).sqrt().is_nan());
assert_ne!(f32::NAN, f32::NAN);
assert_ne!(f64::NAN, f64::NAN);
// negative zero
@@ -178,6 +188,9 @@ fn basic() {
assert!((black_box(1.0f64) % -1.0).is_sign_positive());
assert!((black_box(-1.0f64) % 1.0).is_sign_negative());
assert!((black_box(-1.0f64) % -1.0).is_sign_negative());

assert_eq!((-1.0f32).abs(), 1.0f32);
assert_eq!(34.2f64.abs(), 34.2f64);
}

/// Many of these test values are taken from
@@ -592,4 +605,150 @@ fn rounding() {
assert_eq((-1.3f64).round_ties_even(), -1.0f64);
assert_eq((-1.5f64).round_ties_even(), -2.0f64);
assert_eq((-1.7f64).round_ties_even(), -2.0f64);

assert_eq!(3.8f32.floor(), 3.0f32);
assert_eq!((-1.1f64).floor(), -2.0f64);

assert_eq!((-2.3f32).ceil(), -2.0f32);
assert_eq!(3.8f64.ceil(), 4.0f64);

assert_eq!(0.1f32.trunc(), 0.0f32);
assert_eq!((-0.1f64).trunc(), 0.0f64);

assert_eq!(3.3_f32.round(), 3.0);
assert_eq!(2.5_f32.round(), 3.0);
assert_eq!(3.9_f64.round(), 4.0);
assert_eq!(2.5_f64.round(), 3.0);
}

fn mul_add() {
assert_eq!(3.0f32.mul_add(2.0f32, 5.0f32), 11.0);
assert_eq!(0.0f32.mul_add(-2.0, f32::consts::E), f32::consts::E);
assert_eq!(3.0f64.mul_add(2.0, 5.0), 11.0);
assert_eq!(0.0f64.mul_add(-2.0f64, f64::consts::E), f64::consts::E);
assert_eq!((-3.2f32).mul_add(2.4, f32::NEG_INFINITY), f32::NEG_INFINITY);
assert_eq!((-3.2f64).mul_add(2.4, f64::NEG_INFINITY), f64::NEG_INFINITY);

let f = f32::mul_add(
-0.000000000000000000000000000000000000014728589,
0.0000037105144,
0.000000000000000000000000000000000000000000055,
);
assert_eq!(f.to_bits(), f32::to_bits(-0.0));
}

pub fn libm() {
fn ldexp(a: f64, b: i32) -> f64 {
extern "C" {
fn ldexp(x: f64, n: i32) -> f64;
}
unsafe { ldexp(a, b) }
}

assert_approx_eq!(64f32.sqrt(), 8f32);
assert_approx_eq!(64f64.sqrt(), 8f64);
assert!((-5.0_f32).sqrt().is_nan());
assert!((-5.0_f64).sqrt().is_nan());

assert_approx_eq!(25f32.powi(-2), 0.0016f32);
assert_approx_eq!(23.2f64.powi(2), 538.24f64);

assert_approx_eq!(25f32.powf(-2f32), 0.0016f32);
assert_approx_eq!(400f64.powf(0.5f64), 20f64);

assert_approx_eq!(1f32.exp(), f32::consts::E);
assert_approx_eq!(1f64.exp(), f64::consts::E);

assert_approx_eq!(1f32.exp_m1(), f32::consts::E - 1.0);
assert_approx_eq!(1f64.exp_m1(), f64::consts::E - 1.0);

assert_approx_eq!(10f32.exp2(), 1024f32);
assert_approx_eq!(50f64.exp2(), 1125899906842624f64);

assert_approx_eq!(f32::consts::E.ln(), 1f32);
assert_approx_eq!(1f64.ln(), 0f64);

assert_approx_eq!(0f32.ln_1p(), 0f32);
assert_approx_eq!(0f64.ln_1p(), 0f64);

assert_approx_eq!(10f32.log10(), 1f32);
assert_approx_eq!(f64::consts::E.log10(), f64::consts::LOG10_E);

assert_approx_eq!(8f32.log2(), 3f32);
assert_approx_eq!(f64::consts::E.log2(), f64::consts::LOG2_E);

#[allow(deprecated)]
{
assert_approx_eq!(5.0f32.abs_sub(3.0), 2.0);
assert_approx_eq!(3.0f64.abs_sub(5.0), 0.0);
}

assert_approx_eq!(27.0f32.cbrt(), 3.0f32);
assert_approx_eq!(27.0f64.cbrt(), 3.0f64);

assert_approx_eq!(3.0f32.hypot(4.0f32), 5.0f32);
assert_approx_eq!(3.0f64.hypot(4.0f64), 5.0f64);

assert_eq!(ldexp(0.65f64, 3i32), 5.2f64);
assert_eq!(ldexp(1.42, 0xFFFF), f64::INFINITY);
assert_eq!(ldexp(1.42, -0xFFFF), 0f64);

// Trigonometric functions.

assert_approx_eq!(0f32.sin(), 0f32);
assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64);
assert_approx_eq!(f32::consts::FRAC_PI_6.sin(), 0.5);
assert_approx_eq!(f64::consts::FRAC_PI_6.sin(), 0.5);
assert_approx_eq!(f32::consts::FRAC_PI_4.sin().asin(), f32::consts::FRAC_PI_4);
assert_approx_eq!(f64::consts::FRAC_PI_4.sin().asin(), f64::consts::FRAC_PI_4);

assert_approx_eq!(1.0f32.sinh(), 1.1752012f32);
assert_approx_eq!(1.0f64.sinh(), 1.1752012f64);
assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);

assert_approx_eq!(0f32.cos(), 1f32);
assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64);
assert_approx_eq!(f32::consts::FRAC_PI_3.cos(), 0.5);
assert_approx_eq!(f64::consts::FRAC_PI_3.cos(), 0.5);
assert_approx_eq!(f32::consts::FRAC_PI_4.cos().acos(), f32::consts::FRAC_PI_4);
assert_approx_eq!(f64::consts::FRAC_PI_4.cos().acos(), f64::consts::FRAC_PI_4);

assert_approx_eq!(1.0f32.cosh(), 1.54308f32);
assert_approx_eq!(1.0f64.cosh(), 1.54308f64);
assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);

assert_approx_eq!(1.0f32.tan(), 1.557408f32);
assert_approx_eq!(1.0f64.tan(), 1.557408f64);
assert_approx_eq!(1.0_f32, 1.0_f32.tan().atan());
assert_approx_eq!(1.0_f64, 1.0_f64.tan().atan());
assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32);
assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32);

assert_approx_eq!(
1.0f32.tanh(),
(1.0 - f32::consts::E.powi(-2)) / (1.0 + f32::consts::E.powi(-2))
);
assert_approx_eq!(
1.0f64.tanh(),
(1.0 - f64::consts::E.powi(-2)) / (1.0 + f64::consts::E.powi(-2))
);
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);

assert_approx_eq!(5.0f32.gamma(), 24.0);
assert_approx_eq!(5.0f64.gamma(), 24.0);
assert_approx_eq!((-0.5f32).gamma(), (-2.0) * f32::consts::PI.sqrt());
assert_approx_eq!((-0.5f64).gamma(), (-2.0) * f64::consts::PI.sqrt());

assert_eq!(2.0f32.ln_gamma(), (0.0, 1));
assert_eq!(2.0f64.ln_gamma(), (0.0, 1));
// Gamma(-0.5) = -2*sqrt(π)
let (val, sign) = (-0.5f32).ln_gamma();
assert_approx_eq!(val, (2.0 * f32::consts::PI.sqrt()).ln());
assert_eq!(sign, -1);
let (val, sign) = (-0.5f64).ln_gamma();
assert_approx_eq!(val, (2.0 * f64::consts::PI.sqrt()).ln());
assert_eq!(sign, -1);
}
8 changes: 8 additions & 0 deletions src/tools/miri/tests/pass/float_nan.rs
Original file line number Diff line number Diff line change
@@ -264,6 +264,10 @@ fn test_f32() {
HashSet::from_iter([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)]),
|| F32::from(f32::min(nan, nan)),
);
check_all_outcomes(
HashSet::from_iter([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)]),
|| F32::from(nan.floor()),
);
check_all_outcomes(
HashSet::from_iter([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)]),
|| F32::from(nan.sin()),
@@ -376,6 +380,10 @@ fn test_f64() {
HashSet::from_iter([F64::nan(Pos, Quiet, 0), F64::nan(Neg, Quiet, 0)]),
|| F64::from(f64::min(nan, nan)),
);
check_all_outcomes(
HashSet::from_iter([F64::nan(Pos, Quiet, 0), F64::nan(Neg, Quiet, 0)]),
|| F64::from(nan.floor()),
);
check_all_outcomes(
HashSet::from_iter([F64::nan(Pos, Quiet, 0), F64::nan(Neg, Quiet, 0)]),
|| F64::from(nan.sin()),
156 changes: 0 additions & 156 deletions src/tools/miri/tests/pass/intrinsics-math.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//@compile-flags: -Zmiri-retag-fields=scalar

struct Newtype<'a>(#[allow(dead_code)] &'a mut i32, #[allow(dead_code)] i32, #[allow(dead_code)] i32);
struct Newtype<'a>(
#[allow(dead_code)] &'a mut i32,
#[allow(dead_code)] i32,
#[allow(dead_code)] i32,
);

fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
dealloc();
7 changes: 2 additions & 5 deletions tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
#![deny(coinductive_overlap_in_coherence)]

use std::borrow::Borrow;
use std::cmp::Ordering;
use std::marker::PhantomData;

#[derive(PartialEq, Default)]
//~^ ERROR conflicting implementations of trait `PartialEq<Interval<_>>` for type `Interval<_>`
pub(crate) struct Interval<T>(PhantomData<T>);

// This impl overlaps with the `derive` unless we reject the nested
// `Interval<?1>: PartialOrd<Interval<?1>>` candidate which results
// in a - currently inductive - cycle.
// in a -- currently inductive -- cycle.
impl<T, Q> PartialEq<Q> for Interval<T>
//~^ ERROR implementations of `PartialEq<Interval<_>>` for `Interval<_>` will conflict in the future
//~| WARN this was previously accepted by the compiler but is being phased out
where
T: Borrow<Q>,
Q: ?Sized + PartialOrd,
46 changes: 6 additions & 40 deletions tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr
Original file line number Diff line number Diff line change
@@ -1,51 +1,17 @@
error: implementations of `PartialEq<Interval<_>>` for `Interval<_>` will conflict in the future
--> $DIR/warn-when-cycle-is-error-in-coherence.rs:13:1
error[E0119]: conflicting implementations of trait `PartialEq<Interval<_>>` for type `Interval<_>`
--> $DIR/warn-when-cycle-is-error-in-coherence.rs:5:10
|
LL | #[derive(PartialEq, Default)]
| --------- the second impl is here
| ^^^^^^^^^ conflicting implementation for `Interval<_>`
...
LL | / impl<T, Q> PartialEq<Q> for Interval<T>
LL | |
LL | |
LL | | where
LL | | T: Borrow<Q>,
LL | | Q: ?Sized + PartialOrd,
| |___________________________^ the first impl is here
| |___________________________- first implementation here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #114040 <https://github.com/rust-lang/rust/issues/114040>
= note: impls that are not considered to overlap may be considered to overlap in the future
= note: `Interval<_>: PartialOrd` may be considered to hold in future releases, causing the impls to overlap
note: the lint level is defined here
--> $DIR/warn-when-cycle-is-error-in-coherence.rs:1:9
|
LL | #![deny(coinductive_overlap_in_coherence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error

Future incompatibility report: Future breakage diagnostic:
error: implementations of `PartialEq<Interval<_>>` for `Interval<_>` will conflict in the future
--> $DIR/warn-when-cycle-is-error-in-coherence.rs:13:1
|
LL | #[derive(PartialEq, Default)]
| --------- the second impl is here
...
LL | / impl<T, Q> PartialEq<Q> for Interval<T>
LL | |
LL | |
LL | | where
LL | | T: Borrow<Q>,
LL | | Q: ?Sized + PartialOrd,
| |___________________________^ the first impl is here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #114040 <https://github.com/rust-lang/rust/issues/114040>
= note: impls that are not considered to overlap may be considered to overlap in the future
= note: `Interval<_>: PartialOrd` may be considered to hold in future releases, causing the impls to overlap
note: the lint level is defined here
--> $DIR/warn-when-cycle-is-error-in-coherence.rs:1:9
|
LL | #![deny(coinductive_overlap_in_coherence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0119`.
6 changes: 6 additions & 0 deletions tests/ui/fmt/format-string-wrong-order.rs
Original file line number Diff line number Diff line change
@@ -12,4 +12,10 @@ fn main() {
//~^ ERROR invalid format string: expected `'}'`, found `'?'`
format!("{?:#?}", bar);
//~^ ERROR invalid format string: expected format parameter to occur after `:`
format!("Hello {<5:}!", "x");
//~^ ERROR invalid format string: expected format parameter to occur after `:`
format!("Hello {^5:}!", "x");
//~^ ERROR invalid format string: expected format parameter to occur after `:`
format!("Hello {>5:}!", "x");
//~^ ERROR invalid format string: expected format parameter to occur after `:`
}
20 changes: 19 additions & 1 deletion tests/ui/fmt/format-string-wrong-order.stderr
Original file line number Diff line number Diff line change
@@ -50,5 +50,23 @@ LL | format!("{?:#?}", bar);
|
= note: `?` comes after `:`, try `:?` instead

error: aborting due to 6 previous errors
error: invalid format string: expected format parameter to occur after `:`
--> $DIR/format-string-wrong-order.rs:15:21
|
LL | format!("Hello {<5:}!", "x");
| ^ expected `<` to occur after `:` in format string

error: invalid format string: expected format parameter to occur after `:`
--> $DIR/format-string-wrong-order.rs:17:21
|
LL | format!("Hello {^5:}!", "x");
| ^ expected `^` to occur after `:` in format string

error: invalid format string: expected format parameter to occur after `:`
--> $DIR/format-string-wrong-order.rs:19:21
|
LL | format!("Hello {>5:}!", "x");
| ^ expected `>` to occur after `:` in format string

error: aborting due to 9 previous errors