@@ -600,7 +600,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
600
600
601
601
// Visit to make sure there's a single `return` type to suggest `impl Trait`,
602
602
// otherwise suggest using `Box<dyn Trait>` or an enum.
603
- let mut visitor = ReturnsVisitor :: new ( ) ;
603
+ let mut visitor = ReturnsVisitor :: default ( ) ;
604
604
visitor. visit_body ( & body) ;
605
605
606
606
let tables = self . in_progress_tables . map ( |t| t. borrow ( ) ) . unwrap ( ) ;
@@ -742,7 +742,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
742
742
{
743
743
let body = hir. body ( * body_id) ;
744
744
// Point at all the `return`s in the function as they have failed trait bounds.
745
- let mut visitor = ReturnsVisitor :: new ( ) ;
745
+ let mut visitor = ReturnsVisitor :: default ( ) ;
746
746
visitor. visit_body ( & body) ;
747
747
let tables = self . in_progress_tables . map ( |t| t. borrow ( ) ) . unwrap ( ) ;
748
748
for expr in & visitor. returns {
@@ -1696,17 +1696,12 @@ pub fn suggest_constraining_type_param(
1696
1696
1697
1697
/// Collect all the returned expressions within the input expression.
1698
1698
/// Used to point at the return spans when we want to suggest some change to them.
1699
+ #[ derive( Default ) ]
1699
1700
struct ReturnsVisitor < ' v > {
1700
1701
returns : Vec < & ' v hir:: Expr < ' v > > ,
1701
1702
in_block_tail : bool ,
1702
1703
}
1703
1704
1704
- impl ReturnsVisitor < ' _ > {
1705
- fn new ( ) -> Self {
1706
- ReturnsVisitor { returns : vec ! [ ] , in_block_tail : false }
1707
- }
1708
- }
1709
-
1710
1705
impl < ' v > Visitor < ' v > for ReturnsVisitor < ' v > {
1711
1706
type Map = rustc:: hir:: map:: Map < ' v > ;
1712
1707
@@ -1715,6 +1710,10 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
1715
1710
}
1716
1711
1717
1712
fn visit_expr ( & mut self , ex : & ' v hir:: Expr < ' v > ) {
1713
+ // Visit every expression to detect `return` paths, either through the function's tail
1714
+ // expression or `return` statements. We walk all nodes to find `return` statements, but
1715
+ // we only care about tail expressions when `in_block_tail` is `true`, which means that
1716
+ // they're in the return path of the function body.
1718
1717
match ex. kind {
1719
1718
hir:: ExprKind :: Ret ( Some ( ex) ) => {
1720
1719
self . returns . push ( ex) ;
@@ -1741,7 +1740,7 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
1741
1740
}
1742
1741
1743
1742
fn visit_body ( & mut self , body : & ' v hir:: Body < ' v > ) {
1744
- let prev = self . in_block_tail ;
1743
+ assert ! ( ! self . in_block_tail) ;
1745
1744
if body. generator_kind ( ) . is_none ( ) {
1746
1745
if let hir:: ExprKind :: Block ( block, None ) = body. value . kind {
1747
1746
if block. expr . is_some ( ) {
@@ -1750,6 +1749,5 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
1750
1749
}
1751
1750
}
1752
1751
hir:: intravisit:: walk_body ( self , body) ;
1753
- self . in_block_tail = prev;
1754
1752
}
1755
1753
}
0 commit comments