Skip to content

Commit cfeaad7

Browse files
committed
Auto merge of rust-lang#139862 - Zalathar:rollup-yj9ybc5, r=Zalathar
Rollup of 5 pull requests Successful merges: - rust-lang#138906 (Reject test executables when not supported by target) - rust-lang#139818 (Normalize ADT field in `find_tails_for_unsizing`) - rust-lang#139819 (Use `rust-cache` to speed-up `citool` compilation) - rust-lang#139824 (Remove safe remove) - rust-lang#139859 (CI: rename MacOS runner) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 40dacd5 + 5243a43 commit cfeaad7

File tree

7 files changed

+90
-107
lines changed

7 files changed

+90
-107
lines changed

.github/workflows/ci.yml

+7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ jobs:
5353
steps:
5454
- name: Checkout the source code
5555
uses: actions/checkout@v4
56+
# Cache citool to make its build faster, as it's in the critical path.
57+
# The rust-cache doesn't bleed into the main `job`, so it should not affect any other
58+
# Rust compilation.
59+
- name: Cache citool
60+
uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
61+
with:
62+
workspaces: src/ci/citool
5663
- name: Calculate the CI job matrix
5764
env:
5865
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}

compiler/rustc_incremental/src/persist/fs.rs

+6-28
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) {
290290

291291
// Try to remove the session directory we just allocated. We don't
292292
// know if there's any garbage in it from the failed copy action.
293-
if let Err(err) = safe_remove_dir_all(&session_dir) {
293+
if let Err(err) = std_fs::remove_dir_all(&session_dir) {
294294
sess.dcx().emit_warn(errors::DeletePartial { path: &session_dir, err });
295295
}
296296

@@ -324,7 +324,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) {
324324
incr_comp_session_dir.display()
325325
);
326326

327-
if let Err(err) = safe_remove_dir_all(&*incr_comp_session_dir) {
327+
if let Err(err) = std_fs::remove_dir_all(&*incr_comp_session_dir) {
328328
sess.dcx().emit_warn(errors::DeleteFull { path: &incr_comp_session_dir, err });
329329
}
330330

@@ -715,7 +715,7 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result<
715715
for directory_name in session_directories {
716716
if !lock_file_to_session_dir.items().any(|(_, dir)| *dir == directory_name) {
717717
let path = crate_directory.join(directory_name);
718-
if let Err(err) = safe_remove_dir_all(&path) {
718+
if let Err(err) = std_fs::remove_dir_all(&path) {
719719
sess.dcx().emit_warn(errors::InvalidGcFailed { path: &path, err });
720720
}
721721
}
@@ -821,7 +821,7 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result<
821821
all_except_most_recent(deletion_candidates).into_items().all(|(path, lock)| {
822822
debug!("garbage_collect_session_directories() - deleting `{}`", path.display());
823823

824-
if let Err(err) = safe_remove_dir_all(&path) {
824+
if let Err(err) = std_fs::remove_dir_all(&path) {
825825
sess.dcx().emit_warn(errors::FinalizedGcFailed { path: &path, err });
826826
} else {
827827
delete_session_dir_lock_file(sess, &lock_file_path(&path));
@@ -839,7 +839,7 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result<
839839
fn delete_old(sess: &Session, path: &Path) {
840840
debug!("garbage_collect_session_directories() - deleting `{}`", path.display());
841841

842-
if let Err(err) = safe_remove_dir_all(path) {
842+
if let Err(err) = std_fs::remove_dir_all(path) {
843843
sess.dcx().emit_warn(errors::SessionGcFailed { path, err });
844844
} else {
845845
delete_session_dir_lock_file(sess, &lock_file_path(path));
@@ -862,30 +862,8 @@ fn all_except_most_recent(
862862
}
863863
}
864864

865-
/// Since paths of artifacts within session directories can get quite long, we
866-
/// need to support deleting files with very long paths. The regular
867-
/// WinApi functions only support paths up to 260 characters, however. In order
868-
/// to circumvent this limitation, we canonicalize the path of the directory
869-
/// before passing it to std::fs::remove_dir_all(). This will convert the path
870-
/// into the '\\?\' format, which supports much longer paths.
871-
fn safe_remove_dir_all(p: &Path) -> io::Result<()> {
872-
let canonicalized = match try_canonicalize(p) {
873-
Ok(canonicalized) => canonicalized,
874-
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()),
875-
Err(err) => return Err(err),
876-
};
877-
878-
std_fs::remove_dir_all(canonicalized)
879-
}
880-
881865
fn safe_remove_file(p: &Path) -> io::Result<()> {
882-
let canonicalized = match try_canonicalize(p) {
883-
Ok(canonicalized) => canonicalized,
884-
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()),
885-
Err(err) => return Err(err),
886-
};
887-
888-
match std_fs::remove_file(canonicalized) {
866+
match std_fs::remove_file(p) {
889867
Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(()),
890868
result => result,
891869
}

compiler/rustc_monomorphize/src/collector.rs

+32-31
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
688688
let target_ty = self.monomorphize(target_ty);
689689
let source_ty = self.monomorphize(source_ty);
690690
let (source_ty, target_ty) =
691-
find_vtable_types_for_unsizing(self.tcx.at(span), source_ty, target_ty);
691+
find_tails_for_unsizing(self.tcx.at(span), source_ty, target_ty);
692692
// This could also be a different Unsize instruction, like
693693
// from a fixed sized array to a slice. But we are only
694694
// interested in things that produce a vtable.
@@ -1037,36 +1037,35 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) ->
10371037
///
10381038
/// Finally, there is also the case of custom unsizing coercions, e.g., for
10391039
/// smart pointers such as `Rc` and `Arc`.
1040-
fn find_vtable_types_for_unsizing<'tcx>(
1040+
fn find_tails_for_unsizing<'tcx>(
10411041
tcx: TyCtxtAt<'tcx>,
10421042
source_ty: Ty<'tcx>,
10431043
target_ty: Ty<'tcx>,
10441044
) -> (Ty<'tcx>, Ty<'tcx>) {
1045-
let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
1046-
let typing_env = ty::TypingEnv::fully_monomorphized();
1047-
if tcx.type_has_metadata(inner_source, typing_env) {
1048-
(inner_source, inner_target)
1049-
} else {
1050-
tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, typing_env)
1051-
}
1052-
};
1045+
let typing_env = ty::TypingEnv::fully_monomorphized();
1046+
debug_assert!(!source_ty.has_param(), "{source_ty} should be fully monomorphic");
1047+
debug_assert!(!target_ty.has_param(), "{target_ty} should be fully monomorphic");
10531048

10541049
match (source_ty.kind(), target_ty.kind()) {
1055-
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
1056-
| (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(a, b),
1050+
(
1051+
&ty::Ref(_, source_pointee, _),
1052+
&ty::Ref(_, target_pointee, _) | &ty::RawPtr(target_pointee, _),
1053+
)
1054+
| (&ty::RawPtr(source_pointee, _), &ty::RawPtr(target_pointee, _)) => {
1055+
tcx.struct_lockstep_tails_for_codegen(source_pointee, target_pointee, typing_env)
1056+
}
1057+
1058+
// `Box<T>` could go through the ADT code below, b/c it'll unpeel to `Unique<T>`,
1059+
// and eventually bottom out in a raw ref, but we can micro-optimize it here.
10571060
(_, _)
10581061
if let Some(source_boxed) = source_ty.boxed_ty()
10591062
&& let Some(target_boxed) = target_ty.boxed_ty() =>
10601063
{
1061-
ptr_vtable(source_boxed, target_boxed)
1064+
tcx.struct_lockstep_tails_for_codegen(source_boxed, target_boxed, typing_env)
10621065
}
10631066

1064-
// T as dyn* Trait
1065-
(_, &ty::Dynamic(_, _, ty::DynStar)) => ptr_vtable(source_ty, target_ty),
1066-
10671067
(&ty::Adt(source_adt_def, source_args), &ty::Adt(target_adt_def, target_args)) => {
10681068
assert_eq!(source_adt_def, target_adt_def);
1069-
10701069
let CustomCoerceUnsized::Struct(coerce_index) =
10711070
match crate::custom_coerce_unsize_info(tcx, source_ty, target_ty) {
10721071
Ok(ccu) => ccu,
@@ -1075,21 +1074,23 @@ fn find_vtable_types_for_unsizing<'tcx>(
10751074
return (e, e);
10761075
}
10771076
};
1077+
let coerce_field = &source_adt_def.non_enum_variant().fields[coerce_index];
1078+
// We're getting a possibly unnormalized type, so normalize it.
1079+
let source_field =
1080+
tcx.normalize_erasing_regions(typing_env, coerce_field.ty(*tcx, source_args));
1081+
let target_field =
1082+
tcx.normalize_erasing_regions(typing_env, coerce_field.ty(*tcx, target_args));
1083+
find_tails_for_unsizing(tcx, source_field, target_field)
1084+
}
10781085

1079-
let source_fields = &source_adt_def.non_enum_variant().fields;
1080-
let target_fields = &target_adt_def.non_enum_variant().fields;
1081-
1082-
assert!(
1083-
coerce_index.index() < source_fields.len()
1084-
&& source_fields.len() == target_fields.len()
1085-
);
1086+
// `T` as `dyn* Trait` unsizes *directly*.
1087+
//
1088+
// FIXME(dyn_star): This case is a bit awkward, b/c we're not really computing
1089+
// a tail here. We probably should handle this separately in the *caller* of
1090+
// this function, rather than returning something that is semantically different
1091+
// than what we return above.
1092+
(_, &ty::Dynamic(_, _, ty::DynStar)) => (source_ty, target_ty),
10861093

1087-
find_vtable_types_for_unsizing(
1088-
tcx,
1089-
source_fields[coerce_index].ty(*tcx, source_args),
1090-
target_fields[coerce_index].ty(*tcx, target_args),
1091-
)
1092-
}
10931094
_ => bug!(
10941095
"find_vtable_types_for_unsizing: invalid coercion {:?} -> {:?}",
10951096
source_ty,
@@ -1308,7 +1309,7 @@ fn visit_mentioned_item<'tcx>(
13081309
}
13091310
MentionedItem::UnsizeCast { source_ty, target_ty } => {
13101311
let (source_ty, target_ty) =
1311-
find_vtable_types_for_unsizing(tcx.at(span), source_ty, target_ty);
1312+
find_tails_for_unsizing(tcx.at(span), source_ty, target_ty);
13121313
// This could also be a different Unsize instruction, like
13131314
// from a fixed sized array to a slice. But we are only
13141315
// interested in things that produce a vtable.

compiler/rustc_session/src/output.rs

+7
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
177177
// If we're generating a test executable, then ignore all other output
178178
// styles at all other locations
179179
if session.opts.test {
180+
if !session.target.executables {
181+
session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget {
182+
crate_type: CrateType::Executable,
183+
target_triple: &session.opts.target_triple,
184+
});
185+
return Vec::new();
186+
}
180187
return vec![CrateType::Executable];
181188
}
182189

src/ci/github-actions/jobs.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ runners:
2323
os: ubuntu-24.04-16core-64gb
2424
<<: *base-job
2525

26-
- &job-macos-xl
27-
os: macos-13 # We use the standard runner for now
26+
- &job-macos
27+
os: macos-13
2828
<<: *base-job
2929

3030
- &job-macos-m1
@@ -380,7 +380,7 @@ auto:
380380
NO_OVERFLOW_CHECKS: 1
381381
DIST_REQUIRE_ALL_TOOLS: 1
382382
CODEGEN_BACKENDS: llvm,cranelift
383-
<<: *job-macos-xl
383+
<<: *job-macos
384384

385385
- name: dist-apple-various
386386
env:
@@ -397,18 +397,18 @@ auto:
397397
NO_LLVM_ASSERTIONS: 1
398398
NO_DEBUG_ASSERTIONS: 1
399399
NO_OVERFLOW_CHECKS: 1
400-
<<: *job-macos-xl
400+
<<: *job-macos
401401

402402
- name: x86_64-apple-1
403403
env:
404404
<<: *env-x86_64-apple-tests
405-
<<: *job-macos-xl
405+
<<: *job-macos
406406

407407
- name: x86_64-apple-2
408408
env:
409409
SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc
410410
<<: *env-x86_64-apple-tests
411-
<<: *job-macos-xl
411+
<<: *job-macos
412412

413413
- name: dist-aarch64-apple
414414
env:

tests/crashes/74451.rs

-42
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//@ build-pass
2+
3+
// Regression test for <https://github.com/rust-lang/rust/issues/139812>.
4+
5+
// Make sure that the unsize coercion we collect in mono for `Signal<i32> -> Signal<dyn Any>`
6+
// doesn't choke on the fact that the inner unsized field of `Signal<T>` is a (trivial) alias.
7+
// This exercises a normalize call that is necessary since we're getting a type from the type
8+
// system, which isn't guaranteed to be normalized after substitution.
9+
10+
#![feature(coerce_unsized)]
11+
12+
use std::ops::CoerceUnsized;
13+
14+
trait Mirror {
15+
type Assoc: ?Sized;
16+
}
17+
impl<T: ?Sized> Mirror for T {
18+
type Assoc = T;
19+
}
20+
21+
trait Any {}
22+
impl<T> Any for T {}
23+
24+
struct Signal<'a, T: ?Sized>(<&'a T as Mirror>::Assoc);
25+
26+
// This `CoerceUnsized` impl isn't special; it's a bit more restricted than we'd see in the wild,
27+
// but this ICE also reproduces if we were to make it general over `Signal<T> -> Signal<U>`.
28+
impl<'a> CoerceUnsized<Signal<'a, dyn Any>> for Signal<'a, i32> {}
29+
30+
fn main() {
31+
Signal(&1i32) as Signal<dyn Any>;
32+
}

0 commit comments

Comments
 (0)