|
1 | 1 | // ignore-tidy-filelength |
2 | 2 | use crate::def::{DefKind, Namespace, Res}; |
| 3 | +use crate::def::{CtorKind, DefKind, Namespace, Res}; |
3 | 4 | use crate::def_id::DefId; |
4 | 5 | crate use crate::hir_id::HirId; |
5 | 6 | use crate::{itemlikevisit, LangItem}; |
@@ -1554,6 +1555,63 @@ impl Expr<'_> { |
1554 | 1555 | } |
1555 | 1556 | expr |
1556 | 1557 | } |
| 1558 | + |
| 1559 | + pub fn can_have_side_effects(&self) -> bool { |
| 1560 | + match self.peel_drop_temps().kind { |
| 1561 | + ExprKind::Path(_) | ExprKind::Lit(_) => false, |
| 1562 | + ExprKind::Type(base, _) |
| 1563 | + | ExprKind::Unary(_, base) |
| 1564 | + | ExprKind::Field(base, _) |
| 1565 | + | ExprKind::Index(base, _) |
| 1566 | + | ExprKind::AddrOf(.., base) |
| 1567 | + | ExprKind::Cast(base, _) => { |
| 1568 | + // This isn't exactly true for `Index` and all `Unnary`, but we are using this |
| 1569 | + // method exclusively for diagnostics and there's a *cultural* pressure against |
| 1570 | + // them being used only for its side-effects. |
| 1571 | + base.can_have_side_effects() |
| 1572 | + } |
| 1573 | + ExprKind::Struct(_, fields, init) => fields |
| 1574 | + .iter() |
| 1575 | + .map(|field| field.expr) |
| 1576 | + .chain(init.into_iter()) |
| 1577 | + .all(|e| e.can_have_side_effects()), |
| 1578 | + |
| 1579 | + ExprKind::Array(args) |
| 1580 | + | ExprKind::Tup(args) |
| 1581 | + | ExprKind::Call( |
| 1582 | + Expr { |
| 1583 | + kind: |
| 1584 | + ExprKind::Path(QPath::Resolved( |
| 1585 | + None, |
| 1586 | + Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. }, |
| 1587 | + )), |
| 1588 | + .. |
| 1589 | + }, |
| 1590 | + args, |
| 1591 | + ) => args.iter().all(|arg| arg.can_have_side_effects()), |
| 1592 | + ExprKind::If(..) |
| 1593 | + | ExprKind::Match(..) |
| 1594 | + | ExprKind::MethodCall(..) |
| 1595 | + | ExprKind::Call(..) |
| 1596 | + | ExprKind::Closure(..) |
| 1597 | + | ExprKind::Block(..) |
| 1598 | + | ExprKind::Repeat(..) |
| 1599 | + | ExprKind::Break(..) |
| 1600 | + | ExprKind::Continue(..) |
| 1601 | + | ExprKind::Ret(..) |
| 1602 | + | ExprKind::Loop(..) |
| 1603 | + | ExprKind::Assign(..) |
| 1604 | + | ExprKind::InlineAsm(..) |
| 1605 | + | ExprKind::LlvmInlineAsm(..) |
| 1606 | + | ExprKind::AssignOp(..) |
| 1607 | + | ExprKind::ConstBlock(..) |
| 1608 | + | ExprKind::Box(..) |
| 1609 | + | ExprKind::Binary(..) |
| 1610 | + | ExprKind::Yield(..) |
| 1611 | + | ExprKind::DropTemps(..) |
| 1612 | + | ExprKind::Err => true, |
| 1613 | + } |
| 1614 | + } |
1557 | 1615 | } |
1558 | 1616 |
|
1559 | 1617 | /// Checks if the specified expression is a built-in range literal. |
|
0 commit comments