Skip to content

Commit 0cefa27

Browse files
committed
Auto merge of #164757 - JonathanBrouwer:rollup-QMS3ewH, r=JonathanBrouwer
Rollup of 12 pull requests Successful merges: - #164458 (Avoid stdlib's `impl Hash for Path` for stable hashing) - #161790 (update to illumos sysroot 20210501) - #163087 (rmake: Add helpers for iterating symbols and objects) - #163586 (refactor Windows remove_dir_all) - #163983 (std: use `SOCK_NONBLOCK` in `connect_timeout`) - #164307 (Rename `PostTypeckUntilBorrowck` -> `PostTypeckThroughBorrowck`) - #164425 (Declare `SyntaxContext` through `rustc_index::newtype_index!`) - #156841 (Avoid cloning CFG-related analysis data.) - #164654 (Add reference annotations for unions) - #164717 (Allow `llm-assisted` label to be set without write access) - #164735 (Remove docs mentioning instability of wasm64) - #164737 (Update LLVM PassBuilder constructor calls to pass a context) Failed merges: - #164636 (Remove `record_*` macros from the metadata encoder)
2 parents 7189d39 + dce705a commit 0cefa27

89 files changed

Lines changed: 827 additions & 489 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3843,8 +3843,11 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> {
38433843
location: Location,
38443844
) -> impl Iterator<Item = Location> {
38453845
if location.statement_index == 0 {
3846-
let predecessors = body.basic_blocks.predecessors()[location.block].to_vec();
3847-
Either::Left(predecessors.into_iter().map(move |bb| body.terminator_loc(bb)))
3846+
Either::Left(
3847+
body.basic_blocks.predecessors()[location.block]
3848+
.iter()
3849+
.map(|&bb| body.terminator_loc(bb)),
3850+
)
38483851
} else {
38493852
Either::Right(std::iter::once(Location {
38503853
statement_index: location.statement_index - 1,

‎compiler/rustc_borrowck/src/implied_bounds.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub(super) fn mir_borrowck_implied_outlives_bounds<'tcx>(
4040
// parent body, so for these we do want to define opaque types. Not doing so can result
4141
// in incorrect errors when normalizing implied bounds.
4242
let typing_env = if tcx.is_typeck_child(body_def_id.to_def_id()) {
43-
TypingEnv::post_typeck_until_borrowck(tcx, body_def_id)
43+
TypingEnv::post_typeck_through_borrowck(tcx, body_def_id)
4444
} else {
4545
TypingEnv::non_body_analysis(tcx, body_def_id)
4646
};

‎compiler/rustc_borrowck/src/lib.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ pub(crate) struct BorrowckInferCtxt<'tcx> {
657657

658658
impl<'tcx> BorrowckInferCtxt<'tcx> {
659659
pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, root_def_id: LocalDefId) -> Self {
660-
let typing_mode = if tcx.use_typing_mode_post_typeck_until_borrowck() {
660+
let typing_mode = if tcx.use_typing_mode_post_typeck_through_borrowck() {
661661
TypingMode::borrowck(tcx, def_id)
662662
} else {
663663
TypingMode::analysis_in_body(tcx, def_id)

‎compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ fn collect_defining_uses<'tcx>(
261261
DefiningScopeKind::MirBorrowck,
262262
) {
263263
// A non-defining use. This is a hard error on stable and gets ignored
264-
// with `TypingMode::PostTypeckUntilBorrowck`.
265-
if infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
264+
// with `TypingMode::PostTypeckThroughBorrowck`.
265+
if infcx.tcx.use_typing_mode_post_typeck_through_borrowck() {
266266
match err {
267267
NonDefiningUseReason::Tainted(guar) => add_hidden_type(
268268
infcx.tcx,
@@ -327,7 +327,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
327327
// If we're using the next solver, the unconstrained region may be resolved by a
328328
// fully defining use from another body.
329329
// So we don't generate error eagerly here.
330-
if rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
330+
if rcx.infcx.tcx.use_typing_mode_post_typeck_through_borrowck() {
331331
unconstrained_hidden_type_errors.push(UnexpectedHiddenRegion {
332332
def_id,
333333
hidden_type,
@@ -362,7 +362,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
362362
DefinitionSiteHiddenType::new_error(tcx, guar)
363363
});
364364

365-
if !rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
365+
if !rcx.infcx.tcx.use_typing_mode_post_typeck_through_borrowck() {
366366
// Sometimes, when the hidden type is an inference variable, it can happen that
367367
// the hidden type becomes the opaque type itself. In this case, this was an opaque
368368
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
@@ -539,7 +539,7 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
539539
let mut errors = Vec::new();
540540
for &(key, hidden_type) in opaque_types {
541541
let Some(expected) = hidden_types.get(&key.def_id) else {
542-
if !tcx.use_typing_mode_post_typeck_until_borrowck() {
542+
if !tcx.use_typing_mode_post_typeck_through_borrowck() {
543543
if let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
544544
hidden_type.ty.kind()
545545
&& def_id == key.def_id.to_def_id()

‎compiler/rustc_const_eval/src/check_consts/qualifs.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl Qualif for HasMutInterior {
110110
let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, cx.body.span);
111111
let did = cx.body.source.def_id().expect_local();
112112

113-
let typing_env = if cx.tcx.use_typing_mode_post_typeck_until_borrowck() {
113+
let typing_env = if cx.tcx.use_typing_mode_post_typeck_through_borrowck() {
114114
cx.typing_env
115115
} else {
116116
ty::TypingEnv::new(cx.typing_env.param_env, TypingMode::analysis_in_body(cx.tcx, did))

‎compiler/rustc_const_eval/src/const_eval/eval_queries.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fn retry_codegen_mode_with_postanalysis<'tcx, K: TypeVisitable<TyCtxt<'tcx>>, V>
4242
}
4343
ty::TypingMode::Coherence
4444
| ty::TypingMode::Typeck { .. }
45-
| ty::TypingMode::PostTypeckUntilBorrowck { .. }
45+
| ty::TypingMode::PostTypeckThroughBorrowck { .. }
4646
| ty::TypingMode::PostBorrowck { .. }
4747
| ty::TypingMode::Reflection
4848
| ty::TypingMode::PostAnalysis => {}

‎compiler/rustc_const_eval/src/lib.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fn assert_typing_mode(typing_mode: ty::TypingMode<'_>) {
3434
ty::TypingMode::Coherence
3535
| ty::TypingMode::Typeck { .. }
3636
| ty::TypingMode::Reflection
37-
| ty::TypingMode::PostTypeckUntilBorrowck { .. }
37+
| ty::TypingMode::PostTypeckThroughBorrowck { .. }
3838
| ty::TypingMode::PostBorrowck { .. } => bug!(
3939
"Const eval should always happens in PostAnalysis or Codegen mode. See the comment on `assert_typing_mode` for more details."
4040
),

‎compiler/rustc_data_structures/src/stable_hash.rs‎

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::num::NonZero;
55

66
use rustc_index::bit_set::{self, DenseBitSet};
77
use rustc_index::{Idx, IndexSlice, IndexVec};
8+
use rustc_macros::StableHash;
89
use smallvec::SmallVec;
910
use thin_vec::ThinVec;
1011

@@ -37,6 +38,25 @@ pub trait StableHashCtxt {
3738
fn assert_default_stable_hash_controls(&self, msg: &str);
3839
}
3940

41+
/// Dummy impl of [`StableHashCtxt`], for code that can't provide a real context,
42+
/// and only wants to compute stable hashes for types that don't rely on the context.
43+
pub struct DummyStableHashCtxt;
44+
45+
impl StableHashCtxt for DummyStableHashCtxt {
46+
fn stable_hash_span(&mut self, _span: RawSpan, _hasher: &mut StableHasher) {
47+
panic!("method on dummy stable-hash context was unexpectedly called");
48+
}
49+
fn def_path_hash(&self, _def_id: RawDefId) -> Fingerprint {
50+
panic!("method on dummy stable-hash context was unexpectedly called");
51+
}
52+
fn stable_hash_controls(&self) -> StableHashControls {
53+
panic!("method on dummy stable-hash context was unexpectedly called");
54+
}
55+
fn assert_default_stable_hash_controls(&self, _msg: &str) {
56+
panic!("method on dummy stable-hash context was unexpectedly called");
57+
}
58+
}
59+
4060
// A type used to work around `Span` not being visible in this crate. It is the same size as
4161
// `Span` but has a different alignment.
4262
pub struct RawSpan(pub u64);
@@ -71,6 +91,18 @@ pub struct RawDefId(pub u32, pub u32);
7191
/// - `stable_hash()` must be independent of the host architecture. The
7292
/// `StableHasher` takes care of endianness and `isize`/`usize` platform
7393
/// differences.
94+
///
95+
/// # Consistency across compiler stages
96+
///
97+
/// Because the stage1 compiler is built against the bootstrap stdlib, but the stage2
98+
/// compiler uses in-tree stdlib, implementations of `StableHash` must not rely on `Hash`
99+
/// impls that were provided or derived by the standard library. Doing so leads to weird
100+
/// bugs and CI failures that can block changes to those stdlib hash impls.
101+
///
102+
/// (Unfortunately, as of late 2026 we have many stable-hash impls that _do_
103+
/// leak details of stdlib hash impls.)
104+
///
105+
/// See <https://github.com/rust-lang/rust/pull/164458> for more context.
74106
pub trait StableHash {
75107
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher);
76108
}
@@ -575,8 +607,97 @@ impl<R: Idx, C: Idx> StableHash for bit_set::BitMatrix<R, C> {
575607

576608
impl_stable_traits_for_trivial_type!(::std::ffi::OsStr);
577609

578-
impl_stable_traits_for_trivial_type!(::std::path::Path);
579-
impl_stable_traits_for_trivial_type!(::std::path::PathBuf);
610+
impl StableHash for std::path::Path {
611+
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
612+
use std::path::{Component, Prefix};
613+
614+
/// Tag value to be mixed in with each kind of component/prefix.
615+
#[derive(StableHash)]
616+
enum Tag {
617+
StartOfPath,
618+
PrefixVerbatim,
619+
PrefixVerbatimUNC,
620+
PrefixVerbatimDisk,
621+
PrefixDeviceNS,
622+
PrefixUNC,
623+
PrefixDisk,
624+
RootDir,
625+
CurDir,
626+
ParentDir,
627+
Normal,
628+
EndOfPath,
629+
}
630+
631+
// Explicitly tag the start of each path, so that empty paths always hash something.
632+
Tag::StartOfPath.stable_hash(hcx, hasher);
633+
634+
for (i, component) in self.components().enumerate() {
635+
// Mix in the index of each component, to avoid potentially trivial collisions
636+
// between inputs like `("foo/bar", "baz")` and `("foo", "bar/baz")`.
637+
i.stable_hash(hcx, hasher);
638+
match component {
639+
Component::Prefix(prefix) => match prefix.kind() {
640+
Prefix::Verbatim(os_str) => {
641+
Tag::PrefixVerbatim.stable_hash(hcx, hasher);
642+
os_str.stable_hash(hcx, hasher);
643+
}
644+
Prefix::VerbatimUNC(host, share) => {
645+
Tag::PrefixVerbatimUNC.stable_hash(hcx, hasher);
646+
host.stable_hash(hcx, hasher);
647+
share.stable_hash(hcx, hasher);
648+
}
649+
Prefix::VerbatimDisk(letter) => {
650+
Tag::PrefixVerbatimDisk.stable_hash(hcx, hasher);
651+
letter.stable_hash(hcx, hasher);
652+
}
653+
Prefix::DeviceNS(os_str) => {
654+
Tag::PrefixDeviceNS.stable_hash(hcx, hasher);
655+
os_str.stable_hash(hcx, hasher);
656+
}
657+
Prefix::UNC(host, share) => {
658+
Tag::PrefixUNC.stable_hash(hcx, hasher);
659+
host.stable_hash(hcx, hasher);
660+
share.stable_hash(hcx, hasher);
661+
}
662+
Prefix::Disk(letter) => {
663+
Tag::PrefixDisk.stable_hash(hcx, hasher);
664+
letter.stable_hash(hcx, hasher);
665+
}
666+
},
667+
Component::RootDir => Tag::RootDir.stable_hash(hcx, hasher),
668+
Component::CurDir => Tag::CurDir.stable_hash(hcx, hasher),
669+
Component::ParentDir => Tag::ParentDir.stable_hash(hcx, hasher),
670+
Component::Normal(os_str) => {
671+
Tag::Normal.stable_hash(hcx, hasher);
672+
os_str.stable_hash(hcx, hasher);
673+
}
674+
}
675+
}
676+
677+
// Explicitly tag the end of each path, so that empty paths always hash something.
678+
// (Tagging the start and the end and the component-index is potentially overkill.)
679+
Tag::EndOfPath.stable_hash(hcx, hasher);
680+
}
681+
}
682+
683+
impl StableOrd for std::path::Path {
684+
/// FIXME(Zalathar): Unstably sorting paths is pre-existing behavior, but potentially wrong.
685+
const CAN_USE_UNSTABLE_SORT: bool = true;
686+
/// Stdlib path sorting should (hopefully) not change.
687+
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
688+
}
689+
690+
impl StableHash for std::path::PathBuf {
691+
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
692+
self.as_path().stable_hash(hcx, hasher);
693+
}
694+
}
695+
696+
impl StableOrd for std::path::PathBuf {
697+
const CAN_USE_UNSTABLE_SORT: bool = <std::path::Path as StableOrd>::CAN_USE_UNSTABLE_SORT;
698+
/// Stdlib path sorting should (hopefully) not change.
699+
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
700+
}
580701

581702
// It is not safe to implement StableHash for HashSet, HashMap or any other collection type
582703
// with unstable but observable iteration order.

‎compiler/rustc_data_structures/src/stable_hash/tests.rs‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::Path;
2+
13
use super::*;
24

35
// The tests below compare the computed hashes to particular expected values
@@ -29,6 +31,19 @@ fn hash<T: StableHash>(t: &T) -> Hash128 {
2931
h.finish()
3032
}
3133

34+
/// Computes the stable hash of two values in sequence.
35+
///
36+
/// This is similar to computing the stable hash of `(a, b)`, except that it
37+
/// avoids relying on the actual impl of StableHash for tuples.
38+
fn hash_two(a: &impl StableHash, b: &impl StableHash) -> Hash128 {
39+
let hcx = &mut DummyStableHashCtxt;
40+
let mut hasher = StableHasher::new();
41+
42+
a.stable_hash(hcx, &mut hasher);
43+
b.stable_hash(hcx, &mut hasher);
44+
hasher.finish()
45+
}
46+
3247
// Check that bit set hash includes the domain size.
3348
#[test]
3449
fn test_hash_bit_set() {
@@ -115,3 +130,22 @@ fn test_isize_compression() {
115130
check_hash(0xFF, 0xFFFFFFFFFFFFFFFF);
116131
check_hash(u64::MAX /* -1 */, 1);
117132
}
133+
134+
#[test]
135+
fn path_component_rebracketing() {
136+
let hash_a = hash_two(&Path::new("alfa/bravo"), &Path::new("charlie"));
137+
let hash_b = hash_two(&Path::new("alfa"), &Path::new("bravo/charlie"));
138+
139+
assert_ne!(hash_a, hash_b);
140+
}
141+
142+
#[test]
143+
fn empty_path_rebracketing() {
144+
let nonempty_path = &Path::new("foo");
145+
let empty_path = &Path::new("");
146+
147+
let hash_a = hash_two(nonempty_path, empty_path);
148+
let hash_b = hash_two(empty_path, nonempty_path);
149+
150+
assert_ne!(hash_a, hash_b);
151+
}

‎compiler/rustc_hir_analysis/src/check/check.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,7 +2355,7 @@ pub(super) fn check_coroutine_obligations(
23552355
}
23562356
} else {
23572357
// We're not checking region constraints here, so we can simply drop the
2358-
// added opaque type uses in `TypingMode::PostTypeckUntilBorrowck`.
2358+
// added opaque type uses in `TypingMode::PostTypeckThroughBorrowck`.
23592359
let _ = infcx.take_opaque_types();
23602360
}
23612361

@@ -2372,7 +2372,7 @@ pub(super) fn check_potentially_region_dependent_goals<'tcx>(
23722372
let typeck_results = tcx.typeck(def_id);
23732373
let param_env = tcx.param_env(def_id);
23742374

2375-
// We use `TypingMode::PostTypeckUntilBorrowck` as we want to use the opaque types computed by HIR typeck.
2375+
// We use `TypingMode::PostTypeckThroughBorrowck` as we want to use the opaque types computed by HIR typeck.
23762376
let typing_mode = TypingMode::borrowck(tcx, def_id);
23772377
let infcx = tcx.infer_ctxt().ignoring_regions().build(typing_mode);
23782378
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

0 commit comments

Comments
 (0)