(&mut self)
| 1366 | /// space but heap space proportional to the depth of the `Ast`. |
| 1367 | impl Drop for Ast { |
| 1368 | fn drop(&mut self) { |
| 1369 | use std::mem; |
| 1370 | |
| 1371 | match *self { |
| 1372 | Ast::Empty(_) |
| 1373 | | Ast::Flags(_) |
| 1374 | | Ast::Literal(_) |
| 1375 | | Ast::Dot(_) |
| 1376 | | Ast::Assertion(_) |
| 1377 | // Classes are recursive, so they get their own Drop impl. |
| 1378 | | Ast::Class(_) => return, |
| 1379 | Ast::Repetition(ref x) if !x.ast.has_subexprs() => return, |
| 1380 | Ast::Group(ref x) if !x.ast.has_subexprs() => return, |
| 1381 | Ast::Alternation(ref x) if x.asts.is_empty() => return, |
| 1382 | Ast::Concat(ref x) if x.asts.is_empty() => return, |
| 1383 | _ => {} |
| 1384 | } |
| 1385 | |
| 1386 | let empty_span = || Span::splat(Position::new(0, 0, 0)); |
| 1387 | let empty_ast = || Ast::Empty(empty_span()); |
| 1388 | let mut stack = vec![mem::replace(self, empty_ast())]; |
| 1389 | while let Some(mut ast) = stack.pop() { |
| 1390 | match ast { |
| 1391 | Ast::Empty(_) |
| 1392 | | Ast::Flags(_) |
| 1393 | | Ast::Literal(_) |
| 1394 | | Ast::Dot(_) |
| 1395 | | Ast::Assertion(_) |
| 1396 | // Classes are recursive, so they get their own Drop impl. |
| 1397 | | Ast::Class(_) => {} |
| 1398 | Ast::Repetition(ref mut x) => { |
| 1399 | stack.push(mem::replace(&mut x.ast, empty_ast())); |
| 1400 | } |
| 1401 | Ast::Group(ref mut x) => { |
| 1402 | stack.push(mem::replace(&mut x.ast, empty_ast())); |
| 1403 | } |
| 1404 | Ast::Alternation(ref mut x) => { |
| 1405 | stack.extend(x.asts.drain(..)); |
| 1406 | } |
| 1407 | Ast::Concat(ref mut x) => { |
| 1408 | stack.extend(x.asts.drain(..)); |
| 1409 | } |
| 1410 | } |
| 1411 | } |
| 1412 | } |
| 1413 | } |
| 1414 | |
| 1415 | /// A custom `Drop` impl is used for `ClassSet` such that it uses constant |
nothing calls this directly
no test coverage detected