@@ -6,14 +6,15 @@ use crate::check::callee::{self, DeferredCallResolution};
6
6
use crate :: check:: method:: { self , MethodCallee , SelfSource } ;
7
7
use crate :: check:: { BreakableCtxt , Diverges , Expectation , FallbackMode , FnCtxt , LocalTy } ;
8
8
9
+ use rustc_ast:: TraitObjectSyntax ;
9
10
use rustc_data_structures:: captures:: Captures ;
10
11
use rustc_data_structures:: fx:: FxHashSet ;
11
12
use rustc_errors:: { Applicability , DiagnosticBuilder , ErrorReported } ;
12
13
use rustc_hir as hir;
13
14
use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
14
15
use rustc_hir:: def_id:: DefId ;
15
16
use rustc_hir:: lang_items:: LangItem ;
16
- use rustc_hir:: { ExprKind , GenericArg , Node , QPath } ;
17
+ use rustc_hir:: { ExprKind , GenericArg , Node , QPath , TyKind } ;
17
18
use rustc_infer:: infer:: canonical:: { Canonical , OriginalQueryValues , QueryResponse } ;
18
19
use rustc_infer:: infer:: error_reporting:: TypeAnnotationNeeded :: E0282 ;
19
20
use rustc_infer:: infer:: { InferOk , InferResult } ;
@@ -26,7 +27,9 @@ use rustc_middle::ty::{
26
27
self , AdtKind , CanonicalUserType , DefIdTree , GenericParamDefKind , ToPolyTraitRef , ToPredicate ,
27
28
Ty , UserType ,
28
29
} ;
29
- use rustc_session:: { lint, parse:: feature_err} ;
30
+ use rustc_session:: lint;
31
+ use rustc_session:: lint:: builtin:: BARE_TRAIT_OBJECTS ;
32
+ use rustc_session:: parse:: feature_err;
30
33
use rustc_span:: source_map:: { original_sp, DUMMY_SP } ;
31
34
use rustc_span:: symbol:: { kw, sym, Ident } ;
32
35
use rustc_span:: { self , BytePos , MultiSpan , Span } ;
@@ -947,6 +950,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
947
950
result
948
951
} ) ;
949
952
953
+ if result. is_ok ( ) {
954
+ self . maybe_lint_bare_trait ( qpath, hir_id) ;
955
+ }
956
+
950
957
// Write back the new resolution.
951
958
self . write_resolution ( hir_id, result) ;
952
959
(
@@ -956,6 +963,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
956
963
)
957
964
}
958
965
966
+ fn maybe_lint_bare_trait ( & self , qpath : & QPath < ' _ > , hir_id : hir:: HirId ) {
967
+ if let QPath :: TypeRelative ( self_ty, _) = qpath {
968
+ if let TyKind :: TraitObject ( [ poly_trait_ref, ..] , _, TraitObjectSyntax :: None ) =
969
+ self_ty. kind
970
+ {
971
+ self . tcx . struct_span_lint_hir ( BARE_TRAIT_OBJECTS , hir_id, self_ty. span , |lint| {
972
+ let mut db = lint
973
+ . build ( & format ! ( "trait objects without an explicit `dyn` are deprecated" ) ) ;
974
+ let ( sugg, app) = match self . tcx . sess . source_map ( ) . span_to_snippet ( self_ty. span )
975
+ {
976
+ Ok ( s) if poly_trait_ref. trait_ref . path . is_global ( ) => {
977
+ ( format ! ( "<dyn ({})>" , s) , Applicability :: MachineApplicable )
978
+ }
979
+ Ok ( s) => ( format ! ( "<dyn {}>" , s) , Applicability :: MachineApplicable ) ,
980
+ Err ( _) => ( "<dyn <type>>" . to_string ( ) , Applicability :: HasPlaceholders ) ,
981
+ } ;
982
+ db. span_suggestion ( self_ty. span , "use `dyn`" , sugg, app) ;
983
+ db. emit ( )
984
+ } ) ;
985
+ }
986
+ }
987
+ }
988
+
959
989
/// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
960
990
pub ( in super :: super ) fn get_node_fn_decl (
961
991
& self ,
0 commit comments