@@ -9,7 +9,7 @@ use rustc_hir::intravisit::FnKind;
99use rustc_hir:: { Block , Body , Expr , ExprKind , FnDecl , LangItem , MatchSource , PatKind , QPath , StmtKind } ;
1010use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
1111use rustc_middle:: lint:: in_external_macro;
12- use rustc_middle:: ty:: subst:: GenericArgKind ;
12+ use rustc_middle:: ty:: { self , subst:: GenericArgKind , Ty } ;
1313use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
1414use rustc_span:: def_id:: LocalDefId ;
1515use rustc_span:: source_map:: Span ;
@@ -175,7 +175,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
175175 } else {
176176 RetReplacement :: Empty
177177 } ;
178- check_final_expr ( cx, body. value , vec ! [ ] , replacement) ;
178+ check_final_expr ( cx, body. value , vec ! [ ] , replacement, None ) ;
179179 } ,
180180 FnKind :: ItemFn ( ..) | FnKind :: Method ( ..) => {
181181 check_block_return ( cx, & body. value . kind , sp, vec ! [ ] ) ;
@@ -188,11 +188,11 @@ impl<'tcx> LateLintPass<'tcx> for Return {
188188fn check_block_return < ' tcx > ( cx : & LateContext < ' tcx > , expr_kind : & ExprKind < ' tcx > , sp : Span , mut semi_spans : Vec < Span > ) {
189189 if let ExprKind :: Block ( block, _) = expr_kind {
190190 if let Some ( block_expr) = block. expr {
191- check_final_expr ( cx, block_expr, semi_spans, RetReplacement :: Empty ) ;
191+ check_final_expr ( cx, block_expr, semi_spans, RetReplacement :: Empty , None ) ;
192192 } else if let Some ( stmt) = block. stmts . iter ( ) . last ( ) {
193193 match stmt. kind {
194194 StmtKind :: Expr ( expr) => {
195- check_final_expr ( cx, expr, semi_spans, RetReplacement :: Empty ) ;
195+ check_final_expr ( cx, expr, semi_spans, RetReplacement :: Empty , None ) ;
196196 } ,
197197 StmtKind :: Semi ( semi_expr) => {
198198 // Remove ending semicolons and any whitespace ' ' in between.
@@ -202,7 +202,7 @@ fn check_block_return<'tcx>(cx: &LateContext<'tcx>, expr_kind: &ExprKind<'tcx>,
202202 span_find_starting_semi ( cx. sess ( ) . source_map ( ) , semi_span. with_hi ( sp. hi ( ) ) ) ;
203203 semi_spans. push ( semi_span_to_remove) ;
204204 }
205- check_final_expr ( cx, semi_expr, semi_spans, RetReplacement :: Empty ) ;
205+ check_final_expr ( cx, semi_expr, semi_spans, RetReplacement :: Empty , None ) ;
206206 } ,
207207 _ => ( ) ,
208208 }
@@ -216,6 +216,7 @@ fn check_final_expr<'tcx>(
216216 semi_spans : Vec < Span > , /* containing all the places where we would need to remove semicolons if finding an
217217 * needless return */
218218 replacement : RetReplacement < ' tcx > ,
219+ match_ty_opt : Option < Ty < ' _ > > ,
219220) {
220221 let peeled_drop_expr = expr. peel_drop_temps ( ) ;
221222 match & peeled_drop_expr. kind {
@@ -244,7 +245,22 @@ fn check_final_expr<'tcx>(
244245 RetReplacement :: Expr ( snippet, applicability)
245246 }
246247 } else {
247- replacement
248+ match match_ty_opt {
249+ Some ( match_ty) => {
250+ match match_ty. kind ( ) {
251+ // If the code got till here with
252+ // tuple not getting detected before it,
253+ // then we are sure it's going to be Unit
254+ // type
255+ ty:: Tuple ( _) => RetReplacement :: Unit ,
256+ // We don't want to anything in this case
257+ // cause we can't predict what the user would
258+ // want here
259+ _ => return ,
260+ }
261+ } ,
262+ None => replacement,
263+ }
248264 } ;
249265
250266 if !cx. tcx . hir ( ) . attrs ( expr. hir_id ) . is_empty ( ) {
@@ -268,8 +284,9 @@ fn check_final_expr<'tcx>(
268284 // note, if without else is going to be a type checking error anyways
269285 // (except for unit type functions) so we don't match it
270286 ExprKind :: Match ( _, arms, MatchSource :: Normal ) => {
287+ let match_ty = cx. typeck_results ( ) . expr_ty ( peeled_drop_expr) ;
271288 for arm in arms. iter ( ) {
272- check_final_expr ( cx, arm. body , semi_spans. clone ( ) , RetReplacement :: Unit ) ;
289+ check_final_expr ( cx, arm. body , semi_spans. clone ( ) , RetReplacement :: Unit , Some ( match_ty ) ) ;
273290 }
274291 } ,
275292 // if it's a whole block, check it
@@ -293,6 +310,7 @@ fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, semi_spans: Vec<Span>,
293310 if ret_span. from_expansion ( ) {
294311 return ;
295312 }
313+
296314 let applicability = replacement. applicability ( ) . unwrap_or ( Applicability :: MachineApplicable ) ;
297315 let return_replacement = replacement. to_string ( ) ;
298316 let sugg_help = replacement. sugg_help ( ) ;
0 commit comments