1
+ use hir:: def_id:: DefId ;
2
+ use hir:: HirId ;
1
3
use rustc_ast:: Mutability ;
2
4
use rustc_errors:: Applicability ;
3
5
use rustc_hir as hir;
@@ -48,7 +50,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
48
50
call_expr. span ,
49
51
|lint| {
50
52
let sp = call_expr. span ;
51
- let trait_name = self . tcx . def_path_str ( pick. item . container . id ( ) ) ;
53
+ let trait_name =
54
+ self . trait_path_or_bare_name ( call_expr. hir_id , pick. item . container . id ( ) ) ;
52
55
53
56
let mut lint = lint. build ( & format ! (
54
57
"trait method `{}` will become ambiguous in Rust 2021" ,
@@ -144,16 +147,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
144
147
self . tcx . struct_span_lint_hir ( FUTURE_PRELUDE_COLLISION , expr_id, span, |lint| {
145
148
// "type" refers to either a type or, more likely, a trait from which
146
149
// the associated function or method is from.
147
- let type_name = self . tcx . def_path_str ( pick. item . container . id ( ) ) ;
148
- let type_generics = self . tcx . generics_of ( pick. item . container . id ( ) ) ;
150
+ let trait_path = self . trait_path_or_bare_name ( expr_id , pick. item . container . id ( ) ) ;
151
+ let trait_generics = self . tcx . generics_of ( pick. item . container . id ( ) ) ;
149
152
150
- let parameter_count = type_generics . count ( ) - ( type_generics . has_self as usize ) ;
153
+ let parameter_count = trait_generics . count ( ) - ( trait_generics . has_self as usize ) ;
151
154
let trait_name = if parameter_count == 0 {
152
- type_name
155
+ trait_path
153
156
} else {
154
157
format ! (
155
158
"{}<{}>" ,
156
- type_name ,
159
+ trait_path ,
157
160
std:: iter:: repeat( "_" ) . take( parameter_count) . collect:: <Vec <_>>( ) . join( ", " )
158
161
)
159
162
} ;
@@ -179,4 +182,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
179
182
lint. emit ( ) ;
180
183
} ) ;
181
184
}
185
+
186
+ fn trait_path_or_bare_name ( & self , expr_hir_id : HirId , trait_def_id : DefId ) -> String {
187
+ self . trait_path ( expr_hir_id, trait_def_id) . unwrap_or_else ( || {
188
+ let key = self . tcx . def_key ( trait_def_id) ;
189
+ format ! ( "{}" , key. disambiguated_data. data)
190
+ } )
191
+ }
192
+
193
+ fn trait_path ( & self , expr_hir_id : HirId , trait_def_id : DefId ) -> Option < String > {
194
+ let applicable_traits = self . tcx . in_scope_traits ( expr_hir_id) ?;
195
+ let applicable_trait = applicable_traits. iter ( ) . find ( |t| t. def_id == trait_def_id) ?;
196
+ if applicable_trait. import_ids . is_empty ( ) {
197
+ // The trait was declared within the module, we only need to use its name.
198
+ return None ;
199
+ }
200
+
201
+ for & import_id in & applicable_trait. import_ids {
202
+ let hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( import_id) ;
203
+ let item = self . tcx . hir ( ) . expect_item ( hir_id) ;
204
+ debug ! ( ?item, ?import_id, "import_id" ) ;
205
+ }
206
+
207
+ return None ;
208
+ }
182
209
}
0 commit comments