Skip to content

Commit 2c6b416

Browse files
Add clauses to binders, once again
1 parent 75530e9 commit 2c6b416

File tree

9 files changed

+110
-28
lines changed

9 files changed

+110
-28
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,12 @@ impl<'a> PostExpansionVisitor<'a> {
133133
}
134134
}
135135

136-
for param in params {
137-
if !param.bounds.is_empty() {
138-
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
139-
self.sess.dcx().emit_err(errors::ForbiddenBound { spans });
136+
if !self.features.non_lifetime_binders() {
137+
for param in params {
138+
if !param.bounds.is_empty() {
139+
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
140+
self.sess.dcx().emit_err(errors::ForbiddenBound { spans });
141+
}
140142
}
141143
}
142144
}

compiler/rustc_middle/src/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
504504

505505
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
506506
#[cfg(target_pointer_width = "64")]
507-
rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48);
507+
rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 56);
508508

509509
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
510510
#[derive(TypeVisitable, TypeFoldable)]

compiler/rustc_middle/src/ty/context.rs

+24
Original file line numberDiff line numberDiff line change
@@ -2287,6 +2287,29 @@ macro_rules! nop_list_lift {
22872287
};
22882288
}
22892289

2290+
macro_rules! nop_list_with_cached_type_info_lift {
2291+
($set:ident; $ty:ty => $lifted:ty) => {
2292+
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a ListWithCachedTypeInfo<$ty> {
2293+
type Lifted = &'tcx ListWithCachedTypeInfo<$lifted>;
2294+
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2295+
// Assert that the set has the right type.
2296+
if false {
2297+
let _x: &InternedSet<'tcx, ListWithCachedTypeInfo<$lifted>> =
2298+
&tcx.interners.$set;
2299+
}
2300+
2301+
if self.is_empty() {
2302+
return Some(ListWithCachedTypeInfo::empty());
2303+
}
2304+
tcx.interners
2305+
.$set
2306+
.contains_pointer_to(&InternedInSet(self))
2307+
.then(|| unsafe { mem::transmute(self) })
2308+
}
2309+
}
2310+
};
2311+
}
2312+
22902313
nop_lift! { type_; Ty<'a> => Ty<'tcx> }
22912314
nop_lift! { region; Region<'a> => Region<'tcx> }
22922315
nop_lift! { const_; Const<'a> => Const<'tcx> }
@@ -2302,6 +2325,7 @@ nop_list_lift! {
23022325
poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
23032326
}
23042327
nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2328+
nop_list_with_cached_type_info_lift! { clauses; Clause<'a> => Clause<'tcx> }
23052329

23062330
// This is the impl for `&'a GenericArgs<'a>`.
23072331
nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }

compiler/rustc_middle/src/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ pub struct ParamEnv<'tcx> {
967967
}
968968

969969
impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
970-
fn caller_bounds(self) -> impl inherent::SliceLike<Item = ty::Clause<'tcx>> {
970+
fn caller_bounds(self) -> Clauses<'tcx> {
971971
self.caller_bounds()
972972
}
973973
}
@@ -2197,6 +2197,6 @@ mod size_asserts {
21972197
use super::*;
21982198
// tidy-alphabetical-start
21992199
static_assert_size!(PredicateKind<'_>, 32);
2200-
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 48);
2200+
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 56);
22012201
// tidy-alphabetical-end
22022202
}

compiler/rustc_middle/src/ty/predicate.rs

+6
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@ impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {
179179
}
180180
}
181181

