@@ -272,11 +272,12 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
272272}
273273
274274fn check_unnecessary_operation ( cx : & LateContext < ' _ > , stmt : & Stmt < ' _ > ) {
275+ let mut applicability = Applicability :: MachineApplicable ;
275276 if let StmtKind :: Semi ( expr) = stmt. kind
276277 && !stmt. span . in_external_macro ( cx. sess ( ) . source_map ( ) )
277278 && let ctxt = stmt. span . ctxt ( )
278279 && expr. span . ctxt ( ) == ctxt
279- && let Some ( reduced) = reduce_expression ( cx, expr)
280+ && let Some ( reduced) = reduce_expression ( cx, expr, & mut applicability )
280281 && reduced. iter ( ) . all ( |e| e. span . ctxt ( ) == ctxt)
281282 {
282283 if let ExprKind :: Index ( ..) = & expr. kind {
@@ -319,19 +320,18 @@ fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
319320 stmt. span ,
320321 "unnecessary operation" ,
321322 |diag| {
322- diag. span_suggestion (
323- stmt. span ,
324- "statement can be reduced to" ,
325- snippet,
326- Applicability :: MachineApplicable ,
327- ) ;
323+ diag. span_suggestion ( stmt. span , "statement can be reduced to" , snippet, applicability) ;
328324 } ,
329325 ) ;
330326 }
331327 }
332328}
333329
334- fn reduce_expression < ' a > ( cx : & LateContext < ' _ > , expr : & ' a Expr < ' a > ) -> Option < Vec < & ' a Expr < ' a > > > {
330+ fn reduce_expression < ' a > (
331+ cx : & LateContext < ' _ > ,
332+ expr : & ' a Expr < ' a > ,
333+ applicability : & mut Applicability ,
334+ ) -> Option < Vec < & ' a Expr < ' a > > > {
335335 if expr. span . from_expansion ( ) {
336336 return None ;
337337 }
@@ -345,9 +345,9 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
345345 | ExprKind :: Type ( inner, _)
346346 | ExprKind :: Unary ( _, inner)
347347 | ExprKind :: Field ( inner, _)
348- | ExprKind :: AddrOf ( _, _, inner) => reduce_expression ( cx, inner) . or_else ( || Some ( vec ! [ inner] ) ) ,
348+ | ExprKind :: AddrOf ( _, _, inner) => reduce_expression ( cx, inner, applicability ) . or_else ( || Some ( vec ! [ inner] ) ) ,
349349 ExprKind :: Cast ( inner, _) if expr_type_is_certain ( cx, inner) => {
350- reduce_expression ( cx, inner) . or_else ( || Some ( vec ! [ inner] ) )
350+ reduce_expression ( cx, inner, applicability ) . or_else ( || Some ( vec ! [ inner] ) )
351351 } ,
352352 // In the normal `Struct` case, we bail out if any of the fields has an uncertain type.
353353 // But for two-sided ranges, we know that if the type of one of the sides is certain, then so is the other
@@ -367,9 +367,12 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
367367 }
368368 } ,
369369 ExprKind :: Struct ( _, fields, ref base) => {
370- if fields. iter ( ) . any ( |f| !expr_type_is_certain ( cx, & f. expr ) )
371- || has_drop ( cx, cx. typeck_results ( ) . expr_ty ( expr) )
372- {
370+ if fields. iter ( ) . any ( |f| !expr_type_is_certain ( cx, f. expr ) ) {
371+ // there's a risk that if we take the field exprs out of the context of the struct constructor,
372+ // their types might become ambiguous
373+ * applicability = Applicability :: MaybeIncorrect ;
374+ }
375+ if has_drop ( cx, cx. typeck_results ( ) . expr_ty ( expr) ) {
373376 None
374377 } else {
375378 let base = match base {
@@ -405,7 +408,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
405408 BlockCheckMode :: UnsafeBlock ( UnsafeSource :: UserProvided ) => None ,
406409 BlockCheckMode :: DefaultBlock => Some ( vec ! [ & * * e] ) ,
407410 // in case of compiler-inserted signaling blocks
408- BlockCheckMode :: UnsafeBlock ( _) => reduce_expression ( cx, e) ,
411+ BlockCheckMode :: UnsafeBlock ( _) => reduce_expression ( cx, e, applicability ) ,
409412 }
410413 } )
411414 } else {
0 commit comments