1+ use hir:: def_id:: DefId ;
2+ use hir:: HirId ;
13use rustc_ast:: Mutability ;
24use rustc_errors:: Applicability ;
35use rustc_hir as hir;
@@ -48,7 +50,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4850 call_expr. span ,
4951 |lint| {
5052 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 ( ) ) ;
5255
5356 let mut lint = lint. build ( & format ! (
5457 "trait method `{}` will become ambiguous in Rust 2021" ,
@@ -144,16 +147,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
144147 self . tcx . struct_span_lint_hir ( FUTURE_PRELUDE_COLLISION , expr_id, span, |lint| {
145148 // "type" refers to either a type or, more likely, a trait from which
146149 // 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 ( ) ) ;
149152
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 ) ;
151154 let trait_name = if parameter_count == 0 {
152- type_name
155+ trait_path
153156 } else {
154157 format ! (
155158 "{}<{}>" ,
156- type_name ,
159+ trait_path ,
157160 std:: iter:: repeat( "_" ) . take( parameter_count) . collect:: <Vec <_>>( ) . join( ", " )
158161 )
159162 } ;
@@ -179,4 +182,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
179182 lint. emit ( ) ;
180183 } ) ;
181184 }
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+ }
182209}
0 commit comments