@@ -6,14 +6,15 @@ use crate::check::callee::{self, DeferredCallResolution};
66use crate :: check:: method:: { self , MethodCallee , SelfSource } ;
77use crate :: check:: { BreakableCtxt , Diverges , Expectation , FallbackMode , FnCtxt , LocalTy } ;
88
9+ use rustc_ast:: TraitObjectSyntax ;
910use rustc_data_structures:: captures:: Captures ;
1011use rustc_data_structures:: fx:: FxHashSet ;
1112use rustc_errors:: { Applicability , DiagnosticBuilder , ErrorReported } ;
1213use rustc_hir as hir;
1314use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
1415use rustc_hir:: def_id:: DefId ;
1516use rustc_hir:: lang_items:: LangItem ;
16- use rustc_hir:: { ExprKind , GenericArg , Node , QPath } ;
17+ use rustc_hir:: { ExprKind , GenericArg , Node , QPath , TyKind } ;
1718use rustc_infer:: infer:: canonical:: { Canonical , OriginalQueryValues , QueryResponse } ;
1819use rustc_infer:: infer:: error_reporting:: TypeAnnotationNeeded :: E0282 ;
1920use rustc_infer:: infer:: { InferOk , InferResult } ;
@@ -26,7 +27,9 @@ use rustc_middle::ty::{
2627 self , AdtKind , CanonicalUserType , DefIdTree , GenericParamDefKind , ToPolyTraitRef , ToPredicate ,
2728 Ty , UserType ,
2829} ;
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;
3033use rustc_span:: source_map:: { original_sp, DUMMY_SP } ;
3134use rustc_span:: symbol:: { kw, sym, Ident } ;
3235use rustc_span:: { self , BytePos , MultiSpan , Span } ;
@@ -947,6 +950,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
947950 result
948951 } ) ;
949952
953+ if result. is_ok ( ) {
954+ self . maybe_lint_bare_trait ( qpath, hir_id) ;
955+ }
956+
950957 // Write back the new resolution.
951958 self . write_resolution ( hir_id, result) ;
952959 (
@@ -956,6 +963,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
956963 )
957964 }
958965
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+
959989 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
960990 pub ( in super :: super ) fn get_node_fn_decl (
961991 & self ,
0 commit comments