182+
impl<'tcx> rustc_type_ir::inherent::Clauses<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
183+
fn empty() -> Self {
184+
ty::ListWithCachedTypeInfo::empty()
185+
}
186+
}
187+
182188
impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> {
183189
type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>;
184190

compiler/rustc_middle/src/ty/sty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2090,6 +2090,6 @@ mod size_asserts {
20902090
use super::*;
20912091
// tidy-alphabetical-start
20922092
static_assert_size!(ty::RegionKind<'_>, 24);
2093-
static_assert_size!(ty::TyKind<'_>, 24);
2093+
static_assert_size!(ty::TyKind<'_>, 32);
20942094
// tidy-alphabetical-end
20952095
}

compiler/rustc_type_ir/src/binder.rs

+61-17
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use crate::data_structures::SsoHashSet;
1212
use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
1313
use crate::inherent::*;
1414
use crate::lift::Lift;
15-
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
15+
use crate::visit::{
16+
Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, try_visit,
17+
};
1618
use crate::{self as ty, Interner};
1719

1820
/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
@@ -34,6 +36,7 @@ use crate::{self as ty, Interner};
3436
pub struct Binder<I: Interner, T> {
3537
value: T,
3638
bound_vars: I::BoundVarKinds,
39+
clauses: I::Clauses,
3740
}
3841

3942
// FIXME: We manually derive `Lift` because the `derive(Lift_Generic)` doesn't
@@ -42,13 +45,15 @@ impl<I: Interner, U: Interner, T> Lift<U> for Binder<I, T>
4245
where
4346
T: Lift<U>,
4447
I::BoundVarKinds: Lift<U, Lifted = U::BoundVarKinds>,
48+
I::Clauses: Lift<U, Lifted = U::Clauses>,
4549
{
4650
type Lifted = Binder<U, T::Lifted>;
4751

4852
fn lift_to_interner(self, cx: U) -> Option<Self::Lifted> {
4953
Some(Binder {
5054
value: self.value.lift_to_interner(cx)?,
5155
bound_vars: self.bound_vars.lift_to_interner(cx)?,
56+
clauses: self.clauses.lift_to_interner(cx)?,
5257
})
5358
}
5459
}
@@ -106,15 +111,28 @@ where
106111
!value.has_escaping_bound_vars(),
107112
"`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
108113
);
109-
Binder { value, bound_vars: Default::default() }
114+
Binder { value, bound_vars: Default::default(), clauses: I::Clauses::empty() }
110115
}
111116

112117
pub fn bind_with_vars(value: T, bound_vars: I::BoundVarKinds) -> Binder<I, T> {
113118
if cfg!(debug_assertions) {
114119
let mut validator = ValidateBoundVars::new(bound_vars);
115120
let _ = value.visit_with(&mut validator);
116121
}
117-
Binder { value, bound_vars }
122+
Binder { value, bound_vars, clauses: I::Clauses::empty() }
123+
}
124+
125+
pub fn bind_with_vars_and_clauses(
126+
value: T,
127+
bound_vars: I::BoundVarKinds,
128+
clauses: I::Clauses,
129+
) -> Binder<I, T> {
130+
if cfg!(debug_assertions) {
131+
let mut validator = ValidateBoundVars::new(bound_vars);
132+
value.visit_with(&mut validator);
133+
clauses.visit_with(&mut validator);
134+
}
135+
Binder { bound_vars, value, clauses }
118136
}
119137
}
120138

@@ -135,13 +153,18 @@ impl<I: Interner, T: TypeFoldable<I>> TypeSuperFoldable<I> for Binder<I, T> {
135153
self,
136154
folder: &mut F,
137155
) -> Result<Self, F::Error> {
138-
self.try_map_bound(|ty| ty.try_fold_with(folder))
156+
let Binder { bound_vars, value, clauses } = self;
157+
let clauses = clauses.try_fold_with(folder)?;
158+
let value = value.try_fold_with(folder)?;
159+
Ok(Binder::bind_with_vars_and_clauses(value, bound_vars, clauses))
139160
}
140161
}
141162

142163
impl<I: Interner, T: TypeVisitable<I>> TypeSuperVisitable<I> for Binder<I, T> {
143164
fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
144-
self.as_ref().skip_binder().visit_with(visitor)
165+
let (value, clauses) = self.as_ref().skip_binder_with_clauses();
166+
try_visit!(clauses.visit_with(visitor));
167+
value.visit_with(visitor)
145168
}
146169
}
147170

@@ -166,19 +189,23 @@ impl<I: Interner, T> Binder<I, T> {
166189
self.value
167190
}
168191

192+
pub fn skip_binder_with_clauses(self) -> (T, I::Clauses) {
193+
(self.value, self.clauses)
194+
}
195+
169196
pub fn bound_vars(&self) -> I::BoundVarKinds {
170197
self.bound_vars
171198
}
172199

173200
pub fn as_ref(&self) -> Binder<I, &T> {
174-
Binder { value: &self.value, bound_vars: self.bound_vars }
201+
Binder { value: &self.value, bound_vars: self.bound_vars, clauses: self.clauses }
175202
}
176203

177204
pub fn as_deref(&self) -> Binder<I, &T::Target>
178205
where
179206
T: Deref,
180207
{
181-
Binder { value: &self.value, bound_vars: self.bound_vars }
208+
Binder { value: &self.value, bound_vars: self.bound_vars, clauses: self.clauses }
182209
}
183210

