Rust 1.29.0 is out!

R:\ is a virtualbox drive visible to Windows but actually a Linux dir.

Discourse only allows me to upload images, so here are the two files:

Cargo.toml

[package]
name = "wordladder"
version = "0.1.0"
authors = ["Mark"]

[profile.release]
codegen-units = 1

[dependencies]
regex = "0.2"
rand = "0.4"
lazy_static = "1.0"

src/main.rs:

#[macro_use]
extern crate lazy_static;
extern crate rand;
extern crate regex;

use std::fs::File;
use std::io;
use std::io::{BufReader,BufRead};
use std::collections::HashSet;
use std::time::{Duration, Instant};
use regex::Regex;

static WORDFILE: &str = "/usr/share/hunspell/en_GB.dic";
const SIZE: usize = 4; // Should be even
const STEPS: usize = SIZE;

type WordSet = HashSet<String>;
type WordVec = Vec<String>;
type Letters = Vec<char>;

fn main() {
    if let Ok(words) = read_words(WORDFILE, SIZE) {
        let timer = Instant::now();
        let mut count = 1;
        print!("Try ");
        loop {
            print!(".");
            if let Some(ladder) = generate_ladder(&words, STEPS) {
                println!("{}", count);
                for word in ladder {
                    println!("{}", word);
                }
                break;
            }
            count += 1
        }
        println!("{:.05} sec", as_secs(timer.elapsed()));
    }
}

fn as_secs(duration: Duration) -> f64 {
    duration.as_secs() as f64 + duration.subsec_nanos() as f64 * 1e-9
}

fn generate_ladder(words: &WordSet, steps: usize) -> Option<WordVec> {
    let mut words = words.clone();
    let compatibles = words.clone();
    let mut ladder = vec![];
    let mut prev = update_words_and_ladder(&mut ladder, &mut words,
                                           &compatibles);
    for _ in 0..steps + 1 {
        let compatibles = compatible_words(prev.as_str(), &words);
        if compatibles.is_empty() {
            return None
        }
        prev = update_words_and_ladder(&mut ladder, &mut words,
                                       &compatibles);
    }
    let first: Letters = ladder[0].chars().collect();
    let last: Letters = ladder[ladder.len() - 1].chars().collect();
    for i in 0..first.len() {
        if first[i] == last[i] {
            return None // Don't accept any vertical letters in common
        }
    }
    Some(ladder)
}

fn update_words_and_ladder(ladder: &mut WordVec, words: &mut WordSet,
                           compatibles: &WordSet) -> String {
    let mut rng = rand::thread_rng();
    let prev = rand::seq::sample_iter(&mut rng, compatibles, 1)
        .unwrap()[0];
    ladder.push(prev.to_string());
    words.remove(prev);
    prev.to_string()
}

fn compatible_words(prev: &str, words: &WordSet) -> WordSet {
    let mut compatibles = WordSet::new();
    let prev_chars: Letters = prev.chars().collect();
    let size = prev_chars.len() - 1;
    for word in words.iter() {
        let mut count = 0;
        let word_chars: Letters = word.chars().collect();
        for i in 0..prev_chars.len() {
            if prev_chars[i] == word_chars[i] {
                count += 1;
            }
        }
        if count == size {
            compatibles.insert(word.to_string());
        }
    }
    compatibles
}

fn read_words(wordfile: &str, size: usize) -> io::Result<WordSet> {
    lazy_static! { static ref RE: Regex = Regex::new(r"^[a-z]+").unwrap(); }
    let mut words = WordSet::new();
    let file = File::open(wordfile)?;
    for line in BufReader::new(file).lines() {
        if let Ok(line) = line {
            if let Some(captures) = RE.captures(&line) {
                let word = &captures[0];
                if word.len() == size {
                    words.insert(word.to_uppercase());
                }
            }
        }
    }
    Ok(words)
}

As noted this compiles and runs fine with 1.28 on Windows and Linux even after doing a cargo update. But with 1.29 it only works on Linux. However, taking your hint, I tried it on C: and it worked fine.

So it looks like the problem is with the virtualbox drive (which I guess looks like a network shared drive to Windows). This is a pain for me because I do all my editing on Linux and only use Windows for compiling and testing but will have to always have to copy to C: to do this now: unless it gets fixed of course. So, for now, I'll hold off on 1.29 and hope that this is fixed. (I'll add an issue about it: #54216.)