@@ -164,10 +164,62 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
164
164
suggested_name,
165
165
Applicability :: MaybeIncorrect ,
166
166
) ;
167
- } else {
168
- err. span_label ( span, format ! ( "associated type `{}` not found" , assoc_name) ) ;
167
+ return err. emit ( ) ;
169
168
}
170
169
170
+ // If we didn't find a good item in the supertraits (or couldn't get
171
+ // the supertraits), like in ItemCtxt, then look more generally from
172
+ // all visible traits. If there's one clear winner, just suggest that.
173
+
174
+ let visible_traits: Vec < _ > = self
175
+ . tcx ( )
176
+ . all_traits ( )
177
+ . filter ( |trait_def_id| {
178
+ let viz = self . tcx ( ) . visibility ( * trait_def_id) ;
179
+ if let Some ( def_id) = self . item_def_id ( ) {
180
+ viz. is_accessible_from ( def_id, self . tcx ( ) )
181
+ } else {
182
+ viz. is_visible_locally ( )
183
+ }
184
+ } )
185
+ . collect ( ) ;
186
+
187
+ let wider_candidate_names: Vec < _ > = visible_traits
188
+ . iter ( )
189
+ . flat_map ( |trait_def_id| {
190
+ self . tcx ( ) . associated_items ( * trait_def_id) . in_definition_order ( )
191
+ } )
192
+ . filter_map (
193
+ |item| if item. kind == ty:: AssocKind :: Type { Some ( item. name ) } else { None } ,
194
+ )
195
+ . collect ( ) ;
196
+
197
+ if let ( Some ( suggested_name) , true ) = (
198
+ find_best_match_for_name ( & wider_candidate_names, assoc_name. name , None ) ,
199
+ assoc_name. span != DUMMY_SP ,
200
+ ) {
201
+ if let [ best_trait] = visible_traits
202
+ . iter ( )
203
+ . filter ( |trait_def_id| {
204
+ self . tcx ( )
205
+ . associated_items ( * trait_def_id)
206
+ . filter_by_name_unhygienic ( suggested_name)
207
+ . any ( |item| item. kind == ty:: AssocKind :: Type )
208
+ } )
209
+ . collect :: < Vec < _ > > ( ) [ ..]
210
+ {
211
+ err. span_label (
212
+ assoc_name. span ,
213
+ format ! (
214
+ "there is a similarly named associated type `{suggested_name}` in the trait `{}`" ,
215
+ self . tcx( ) . def_path_str( * best_trait)
216
+ ) ,
217
+ ) ;
218
+ return err. emit ( ) ;
219
+ }
220
+ }
221
+
222
+ err. span_label ( span, format ! ( "associated type `{}` not found" , assoc_name) ) ;
171
223
err. emit ( )
172
224
}
173
225
0 commit comments