echoes 0.12.0

Find duplicated Rust doctests, functions and contexts
Documentation
//! Original transitive helper budgets follow lexical binding lifetimes.

fn borrowed_form(file: &syn::File) -> syn_canon::CanonicalForm {
    let context =
        syn_canon::SourceContext::new(core::iter::once((&[][..], file)), syn_canon::Edition::E2021);
    let function = file
        .items
        .iter()
        .find_map(|item| match item {
            syn::Item::Fn(function) if function.sig.ident == "f" => Some(function),
            _ => None,
        })
        .unwrap();
    context
        .function(&function.sig, &function.block)
        .unwrap()
        .canonicalize()
}

fn pair(first: &str, second: &str, equal: bool) {
    let first_file: syn::File = syn::parse_str(first).unwrap();
    let second_file: syn::File = syn::parse_str(second).unwrap();
    let borrowed_first = borrowed_form(&first_file);
    let borrowed_second = borrowed_form(&second_file);
    let standalone_first = syn_canon::canonicalize(first_file);
    let standalone_second = syn_canon::canonicalize(second_file);
    assert_eq!(
        standalone_first == standalone_second,
        equal,
        "standalone preserves the original helper union and binding scopes"
    );
    assert_eq!(
        borrowed_first == borrowed_second,
        equal,
        "borrowed preserves the original helper union and binding scopes"
    );
}

fn source(prefix: &str, statements: &str, repetitions: usize) -> String {
    format!(
        "fn f(p:bool,callback:fn(bool)->bool)->(bool,bool){{{prefix}{statements}(a,b)}}fn h(p:bool)->bool{{g(p)}}fn g(p:bool)->bool{{{}p}}fn k(p:bool)->bool{{false;false;false;false;p}}",
        "p;".repeat(repetitions)
    )
}

fn union_pair(prefix: &str, first: &str, second: &str) {
    pair(
        &source(prefix, first, 8187),
        &source(prefix, second, 8187),
        false,
    );
    pair(
        &source(prefix, first, 8182),
        &source(prefix, second, 8182),
        true,
    );
}

#[derive(Default)]
struct DeclarationNodes(usize);

impl syn::visit::Visit<'_> for DeclarationNodes {
    fn visit_stmt(&mut self, stmt: &syn::Stmt) {
        self.0 += 1;
        syn::visit::visit_stmt(self, stmt);
    }

    fn visit_expr(&mut self, expr: &syn::Expr) {
        self.0 += 1;
        syn::visit::visit_expr(self, expr);
    }

    fn visit_item(&mut self, item: &syn::Item) {
        self.0 += 1;
        syn::visit::visit_item(self, item);
    }
}

fn declaration_nodes(file: &syn::File, names: &[&str]) -> usize {
    let mut count = DeclarationNodes::default();
    for item in &file.items {
        if let syn::Item::Fn(function) = item
            && names.iter().any(|name| function.sig.ident == *name)
        {
            count.0 += 1;
            syn::visit::visit_block(&mut count, &function.block);
        }
    }
    count.0
}

#[test]
fn only_the_complete_transitive_union_exceeds_the_node_cap() {
    let exhausted = source("", "let a=h(p);let b=k(!p);", 8187);
    let admitted = source("", "let a=h(p);let b=k(!p);", 8182);
    let exhausted_file: syn::File = syn::parse_str(&exhausted).unwrap();
    assert_eq!(declaration_nodes(&exhausted_file, &["h", "g"]), 16_382);
    assert_eq!(declaration_nodes(&exhausted_file, &["h", "g", "k"]), 16_393);
    let admitted_file: syn::File = syn::parse_str(&admitted).unwrap();
    assert_eq!(declaration_nodes(&admitted_file, &["h", "g", "k"]), 16_383);
    pair(
        &exhausted,
        &source("", "let b=k(!p);let a=h(p);", 8187),
        false,
    );
    pair(
        &admitted,
        &source("", "let b=k(!p);let a=h(p);", 8182),
        true,
    );
}

#[test]
fn completed_patterns_restore_later_enclosing_helper_roots() {
    for prefix in [
        "match Some(p){Some(h)=>{let _=h;},None=>{}}",
        "for h in [p]{let _=h;}",
        "if let Some(h)=Some(p){let _=h;}",
        "while let Some(h)=Some(p){let _=h;break;}",
        "if let Some(h)=Some(p)&&h{let _=h;}",
        "while let Some(h)=Some(p)&&h{let _=h;break;}",
        "{let h=p;let _=h;}",
        "let closure=|h:bool|h;let _=closure(p);",
    ] {
        union_pair(prefix, "let a=h(p);let b=k(!p);", "let b=k(!p);let a=h(p);");
    }
}

