@@ -101,6 +101,13 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
101
101
) ) ;
102
102
}
103
103
104
+ fn prove_wf ( & self , arg : ty:: GenericArg < ' tcx > ) {
105
+ self . prove_predicate (
106
+ ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( arg) ) . to_predicate ( self . tcx ( ) ) ,
107
+ ObligationCause :: dummy_with_span ( self . span ) ,
108
+ ) ;
109
+ }
110
+
104
111
fn tcx ( & self ) -> TyCtxt < ' tcx > {
105
112
self . ocx . infcx . tcx
106
113
}
@@ -111,16 +118,8 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
111
118
mir_ty : Ty < ' tcx > ,
112
119
user_ty : Ty < ' tcx > ,
113
120
) -> Result < ( ) , NoSolution > {
114
- let user_ty = self . normalize ( user_ty) ;
115
- self . eq ( mir_ty, user_ty) ?;
116
-
117
- // FIXME(#xxxx): We should check well-formedness before normalization.
118
- self . prove_predicate (
119
- ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( user_ty. into ( ) ) )
120
- . to_predicate ( self . tcx ( ) ) ,
121
- ObligationCause :: dummy_with_span ( self . span ) ,
122
- ) ;
123
-
121
+ self . prove_wf ( user_ty. into ( ) ) ;
122
+ self . eq ( mir_ty, self . normalize ( user_ty) ) ?;
124
123
Ok ( ( ) )
125
124
}
126
125
@@ -147,8 +146,6 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
147
146
// outlives" error messages.
148
147
let instantiated_predicates = tcx. predicates_of ( def_id) . instantiate ( tcx, substs) ;
149
148
150
- let cause = ObligationCause :: dummy_with_span ( self . span ) ;
151
-
152
149
debug ! ( ?instantiated_predicates) ;
153
150
for ( instantiated_predicate, predicate_span) in
154
151
zip ( instantiated_predicates. predicates , instantiated_predicates. spans )
@@ -164,35 +161,29 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
164
161
self . prove_predicate ( instantiated_predicate, cause) ;
165
162
}
166
163
164
+ // Now prove the well-formedness of `def_id` with `substs`.
165
+ // Note for some items, proving the WF of `ty` is not sufficient because the
166
+ // well-formedness of an item may depend on the WF of gneneric args not present in the
167
+ // item's type. Currently this is true for associated consts, e.g.:
168
+ // ```rust
169
+ // impl<T> MyTy<T> {
170
+ // const CONST: () = { /* arbitrary code that depends on T being WF */ };
171
+ // }
172
+ // ```
173
+ for arg in substs {
174
+ self . prove_wf ( arg) ;
175
+ }
176
+
167
177
if let Some ( UserSelfTy { impl_def_id, self_ty } ) = user_self_ty {
178
+ self . prove_wf ( self_ty. into ( ) ) ;
179
+
168
180
let self_ty = self . normalize ( self_ty) ;
169
181
let impl_self_ty = tcx. bound_type_of ( impl_def_id) . subst ( tcx, substs) ;
170
182
let impl_self_ty = self . normalize ( impl_self_ty) ;
171
183
172
184
self . eq ( self_ty, impl_self_ty) ?;
173
-
174
- self . prove_predicate (
175
- ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( impl_self_ty. into ( ) ) )
176
- . to_predicate ( tcx) ,
177
- cause. clone ( ) ,
178
- ) ;
179
185
}
180
186
181
- // In addition to proving the predicates, we have to
182
- // prove that `ty` is well-formed -- this is because
183
- // the WF of `ty` is predicated on the substs being
184
- // well-formed, and we haven't proven *that*. We don't
185
- // want to prove the WF of types from `substs` directly because they
186
- // haven't been normalized.
187
- //
188
- // FIXME(nmatsakis): Well, perhaps we should normalize
189
- // them? This would only be relevant if some input
190
- // type were ill-formed but did not appear in `ty`,
191
- // which...could happen with normalization...
192
- self . prove_predicate (
193
- ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( ty. into ( ) ) ) . to_predicate ( tcx) ,
194
- cause,
195
- ) ;
196
187
Ok ( ( ) )
197
188
}
198
189
}
0 commit comments