Skip to content

Automatically make trivial types noop-traversable #117726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f232e01
Improve docs of traversable derivation macros
eggyal Feb 26, 2023
6c218fc
Generify traversable derivation macros
eggyal Feb 26, 2023
f2b7d0d
Skip trivial fields in derived traversables
eggyal Nov 9, 2023
63f7ed7
Add specialisation machinery for trivial traversal
eggyal Feb 25, 2023
d61c017
Enable skipping of derived traversals, with reason
eggyal Mar 23, 2023
e203c63
Use specialisation in explicit traversable impls
eggyal Feb 26, 2023
91257e8
Derive traversable impls for BindingForm
eggyal Feb 25, 2023
cb70056
Derive traversable impls for Obligation
eggyal Feb 26, 2023
a5ef24f
Derive traversable impls for GenericArgKind
eggyal Oct 29, 2023
2a78b7a
Simplify traversable impls in solver wrapper types
eggyal Feb 25, 2023
39373e6
Newtype for FakeRead semi-traversable tuple
eggyal Mar 20, 2023
f5190b7
Newtype for AscribeUserType semi-traversable tuple
eggyal Mar 20, 2023
a3f16b7
Newtype for InstanceOfArg semi-traversable tuple
eggyal Mar 20, 2023
8608548
Remove superfluous traversable impls
eggyal Feb 25, 2023
8c60fa3
Remove traversable impl for mir::Local
eggyal Nov 1, 2023
d779e9e
Remove traversable impl for ErrorGuaranteed
eggyal Nov 1, 2023
e4e5491
Remove traversable impl for bool
eggyal Feb 25, 2023
e3b5dd0
Remove traversable impl for usize
eggyal Oct 28, 2023
8f87cc3
Use rustc_type_ir directly in derived traversables
eggyal Feb 25, 2023
f3e8b6a
Derive traversables over generic interners
eggyal Mar 21, 2023
c5e9447
Use Spanned not semi-traversable Span tuples
eggyal Mar 20, 2023
1a88b49
Generify trivial traversables over the interner
eggyal Mar 21, 2023
bc4df58
Require explanation of trivial traversable derives
eggyal Mar 17, 2023
51b5454
Derive traversable impls for ConstKind
eggyal Oct 29, 2023
699c6e4
Derive traversable impls for more type lib kinds
eggyal Oct 29, 2023
78c18c8
Remove TrivialTypeTraversal macros
eggyal Feb 25, 2023
5744209
Unimpl TypeSuperVisitable for UnevaluatedConst
eggyal Feb 26, 2023
f22bb8e
Generify traversals of interned types
eggyal Feb 26, 2023
37bab7a
Enforce ClosureOutlivesSubjectTy not traversable
eggyal Oct 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Generify traversals of interned types
  • Loading branch information
eggyal committed Nov 9, 2023
commit f22bb8ea550364c1de0aa522d5faad40ee32975e
4 changes: 4 additions & 0 deletions compiler/rustc_data_structures/src/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ mod private {
#[rustc_pass_by_value]
pub struct Interned<'a, T>(pub &'a T, pub private::PrivateZst);

pub trait Internable<'a, I>: Sized {
fn intern(self, interner: I) -> Interned<'a, Self>;
}

impl<'a, T> Interned<'a, T> {
/// Create a new `Interned` value. The value referred to *must* be interned
/// and thus be unique, and it *must* remain unique in the future. This
Expand Down
54 changes: 3 additions & 51 deletions compiler/rustc_middle/src/traits/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use rustc_data_structures::intern::Interned;
use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints};
use crate::traits::query::NoSolution;
use crate::traits::{Canonical, DefiningAnchor};
use crate::ty::{
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitor,
};
use crate::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_span::def_id::DefId;

use super::BuiltinImplSource;
Expand Down Expand Up @@ -112,7 +110,7 @@ pub struct PredefinedOpaquesData<'tcx> {
pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
}

#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable, TypeVisitable, TypeFoldable)]
pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<'tcx>>);

impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
Expand All @@ -135,7 +133,7 @@ pub type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>;
/// solver, merge the two responses again.
pub type QueryResult<'tcx> = Result<CanonicalResponse<'tcx>, NoSolution>;

#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>);

impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
Expand All @@ -154,52 +152,6 @@ pub struct ExternalConstraintsData<'tcx> {
pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
}

// FIXME: Having to clone `region_constraints` for folding feels bad and
// probably isn't great wrt performance.
//
// Not sure how to fix this, maybe we should also intern `opaque_types` and
// `region_constraints` here or something.
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(folder.interner().mk_external_constraints((*self).clone().try_fold_with(folder)?))
}
}

impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
&self,
visitor: &mut V,
) -> std::ops::ControlFlow<V::BreakTy> {
(**self).visit_with(visitor)
}
}

// FIXME: Having to clone `region_constraints` for folding feels bad and
// probably isn't great wrt performance.
//
// Not sure how to fix this, maybe we should also intern `opaque_types` and
// `region_constraints` here or something.
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(folder.interner().mk_predefined_opaques_in_body((*self).clone().try_fold_with(folder)?))
}
}

impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
&self,
visitor: &mut V,
) -> std::ops::ControlFlow<V::BreakTy> {
(**self).visit_with(visitor)
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)]
pub enum IsNormalizesToHack {
Yes,
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::intern::{Internable, Interned};
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
Expand Down Expand Up @@ -1549,11 +1549,17 @@ macro_rules! direct_interners {
}
}

impl<'tcx> Internable<'tcx, TyCtxt<'tcx>> for $ty {
fn intern(self, tcx: TyCtxt<'tcx>) -> Interned<'tcx, Self> {
Interned::new_unchecked(tcx.interners.$name.intern(self, |v| {
InternedInSet(tcx.interners.arena.alloc(v))
}).0)
}
}

impl<'tcx> TyCtxt<'tcx> {
$vis fn $method(self, v: $ty) -> $ret_ty {
$ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
InternedInSet(self.interners.arena.alloc(v))
}).0))
$ret_ctor(v.intern(self))
}
})+
}
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_type_ir/src/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@
//! - u.fold_with(folder)
//! ```

use rustc_data_structures::sync::Lrc;
use rustc_data_structures::{
intern::{Internable, Interned},
sync::Lrc,
};
use rustc_index::{Idx, IndexVec};
use std::marker::PhantomData;
use std::mem;
Expand Down Expand Up @@ -403,3 +406,9 @@ impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix,
self.raw.try_fold_with(folder).map(IndexVec::from_raw)
}
}

impl<'a, I: Interner, T: Internable<'a, I> + TypeFoldable<I>> TypeFoldable<I> for Interned<'a, T> {
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
(*self).clone().try_fold_with(folder).map(|v| v.intern(folder.interner()))
}
}
8 changes: 7 additions & 1 deletion compiler/rustc_type_ir/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
//! - u.visit_with(visitor)
//! ```

use rustc_data_structures::sync::Lrc;
use rustc_data_structures::{intern::Interned, sync::Lrc};
use rustc_index::{Idx, IndexVec};
use std::fmt;
use std::marker::PhantomData;
Expand Down Expand Up @@ -250,3 +250,9 @@ impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix
self.iter().try_for_each(|t| t.visit_with(visitor))
}
}

impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Interned<'_, T> {
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
(**self).visit_with(visitor)
}
}