3
3
4
4
use rustc_data_structures:: fx:: FxIndexMap ;
5
5
use rustc_hir:: LangItem ;
6
- use rustc_hir:: def:: DefKind ;
7
- use rustc_middle:: ty:: fold:: FnMutDelegate ;
8
6
use rustc_middle:: ty:: { self , Ty , TyCtxt , Upcast } ;
9
7
use rustc_span:: Span ;
10
- use rustc_span:: def_id:: DefId ;
11
-
12
- use crate :: hir_ty_lowering:: PredicateFilter ;
13
8
14
9
/// Collects together a list of type bounds. These lists of bounds occur in many places
15
10
/// in Rust's syntax:
@@ -47,12 +42,9 @@ impl<'tcx> Bounds<'tcx> {
47
42
pub ( crate ) fn push_trait_bound (
48
43
& mut self ,
49
44
tcx : TyCtxt < ' tcx > ,
50
- defining_def_id : DefId ,
51
45
bound_trait_ref : ty:: PolyTraitRef < ' tcx > ,
52
46
span : Span ,
53
47
polarity : ty:: PredicatePolarity ,
54
- constness : ty:: BoundConstness ,
55
- predicate_filter : PredicateFilter ,
56
48
) {
57
49
let clause = (
58
50
bound_trait_ref
@@ -68,136 +60,6 @@ impl<'tcx> Bounds<'tcx> {
68
60
} else {
69
61
self . clauses . push ( clause) ;
70
62
}
71
-
72
- // FIXME(effects): Lift this out of `push_trait_bound`, and move it somewhere else.
73
- // Perhaps moving this into `lower_poly_trait_ref`, just like we lower associated
74
- // type bounds.
75
- if !tcx. features ( ) . effects {
76
- return ;
77
- }
78
- match predicate_filter {
79
- PredicateFilter :: SelfOnly | PredicateFilter :: SelfThatDefines ( _) => {
80
- return ;
81
- }
82
- PredicateFilter :: All | PredicateFilter :: SelfAndAssociatedTypeBounds => {
83
- // Ok.
84
- }
85
- }
86
-
87
- // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the
88
- // associated type of `<T as Tr>` and make sure that the effect is compatible.
89
- let compat_val = match ( tcx. def_kind ( defining_def_id) , constness) {
90
- // FIXME(effects): revisit the correctness of this
91
- ( _, ty:: BoundConstness :: Const ) => tcx. consts . false_ ,
92
- // body owners that can have trait bounds
93
- ( DefKind :: Const | DefKind :: Fn | DefKind :: AssocFn , ty:: BoundConstness :: ConstIfConst ) => {
94
- tcx. expected_host_effect_param_for_body ( defining_def_id)
95
- }
96
-
97
- ( _, ty:: BoundConstness :: NotConst ) => {
98
- if !tcx. is_const_trait ( bound_trait_ref. def_id ( ) ) {
99
- return ;
100
- }
101
- tcx. consts . true_
102
- }
103
- ( DefKind :: Trait , ty:: BoundConstness :: ConstIfConst ) => {
104
- // we are in a trait, where `bound_trait_ref` could be:
105
- // (1) a super trait `trait Foo: ~const Bar`.
106
- // - This generates `<Self as Foo>::Effects: TyCompat<<Self as Bar>::Effects>`
107
- //
108
- // (2) a where clause `where for<..> Something: ~const Bar`.
109
- // - This generates `for<..> <Self as Foo>::Effects: TyCompat<<Something as Bar>::Effects>`
110
- let Some ( own_fx) = tcx. associated_type_for_effects ( defining_def_id) else {
111
- tcx. dcx ( ) . span_delayed_bug ( span, "should not have allowed `~const` on a trait that doesn't have `#[const_trait]`" ) ;
112
- return ;
113
- } ;
114
- let own_fx_ty = Ty :: new_projection (
115
- tcx,
116
- own_fx,
117
- ty:: GenericArgs :: identity_for_item ( tcx, own_fx) ,
118
- ) ;
119
- let Some ( their_fx) = tcx. associated_type_for_effects ( bound_trait_ref. def_id ( ) )
120
- else {
121
- tcx. dcx ( ) . span_delayed_bug ( span, "`~const` on trait without Effects assoc" ) ;
122
- return ;
123
- } ;
124
- let their_fx_ty =
125
- Ty :: new_projection ( tcx, their_fx, bound_trait_ref. skip_binder ( ) . args ) ;
126
- let compat = tcx. require_lang_item ( LangItem :: EffectsTyCompat , Some ( span) ) ;
127
- let clause = bound_trait_ref
128
- . map_bound ( |_| {
129
- let trait_ref = ty:: TraitRef :: new ( tcx, compat, [ own_fx_ty, their_fx_ty] ) ;
130
- ty:: ClauseKind :: Trait ( ty:: TraitPredicate {
131
- trait_ref,
132
- polarity : ty:: PredicatePolarity :: Positive ,
133
- } )
134
- } )
135
- . upcast ( tcx) ;
136
-
137
- self . clauses . push ( ( clause, span) ) ;
138
- return ;
139
- }
140
-
141
- ( DefKind :: Impl { of_trait : true } , ty:: BoundConstness :: ConstIfConst ) => {
142
- // this is a where clause on an impl header.
143
- // push `<T as Tr>::Effects` into the set for the `Min` bound.
144
- let Some ( assoc) = tcx. associated_type_for_effects ( bound_trait_ref. def_id ( ) ) else {
145
- tcx. dcx ( ) . span_delayed_bug ( span, "`~const` on trait without Effects assoc" ) ;
146
- return ;
147
- } ;
148
-
149
- let ty = bound_trait_ref
150
- . map_bound ( |trait_ref| Ty :: new_projection ( tcx, assoc, trait_ref. args ) ) ;
151
-
152
- // When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the
153
- // binders to dummy ones i.e. `X<'static, ()>` so they can be referenced in
154
- // the `Min` associated type properly (which doesn't allow using `for<>`)
155
- // This should work for any bound variables as long as they don't have any
156
- // bounds e.g. `for<T: Trait>`.
157
- // FIXME(effects) reconsider this approach to allow compatibility with `for<T: Tr>`
158
- let ty = tcx. replace_bound_vars_uncached ( ty, FnMutDelegate {
159
- regions : & mut |_| tcx. lifetimes . re_static ,
160
- types : & mut |_| tcx. types . unit ,
161
- consts : & mut |_| unimplemented ! ( "`~const` does not support const binders" ) ,
162
- } ) ;
163
-
164
- self . effects_min_tys . insert ( ty, span) ;
165
- return ;
166
- }
167
- // for
168
- // ```
169
- // trait Foo { type Bar: ~const Trait }
170
- // ```
171
- // ensure that `<Self::Bar as Trait>::Effects: TyCompat<Self::Effects>`.
172
- //
173
- // FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor
174
- // that uses a `Bar` that implements `Trait` with `Maybe` effects.
175
- ( DefKind :: AssocTy , ty:: BoundConstness :: ConstIfConst ) => {
176
- // FIXME(effects): implement this
177
- return ;
178
- }
179
- // probably illegal in this position.
180
- ( _, ty:: BoundConstness :: ConstIfConst ) => {
181
- tcx. dcx ( ) . span_delayed_bug ( span, "invalid `~const` encountered" ) ;
182
- return ;
183
- }
184
- } ;
185
- // create a new projection type `<T as Tr>::Effects`
186
- let Some ( assoc) = tcx. associated_type_for_effects ( bound_trait_ref. def_id ( ) ) else {
187
- tcx. dcx ( ) . span_delayed_bug (
188
- span,
189
- "`~const` trait bound has no effect assoc yet no errors encountered?" ,
190
- ) ;
191
- return ;
192
- } ;
193
- let self_ty = Ty :: new_projection ( tcx, assoc, bound_trait_ref. skip_binder ( ) . args ) ;
194
- // make `<T as Tr>::Effects: Compat<runtime>`
195
- let new_trait_ref =
196
- ty:: TraitRef :: new ( tcx, tcx. require_lang_item ( LangItem :: EffectsCompat , Some ( span) ) , [
197
- ty:: GenericArg :: from ( self_ty) ,
198
- compat_val. into ( ) ,
199
- ] ) ;
200
- self . clauses . push ( ( bound_trait_ref. rebind ( new_trait_ref) . upcast ( tcx) , span) ) ;
201
63
}
202
64
203
65
pub ( crate ) fn push_projection_bound (
0 commit comments