33
44use rustc_data_structures:: fx:: FxIndexMap ;
55use rustc_hir:: LangItem ;
6- use rustc_hir:: def:: DefKind ;
7- use rustc_middle:: ty:: fold:: FnMutDelegate ;
86use rustc_middle:: ty:: { self , Ty , TyCtxt , Upcast } ;
97use rustc_span:: Span ;
10- use rustc_span:: def_id:: DefId ;
11-
12- use crate :: hir_ty_lowering:: PredicateFilter ;
138
149/// Collects together a list of type bounds. These lists of bounds occur in many places
1510/// in Rust's syntax:
@@ -47,12 +42,9 @@ impl<'tcx> Bounds<'tcx> {
4742 pub ( crate ) fn push_trait_bound (
4843 & mut self ,
4944 tcx : TyCtxt < ' tcx > ,
50- defining_def_id : DefId ,
5145 bound_trait_ref : ty:: PolyTraitRef < ' tcx > ,
5246 span : Span ,
5347 polarity : ty:: PredicatePolarity ,
54- constness : Option < ty:: BoundConstness > ,
55- predicate_filter : PredicateFilter ,
5648 ) {
5749 let clause = (
5850 bound_trait_ref
@@ -68,137 +60,6 @@ impl<'tcx> Bounds<'tcx> {
6860 } else {
6961 self . clauses . push ( clause) ;
7062 }
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) ) ;
20263 }
20364
20465 pub ( crate ) fn push_projection_bound (
0 commit comments