@@ -2,7 +2,7 @@ use rustc::lint::*;
22use rustc:: ty:: TypeVariants :: { TyRawPtr , TyRef } ;
33use rustc:: ty;
44use rustc:: hir:: * ;
5- use utils:: { match_def_path, paths, span_lint, span_lint_and_then} ;
5+ use utils:: { match_def_path, paths, span_lint, span_lint_and_then, snippet } ;
66use utils:: sugg;
77
88/// **What it does:** Checks for transmutes that can't ever be correct on any
@@ -87,7 +87,7 @@ impl LintPass for Transmute {
8787impl LateLintPass for Transmute {
8888 fn check_expr ( & mut self , cx : & LateContext , e : & Expr ) {
8989 if let ExprCall ( ref path_expr, ref args) = e. node {
90- if let ExprPath ( None , _ ) = path_expr. node {
90+ if let ExprPath ( None , ref path ) = path_expr. node {
9191 let def_id = cx. tcx . expect_def ( path_expr. id ) . def_id ( ) ;
9292
9393 if match_def_path ( cx, def_id, & paths:: TRANSMUTE ) {
@@ -170,11 +170,10 @@ impl LateLintPass for Transmute {
170170 ( "&*" , "*const" )
171171 } ;
172172
173-
174173 let arg = if from_pty. ty == to_rty. ty {
175174 arg
176175 } else {
177- arg. as_ty ( & format ! ( "{} {}" , cast, to_rty. ty) )
176+ arg. as_ty ( & format ! ( "{} {}" , cast, get_type_snippet ( cx , path , to_rty. ty) ) )
178177 } ;
179178
180179 db. span_suggestion ( e. span , "try" , sugg:: make_unop ( deref, arg) . to_string ( ) ) ;
@@ -187,3 +186,19 @@ impl LateLintPass for Transmute {
187186 }
188187 }
189188}
189+
190+ /// Get the snippet of `Bar` in `…::transmute<Foo, &Bar>`. If that snippet is not available , use
191+ /// the type's `ToString` implementation. In weird cases it could lead to types with invalid `'_`
192+ /// lifetime, but it should be rare.
193+ fn get_type_snippet ( cx : & LateContext , path : & Path , to_rty : ty:: Ty ) -> String {
194+ if_let_chain ! { [
195+ let Some ( seg) = path. segments. last( ) ,
196+ let PathParameters :: AngleBracketedParameters ( ref ang) = seg. parameters,
197+ let Some ( to_ty) = ang. types. get( 1 ) ,
198+ let TyRptr ( _, ref to_ty) = to_ty. node,
199+ ] , {
200+ return snippet( cx, to_ty. ty. span, & to_rty. to_string( ) ) . to_string( ) ;
201+ } }
202+
203+ to_rty. to_string ( )
204+ }
0 commit comments