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 : ty:: BoundConstness ,
55- predicate_filter : PredicateFilter ,
5648 ) {
5749 let clause = (
5850 bound_trait_ref
@@ -68,136 +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- ( _, 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) ) ;
20163 }
20264
20365 pub ( crate ) fn push_projection_bound (
0 commit comments