@@ -164,37 +164,60 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
164
164
165
165
/// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
166
166
fn compute_trait_ref ( & mut self , trait_ref : & ty:: TraitRef < ' tcx > , elaborate : Elaborate ) {
167
+ let tcx = self . infcx . tcx ;
167
168
let obligations = self . nominal_obligations ( trait_ref. def_id , trait_ref. substs ) ;
168
- let assoc_items = self . infcx . tcx . associated_items ( trait_ref . def_id ) ;
169
+
169
170
let cause = self . cause ( traits:: MiscObligation ) ;
170
171
let param_env = self . param_env ;
171
172
172
173
if let Elaborate :: All = elaborate {
174
+ let trait_assoc_items = tcx. associated_items ( trait_ref. def_id ) ;
175
+
173
176
let predicates = obligations. iter ( )
174
177
. map ( |obligation| obligation. predicate . clone ( ) )
175
178
. collect ( ) ;
176
- let implied_obligations = traits:: elaborate_predicates ( self . infcx . tcx , predicates) ;
179
+ let implied_obligations = traits:: elaborate_predicates ( tcx, predicates) ;
177
180
let item_span: Option < Span > = self . item . map ( |i| i. span ) ;
178
181
let item = & self . item ;
179
182
let implied_obligations = implied_obligations. map ( |pred| {
180
183
let mut cause = cause. clone ( ) ;
181
- if let ty:: Predicate :: Trait ( proj) = & pred {
184
+ match & pred {
185
+ ty:: Predicate :: Projection ( proj) => {
186
+ if let Some ( hir:: ItemKind :: Impl ( .., impl_items) ) = item. map ( |i| & i. kind ) {
187
+ let trait_assoc_item = tcx. associated_item ( proj. projection_def_id ( ) ) ;
188
+ if let Some ( impl_item) = impl_items. iter ( ) . filter ( |item| {
189
+ item. ident == trait_assoc_item. ident
190
+ } ) . next ( ) {
191
+ cause. span = impl_item. span ;
192
+ cause. code = traits:: AssocTypeBound (
193
+ item_span,
194
+ trait_assoc_item. ident . span ,
195
+ ) ;
196
+ }
197
+ }
198
+ }
199
+ ty:: Predicate :: Trait ( proj) => {
182
200
if let (
183
201
ty:: Projection ( ty:: ProjectionTy { item_def_id, .. } ) ,
184
- Some ( hir:: ItemKind :: Impl ( .., bounds ) ) ,
202
+ Some ( hir:: ItemKind :: Impl ( .., impl_items ) ) ,
185
203
) = ( & proj. skip_binder ( ) . self_ty ( ) . kind , item. map ( |i| & i. kind ) ) {
186
- if let Some ( ( bound , assoc_item ) ) = assoc_items . clone ( )
204
+ if let Some ( ( impl_item , trait_assoc_item ) ) = trait_assoc_items . clone ( )
187
205
. filter ( |i| i. def_id == * item_def_id)
188
206
. next ( )
189
- . and_then ( |assoc_item| bounds . iter ( )
190
- . filter ( |b| b . ident == assoc_item . ident )
207
+ . and_then ( |trait_assoc_item| impl_items . iter ( )
208
+ . filter ( |i| i . ident == trait_assoc_item . ident )
191
209
. next ( )
192
- . map ( |bound | ( bound , assoc_item ) ) )
210
+ . map ( |impl_item | ( impl_item , trait_assoc_item ) ) )
193
211
{
194
- cause. span = bound. span ;
195
- cause. code = traits:: AssocTypeBound ( item_span, assoc_item. ident . span ) ;
212
+ cause. span = impl_item. span ;
213
+ cause. code = traits:: AssocTypeBound (
214
+ item_span,
215
+ trait_assoc_item. ident . span ,
216
+ ) ;
217
+ }
196
218
}
197
219
}
220
+ _ => { }
198
221
}
199
222
traits:: Obligation :: new ( cause, param_env, pred)
200
223
} ) ;
0 commit comments