Q: Is there any difference between these two ways to get lowercase `Vec` Is there any difference between these two ways to get lowercase Vec. This version iterates over chars, converts them and collects the results:
fn lower(s: &str) -> Vec<char> {
    s.chars().flat_map(|c| c.to_lowercase()).collect()
}

and this version first converts to a String and then collects the chars of that:
fn lower_via_string(s: &str) -> Vec<char> {
    s.to_lowercase().chars().collect()
}


A: A short look at the code for str::to_lowercase immediately revealed a counterexample: It appears that Σ at the end of words receives special treatment from str::to_lowercase, which chars()-then-char::to_lowercase can't give, so the results differ on "xΣ ".
Playground

Before looking at the code of std::to_lowercase, I thought: Well, it should be really easy to find a counterexample with a fuzzer. I messed up the setup at first and it didn't find anything, but now was able to get it right, so I'll add it for completeness:
cargo new theyrenotequal
cd theyrenotequal
cargo fuzz init
cat >fuzz/fuzz_targets/fuzz_target_1.rs

#![no_main]
use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &str| {
    if data.to_lowercase().chars().collect::<Vec<_>>()
        != data
            .chars()
            .flat_map(|c| c.to_lowercase())
            .collect::<Vec<_>>()
    {
        panic!("Fuxxed: {}", data)
    }
});

cargo fuzz run fuzz_target_1 -Zbuild-std

That spat out "AΣ#ӮѮ" after 8 million iterations.

A: Completing the answer of @Caesar, in case the behavioral difference doesn't matter, there is still a performance difference.
String::to_lowercase() allcates a new String and fills it with the characters. char::to_lowercase() only does that on-the-fly. So the former is expected to be much slower. I don't think there can't be a version of String::to_lowercase() that returns an iterator and avoids the penalty of the allocation, just that it hasn't done yet.
