@@ -9,8 +9,7 @@ use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, Saf
99use rustc_infer:: infer:: TyCtxtInferExt ;
1010use rustc_lint:: { LateContext , LateLintPass } ;
1111use rustc_middle:: ty:: {
12- self , Binder , ClosureKind , FnSig , GenericArg , GenericArgKind , List , Region , RegionKind , Ty , TypeVisitableExt ,
13- TypeckResults ,
12+ self , Binder , ClosureKind , FnSig , GenericArg , GenericArgKind , List , Region , Ty , TypeVisitableExt , TypeckResults ,
1413} ;
1514use rustc_session:: declare_lint_pass;
1615use rustc_span:: symbol:: sym;
@@ -176,6 +175,17 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
176175 }
177176 } ,
178177 } ;
178+ if let Some ( outer) = outer_receiver
179+ && ty_has_static ( sig. output ( ) )
180+ && let generic_args = typeck. node_args ( outer. hir_id )
181+ // HACK: Given a closure in `T.method(|| f())`, where `fn f() -> U where U: 'static`, `T.method(f)`
182+ // will succeed iff `T: 'static`. But the region of `T` is always erased by `typeck.expr_ty()` when
183+ // T is a generic type. For example, return type of `Option<String>::as_deref()` is a generic.
184+ // So we have a hack like this.
185+ && generic_args. len ( ) > 0
186+ {
187+ return ;
188+ }
179189 if check_sig ( closure_sig, sig)
180190 && let generic_args = typeck. node_args ( callee. hir_id )
181191 // Given some trait fn `fn f() -> ()` and some type `T: Trait`, `T::f` is not
@@ -275,7 +285,7 @@ fn check_sig<'tcx>(closure_sig: FnSig<'tcx>, call_sig: FnSig<'tcx>) -> bool {
275285/// This is needed because rustc is unable to late bind early-bound regions in a function signature.
276286fn has_late_bound_to_non_late_bound_regions ( from_sig : FnSig < ' _ > , to_sig : FnSig < ' _ > ) -> bool {
277287 fn check_region ( from_region : Region < ' _ > , to_region : Region < ' _ > ) -> bool {
278- matches ! ( from_region. kind ( ) , RegionKind :: ReBound ( .. ) ) && !matches ! ( to_region. kind ( ) , RegionKind :: ReBound ( .. ) )
288+ from_region. is_bound ( ) && !to_region. is_bound ( )
279289 }
280290
281291 fn check_subs ( from_subs : & [ GenericArg < ' _ > ] , to_subs : & [ GenericArg < ' _ > ] ) -> bool {
@@ -328,3 +338,8 @@ fn has_late_bound_to_non_late_bound_regions(from_sig: FnSig<'_>, to_sig: FnSig<'
328338 . zip ( to_sig. inputs_and_output )
329339 . any ( |( from_ty, to_ty) | check_ty ( from_ty, to_ty) )
330340}
341+
342+ fn ty_has_static ( ty : Ty < ' _ > ) -> bool {
343+ ty. walk ( )
344+ . any ( |arg| matches ! ( arg. unpack( ) , GenericArgKind :: Lifetime ( re) if re. is_static( ) ) )
345+ }
0 commit comments