184211
pub fn map_bound_ref<F, U: TypeVisitable<I>>(&self, f: F) -> Binder<I, U>
@@ -192,26 +219,39 @@ impl<I: Interner, T> Binder<I, T> {
192219
where
193220
F: FnOnce(T) -> U,
194221
{
195-
let Binder { value, bound_vars } = self;
222+
let Binder { value, bound_vars, clauses } = self;
196223
let value = f(value);
197224
if cfg!(debug_assertions) {
198225
let mut validator = ValidateBoundVars::new(bound_vars);
199226
let _ = value.visit_with(&mut validator);
200227
}
201-
Binder { value, bound_vars }
228+
Binder { value, bound_vars, clauses }
229+
}
230+
231+
pub fn map_clauses<F, U: TypeVisitable<I>>(self, f: F) -> Self
232+
where
233+
F: FnOnce(I::Clauses) -> I::Clauses,
234+
{
235+
let Binder { value, bound_vars, clauses } = self;
236+
let clauses = f(clauses);
237+
if cfg!(debug_assertions) {
238+
let mut validator = ValidateBoundVars::new(bound_vars);
239+
clauses.visit_with(&mut validator);
240+
}
241+
Binder { value, bound_vars, clauses }
202242
}
203243

204244
pub fn try_map_bound<F, U: TypeVisitable<I>, E>(self, f: F) -> Result<Binder<I, U>, E>
205245
where
206246
F: FnOnce(T) -> Result<U, E>,
207247
{
208-
let Binder { value, bound_vars } = self;
248+
let Binder { value, bound_vars, clauses } = self;
209249
let value = f(value)?;
210250
if cfg!(debug_assertions) {
211251
let mut validator = ValidateBoundVars::new(bound_vars);
212252
let _ = value.visit_with(&mut validator);
213253
}
214-
Ok(Binder { value, bound_vars })
254+
Ok(Binder { value, bound_vars, clauses })
215255
}
216256

217257
/// Wraps a `value` in a binder, using the same bound variables as the
@@ -227,7 +267,7 @@ impl<I: Interner, T> Binder<I, T> {
227267
where
228268
U: TypeVisitable<I>,
229269
{
230-
Binder::bind_with_vars(value, self.bound_vars)
270+
Binder::bind_with_vars_and_clauses(value, self.bound_vars, self.clauses)
231271
}
232272

233273
/// Unwraps and returns the value within, but only if it contains
@@ -245,21 +285,25 @@ impl<I: Interner, T> Binder<I, T> {
245285
T: TypeVisitable<I>,
246286
{
247287
// `self.value` is equivalent to `self.skip_binder()`
248-
if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
288+
if self.value.has_escaping_bound_vars() && self.clauses.is_empty() {
289+
None
290+
} else {
291+
Some(self.skip_binder())
292+
}
249293
}
250294
}
251295

252296
impl<I: Interner, T> Binder<I, Option<T>> {
253297
pub fn transpose(self) -> Option<Binder<I, T>> {
254-
let Binder { value, bound_vars } = self;
255-
value.map(|value| Binder { value, bound_vars })
298+
let Binder { value, bound_vars, clauses } = self;
299+
value.map(|value| Binder { value, bound_vars, clauses })
256300
}
257301
}
258302

259303
impl<I: Interner, T: IntoIterator> Binder<I, T> {
260304
pub fn iter(self) -> impl Iterator<Item = Binder<I, T::Item>> {
261-
let Binder { value, bound_vars } = self;
262-
value.into_iter().map(move |value| Binder { value, bound_vars })
305+
let Binder { value, bound_vars, clauses } = self;
306+
value.into_iter().map(move |value| Binder { value, bound_vars, clauses })
263307
}
264308
}
265309

compiler/rustc_type_ir/src/inherent.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,12 @@ pub trait Clause<I: Interner<Clause = Self>>:
515515
fn instantiate_supertrait(self, cx: I, trait_ref: ty::Binder<I, ty::TraitRef<I>>) -> Self;
516516
}
517517

518+
pub trait Clauses<I: Interner>:
519+
SliceLike<Item = I::Clause> + Debug + Hash + Eq + TypeSuperVisitable<I> + TypeFoldable<I> + Flags
520+
{
521+
fn empty() -> Self;
522+
}
523+
518524
/// Common capabilities of placeholder kinds
519525
pub trait PlaceholderLike: Copy + Debug + Hash + Eq {
520526
fn universe(self) -> ty::UniverseIndex;
@@ -566,7 +572,7 @@ pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq {
566572
}
567573

568574
pub trait ParamEnv<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
569-
fn caller_bounds(self) -> impl SliceLike<Item = I::Clause>;
575+
fn caller_bounds(self) -> I::Clauses;
570576
}
571577

572578
pub trait Features<I: Interner>: Copy {

compiler/rustc_type_ir/src/interner.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::ir_print::IrPrint;
1212
use crate::lang_items::TraitSolverLangItem;
1313
use crate::relate::Relate;
1414
use crate::solve::{CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult};
15-
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
15+
use crate::visit::TypeVisitable;
1616
use crate::{self as ty, search_graph};
1717

1818
pub trait Interner:
@@ -127,7 +127,7 @@ pub trait Interner:
127127
type ParamEnv: ParamEnv<Self>;
128128
type Predicate: Predicate<Self>;
129129
type Clause: Clause<Self>;
130-
type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
130+
type Clauses: Clauses<Self>;
131131

132132
fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R;
133133

0 commit comments

Comments
 (0)