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 : Option < ty:: BoundConstness > ,
55
- predicate_filter : PredicateFilter ,
56
48
) {
57
49
let clause = (
58
50
bound_trait_ref
@@ -68,137 +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
- ( _, Some ( ty:: BoundConstness :: Const ) ) => tcx. consts . false_ ,
92
- // body owners that can have trait bounds
93
- (
94
- DefKind :: Const | DefKind :: Fn | DefKind :: AssocFn ,
95
- Some ( ty:: BoundConstness :: ConstIfConst ) ,
96
- ) => tcx. expected_host_effect_param_for_body ( defining_def_id) ,
97
-
98
- ( _, None ) => {
99
- if !tcx. is_const_trait ( bound_trait_ref. def_id ( ) ) {
100
- return ;
101
- }
102
- tcx. consts . true_
103
- }
104
- ( DefKind :: Trait , Some ( ty:: BoundConstness :: ConstIfConst ) ) => {
105
- // we are in a trait, where `bound_trait_ref` could be:
106
- // (1) a super trait `trait Foo: ~const Bar`.
107
- // - This generates `<Self as Foo>::Effects: TyCompat<<Self as Bar>::Effects>`
108
- //
109
- // (2) a where clause `where for<..> Something: ~const Bar`.
110
- // - This generates `for<..> <Self as Foo>::Effects: TyCompat<<Something as Bar>::Effects>`
111
- let Some ( own_fx) = tcx. associated_type_for_effects ( defining_def_id) else {
112
- tcx. dcx ( ) . span_delayed_bug ( span, "should not have allowed `~const` on a trait that doesn't have `#[const_trait]`" ) ;
113
- return ;
114
- } ;
115
- let own_fx_ty = Ty :: new_projection (
116
- tcx,
117
- own_fx,
118
- ty:: GenericArgs :: identity_for_item ( tcx, own_fx) ,
119
- ) ;
120
- let Some ( their_fx) = tcx. associated_type_for_effects ( bound_trait_ref. def_id ( ) )
121
- else {
122
- tcx. dcx ( ) . span_delayed_bug ( span, "`~const` on trait without Effects assoc" ) ;
123
- return ;
124
- } ;
125
- let their_fx_ty =
126
- Ty :: new_projection ( tcx, their_fx, bound_trait_ref. skip_binder ( ) . args ) ;
127
- let compat = tcx. require_lang_item ( LangItem :: EffectsTyCompat , Some ( span) ) ;
128
- let clause = bound_trait_ref
129
- . map_bound ( |_| {
130
- let trait_ref = ty:: TraitRef :: new ( tcx, compat, [ own_fx_ty, their_fx_ty] ) ;
131
- ty:: ClauseKind :: Trait ( ty:: TraitPredicate {
132
- trait_ref,
133
- polarity : ty:: PredicatePolarity :: Positive ,
134
- } )
135
- } )
136
- . upcast ( tcx) ;
137
-
138
- self . clauses . push ( ( clause, span) ) ;
139
- return ;
140
- }
141
-
142
- ( DefKind :: Impl { of_trait : true } , Some ( ty:: BoundConstness :: ConstIfConst ) ) => {
143
- // this is a where clause on an impl header.
144
- // push `<T as Tr>::Effects` into the set for the `Min` bound.
145
- let Some ( assoc) = tcx. associated_type_for_effects ( bound_trait_ref. def_id ( ) ) else {
146
- tcx. dcx ( ) . span_delayed_bug ( span, "`~const` on trait without Effects assoc" ) ;
147
- return ;
148
- } ;
149
-
150
- let ty = bound_trait_ref
151
- . map_bound ( |trait_ref| Ty :: new_projection ( tcx, assoc, trait_ref. args ) ) ;
152
-
153
- // When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the
154
- // binders to dummy ones i.e. `X<'static, ()>` so they can be referenced in
155
- // the `Min` associated type properly (which doesn't allow using `for<>`)
156
- // This should work for any bound variables as long as they don't have any
157
- // bounds e.g. `for<T: Trait>`.
158
- // FIXME(effects) reconsider this approach to allow compatibility with `for<T: Tr>`
159
- let ty = tcx. replace_bound_vars_uncached ( ty, FnMutDelegate {
160
- regions : & mut |_| tcx. lifetimes . re_static ,
161
- types : & mut |_| tcx. types . unit ,
162
- consts : & mut |_| unimplemented ! ( "`~const` does not support const binders" ) ,
163
- } ) ;
164
-
165
- self . effects_min_tys . insert ( ty, span) ;
166
- return ;
167
- }
168
- // for
169
- // ```
170
- // trait Foo { type Bar: ~const Trait }
171
- // ```
172
- // ensure that `<Self::Bar as Trait>::Effects: TyCompat<Self::Effects>`.
173
- //
174
- // FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor
175
- // that uses a `Bar` that implements `Trait` with `Maybe` effects.
176
- ( DefKind :: AssocTy , Some ( ty:: BoundConstness :: ConstIfConst ) ) => {
177
- // FIXME(effects): implement this
178
- return ;
179
- }
180
- // probably illegal in this position.
181
- ( _, Some ( ty:: BoundConstness :: ConstIfConst ) ) => {
182
- tcx. dcx ( ) . span_delayed_bug ( span, "invalid `~const` encountered" ) ;
183
- return ;
184
- }
185
- } ;
186
- // create a new projection type `<T as Tr>::Effects`
187
- let Some ( assoc) = tcx. associated_type_for_effects ( bound_trait_ref. def_id ( ) ) else {
188
- tcx. dcx ( ) . span_delayed_bug (
189
- span,
190
- "`~const` trait bound has no effect assoc yet no errors encountered?" ,
191
- ) ;
192
- return ;
193
- } ;
194
- let self_ty = Ty :: new_projection ( tcx, assoc, bound_trait_ref. skip_binder ( ) . args ) ;
195
- // make `<T as Tr>::Effects: Compat<runtime>`
196
- let new_trait_ref =
197
- ty:: TraitRef :: new ( tcx, tcx. require_lang_item ( LangItem :: EffectsCompat , Some ( span) ) , [
198
- ty:: GenericArg :: from ( self_ty) ,
199
- compat_val. into ( ) ,
200
- ] ) ;
201
- self . clauses . push ( ( bound_trait_ref. rebind ( new_trait_ref) . upcast ( tcx) , span) ) ;
202
63
}
203
64
204
65
pub ( crate ) fn push_projection_bound (
0 commit comments