@@ -13,6 +13,7 @@ use crate::errors::{
1313} ; 
1414use  crate :: middle:: resolve_lifetime as  rl; 
1515use  crate :: require_c_abi_if_c_variadic; 
16+ use  rustc_ast:: TraitObjectSyntax ; 
1617use  rustc_data_structures:: fx:: { FxHashMap ,  FxHashSet } ; 
1718use  rustc_errors:: { struct_span_err,  Applicability ,  ErrorReported ,  FatalError } ; 
1819use  rustc_hir as  hir; 
@@ -24,7 +25,8 @@ use rustc_hir::{GenericArg, GenericArgs};
2425use  rustc_middle:: ty:: subst:: { self ,  GenericArgKind ,  InternalSubsts ,  Subst ,  SubstsRef } ; 
2526use  rustc_middle:: ty:: GenericParamDefKind ; 
2627use  rustc_middle:: ty:: { self ,  Const ,  DefIdTree ,  Ty ,  TyCtxt ,  TypeFoldable } ; 
27- use  rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ; 
28+ use  rustc_session:: lint:: builtin:: { AMBIGUOUS_ASSOCIATED_ITEMS ,  BARE_TRAIT_OBJECTS } ; 
29+ use  rustc_span:: edition:: Edition ; 
2830use  rustc_span:: lev_distance:: find_best_match_for_name; 
2931use  rustc_span:: symbol:: { Ident ,  Symbol } ; 
3032use  rustc_span:: { Span ,  DUMMY_SP } ; 
@@ -2266,13 +2268,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22662268    /// Parses the programmer's textual representation of a type into our 
22672269     /// internal notion of a type. 
22682270     pub  fn  ast_ty_to_ty ( & self ,  ast_ty :  & hir:: Ty < ' _ > )  -> Ty < ' tcx >  { 
2269-         self . ast_ty_to_ty_inner ( ast_ty,  false ) 
2271+         self . ast_ty_to_ty_inner ( ast_ty,  false ,  false ) 
2272+     } 
2273+ 
2274+     /// Parses the programmer's textual representation of a type into our 
2275+      /// internal notion of a type.  This is meant to be used within a path. 
2276+      pub  fn  ast_ty_to_ty_in_path ( & self ,  ast_ty :  & hir:: Ty < ' _ > )  -> Ty < ' tcx >  { 
2277+         self . ast_ty_to_ty_inner ( ast_ty,  false ,  true ) 
22702278    } 
22712279
22722280    /// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait 
22732281     /// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors. 
22742282     #[ tracing:: instrument( level = "debug" ,  skip( self ) ) ]  
2275-     fn  ast_ty_to_ty_inner ( & self ,  ast_ty :  & hir:: Ty < ' _ > ,  borrowed :  bool )  -> Ty < ' tcx >  { 
2283+     fn  ast_ty_to_ty_inner ( & self ,  ast_ty :  & hir:: Ty < ' _ > ,  borrowed :  bool ,   in_path :   bool )  -> Ty < ' tcx >  { 
22762284        let  tcx = self . tcx ( ) ; 
22772285
22782286        let  result_ty = match  ast_ty. kind  { 
@@ -2283,7 +2291,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22832291            hir:: TyKind :: Rptr ( ref  region,  ref  mt)  => { 
22842292                let  r = self . ast_region_to_region ( region,  None ) ; 
22852293                debug ! ( ?r) ; 
2286-                 let  t = self . ast_ty_to_ty_inner ( mt. ty ,  true ) ; 
2294+                 let  t = self . ast_ty_to_ty_inner ( mt. ty ,  true ,   false ) ; 
22872295                tcx. mk_ref ( r,  ty:: TypeAndMut  {  ty :  t,  mutbl :  mt. mutbl  } ) 
22882296            } 
22892297            hir:: TyKind :: Never  => tcx. types . never , 
@@ -2302,6 +2310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
23022310                ) ) 
23032311            } 
23042312            hir:: TyKind :: TraitObject ( bounds,  ref  lifetime,  _)  => { 
2313+                 self . maybe_lint_bare_trait ( ast_ty,  in_path) ; 
23052314                self . conv_object_ty_poly_trait_ref ( ast_ty. span ,  bounds,  lifetime,  borrowed) 
23062315            } 
23072316            hir:: TyKind :: Path ( hir:: QPath :: Resolved ( ref  maybe_qself,  ref  path) )  => { 
@@ -2329,7 +2338,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
23292338            } 
23302339            hir:: TyKind :: Path ( hir:: QPath :: TypeRelative ( ref  qself,  ref  segment) )  => { 
23312340                debug ! ( ?qself,  ?segment) ; 
2332-                 let  ty = self . ast_ty_to_ty ( qself) ; 
2341+                 let  ty = self . ast_ty_to_ty_inner ( qself,   false ,   true ) ; 
23332342
23342343                let  res = if  let  hir:: TyKind :: Path ( hir:: QPath :: Resolved ( _,  path) )  = qself. kind  { 
23352344                    path. res 
@@ -2586,4 +2595,62 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25862595        } 
25872596        Some ( r) 
25882597    } 
2598+ 
2599+     fn  maybe_lint_bare_trait ( & self ,  self_ty :  & hir:: Ty < ' _ > ,  in_path :  bool )  { 
2600+         let  tcx = self . tcx ( ) ; 
2601+         if  let  hir:: TyKind :: TraitObject ( [ poly_trait_ref,  ..] ,  _,  TraitObjectSyntax :: None )  =
2602+             self_ty. kind 
2603+         { 
2604+             let  needs_bracket = in_path
2605+                 && !tcx
2606+                     . sess 
2607+                     . source_map ( ) 
2608+                     . span_to_prev_source ( self_ty. span ) 
2609+                     . ok ( ) 
2610+                     . map_or ( false ,  |s| s. trim_end ( ) . ends_with ( '<' ) ) ; 
2611+ 
2612+             let  is_global = poly_trait_ref. trait_ref . path . is_global ( ) ; 
2613+             let  sugg = Vec :: from_iter ( [ 
2614+                 ( 
2615+                     self_ty. span . shrink_to_lo ( ) , 
2616+                     format ! ( 
2617+                         "{}dyn {}" , 
2618+                         if  needs_bracket {  "<"  }  else {  ""  } , 
2619+                         if  is_global {  "("  }  else {  ""  } , 
2620+                     ) , 
2621+                 ) , 
2622+                 ( 
2623+                     self_ty. span . shrink_to_hi ( ) , 
2624+                     format ! ( 
2625+                         "{}{}" , 
2626+                         if  is_global {  ")"  }  else {  ""  } , 
2627+                         if  needs_bracket {  ">"  }  else {  ""  } , 
2628+                     ) , 
2629+                 ) , 
2630+             ] ) ; 
2631+             if  self_ty. span . edition ( )  >= Edition :: Edition2021  { 
2632+                 let  msg = "trait objects must include the `dyn` keyword" ; 
2633+                 let  label = "add `dyn` keyword before this trait" ; 
2634+                 rustc_errors:: struct_span_err!( tcx. sess,  self_ty. span,  E0782 ,  "{}" ,  msg) 
2635+                     . multipart_suggestion_verbose ( label,  sugg,  Applicability :: MachineApplicable ) 
2636+                     . emit ( ) ; 
2637+             }  else  { 
2638+                 let  msg = "trait objects without an explicit `dyn` are deprecated" ; 
2639+                 tcx. struct_span_lint_hir ( 
2640+                     BARE_TRAIT_OBJECTS , 
2641+                     self_ty. hir_id , 
2642+                     self_ty. span , 
2643+                     |lint| { 
2644+                         lint. build ( msg) 
2645+                             . multipart_suggestion_verbose ( 
2646+                                 "use `dyn`" , 
2647+                                 sugg, 
2648+                                 Applicability :: MachineApplicable , 
2649+                             ) 
2650+                             . emit ( ) 
2651+                     } , 
2652+                 ) ; 
2653+             } 
2654+         } 
2655+     } 
25892656} 
0 commit comments