Returning HashSet intersection from function

I want to identify the common characters in 2 str slices and decided to come up with a function that takes 2 str slices and returns the intersection of the characters of the 2 slices. However I'm fighting with the compiler on this one. Any help? The Iterator return type should not be kept, I just want some type that I can easily manipulate in further functions. (Just started learning Rust :-))

fn common_chars<'a>(s1: &'a str, s2: &'a str) -> impl Iterator<Item = &'a char> {
      let a : HashSet<char>  = HashSet::from_iter(s1.chars());
      let b : HashSet<char>  = HashSet::from_iter(s2.chars());
      return a.intersection(&b);
}

I'm getting the following error:

mathieu@linda:~/code/aoc/2022/day3 (main)$ cargo build
   Compiling day3 v0.1.0 (/home/mathieu/code/aoc/2022/day3)
error[E0515]: cannot return value referencing local variable `b`
  --> src/main.rs:19:12
   |
19 |     return a.intersection(&b);
   |            ^^^^^^^^^^^^^^^--^
   |            |              |
   |            |              `b` is borrowed here
   |            returns a value referencing data owned by the current function
   |
   = help: use `.collect()` to allocate the iterator

error[E0515]: cannot return reference to local variable `a`
  --> src/main.rs:19:12
   |
19 |     return a.intersection(&b);
   |            ^^^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function

Then you can simply collect elements into a vector or a hashset. For that you can do, a.intersection(&b).collect() and adjust the return type to be Vec<char> or HashSet<char>.

fn common_chars<'a>(s1: &'a str, s2: &'a str) -> Vec<&'a char> {
      let a: HashSet<char> = HashSet::from_iter(s1.chars());
      let b: HashSet<char> = HashSet::from_iter(s2.chars());
      return a.intersection(&b).collect();
}

Produces a similar error

error[E0515]: cannot return value referencing local variable `b`
  --> src/main.rs:19:12
   |
19 |     return a.intersection(&b).collect();
   |            ^^^^^^^^^^^^^^^--^^^^^^^^^^^
   |            |              |
   |            |              `b` is borrowed here
   |            returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing local variable `a`
  --> src/main.rs:19:12
   |
19 |     return a.intersection(&b).collect();
   |            ------------------^^^^^^^^^^
   |            |
   |            returns a value referencing data owned by the current function
   |            `a` is borrowed here

You can't return a Vec<&'a char> with the technique you are using. The HashSet copies the characters of the string into itself, and the a.intersection(&b) returns an iterator referring to the characters in the set and not the string. Since the set is local to the function, you cannot return a reference to it.
You can return a Vec<char> here and instead do return a.intersection(&b).copied().collect();.

1 Like

Thanks, the copied() did the trick mostly. I'll worry about efficiency and copying later :slight_smile: