44pub use self :: StabilityLevel :: * ;
55
66use crate :: lint:: { self , Lint , in_derive_expansion} ;
7+ use crate :: lint:: builtin:: BuiltinLintDiagnostics ;
78use crate :: hir:: { self , Item , Generics , StructField , Variant , HirId } ;
89use crate :: hir:: def:: { Res , DefKind } ;
910use crate :: hir:: def_id:: { CrateNum , CRATE_DEF_INDEX , DefId , LOCAL_CRATE } ;
1011use crate :: hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
1112use crate :: ty:: query:: Providers ;
1213use crate :: middle:: privacy:: AccessLevels ;
1314use crate :: session:: { DiagnosticMessageId , Session } ;
15+ use errors:: DiagnosticBuilder ;
1416use syntax:: symbol:: { Symbol , sym} ;
1517use syntax_pos:: { Span , MultiSpan } ;
16- use syntax:: ast:: Attribute ;
18+ use syntax:: ast:: { Attribute , CRATE_NODE_ID } ;
1719use syntax:: errors:: Applicability ;
1820use syntax:: feature_gate:: { GateIssue , emit_feature_err} ;
19- use syntax:: attr:: { self , Stability , Deprecation } ;
21+ use syntax:: attr:: { self , Stability , Deprecation , RustcDeprecation } ;
2022use crate :: ty:: { self , TyCtxt } ;
2123use crate :: util:: nodemap:: { FxHashSet , FxHashMap } ;
2224
@@ -531,6 +533,79 @@ pub fn deprecation_in_effect(since: &str) -> bool {
531533 }
532534}
533535
536+ pub fn deprecation_suggestion (
537+ diag : & mut DiagnosticBuilder < ' _ > , suggestion : Option < Symbol > , span : Span
538+ ) {
539+ if let Some ( suggestion) = suggestion {
540+ diag. span_suggestion (
541+ span,
542+ "replace the use of the deprecated item" ,
543+ suggestion. to_string ( ) ,
544+ Applicability :: MachineApplicable ,
545+ ) ;
546+ }
547+ }
548+
549+ fn deprecation_message_common ( message : String , reason : Option < Symbol > ) -> String {
550+ match reason {
551+ Some ( reason) => format ! ( "{}: {}" , message, reason) ,
552+ None => message,
553+ }
554+ }
555+
556+ pub fn deprecation_message ( depr : & Deprecation , path : & str ) -> ( String , & ' static Lint ) {
557+ let message = format ! ( "use of deprecated item '{}'" , path) ;
558+ ( deprecation_message_common ( message, depr. note ) , lint:: builtin:: DEPRECATED )
559+ }
560+
561+ pub fn rustc_deprecation_message ( depr : & RustcDeprecation , path : & str ) -> ( String , & ' static Lint ) {
562+ let ( message, lint) = if deprecation_in_effect ( & depr. since . as_str ( ) ) {
563+ ( format ! ( "use of deprecated item '{}'" , path) , lint:: builtin:: DEPRECATED )
564+ } else {
565+ ( format ! ( "use of item '{}' that will be deprecated in future version {}" , path, depr. since) ,
566+ lint:: builtin:: DEPRECATED_IN_FUTURE )
567+ } ;
568+ ( deprecation_message_common ( message, Some ( depr. reason ) ) , lint)
569+ }
570+
571+ pub fn early_report_deprecation (
572+ sess : & Session ,
573+ message : & str ,
574+ suggestion : Option < Symbol > ,
575+ lint : & ' static Lint ,
576+ span : Span ,
577+ ) {
578+ if in_derive_expansion ( span) {
579+ return ;
580+ }
581+
582+ let diag = BuiltinLintDiagnostics :: DeprecatedMacro ( suggestion, span) ;
583+ sess. buffer_lint_with_diagnostic ( lint, CRATE_NODE_ID , span, message, diag) ;
584+ }
585+
586+ fn late_report_deprecation (
587+ tcx : TyCtxt < ' _ > ,
588+ message : & str ,
589+ suggestion : Option < Symbol > ,
590+ lint : & ' static Lint ,
591+ span : Span ,
592+ def_id : DefId ,
593+ hir_id : HirId ,
594+ ) {
595+ if in_derive_expansion ( span) {
596+ return ;
597+ }
598+
599+ let mut diag = tcx. struct_span_lint_hir ( lint, hir_id, span, message) ;
600+ if let hir:: Node :: Expr ( _) = tcx. hir ( ) . get ( hir_id) {
601+ deprecation_suggestion ( & mut diag, suggestion, span) ;
602+ }
603+ diag. emit ( ) ;
604+ if hir_id == hir:: DUMMY_HIR_ID {
605+ span_bug ! ( span, "emitted a {} lint with dummy HIR id: {:?}" , lint. name, def_id) ;
606+ }
607+ }
608+
534609struct Checker < ' tcx > {
535610 tcx : TyCtxt < ' tcx > ,
536611}
@@ -593,38 +668,6 @@ impl<'tcx> TyCtxt<'tcx> {
593668 /// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
594669 /// `id`.
595670 pub fn eval_stability ( self , def_id : DefId , id : Option < HirId > , span : Span ) -> EvalResult {
596- let lint_deprecated = |def_id : DefId ,
597- id : HirId ,
598- note : Option < Symbol > ,
599- suggestion : Option < Symbol > ,
600- message : & str ,
601- lint : & ' static Lint | {
602- if in_derive_expansion ( span) {
603- return ;
604- }
605- let msg = if let Some ( note) = note {
606- format ! ( "{}: {}" , message, note)
607- } else {
608- format ! ( "{}" , message)
609- } ;
610-
611- let mut diag = self . struct_span_lint_hir ( lint, id, span, & msg) ;
612- if let Some ( suggestion) = suggestion {
613- if let hir:: Node :: Expr ( _) = self . hir ( ) . get ( id) {
614- diag. span_suggestion (
615- span,
616- "replace the use of the deprecated item" ,
617- suggestion. to_string ( ) ,
618- Applicability :: MachineApplicable ,
619- ) ;
620- }
621- }
622- diag. emit ( ) ;
623- if id == hir:: DUMMY_HIR_ID {
624- span_bug ! ( span, "emitted a {} lint with dummy HIR id: {:?}" , lint. name, def_id) ;
625- }
626- } ;
627-
628671 // Deprecated attributes apply in-crate and cross-crate.
629672 if let Some ( id) = id {
630673 if let Some ( depr_entry) = self . lookup_deprecation_entry ( def_id) {
@@ -634,14 +677,9 @@ impl<'tcx> TyCtxt<'tcx> {
634677 . map_or ( false , |parent_depr| parent_depr. same_origin ( & depr_entry) ) ;
635678
636679 if !skip {
637- let path = self . def_path_str ( def_id) ;
638- let message = format ! ( "use of deprecated item '{}'" , path) ;
639- lint_deprecated ( def_id,
640- id,
641- depr_entry. attr . note ,
642- None ,
643- & message,
644- lint:: builtin:: DEPRECATED ) ;
680+ let ( message, lint) =
681+ deprecation_message ( & depr_entry. attr , & self . def_path_str ( def_id) ) ;
682+ late_report_deprecation ( self , & message, None , lint, span, def_id, id) ;
645683 }
646684 } ;
647685 }
@@ -661,27 +699,11 @@ impl<'tcx> TyCtxt<'tcx> {
661699 if let Some ( id) = id {
662700 if let Some ( stability) = stability {
663701 if let Some ( depr) = & stability. rustc_depr {
664- let path = self . def_path_str ( def_id) ;
665- if deprecation_in_effect ( & depr. since . as_str ( ) ) {
666- let message = format ! ( "use of deprecated item '{}'" , path) ;
667- lint_deprecated ( def_id,
668- id,
669- Some ( depr. reason ) ,
670- depr. suggestion ,
671- & message,
672- lint:: builtin:: DEPRECATED ) ;
673- } else {
674- let message = format ! ( "use of item '{}' \
675- that will be deprecated in future version {}",
676- path,
677- depr. since) ;
678- lint_deprecated ( def_id,
679- id,
680- Some ( depr. reason ) ,
681- depr. suggestion ,
682- & message,
683- lint:: builtin:: DEPRECATED_IN_FUTURE ) ;
684- }
702+ let ( message, lint) =
703+ rustc_deprecation_message ( depr, & self . def_path_str ( def_id) ) ;
704+ late_report_deprecation (
705+ self , & message, depr. suggestion , lint, span, def_id, id
706+ ) ;
685707 }
686708 }
687709 }
0 commit comments