Skip to content

Commit 862bba6

Browse files
committed
Auto merge of #116830 - nnethercote:rustc_type_ir, r=compiler-errors
Remove `IdFunctor` trait. It's defined in `rustc_data_structures` but is only used in `rustc_type_ir`. The code is shorter and easier to read if we remove this layer of abstraction and just do the things directly where they are needed. r? `@BoxyUwU`
2 parents 5d5edf0 + 178ba0e commit 862bba6

File tree

4 files changed

+41
-128
lines changed

4 files changed

+41
-128
lines changed

compiler/rustc_data_structures/src/functor.rs

-116
This file was deleted.

compiler/rustc_data_structures/src/lib.rs

-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
1111
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1212
#![feature(array_windows)]
13-
#![feature(associated_type_bounds)]
1413
#![feature(auto_traits)]
1514
#![feature(cell_leak)]
1615
#![feature(core_intrinsics)]
@@ -21,15 +20,12 @@
2120
#![feature(min_specialization)]
2221
#![feature(never_type)]
2322
#![feature(type_alias_impl_trait)]
24-
#![feature(new_uninit)]
2523
#![feature(lazy_cell)]
2624
#![feature(rustc_attrs)]
2725
#![feature(negative_impls)]
2826
#![feature(test)]
2927
#![feature(thread_id_value)]
30-
#![feature(vec_into_raw_parts)]
3128
#![feature(allocator_api)]
32-
#![feature(get_mut_unchecked)]
3329
#![feature(lint_reasons)]
3430
#![feature(unwrap_infallible)]
3531
#![feature(strict_provenance)]
@@ -65,7 +61,6 @@ pub mod binary_search_util;
6561
pub mod captures;
6662
pub mod flat_map_in_place;
6763
pub mod flock;
68-
pub mod functor;
6964
pub mod fx;
7065
pub mod graph;
7166
pub mod intern;

compiler/rustc_type_ir/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#![feature(associated_type_defaults)]
22
#![feature(fmt_helpers_for_derive)]
3+
#![feature(get_mut_unchecked)]
34
#![feature(min_specialization)]
45
#![feature(never_type)]
6+
#![feature(new_uninit)]
57
#![feature(rustc_attrs)]
68
#![feature(unwrap_infallible)]
79
#![deny(rustc::untranslatable_diagnostic)]

compiler/rustc_type_ir/src/structural_impls.rs

+39-7
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
use crate::fold::{FallibleTypeFolder, TypeFoldable};
66
use crate::visit::{TypeVisitable, TypeVisitor};
77
use crate::{ConstKind, FloatTy, InferTy, IntTy, Interner, UintTy, UniverseIndex};
8-
use rustc_data_structures::functor::IdFunctor;
98
use rustc_data_structures::sync::Lrc;
109
use rustc_index::{Idx, IndexVec};
1110

1211
use core::fmt;
1312
use std::marker::PhantomData;
13+
use std::mem;
1414
use std::ops::ControlFlow;
1515

1616
///////////////////////////////////////////////////////////////////////////
@@ -108,8 +108,39 @@ impl<I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>> TypeVisitable<I> for
108108
}
109109

110110
impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Lrc<T> {
111-
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
112-
self.try_map_id(|value| value.try_fold_with(folder))
111+
fn try_fold_with<F: FallibleTypeFolder<I>>(mut self, folder: &mut F) -> Result<Self, F::Error> {
112+
// We merely want to replace the contained `T`, if at all possible,
113+
// so that we don't needlessly allocate a new `Lrc` or indeed clone
114+
// the contained type.
115+
unsafe {
116+
// First step is to ensure that we have a unique reference to
117+
// the contained type, which `Lrc::make_mut` will accomplish (by
118+
// allocating a new `Lrc` and cloning the `T` only if required).
119+
// This is done *before* casting to `Lrc<ManuallyDrop<T>>` so that
120+
// panicking during `make_mut` does not leak the `T`.
121+
Lrc::make_mut(&mut self);
122+
123+
// Casting to `Lrc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
124+
// is `repr(transparent)`.
125+
let ptr = Lrc::into_raw(self).cast::<mem::ManuallyDrop<T>>();
126+
let mut unique = Lrc::from_raw(ptr);
127+
128+
// Call to `Lrc::make_mut` above guarantees that `unique` is the
129+
// sole reference to the contained value, so we can avoid doing
130+
// a checked `get_mut` here.
131+
let slot = Lrc::get_mut_unchecked(&mut unique);
132+
133+
// Semantically move the contained type out from `unique`, fold
134+
// it, then move the folded value back into `unique`. Should
135+
// folding fail, `ManuallyDrop` ensures that the "moved-out"
136+
// value is not re-dropped.
137+
let owned = mem::ManuallyDrop::take(slot);
138+
let folded = owned.try_fold_with(folder)?;
139+
*slot = mem::ManuallyDrop::new(folded);
140+
141+
// Cast back to `Lrc<T>`.
142+
Ok(Lrc::from_raw(Lrc::into_raw(unique).cast()))
143+
}
113144
}
114145
}
115146

@@ -120,8 +151,9 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Lrc<T> {
120151
}
121152

122153
impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Box<T> {
123-
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
124-
self.try_map_id(|value| value.try_fold_with(folder))
154+
fn try_fold_with<F: FallibleTypeFolder<I>>(mut self, folder: &mut F) -> Result<Self, F::Error> {
155+
*self = (*self).try_fold_with(folder)?;
156+
Ok(self)
125157
}
126158
}
127159

@@ -133,7 +165,7 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<T> {
133165

134166
impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Vec<T> {
135167
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
136-
self.try_map_id(|t| t.try_fold_with(folder))
168+
self.into_iter().map(|t| t.try_fold_with(folder)).collect()
137169
}
138170
}
139171

@@ -161,7 +193,7 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<[T]> {
161193

162194
impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix, T> {
163195
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
164-
self.try_map_id(|x| x.try_fold_with(folder))
196+
self.raw.try_fold_with(folder).map(IndexVec::from_raw)
165197
}
166198
}
167199

0 commit comments

Comments
 (0)