11#![ allow( rustc:: default_hash_types) ]
22
3+ mod borrowed_box;
34mod box_vec;
45mod linked_list;
56mod option_option;
@@ -18,9 +19,9 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
1819use rustc_hir as hir;
1920use rustc_hir:: intravisit:: { walk_body, walk_expr, walk_ty, FnKind , NestedVisitorMap , Visitor } ;
2021use rustc_hir:: {
21- BinOpKind , Block , Body , Expr , ExprKind , FnDecl , FnRetTy , FnSig , GenericArg , GenericBounds , GenericParamKind , HirId ,
22- ImplItem , ImplItemKind , Item , ItemKind , Lifetime , Lit , Local , MatchSource , MutTy , Mutability , Node , QPath , Stmt ,
23- StmtKind , SyntheticTyParamKind , TraitFn , TraitItem , TraitItemKind , TyKind , UnOp ,
22+ BinOpKind , Block , Body , Expr , ExprKind , FnDecl , FnRetTy , FnSig , GenericArg , GenericParamKind , HirId , ImplItem ,
23+ ImplItemKind , Item , ItemKind , Lit , Local , MatchSource , MutTy , Mutability , Node , QPath , Stmt , StmtKind , TraitFn ,
24+ TraitItem , TraitItemKind , TyKind , UnOp ,
2425} ;
2526use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
2627use rustc_middle:: hir:: map:: Map ;
@@ -376,7 +377,11 @@ impl Types {
376377 QPath :: LangItem ( ..) => { } ,
377378 }
378379 } ,
379- TyKind :: Rptr ( ref lt, ref mut_ty) => self . check_ty_rptr ( cx, hir_ty, is_local, lt, mut_ty) ,
380+ TyKind :: Rptr ( ref lt, ref mut_ty) => {
381+ if !borrowed_box:: check ( cx, hir_ty, is_local, lt, mut_ty) {
382+ self . check_ty ( cx, & mut_ty. ty , is_local) ;
383+ }
384+ } ,
380385 TyKind :: Slice ( ref ty) | TyKind :: Array ( ref ty, _) | TyKind :: Ptr ( MutTy { ref ty, .. } ) => {
381386 self . check_ty ( cx, ty, is_local)
382387 } ,
@@ -388,115 +393,6 @@ impl Types {
388393 _ => { } ,
389394 }
390395 }
391-
392- fn check_ty_rptr (
393- & mut self ,
394- cx : & LateContext < ' _ > ,
395- hir_ty : & hir:: Ty < ' _ > ,
396- is_local : bool ,
397- lt : & Lifetime ,
398- mut_ty : & MutTy < ' _ > ,
399- ) {
400- match mut_ty. ty . kind {
401- TyKind :: Path ( ref qpath) => {
402- let hir_id = mut_ty. ty . hir_id ;
403- let def = cx. qpath_res ( qpath, hir_id) ;
404- if_chain ! {
405- if let Some ( def_id) = def. opt_def_id( ) ;
406- if Some ( def_id) == cx. tcx. lang_items( ) . owned_box( ) ;
407- if let QPath :: Resolved ( None , ref path) = * qpath;
408- if let [ ref bx] = * path. segments;
409- if let Some ( ref params) = bx. args;
410- if !params. parenthesized;
411- if let Some ( inner) = params. args. iter( ) . find_map( |arg| match arg {
412- GenericArg :: Type ( ty) => Some ( ty) ,
413- _ => None ,
414- } ) ;
415- then {
416- if is_any_trait( inner) {
417- // Ignore `Box<Any>` types; see issue #1884 for details.
418- return ;
419- }
420-
421- let ltopt = if lt. is_elided( ) {
422- String :: new( )
423- } else {
424- format!( "{} " , lt. name. ident( ) . as_str( ) )
425- } ;
426-
427- if mut_ty. mutbl == Mutability :: Mut {
428- // Ignore `&mut Box<T>` types; see issue #2907 for
429- // details.
430- return ;
431- }
432-
433- // When trait objects or opaque types have lifetime or auto-trait bounds,
434- // we need to add parentheses to avoid a syntax error due to its ambiguity.
435- // Originally reported as the issue #3128.
436- let inner_snippet = snippet( cx, inner. span, ".." ) ;
437- let suggestion = match & inner. kind {
438- TyKind :: TraitObject ( bounds, lt_bound) if bounds. len( ) > 1 || !lt_bound. is_elided( ) => {
439- format!( "&{}({})" , ltopt, & inner_snippet)
440- } ,
441- TyKind :: Path ( qpath)
442- if get_bounds_if_impl_trait( cx, qpath, inner. hir_id)
443- . map_or( false , |bounds| bounds. len( ) > 1 ) =>
444- {
445- format!( "&{}({})" , ltopt, & inner_snippet)
446- } ,
447- _ => format!( "&{}{}" , ltopt, & inner_snippet) ,
448- } ;
449- span_lint_and_sugg(
450- cx,
451- BORROWED_BOX ,
452- hir_ty. span,
453- "you seem to be trying to use `&Box<T>`. Consider using just `&T`" ,
454- "try" ,
455- suggestion,
456- // To make this `MachineApplicable`, at least one needs to check if it isn't a trait item
457- // because the trait impls of it will break otherwise;
458- // and there may be other cases that result in invalid code.
459- // For example, type coercion doesn't work nicely.
460- Applicability :: Unspecified ,
461- ) ;
462- return ; // don't recurse into the type
463- }
464- } ;
465- self . check_ty ( cx, & mut_ty. ty , is_local) ;
466- } ,
467- _ => self . check_ty ( cx, & mut_ty. ty , is_local) ,
468- }
469- }
470- }
471-
472- // Returns true if given type is `Any` trait.
473- fn is_any_trait ( t : & hir:: Ty < ' _ > ) -> bool {
474- if_chain ! {
475- if let TyKind :: TraitObject ( ref traits, _) = t. kind;
476- if !traits. is_empty( ) ;
477- // Only Send/Sync can be used as additional traits, so it is enough to
478- // check only the first trait.
479- if match_path( & traits[ 0 ] . trait_ref. path, & paths:: ANY_TRAIT ) ;
480- then {
481- return true ;
482- }
483- }
484-
485- false
486- }
487-
488- fn get_bounds_if_impl_trait < ' tcx > ( cx : & LateContext < ' tcx > , qpath : & QPath < ' _ > , id : HirId ) -> Option < GenericBounds < ' tcx > > {
489- if_chain ! {
490- if let Some ( did) = cx. qpath_res( qpath, id) . opt_def_id( ) ;
491- if let Some ( Node :: GenericParam ( generic_param) ) = cx. tcx. hir( ) . get_if_local( did) ;
492- if let GenericParamKind :: Type { synthetic, .. } = generic_param. kind;
493- if synthetic == Some ( SyntheticTyParamKind :: ImplTrait ) ;
494- then {
495- Some ( generic_param. bounds)
496- } else {
497- None
498- }
499- }
500396}
501397
502398declare_clippy_lint ! {
0 commit comments