#[test]
fn match_arms_restore_roots_for_the_next_arm_and_discriminant() {
    for prefix in [
        "match Some(p){Some(h)=>{let _=h;},None=>{let _=h(p);}}",
        "match Some(h(p)){Some(h)=>{let _=h;},None=>{}}",
        "match Some(p){Some(q)if h(q)=>{},_=>{}}",
    ] {
        union_pair(prefix, "let a=k(p);let b=k(!p);", "let b=k(!p);let a=k(p);");
    }
}

#[test]
fn if_condition_bindings_do_not_mask_else_roots() {
    for prefix in [
        "if let Some(h)=Some(p){let _=h;}else{let _=h(p);}",
        "if let Some(h)=Some(p)&&h{let _=h;}else{let _=h(p);}",
        "if let Some(h)=Some(p){let _=h;}else if let Some(h)=Some(h(p)){let _=h;}",
    ] {
        union_pair(prefix, "let a=k(p);let b=k(!p);", "let b=k(!p);let a=k(p);");
    }
}

#[test]
fn iterators_and_let_initializers_resolve_before_their_patterns() {
    for prefix in [
        "for h in [h(p)]{let _=h;}",
        "if let Some(h)=Some(h(p)){let _=h;}",
        "while let Some(h)=Some(h(p)){let _=h;break;}",
        "if let Some(q)=Some(p)&&let Some(h)=Some(h(q)){let _=h;}",
        "while let Some(q)=Some(p)&&let Some(h)=Some(h(q)){let _=h;break;}",
        "let h=h(p);let _=h;",
        "let Some(h)=Some(h(p))else{return(p,p)};let _=h;",
    ] {
        union_pair(prefix, "let a=k(p);let b=k(!p);", "let b=k(!p);let a=k(p);");
    }
}

#[test]
fn live_callable_patterns_mask_farther_roots_without_exhaustion() {
    for prefix in [
        "match Some(callback){Some(h)if h(p)=>{let _=h(!p);},Some(_)=>{},None=>{}}",
        "for h in [callback]{let _=h(p);}",
        "if let Some(h)=Some(callback){let _=h(p);}",
        "while let Some(h)=Some(callback){let _=h(p);break;}",
        "if let Some(h)=Some(callback)&&h(p)&&let Some(q)=Some(h(!p)){let _=h(q);}",
        "while let Some(h)=Some(callback)&&h(p)&&let Some(q)=Some(h(!p)){let _=h(q);break;}",
        "{let h=callback;let _=h(p);}",
        "let closure=|h:fn(bool)->bool|h(p);let _=closure(callback);",
        "let h=callback;{let _=h(p);}let closure=||h(!p);let _=closure();",
    ] {
        pair(
            &source(prefix, "let a=k(p);let b=k(!p);", 8187),
            &source(prefix, "let b=k(!p);let a=k(p);", 8187),
            true,
        );
    }
}

#[test]
fn nested_blocks_and_closures_still_include_unmasked_roots() {
    for prefix in [
        "{let _=h(p);}",
        "let closure=||h(p);let _=closure();",
        "let closure=|q:bool|h(q);let _=closure(p);",
        "if let Some(h)=Some(callback){let closure=|q:bool|h(q);let _=closure(p);}let _=h(p);",
    ] {
        union_pair(prefix, "let a=k(p);let b=k(!p);", "let b=k(!p);let a=k(p);");
    }
}

#[test]
fn exhausted_scope_unions_keep_dead_enclosing_bindings() {
    for prefix in [
        "match Some(p){Some(h)=>{let _=h;},None=>{}}",
        "for h in [p]{let _=h;}",
        "if let Some(h)=Some(p){let _=h;}",
        "while let Some(h)=Some(p){let _=h;break;}",
        "if let Some(h)=Some(p)&&h{let _=h;}",
        "while let Some(h)=Some(p)&&h{let _=h;break;}",
    ] {
        let plain = source(prefix, "let a=h(p);let b=k(!p);", 8187);
        let dead = source(prefix, "let unused=false;let a=h(p);let b=k(!p);", 8187);
        pair(&plain, &dead, false);
    }
}