Skip to content

Commit ca181d6

Browse files
committed
Auto merge of #116830 - nnethercote:rustc_type_ir, r=<try>
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 39164b8 + fd35413 commit ca181d6

File tree

4 files changed

+41
-129
lines changed

4 files changed

+41
-129
lines changed

compiler/rustc_data_structures/src/functor.rs

-116
This file was deleted.

compiler/rustc_data_structures/src/lib.rs

-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
99
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1010
#![feature(array_windows)]
11-
#![feature(associated_type_bounds)]
1211
#![feature(auto_traits)]
1312
#![feature(cell_leak)]
1413
#![feature(core_intrinsics)]
@@ -19,15 +18,11 @@
1918
#![feature(min_specialization)]
2019
#![feature(never_type)]
2120
#![feature(type_alias_impl_trait)]
22-
#![feature(new_uninit)]
2321
#![feature(lazy_cell)]
2422
#![feature(rustc_attrs)]
2523
#![feature(negative_impls)]
2624
#![feature(test)]
2725
#![feature(thread_id_value)]
28-
#![feature(vec_into_raw_parts)]
29-
#![feature(allocator_api)]
30-
#![feature(get_mut_unchecked)]
3126
#![feature(lint_reasons)]
3227
#![feature(unwrap_infallible)]
3328
#![feature(strict_provenance)]
@@ -63,7 +58,6 @@ pub mod binary_search_util;
6358
pub mod captures;
6459
pub mod flat_map_in_place;
6560
pub mod flock;
66-
pub mod functor;
6761
pub mod fx;
6862
pub mod graph;
6963
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)