Fix Windows "filename, directory name, or volume label syntax is incorrect"
diff --git a/gen/build/src/out.rs b/gen/build/src/out.rs
index 5fe957c..c11ac68 100644
--- a/gen/build/src/out.rs
+++ b/gen/build/src/out.rs
@@ -8,7 +8,7 @@
     let path = path.as_ref();
 
     let mut create_dir_error = None;
-    if path.exists() {
+    if fs::exists(path) {
         if let Ok(existing) = fs::read(path) {
             if existing == content {
                 // Avoid bumping modified time with unchanged contents.
@@ -34,7 +34,7 @@
     let link = link.as_ref();
 
     let mut create_dir_error = None;
-    if link.exists() {
+    if fs::exists(link) {
         best_effort_remove(link);
     } else {
         let parent = link.parent().unwrap();
@@ -68,7 +68,7 @@
     let link = link.as_ref();
 
     let mut create_dir_error = None;
-    if link.exists() {
+    if fs::exists(link) {
         best_effort_remove(link);
     } else {
         let parent = link.parent().unwrap();
@@ -91,7 +91,7 @@
         // be used according to what the symlink *points to*. Trying to use
         // remove_file to remove a symlink which points to a directory fails
         // with "Access is denied".
-        fs::metadata(path)
+        fs::metadata(path).or_else(|_| fs::symlink_metadata(path))
     } else {
         // On non-Windows, we check metadata not following symlinks. All
         // symlinks are removed using remove_file.
diff --git a/gen/src/fs.rs b/gen/src/fs.rs
index bfda582..7bc3bbc 100644
--- a/gen/src/fs.rs
+++ b/gen/src/fs.rs
@@ -68,6 +68,13 @@
     }
 }
 
+pub(crate) fn exists(path: impl AsRef<Path>) -> bool {
+    let path = path.as_ref();
+    // If path is a symlink, this returns true, regardless of whether the
+    // symlink points to a path that exists.
+    std::fs::symlink_metadata(path).is_ok()
+}
+
 pub(crate) fn read(path: impl AsRef<Path>) -> Result<Vec<u8>> {
     let path = path.as_ref();
     match std::fs::read(path) {