@@ -2986,6 +2986,51 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2986
2986
Some ( r)
2987
2987
}
2988
2988
2989
+ /// make sure that we are in the condition to suggest the blanket implementation, if we are in the
2990
+ /// case of suggest it, use the function `err_reporter` to report the error or suggestion.
2991
+ fn maybe_lint_blanket_trait_impl < T : rustc_errors:: EmissionGuarantee > (
2992
+ & self ,
2993
+ self_ty : & hir:: Ty < ' _ > ,
2994
+ diagnostic : & mut DiagnosticBuilder < ' _ , T > ,
2995
+ ) {
2996
+ let tcx = self . tcx ( ) ;
2997
+ let parent_id = tcx. hir ( ) . get_parent_item ( self_ty. hir_id ) ;
2998
+ if let hir:: Node :: Item ( hir:: Item {
2999
+ kind :
3000
+ hir:: ItemKind :: Impl ( hir:: Impl {
3001
+ self_ty : impl_self_typ, of_trait : Some ( trait_ref) , generics, ..
3002
+ } ) ,
3003
+ ..
3004
+ } ) = tcx. hir ( ) . get_by_def_id ( parent_id) && self_ty. hir_id == impl_self_typ. hir_id
3005
+ {
3006
+ let trait_span = trait_ref. path . span ;
3007
+ let target_span = if let Some ( span) = generics. span_for_param_suggestion ( ) {
3008
+ span
3009
+ } else {
3010
+ trait_span
3011
+ } ;
3012
+ let is_local = trait_ref. trait_def_id ( ) . map_or ( false , |def_id| def_id. is_local ( ) ) ;
3013
+ if is_local {
3014
+ let trait_name = tcx. sess . source_map ( ) . span_to_snippet ( trait_span) . unwrap ( ) ;
3015
+ let self_name = tcx. sess . source_map ( ) . span_to_snippet ( self_ty. span ) . unwrap ( ) ;
3016
+ let blanket_msg = format ! (
3017
+ "use a blanket implementation to implement {} for all types that also implement {}" ,
3018
+ trait_name, self_name
3019
+ ) ;
3020
+ let blanket_sugg = vec ! [
3021
+ ( target_span, "<T: " . to_owned( ) ) ,
3022
+ ( trait_span. shrink_to_hi( ) , format!( "{}>" , self_name) ) ,
3023
+ ( self_ty. span, "T" . to_owned( ) ) ,
3024
+ ] ;
3025
+ diagnostic. multipart_suggestion (
3026
+ blanket_msg,
3027
+ blanket_sugg,
3028
+ Applicability :: Unspecified ,
3029
+ ) ;
3030
+ }
3031
+ }
3032
+ }
3033
+
2989
3034
fn maybe_lint_bare_trait ( & self , self_ty : & hir:: Ty < ' _ > , in_path : bool ) {
2990
3035
let tcx = self . tcx ( ) ;
2991
3036
if let hir:: TyKind :: TraitObject ( [ poly_trait_ref, ..] , _, TraitObjectSyntax :: None ) =
@@ -3021,23 +3066,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
3021
3066
if self_ty. span . edition ( ) >= Edition :: Edition2021 {
3022
3067
let msg = "trait objects must include the `dyn` keyword" ;
3023
3068
let label = "add `dyn` keyword before this trait" ;
3024
- rustc_errors:: struct_span_err!( tcx. sess, self_ty. span, E0782 , "{}" , msg)
3025
- . multipart_suggestion_verbose ( label, sugg, Applicability :: MachineApplicable )
3026
- . emit ( ) ;
3069
+ let mut diag =
3070
+ rustc_errors:: struct_span_err!( tcx. sess, self_ty. span, E0782 , "{}" , msg) ;
3071
+ diag. multipart_suggestion_verbose ( label, sugg, Applicability :: MachineApplicable ) ;
3072
+ self . maybe_lint_blanket_trait_impl ( & self_ty, & mut diag) ;
3073
+ diag. emit ( ) ;
3027
3074
} else {
3028
3075
let msg = "trait objects without an explicit `dyn` are deprecated" ;
3029
3076
tcx. struct_span_lint_hir (
3030
3077
BARE_TRAIT_OBJECTS ,
3031
3078
self_ty. hir_id ,
3032
3079
self_ty. span ,
3033
3080
|lint| {
3034
- lint. build ( msg)
3035
- . multipart_suggestion_verbose (
3036
- "use `dyn`" ,
3037
- sugg,
3038
- Applicability :: MachineApplicable ,
3039
- )
3040
- . emit ( ) ;
3081
+ let mut diag = lint. build ( msg) ;
3082
+ diag. multipart_suggestion_verbose (
3083
+ "use `dyn`" ,
3084
+ sugg,
3085
+ Applicability :: MachineApplicable ,
3086
+ ) ;
3087
+ self . maybe_lint_blanket_trait_impl :: < ( ) > ( & self_ty, & mut diag) ;
3088
+ diag. emit ( ) ;
3041
3089
} ,
3042
3090
) ;
3043
3091
}
0 commit comments