Skip to content

Commit 4bf8448

Browse files
committed
Auto merge of #134025 - workingjubilee:rollup-xb4212q, r=<try>
[TEST] Rollup of 5 pull requests Successful merges: - #133733 ( compiletest: show the difference between the normalized output and the actual output for lines which didn't match) - #133861 (Add allocate_bytes and refactor allocate_str in InterpCx for raw byte…) - #133967 ([AIX] Pass -bnoipath when adding rust upstream dynamic crates) - #133976 (Removed Unnecessary Spaces From RELEASES.md) - #133980 ([AIX] Remove option "-n" from AIX "ln" command) r? `@ghost` `@rustbot` modify labels: rollup try-job: i686-mingw
2 parents 728f2da + 7e81657 commit 4bf8448

File tree

7 files changed

+175
-53
lines changed

7 files changed

+175
-53
lines changed

RELEASES.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ Compatibility Notes
503503
* We have renamed `std::panic::PanicInfo` to `std::panic::PanicHookInfo`. The old name will continue to work as an alias, but will result in a deprecation warning starting in Rust 1.82.0.
504504

505505
`core::panic::PanicInfo` will remain unchanged, however, as this is now a *different type*.
506-
506+
507507
The reason is that these types have different roles: `std::panic::PanicHookInfo` is the argument to the [panic hook](https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html) in std context (where panics can have an arbitrary payload), while `core::panic::PanicInfo` is the argument to the [`#[panic_handler]`](https://doc.rust-lang.org/nomicon/panic-handler.html) in no_std context (where panics always carry a formatted *message*). Separating these types allows us to add more useful methods to these types, such as `std::panic::PanicHookInfo::payload_as_str()` and `core::panic::PanicInfo::message()`.
508508

509509
* The new sort implementations may panic if a type's implementation of [`Ord`](https://doc.rust-lang.org/std/cmp/trait.Ord.html) (or the given comparison function) does not implement a [total order](https://en.wikipedia.org/wiki/Total_order) as the trait requires. `Ord`'s supertraits (`PartialOrd`, `Eq`, and `PartialEq`) must also be consistent. The previous implementations would not "notice" any problem, but the new implementations have a good chance of detecting inconsistencies, throwing a panic rather than returning knowingly unsorted data.
@@ -584,7 +584,7 @@ Stabilized APIs
584584
- [`impl Default for Arc<CStr>`](https://doc.rust-lang.org/beta/alloc/sync/struct.Arc.html#impl-Default-for-Arc%3CCStr%3E)
585585
- [`impl Default for Arc<[T]>`](https://doc.rust-lang.org/beta/alloc/sync/struct.Arc.html#impl-Default-for-Arc%3C%5BT%5D%3E)
586586
- [`impl IntoIterator for Box<[T]>`](https://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#impl-IntoIterator-for-Box%3C%5BI%5D,+A%3E)
587-
- [`impl FromIterator<String> for Box<str>`](https://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#impl-FromIterator%3CString%3E-for-Box%3Cstr%3E)
587+
- [`impl FromIterator<String> for Box<str>`](https://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#impl-FromIterator%3CString%3E-for-Box%3Cstr%3E)
588588
- [`impl FromIterator<char> for Box<str>`](https://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#impl-FromIterator%3Cchar%3E-for-Box%3Cstr%3E)
589589
- [`LazyCell`](https://doc.rust-lang.org/beta/core/cell/struct.LazyCell.html)
590590
- [`LazyLock`](https://doc.rust-lang.org/beta/std/sync/struct.LazyLock.html)
@@ -1816,7 +1816,7 @@ Compiler
18161816
- [Detect uninhabited types early in const eval](https://github.com/rust-lang/rust/pull/109435/)
18171817
- [Switch to LLD as default linker for {arm,thumb}v4t-none-eabi](https://github.com/rust-lang/rust/pull/109721/)
18181818
- [Add tier 3 target `loongarch64-unknown-linux-gnu`](https://github.com/rust-lang/rust/pull/96971)
1819-
- [Add tier 3 target for `i586-pc-nto-qnx700` (QNX Neutrino RTOS, version 7.0)](https://github.com/rust-lang/rust/pull/109173/),
1819+
- [Add tier 3 target for `i586-pc-nto-qnx700` (QNX Neutrino RTOS, version 7.0)](https://github.com/rust-lang/rust/pull/109173/),
18201820
- [Insert alignment checks for pointer dereferences as debug assertions](https://github.com/rust-lang/rust/pull/98112)
18211821
This catches undefined behavior at runtime, and may cause existing code to fail.
18221822

@@ -2023,7 +2023,7 @@ Compatibility Notes
20232023
If `tools = [...]` is set in config.toml, we will respect a missing rustdoc in that list. By
20242024
default rustdoc remains included. To retain the prior behavior explicitly add `"rustdoc"` to the
20252025
list.
2026-
2026+
20272027
<a id="1.69.0-Internal-Changes"></a>
20282028

20292029
Internal Changes

compiler/rustc_codegen_ssa/src/back/link.rs

+9
Original file line numberDiff line numberDiff line change
@@ -2753,6 +2753,15 @@ fn add_upstream_rust_crates(
27532753
.find(|(ty, _)| *ty == crate_type)
27542754
.expect("failed to find crate type in dependency format list");
27552755

2756+
if sess.target.is_like_aix {
2757+
// Unlike ELF linkers, AIX doesn't feature `DT_SONAME` to override
2758+
// the dependency name when outputing a shared library. Thus, `ld` will
2759+
// use the full path to shared libraries as the dependency if passed it
2760+
// by default unless `noipath` is passed.
2761+
// https://www.ibm.com/docs/en/aix/7.3?topic=l-ld-command.
2762+
cmd.link_or_cc_arg("-bnoipath");
2763+
}
2764+
27562765
for &cnum in &codegen_results.crate_info.used_crates {
27572766
// We may not pass all crates through to the linker. Some crates may appear statically in
27582767
// an existing dylib, meaning we'll pick up all the symbols from the dylib.

compiler/rustc_const_eval/src/interpret/place.rs

+32-13
Original file line numberDiff line numberDiff line change
@@ -1018,29 +1018,48 @@ where
10181018
self.allocate_dyn(layout, kind, MemPlaceMeta::None)
10191019
}
10201020

1021-
/// Returns a wide MPlace of type `str` to a new 1-aligned allocation.
1022-
/// Immutable strings are deduplicated and stored in global memory.
1023-
pub fn allocate_str(
1021+
/// Allocates a sequence of bytes in the interpreter's memory.
1022+
/// For immutable allocations, uses deduplication to reuse existing memory.
1023+
/// For mutable allocations, creates a new unique allocation.
1024+
pub fn allocate_bytes(
10241025
&mut self,
1025-
str: &str,
1026+
bytes: &[u8],
1027+
align: Align,
10261028
kind: MemoryKind<M::MemoryKind>,
10271029
mutbl: Mutability,
1028-
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
1029-
let tcx = self.tcx.tcx;
1030-
1030+
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
10311031
// Use cache for immutable strings.
1032-
let ptr = if mutbl.is_not() {
1032+
if mutbl.is_not() {
10331033
// Use dedup'd allocation function.
10341034
let salt = M::get_global_alloc_salt(self, None);
1035-
let id = tcx.allocate_bytes_dedup(str.as_bytes(), salt);
1035+
let id = self.tcx.allocate_bytes_dedup(bytes, salt);
10361036

10371037
// Turn untagged "global" pointers (obtained via `tcx`) into the machine pointer to the allocation.
1038-
M::adjust_alloc_root_pointer(&self, Pointer::from(id), Some(kind))?
1038+
M::adjust_alloc_root_pointer(&self, Pointer::from(id), Some(kind))
10391039
} else {
1040-
self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?
1041-
};
1042-
let meta = Scalar::from_target_usize(u64::try_from(str.len()).unwrap(), self);
1040+
// Allocate new memory for mutable data.
1041+
self.allocate_bytes_ptr(bytes, align, kind, mutbl)
1042+
}
1043+
}
1044+
1045+
/// Allocates a string in the interpreter's memory with metadata for length.
1046+
/// Uses `allocate_bytes` internally but adds string-specific metadata handling.
1047+
pub fn allocate_str(
1048+
&mut self,
1049+
str: &str,
1050+
kind: MemoryKind<M::MemoryKind>,
1051+
mutbl: Mutability,
1052+
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
1053+
let bytes = str.as_bytes();
1054+
let ptr = self.allocate_bytes(bytes, Align::ONE, kind, mutbl)?;
1055+
1056+
// Create length metadata for the string.
1057+
let meta = Scalar::from_target_usize(u64::try_from(bytes.len()).unwrap(), self);
1058+
1059+
// Get layout for Rust's str type.
10431060
let layout = self.layout_of(self.tcx.types.str_).unwrap();
1061+
1062+
// Combine pointer and metadata into a wide pointer.
10441063
interp_ok(self.ptr_with_meta_to_mplace(
10451064
ptr.into(),
10461065
MemPlaceMeta::Meta(meta),

src/tools/compiletest/src/runtest.rs

+106-30
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::common::{
2222
UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, Ui, expected_output_path, incremental_dir,
2323
output_base_dir, output_base_name, output_testname_unique,
2424
};
25-
use crate::compute_diff::{write_diff, write_filtered_diff};
25+
use crate::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff};
2626
use crate::errors::{self, Error, ErrorKind};
2727
use crate::header::TestProps;
2828
use crate::read2::{Truncated, read2_abbreviated};
@@ -2295,17 +2295,31 @@ impl<'test> TestCx<'test> {
22952295
match output_kind {
22962296
TestOutput::Compile => {
22972297
if !self.props.dont_check_compiler_stdout {
2298-
errors +=
2299-
self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
2298+
errors += self.compare_output(
2299+
stdout_kind,
2300+
&normalized_stdout,
2301+
&proc_res.stdout,
2302+
&expected_stdout,
2303+
);
23002304
}
23012305
if !self.props.dont_check_compiler_stderr {
2302-
errors +=
2303-
self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
2306+
errors += self.compare_output(
2307+
stderr_kind,
2308+
&normalized_stderr,
2309+
&stderr,
2310+
&expected_stderr,
2311+
);
23042312
}
23052313
}
23062314
TestOutput::Run => {
2307-
errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
2308-
errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
2315+
errors += self.compare_output(
2316+
stdout_kind,
2317+
&normalized_stdout,
2318+
&proc_res.stdout,
2319+
&expected_stdout,
2320+
);
2321+
errors +=
2322+
self.compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr);
23092323
}
23102324
}
23112325
errors
@@ -2533,7 +2547,13 @@ impl<'test> TestCx<'test> {
25332547
}
25342548
}
25352549

2536-
fn compare_output(&self, stream: &str, actual: &str, expected: &str) -> usize {
2550+
fn compare_output(
2551+
&self,
2552+
stream: &str,
2553+
actual: &str,
2554+
actual_unnormalized: &str,
2555+
expected: &str,
2556+
) -> usize {
25372557
let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) {
25382558
// FIXME: We ignore the first line of SVG files
25392559
// because the width parameter is non-deterministic.
@@ -2590,28 +2610,14 @@ impl<'test> TestCx<'test> {
25902610
if expected.is_empty() {
25912611
println!("normalized {}:\n{}\n", stream, actual);
25922612
} else {
2593-
println!("diff of {stream}:\n");
2594-
if let Some(diff_command) = self.config.diff_command.as_deref() {
2595-
let mut args = diff_command.split_whitespace();
2596-
let name = args.next().unwrap();
2597-
match Command::new(name)
2598-
.args(args)
2599-
.args([&expected_path, &actual_path])
2600-
.output()
2601-
{
2602-
Err(err) => {
2603-
self.fatal(&format!(
2604-
"failed to call custom diff command `{diff_command}`: {err}"
2605-
));
2606-
}
2607-
Ok(output) => {
2608-
let output = String::from_utf8_lossy(&output.stdout);
2609-
print!("{output}");
2610-
}
2611-
}
2612-
} else {
2613-
print!("{}", write_diff(expected, actual, 3));
2614-
}
2613+
self.show_diff(
2614+
stream,
2615+
&expected_path,
2616+
&actual_path,
2617+
expected,
2618+
actual,
2619+
actual_unnormalized,
2620+
);
26152621
}
26162622
} else {
26172623
// Delete non-revision .stderr/.stdout file if revisions are used.
@@ -2633,6 +2639,76 @@ impl<'test> TestCx<'test> {
26332639
if self.config.bless { 0 } else { 1 }
26342640
}
26352641

2642+
/// Returns whether to show the full stderr/stdout.
2643+
fn show_diff(
2644+
&self,
2645+
stream: &str,
2646+
expected_path: &Path,
2647+
actual_path: &Path,
2648+
expected: &str,
2649+
actual: &str,
2650+
actual_unnormalized: &str,
2651+
) {
2652+
eprintln!("diff of {stream}:\n");
2653+
if let Some(diff_command) = self.config.diff_command.as_deref() {
2654+
let mut args = diff_command.split_whitespace();
2655+
let name = args.next().unwrap();
2656+
match Command::new(name).args(args).args([expected_path, actual_path]).output() {
2657+
Err(err) => {
2658+
self.fatal(&format!(
2659+
"failed to call custom diff command `{diff_command}`: {err}"
2660+
));
2661+
}
2662+
Ok(output) => {
2663+
let output = String::from_utf8_lossy(&output.stdout);
2664+
eprint!("{output}");
2665+
}
2666+
}
2667+
} else {
2668+
eprint!("{}", write_diff(expected, actual, 3));
2669+
}
2670+
2671+
// NOTE: argument order is important, we need `actual` to be on the left so the line number match up when we compare it to `actual_unnormalized` below.
2672+
let diff_results = make_diff(actual, expected, 0);
2673+
2674+
let (mut mismatches_normalized, mut mismatch_line_nos) = (String::new(), vec![]);
2675+
for hunk in diff_results {
2676+
let mut line_no = hunk.line_number;
2677+
for line in hunk.lines {
2678+
// NOTE: `Expected` is actually correct here, the argument order is reversed so our line numbers match up
2679+
if let DiffLine::Expected(normalized) = line {
2680+
mismatches_normalized += &normalized;
2681+
mismatches_normalized += "\n";
2682+
mismatch_line_nos.push(line_no);
2683+
line_no += 1;
2684+
}
2685+
}
2686+
}
2687+
let mut mismatches_unnormalized = String::new();
2688+
let diff_normalized = make_diff(actual, actual_unnormalized, 0);
2689+
for hunk in diff_normalized {
2690+
if mismatch_line_nos.contains(&hunk.line_number) {
2691+
for line in hunk.lines {
2692+
if let DiffLine::Resulting(unnormalized) = line {
2693+
mismatches_unnormalized += &unnormalized;
2694+
mismatches_unnormalized += "\n";
2695+
}
2696+
}
2697+
}
2698+
}
2699+
2700+
let normalized_diff = make_diff(&mismatches_normalized, &mismatches_unnormalized, 0);
2701+
// HACK: instead of checking if each hunk is empty, this only checks if the whole input is empty. we should be smarter about this so we don't treat added or removed output as normalized.
2702+
if !normalized_diff.is_empty()
2703+
&& !mismatches_unnormalized.is_empty()
2704+
&& !mismatches_normalized.is_empty()
2705+
{
2706+
eprintln!("Note: some mismatched output was normalized before being compared");
2707+
// FIXME: respect diff_command
2708+
eprint!("{}", write_diff(&mismatches_unnormalized, &mismatches_normalized, 0));
2709+
}
2710+
}
2711+
26362712
fn check_and_prune_duplicate_outputs(
26372713
&self,
26382714
proc_res: &ProcRes,

src/tools/compiletest/src/runtest/coverage.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@ impl<'test> TestCx<'test> {
3939
let expected_coverage_dump = self.load_expected_output(kind);
4040
let actual_coverage_dump = self.normalize_output(&proc_res.stdout, &[]);
4141

42-
let coverage_dump_errors =
43-
self.compare_output(kind, &actual_coverage_dump, &expected_coverage_dump);
42+
let coverage_dump_errors = self.compare_output(
43+
kind,
44+
&actual_coverage_dump,
45+
&proc_res.stdout,
46+
&expected_coverage_dump,
47+
);
4448

4549
if coverage_dump_errors > 0 {
4650
self.fatal_proc_rec(
@@ -135,8 +139,12 @@ impl<'test> TestCx<'test> {
135139
self.fatal_proc_rec(&err, &proc_res);
136140
});
137141

138-
let coverage_errors =
139-
self.compare_output(kind, &normalized_actual_coverage, &expected_coverage);
142+
let coverage_errors = self.compare_output(
143+
kind,
144+
&normalized_actual_coverage,
145+
&proc_res.stdout,
146+
&expected_coverage,
147+
);
140148

141149
if coverage_errors > 0 {
142150
self.fatal_proc_rec(

src/tools/compiletest/src/runtest/ui.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl TestCx<'_> {
100100
)
101101
});
102102

103-
errors += self.compare_output("fixed", &fixed_code, &expected_fixed);
103+
errors += self.compare_output("fixed", &fixed_code, &fixed_code, &expected_fixed);
104104
} else if !expected_fixed.is_empty() {
105105
panic!(
106106
"the `//@ run-rustfix` directive wasn't found but a `*.fixed` \

tests/run-make/libs-through-symlinks/Makefile

+11-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,20 @@ include ../tools.mk
33

44
# ignore-windows
55

6+
# The option -n for the AIX ln command has a different purpose than it does
7+
# on Linux. On Linux, the -n option is used to treat the destination path as
8+
# normal file if it is a symbolic link to a directory, which is the default
9+
# behavior of the AIX ln command.
10+
ifeq ($(UNAME),AIX)
11+
LN_FLAGS := -sf
12+
else
13+
LN_FLAGS := -nsf
14+
endif
15+
616
NAME := $(shell $(RUSTC) --print file-names foo.rs)
717

818
all:
919
mkdir -p $(TMPDIR)/outdir
1020
$(RUSTC) foo.rs -o $(TMPDIR)/outdir/$(NAME)
11-
ln -nsf outdir/$(NAME) $(TMPDIR)
21+
ln $(LN_FLAGS) outdir/$(NAME) $(TMPDIR)
1222
RUSTC_LOG=rustc_metadata::loader $(RUSTC) bar.rs

0 commit comments

Comments
 (0)