@@ -78,13 +78,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
7878 }
7979
8080 if self_ty. span . edition ( ) . at_least_rust_2021 ( ) {
81- let msg = "expected a type, found a trait" ;
82- let label = "you can add the `dyn` keyword if you want a trait object" ;
83- let mut diag =
84- rustc_errors:: struct_span_code_err!( self . dcx( ) , self_ty. span, E0782 , "{}" , msg) ;
81+ let mut diag = rustc_errors:: struct_span_code_err!(
82+ self . dcx( ) ,
83+ self_ty. span,
84+ E0782 ,
85+ "{}" ,
86+ "expected a type, found a trait"
87+ ) ;
8588 if self_ty. span . can_be_used_for_suggestions ( )
8689 && !self . maybe_suggest_impl_trait ( self_ty, & mut diag)
87- && !self . maybe_suggest_dyn_trait ( self_ty, label , sugg, & mut diag)
90+ && !self . maybe_suggest_dyn_trait ( self_ty, sugg, & mut diag)
8891 {
8992 self . maybe_suggest_add_generic_impl_trait ( self_ty, & mut diag) ;
9093 }
@@ -131,8 +134,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
131134 diag : & mut Diag < ' _ > ,
132135 ) -> bool {
133136 let tcx = self . tcx ( ) ;
134- let msg = "you might be missing a type parameter" ;
135- let mut sugg = vec ! [ ] ;
136137
137138 let parent_hir_id = tcx. parent_hir_id ( self_ty. hir_id ) ;
138139 let parent_item = tcx. hir_get_parent_item ( self_ty. hir_id ) . def_id ;
@@ -160,13 +161,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
160161 _ => return false ,
161162 } ;
162163
163- // FIXME: `T` may already be taken.
164- sugg. push ( (
165- generics. where_clause_span ,
166- format ! ( "<T: {}>" , self . tcx( ) . sess. source_map( ) . span_to_snippet( self_ty. span) . unwrap( ) ) ,
167- ) ) ;
168- sugg. push ( ( self_ty. span , "T" . to_string ( ) ) ) ;
169- diag. multipart_suggestion_verbose ( msg, sugg, Applicability :: MachineApplicable ) ;
164+ let Ok ( rendered_ty) = tcx. sess . source_map ( ) . span_to_snippet ( self_ty. span ) else {
165+ return false ;
166+ } ;
167+
168+ let param = "TUV"
169+ . chars ( )
170+ . map ( |c| c. to_string ( ) )
171+ . chain ( ( 0 ..) . map ( |i| format ! ( "P{i}" ) ) )
172+ . find ( |s| !generics. params . iter ( ) . any ( |param| param. name . ident ( ) . as_str ( ) == s) )
173+ . expect ( "we definitely can find at least one param name to generate" ) ;
174+ let mut sugg = vec ! [ ( self_ty. span, param. to_string( ) ) ] ;
175+ if let Some ( insertion_span) = generics. span_for_param_suggestion ( ) {
176+ sugg. push ( ( insertion_span, format ! ( ", {param}: {}" , rendered_ty) ) ) ;
177+ } else {
178+ sugg. push ( ( generics. where_clause_span , format ! ( "<{param}: {}>" , rendered_ty) ) ) ;
179+ }
180+ diag. multipart_suggestion_verbose (
181+ "you might be missing a type parameter" ,
182+ sugg,
183+ Applicability :: MachineApplicable ,
184+ ) ;
170185 true
171186 }
172187 /// Make sure that we are in the condition to suggest the blanket implementation.
@@ -227,7 +242,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
227242 fn maybe_suggest_dyn_trait (
228243 & self ,
229244 self_ty : & hir:: Ty < ' _ > ,
230- label : & str ,
231245 sugg : Vec < ( Span , String ) > ,
232246 diag : & mut Diag < ' _ > ,
233247 ) -> bool {
@@ -270,7 +284,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
270284
271285 // FIXME: Only emit this suggestion if the trait is dyn-compatible.
272286 diag. multipart_suggestion_verbose (
273- label . to_string ( ) ,
287+ "you can add the `dyn` keyword if you want a trait object" ,
274288 sugg,
275289 Applicability :: MachineApplicable ,
276290 ) ;
0 commit comments