diff --git a/.all-contributorsrc b/.all-contributorsrc
index 2f20971..8207a03 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -847,6 +847,251 @@
       "contributions": [
         "content"
       ]
+    },
+    {
+      "login": "PiDelport",
+      "name": "Pi Delport",
+      "avatar_url": "https://avatars.githubusercontent.com/u/630271?v=4",
+      "profile": "https://about.me/pjdelport",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "sateeshkumarb",
+      "name": "Sateesh ",
+      "avatar_url": "https://avatars.githubusercontent.com/u/429263?v=4",
+      "profile": "https://github.com/sateeshkumarb",
+      "contributions": [
+        "code",
+        "content"
+      ]
+    },
+    {
+      "login": "kayuapi",
+      "name": "ZC",
+      "avatar_url": "https://avatars.githubusercontent.com/u/10304328?v=4",
+      "profile": "https://github.com/kayuapi",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "hyperparabolic",
+      "name": "hyperparabolic",
+      "avatar_url": "https://avatars.githubusercontent.com/u/12348474?v=4",
+      "profile": "https://github.com/hyperparabolic",
+      "contributions": [
+        "code"
+      ]
+    },
+    {
+      "login": "kolbma",
+      "name": "arlecchino",
+      "avatar_url": "https://avatars.githubusercontent.com/u/5228369?v=4",
+      "profile": "https://www.net4visions.at",
+      "contributions": [
+        "doc"
+      ]
+    },
+    {
+      "login": "jazzplato",
+      "name": "Richthofen",
+      "avatar_url": "https://avatars.githubusercontent.com/u/7576730?v=4",
+      "profile": "https://richthofen.io/",
+      "contributions": [
+        "code"
+      ]
+    },
+    {
+      "login": "cseltol",
+      "name": "Ivan Nerazumov",
+      "avatar_url": "https://avatars.githubusercontent.com/u/64264529?v=4",
+      "profile": "https://github.com/cseltol",
+      "contributions": [
+        "doc"
+      ]
+    },
+    {
+      "login": "lauralindzey",
+      "name": "lauralindzey",
+      "avatar_url": "https://avatars.githubusercontent.com/u/65185744?v=4",
+      "profile": "https://github.com/lauralindzey",
+      "contributions": [
+        "doc"
+      ]
+    },
+    {
+      "login": "sinharaksh1t",
+      "name": "Rakshit Sinha",
+      "avatar_url": "https://avatars.githubusercontent.com/u/28585848?v=4",
+      "profile": "https://github.com/sinharaksh1t",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "dbednar230",
+      "name": "Damian",
+      "avatar_url": "https://avatars.githubusercontent.com/u/54457902?v=4",
+      "profile": "https://github.com/dbednar230",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "benarmstead",
+      "name": "Ben Armstead",
+      "avatar_url": "https://avatars.githubusercontent.com/u/70973680?v=4",
+      "profile": "https://benarmstead.co.uk",
+      "contributions": [
+        "code"
+      ]
+    },
+    {
+      "login": "anuk909",
+      "name": "anuk909",
+      "avatar_url": "https://avatars.githubusercontent.com/u/34924662?v=4",
+      "profile": "https://github.com/anuk909",
+      "contributions": [
+        "content",
+        "code"
+      ]
+    },
+    {
+      "login": "granddaifuku",
+      "name": "granddaifuku",
+      "avatar_url": "https://avatars.githubusercontent.com/u/49578068?v=4",
+      "profile": "https://granddaifuku.com/",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "Weilet",
+      "name": "Weilet",
+      "avatar_url": "https://avatars.githubusercontent.com/u/32561597?v=4",
+      "profile": "https://weilet.me",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "Millione",
+      "name": "LIU JIE",
+      "avatar_url": "https://avatars.githubusercontent.com/u/38575932?v=4",
+      "profile": "https://github.com/Millione",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "abusch",
+      "name": "Antoine BΓΌsch",
+      "avatar_url": "https://avatars.githubusercontent.com/u/506344?v=4",
+      "profile": "https://github.com/abusch",
+      "contributions": [
+        "code"
+      ]
+    },
+    {
+      "login": "frogtd",
+      "name": "frogtd",
+      "avatar_url": "https://avatars.githubusercontent.com/u/31412003?v=4",
+      "profile": "https://frogtd.com/",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "EmisonLu",
+      "name": "Zhenghao Lu",
+      "avatar_url": "https://avatars.githubusercontent.com/u/54395432?v=4",
+      "profile": "https://github.com/EmisonLu",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "fredr",
+      "name": "Fredrik Enestad",
+      "avatar_url": "https://avatars.githubusercontent.com/u/762956?v=4",
+      "profile": "https://soundtrackyourbrand.com",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "xuesongbj",
+      "name": "xuesong",
+      "avatar_url": "https://avatars.githubusercontent.com/u/18476085?v=4",
+      "profile": "http://xuesong.pydevops.com",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "MpdWalsh",
+      "name": "Michael Walsh",
+      "avatar_url": "https://avatars.githubusercontent.com/u/48160144?v=4",
+      "profile": "https://github.com/MpdWalsh",
+      "contributions": [
+        "code"
+      ]
+    },
+    {
+      "login": "alirezaghey",
+      "name": "alirezaghey",
+      "avatar_url": "https://avatars.githubusercontent.com/u/26653424?v=4",
+      "profile": "https://github.com/alirezaghey",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "frvannes16",
+      "name": "Franklin van Nes",
+      "avatar_url": "https://avatars.githubusercontent.com/u/3188475?v=4",
+      "profile": "https://github.com/frvannes16",
+      "contributions": [
+        "code"
+      ]
+    },
+    {
+      "login": "nekonako",
+      "name": "nekonako",
+      "avatar_url": "https://avatars.githubusercontent.com/u/46141275?v=4",
+      "profile": "https://nekonako.github.io",
+      "contributions": [
+        "code"
+      ]
+    },
+    {
+      "login": "tan-zx",
+      "name": "ZX",
+      "avatar_url": "https://avatars.githubusercontent.com/u/67887489?v=4",
+      "profile": "https://github.com/tan-zx",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "sundevilyang",
+      "name": "Yang Wen",
+      "avatar_url": "https://avatars.githubusercontent.com/u/1499214?v=4",
+      "profile": "https://github.com/sundevilyang",
+      "contributions": [
+        "content"
+      ]
+    },
+    {
+      "login": "highb",
+      "name": "Brandon High",
+      "avatar_url": "https://avatars.githubusercontent.com/u/759848?v=4",
+      "profile": "https://brandon-high.com",
+      "contributions": [
+        "doc"
+      ]
     }
   ],
   "contributorsPerLine": 8,
diff --git a/.gitignore b/.gitignore
index 06de871..253f8f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ exercises/clippy/Cargo.toml
 exercises/clippy/Cargo.lock
 .idea
 .vscode
+*.iml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1686bdd..fcc39e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,53 @@
+<a name="4.6.0"></a>
+## 4.6.0 (2021-09-25)
+
+
+#### Features
+
+*   add advanced_errs2 ([abd6b70c](https://github.com/rust-lang/rustlings/commit/abd6b70c72dc6426752ff41f09160b839e5c449e))
+*   add advanced_errs1 ([882d535b](https://github.com/rust-lang/rustlings/commit/882d535ba8628d5e0b37e8664b3e2f26260b2671))
+*   Add a farewell message when quitting `watch` ([1caef0b4](https://github.com/rust-lang/rustlings/commit/1caef0b43494c8b8cdd6c9260147e70d510f1aca))
+*   add more watch commands ([a7dc080b](https://github.com/rust-lang/rustlings/commit/a7dc080b95e49146fbaafe6922a6de2f8cb1582a), closes [#842](https://github.com/rust-lang/rustlings/issues/842))
+* **modules:**  update exercises, add modules3 (#822) ([dfd2fab4](https://github.com/rust-lang/rustlings/commit/dfd2fab4f33d1bf59e2e5ee03123c0c9a67a9481))
+* **quiz1:**  add default function name in comment (#838) ([0a11bad7](https://github.com/rust-lang/rustlings/commit/0a11bad71402b5403143d642f439f57931278c07))
+
+#### Bug Fixes
+
+*   Correct small typo in exercises/conversions/from_str.rs ([86cc8529](https://github.com/rust-lang/rustlings/commit/86cc85295ae36948963ae52882e285d7e3e29323))
+* **cli:**  typo in exercise.rs (#848) ([06d5c097](https://github.com/rust-lang/rustlings/commit/06d5c0973a3dffa3c6c6f70acb775d4c6630323c))
+* **from_str, try_from_into:**  custom error types ([2dc93cad](https://github.com/rust-lang/rustlings/commit/2dc93caddad43821743e4903d89b355df58d7a49))
+* **modules2:**  fix typo (#835) ([1c3beb0a](https://github.com/rust-lang/rustlings/commit/1c3beb0a59178c950dc05fe8ee2346b017429ae0))
+* **move_semantics5:**
+  *  change &mut *y to &mut x (#814) ([d75759e8](https://github.com/rust-lang/rustlings/commit/d75759e829fdcd64ef071cf4b6eae2a011a7718b))
+  *  Clarify instructions ([df25684c](https://github.com/rust-lang/rustlings/commit/df25684cb79f8413915e00b5efef29369849cef1))
+* **quiz1:**  Fix inconsistent wording (#826) ([03131a3d](https://github.com/rust-lang/rustlings/commit/03131a3d35d9842598150f9da817f7cc26e2669a))
+
+
+
+<a name="4.5.0"></a>
+## 4.5.0 (2021-07-07)
+
+
+#### Features
+
+*   Add move_semantics5 exercise. (#746) ([399ab328](https://github.com/rust-lang/rustlings/commit/399ab328d8d407265c09563aa4ef4534b2503ff2))
+* **cli:**  Add "next" to run the next unsolved exercise. (#785) ([d20e413a](https://github.com/rust-lang/rustlings/commit/d20e413a68772cd493561f2651cf244e822b7ca5))
+
+#### Bug Fixes
+
+*   rename result1 to errors4 ([50ab289d](https://github.com/rust-lang/rustlings/commit/50ab289da6b9eb19a7486c341b00048c516b88c0))
+*   move_semantics5 hints ([1b858285](https://github.com/rust-lang/rustlings/commit/1b85828548f46f58b622b5e0c00f8c989f928807))
+*   remove trailing whitespaces from iterators1 ([4d4fa774](https://github.com/rust-lang/rustlings/commit/4d4fa77459392acd3581c6068aa8be9a02de12fc))
+*   add hints to generics1 and generics2 exercises ([31457940](https://github.com/rust-lang/rustlings/commit/31457940846b3844d78d4a4d2b074bc8d6aaf1eb))
+*   remove trailing whitespace ([d9b69bd1](https://github.com/rust-lang/rustlings/commit/d9b69bd1a0a7a99f2c0d80933ad2eea44c8c71b2))
+* **installation:**  first PowerShell command ([aa9a943d](https://github.com/rust-lang/rustlings/commit/aa9a943ddf3ae260782e73c26bcc9db60e5894b6))
+* **iterators5:**  derive Clone, Copy ([91fc9e31](https://github.com/rust-lang/rustlings/commit/91fc9e3118f4af603c9911698cc2a234725cb032))
+* **quiz1:**  Updated question description (#794) ([d8766496](https://github.com/rust-lang/rustlings/commit/d876649616cc8a8dd5f539f8bc1a5434b960b1e9))
+* **try_from_into, from_str:**  hints for dyn Error ([11d2cf0d](https://github.com/rust-lang/rustlings/commit/11d2cf0d604dee3f5023c17802d69438e69fa50e))
+* **variables5:**  confine the answer further ([48ffcbd2](https://github.com/rust-lang/rustlings/commit/48ffcbd2c4cc4d936c2c7480019190f179813cc5))
+
+
+
 <a name="4.4.0"></a>
 ## 4.4.0 (2021-04-24)
 
diff --git a/Cargo.lock b/Cargo.lock
index cc8ff94..e536d1b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,19 +1,21 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+version = 3
+
 [[package]]
 name = "aho-corasick"
-version = "0.7.15"
+version = "0.7.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
 name = "argh"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91792f088f87cdc7a2cfb1d617fa5ea18d7f1dc22ef0e1b5f82f3157cdc522be"
+checksum = "2e7317a549bc17c5278d9e72bb6e62c6aa801ac2567048e39ebc1c194249323e"
 dependencies = [
  "argh_derive",
  "argh_shared",
@@ -21,9 +23,9 @@ dependencies = [
 
 [[package]]
 name = "argh_derive"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4eb0c0c120ad477412dc95a4ce31e38f2113e46bd13511253f79196ca68b067"
+checksum = "60949c42375351e9442e354434b0cba2ac402c1237edf673cac3a4bf983b8d3c"
 dependencies = [
  "argh_shared",
  "heck",
@@ -34,9 +36,9 @@ dependencies = [
 
 [[package]]
 name = "argh_shared"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "781f336cc9826dbaddb9754cb5db61e64cab4f69668bd19dcc4a0394a86f4cb1"
+checksum = "8a61eb019cb8f415d162cb9f12130ee6bbe9168b7d953c17f4ad049e4051ca00"
 
 [[package]]
 name = "assert_cmd"
@@ -69,9 +71,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
 [[package]]
 name = "bitflags"
-version = "1.2.1"
+version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "cfg-if"
@@ -156,9 +158,9 @@ dependencies = [
 
 [[package]]
 name = "filetime"
-version = "0.2.14"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
+checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
@@ -218,18 +220,18 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 
 [[package]]
 name = "heck"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
 dependencies = [
  "unicode-segmentation",
 ]
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.18"
+version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
 dependencies = [
  "libc",
 ]
@@ -269,9 +271,9 @@ dependencies = [
 
 [[package]]
 name = "instant"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
+checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
 dependencies = [
  "cfg-if 1.0.0",
 ]
@@ -287,9 +289,9 @@ dependencies = [
 
 [[package]]
 name = "itoa"
-version = "0.4.7"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
 
 [[package]]
 name = "kernel32-sys"
@@ -315,15 +317,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.93"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
+checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5"
 
 [[package]]
 name = "lock_api"
-version = "0.4.3"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
+checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb"
 dependencies = [
  "scopeguard",
 ]
@@ -339,9 +341,9 @@ dependencies = [
 
 [[package]]
 name = "memchr"
-version = "2.3.4"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
 
 [[package]]
 name = "mio"
@@ -405,9 +407,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
 
 [[package]]
 name = "notify"
-version = "4.0.16"
+version = "4.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2599080e87c9bd051ddb11b10074f4da7b1223298df65d4c2ec5bcf309af1533"
+checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257"
 dependencies = [
  "bitflags",
  "filetime",
@@ -466,9 +468,9 @@ dependencies = [
 
 [[package]]
 name = "predicates"
-version = "1.0.7"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eeb433456c1a57cc93554dea3ce40b4c19c4057e41c55d4a0f3d84ea71c325aa"
+checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df"
 dependencies = [
  "difference",
  "float-cmp",
@@ -485,9 +487,9 @@ checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
 
 [[package]]
 name = "predicates-tree"
-version = "1.0.2"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2"
+checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d"
 dependencies = [
  "predicates-core",
  "treeline",
@@ -495,9 +497,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.26"
+version = "1.0.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
+checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
 dependencies = [
  "unicode-xid",
 ]
@@ -513,18 +515,18 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.2.6"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041"
+checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
 dependencies = [
  "bitflags",
 ]
 
 [[package]]
 name = "regex"
-version = "1.4.6"
+version = "1.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -533,13 +535,13 @@ dependencies = [
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.23"
+version = "0.6.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
 
 [[package]]
 name = "rustlings"
-version = "4.4.0"
+version = "4.6.0"
 dependencies = [
  "argh",
  "assert_cmd",
@@ -576,18 +578,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
 name = "serde"
-version = "1.0.125"
+version = "1.0.129"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
+checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.125"
+version = "1.0.129"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
+checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -596,9 +598,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.64"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
+checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
 dependencies = [
  "itoa",
  "ryu",
@@ -607,9 +609,9 @@ dependencies = [
 
 [[package]]
 name = "slab"
-version = "0.4.3"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
+checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
 
 [[package]]
 name = "smallvec"
@@ -619,9 +621,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
 
 [[package]]
 name = "syn"
-version = "1.0.70"
+version = "1.0.75"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9505f307c872bab8eb46f77ae357c8eba1fdacead58ee5a850116b1d7f82883"
+checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -630,9 +632,9 @@ dependencies = [
 
 [[package]]
 name = "terminal_size"
-version = "0.1.16"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406"
+checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
 dependencies = [
  "libc",
  "winapi 0.3.9",
@@ -664,9 +666,9 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.7.1"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
+checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
 
 [[package]]
 name = "unicode-width"
@@ -676,9 +678,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
 
 [[package]]
 name = "unicode-xid"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
 
 [[package]]
 name = "walkdir"
diff --git a/Cargo.toml b/Cargo.toml
index 0a75704..3003269 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,8 +1,8 @@
 [package]
 name = "rustlings"
-version = "4.4.0"
-authors = ["Marisa <mokou@posteo.de>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
-edition = "2018"
+version = "4.6.0"
+authors = ["anastasie <ana@ana.st>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
+edition = "2021"
 
 [dependencies]
 argh = "0.1.4"
diff --git a/README.md b/README.md
index 8ca25ba..c9bb8b8 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
-[![All Contributors](https://img.shields.io/badge/all_contributors-91-orange.svg?style=flat-square)](#contributors-)
+[![All Contributors](https://img.shields.io/badge/all_contributors-118-orange.svg?style=flat-square)](#contributors-)
 <!-- ALL-CONTRIBUTORS-BADGE:END -->
 
 # rustlings πŸ¦€β€οΈ
@@ -16,6 +16,7 @@ Alternatively, for a first-time Rust learner, there are several other resources:
 ## Getting Started
 
 _Note: If you're on MacOS, make sure you've installed Xcode and its developer tools by typing `xcode-select --install`._
+_Note: If you're on Linux, make sure you've installed gcc. Deb: `sudo apt install gcc`. Yum: `sudo yum -y install gcc`._
 
 You will need to have Rust installed. You can get it by visiting https://rustup.rs. This'll also install Cargo, Rust's package/project manager.
 
@@ -36,7 +37,7 @@ This will install Rustlings and give you access to the `rustlings` command. Run
 In PowerShell (Run as Administrator), set `ExecutionPolicy` to `RemoteSigned`:
 
 ```ps
-Set-ExecutionPolicy RemoteSigned
+Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
 ```
 
 Then, you can run:
@@ -57,12 +58,12 @@ When you get a permission denied message then you have to exclude the directory
 
 ## Manually
 
-Basically: Clone the repository, checkout to the latest tag, run `cargo install`.
+Basically: Clone the repository at the latest tag, run `cargo install`.
 
 ```bash
-git clone https://github.com/rust-lang/rustlings
+# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 4.6.0)
+git clone -b 4.6.0 --depth 1 https://github.com/rust-lang/rustlings
 cd rustlings
-git checkout tags/4.4.0 # or whatever the latest version is (find out at https://github.com/rust-lang/rustlings/releases/latest)
 cargo install --force --path .
 ```
 
@@ -97,6 +98,12 @@ In case you want to go by your own order, or want to only verify a single exerci
 rustlings run myExercise1
 ```
 
+Or simply use the following command to run the next unsolved exercise in the course:
+
+```bash
+rustlings run next
+```
+
 In case you get stuck, you can run the following command to get a hint for your
 exercise:
 
@@ -104,6 +111,12 @@ exercise:
 rustlings hint myExercise1
 ```
 
+You can also get the hint for the next unsolved exercise with the following command:
+
+``` bash
+rustlings hint next
+```
+
 To check your progress, you can run the following command:
 ```bash
 rustlings list
@@ -279,6 +292,39 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
     <td align="center"><a href="https://github.com/hongshaoyang"><img src="https://avatars.githubusercontent.com/u/19281800?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Shao Yang Hong</b></sub></a><br /><a href="#content-hongshaoyang" title="Content">πŸ–‹</a></td>
     <td align="center"><a href="https://github.com/bmacer"><img src="https://avatars.githubusercontent.com/u/13931806?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon Macer</b></sub></a><br /><a href="#content-bmacer" title="Content">πŸ–‹</a></td>
     <td align="center"><a href="https://github.com/stoiandan"><img src="https://avatars.githubusercontent.com/u/10388612?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stoian Dan</b></sub></a><br /><a href="#content-stoiandan" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://about.me/pjdelport"><img src="https://avatars.githubusercontent.com/u/630271?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pi Delport</b></sub></a><br /><a href="#content-PiDelport" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/sateeshkumarb"><img src="https://avatars.githubusercontent.com/u/429263?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sateesh </b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=sateeshkumarb" title="Code">πŸ’»</a> <a href="#content-sateeshkumarb" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/kayuapi"><img src="https://avatars.githubusercontent.com/u/10304328?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ZC</b></sub></a><br /><a href="#content-kayuapi" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/hyperparabolic"><img src="https://avatars.githubusercontent.com/u/12348474?v=4?s=100" width="100px;" alt=""/><br /><sub><b>hyperparabolic</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=hyperparabolic" title="Code">πŸ’»</a></td>
+    <td align="center"><a href="https://www.net4visions.at"><img src="https://avatars.githubusercontent.com/u/5228369?v=4?s=100" width="100px;" alt=""/><br /><sub><b>arlecchino</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=kolbma" title="Documentation">πŸ“–</a></td>
+  </tr>
+  <tr>
+    <td align="center"><a href="https://richthofen.io/"><img src="https://avatars.githubusercontent.com/u/7576730?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Richthofen</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=jazzplato" title="Code">πŸ’»</a></td>
+    <td align="center"><a href="https://github.com/cseltol"><img src="https://avatars.githubusercontent.com/u/64264529?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ivan Nerazumov</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=cseltol" title="Documentation">πŸ“–</a></td>
+    <td align="center"><a href="https://github.com/lauralindzey"><img src="https://avatars.githubusercontent.com/u/65185744?v=4?s=100" width="100px;" alt=""/><br /><sub><b>lauralindzey</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=lauralindzey" title="Documentation">πŸ“–</a></td>
+    <td align="center"><a href="https://github.com/sinharaksh1t"><img src="https://avatars.githubusercontent.com/u/28585848?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rakshit Sinha</b></sub></a><br /><a href="#content-sinharaksh1t" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/dbednar230"><img src="https://avatars.githubusercontent.com/u/54457902?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Damian</b></sub></a><br /><a href="#content-dbednar230" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://benarmstead.co.uk"><img src="https://avatars.githubusercontent.com/u/70973680?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ben Armstead</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=benarmstead" title="Code">πŸ’»</a></td>
+    <td align="center"><a href="https://github.com/anuk909"><img src="https://avatars.githubusercontent.com/u/34924662?v=4?s=100" width="100px;" alt=""/><br /><sub><b>anuk909</b></sub></a><br /><a href="#content-anuk909" title="Content">πŸ–‹</a> <a href="https://github.com/rust-lang/rustlings/commits?author=anuk909" title="Code">πŸ’»</a></td>
+    <td align="center"><a href="https://granddaifuku.com/"><img src="https://avatars.githubusercontent.com/u/49578068?v=4?s=100" width="100px;" alt=""/><br /><sub><b>granddaifuku</b></sub></a><br /><a href="#content-granddaifuku" title="Content">πŸ–‹</a></td>
+  </tr>
+  <tr>
+    <td align="center"><a href="https://weilet.me"><img src="https://avatars.githubusercontent.com/u/32561597?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Weilet</b></sub></a><br /><a href="#content-Weilet" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/Millione"><img src="https://avatars.githubusercontent.com/u/38575932?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LIU JIE</b></sub></a><br /><a href="#content-Millione" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/abusch"><img src="https://avatars.githubusercontent.com/u/506344?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antoine BΓΌsch</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=abusch" title="Code">πŸ’»</a></td>
+    <td align="center"><a href="https://frogtd.com/"><img src="https://avatars.githubusercontent.com/u/31412003?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frogtd</b></sub></a><br /><a href="#content-frogtd" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/EmisonLu"><img src="https://avatars.githubusercontent.com/u/54395432?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zhenghao Lu</b></sub></a><br /><a href="#content-EmisonLu" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://soundtrackyourbrand.com"><img src="https://avatars.githubusercontent.com/u/762956?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fredrik Enestad</b></sub></a><br /><a href="#content-fredr" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="http://xuesong.pydevops.com"><img src="https://avatars.githubusercontent.com/u/18476085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>xuesong</b></sub></a><br /><a href="#content-xuesongbj" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/MpdWalsh"><img src="https://avatars.githubusercontent.com/u/48160144?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Walsh</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=MpdWalsh" title="Code">πŸ’»</a></td>
+  </tr>
+  <tr>
+    <td align="center"><a href="https://github.com/alirezaghey"><img src="https://avatars.githubusercontent.com/u/26653424?v=4?s=100" width="100px;" alt=""/><br /><sub><b>alirezaghey</b></sub></a><br /><a href="#content-alirezaghey" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/frvannes16"><img src="https://avatars.githubusercontent.com/u/3188475?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Franklin van Nes</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=frvannes16" title="Code">πŸ’»</a></td>
+    <td align="center"><a href="https://nekonako.github.io"><img src="https://avatars.githubusercontent.com/u/46141275?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nekonako</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nekonako" title="Code">πŸ’»</a></td>
+    <td align="center"><a href="https://github.com/tan-zx"><img src="https://avatars.githubusercontent.com/u/67887489?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ZX</b></sub></a><br /><a href="#content-tan-zx" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://github.com/sundevilyang"><img src="https://avatars.githubusercontent.com/u/1499214?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yang Wen</b></sub></a><br /><a href="#content-sundevilyang" title="Content">πŸ–‹</a></td>
+    <td align="center"><a href="https://brandon-high.com"><img src="https://avatars.githubusercontent.com/u/759848?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon High</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=highb" title="Documentation">πŸ“–</a></td>
   </tr>
 </table>
 
diff --git a/exercises/README.md b/exercises/README.md
index 0c71524..73754db 100644
--- a/exercises/README.md
+++ b/exercises/README.md
@@ -9,8 +9,8 @@
 | primitive_types        | Β§4.3          |
 | structs                | Β§5.1          |
 | enums                  | Β§6            |
-| modules                | Β§7.2          |
-| collections            | Β§8.1          |
+| modules                | Β§7            |
+| collections            | Β§8.1, Β§8.3    |
 | strings                | Β§8.2          |
 | error_handling         | Β§9            |
 | generics               | Β§10           |
diff --git a/exercises/advanced_errors/advanced_errs1.rs b/exercises/advanced_errors/advanced_errs1.rs
new file mode 100644
index 0000000..4bc7b63
--- /dev/null
+++ b/exercises/advanced_errors/advanced_errs1.rs
@@ -0,0 +1,98 @@
+// advanced_errs1.rs
+
+// Remember back in errors6, we had multiple mapping functions so that we
+// could translate lower-level errors into our custom error type using
+// `map_err()`? What if we could use the `?` operator directly instead?
+
+// Make this code compile! Execute `rustlings hint advanced_errs1` for
+// hints :)
+
+// I AM NOT DONE
+
+use std::num::ParseIntError;
+use std::str::FromStr;
+
+// This is a custom error type that we will be using in the `FromStr`
+// implementation.
+#[derive(PartialEq, Debug)]
+enum ParsePosNonzeroError {
+    Creation(CreationError),
+    ParseInt(ParseIntError),
+}
+
+impl From<CreationError> for ParsePosNonzeroError {
+    fn from(e: CreationError) -> Self {
+        // TODO: complete this implementation so that the `?` operator will
+        // work for `CreationError`
+    }
+}
+
+// TODO: implement another instance of the `From` trait here so that the
+// `?` operator will work in the other place in the `FromStr`
+// implementation below.
+
+// Don't change anything below this line.
+
+impl FromStr for PositiveNonzeroInteger {
+    type Err = ParsePosNonzeroError;
+    fn from_str(s: &str) -> Result<PositiveNonzeroInteger, Self::Err> {
+        let x: i64 = s.parse()?;
+        Ok(PositiveNonzeroInteger::new(x)?)
+    }
+}
+
+#[derive(PartialEq, Debug)]
+struct PositiveNonzeroInteger(u64);
+
+#[derive(PartialEq, Debug)]
+enum CreationError {
+    Negative,
+    Zero,
+}
+
+impl PositiveNonzeroInteger {
+    fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
+        match value {
+            x if x < 0 => Err(CreationError::Negative),
+            x if x == 0 => Err(CreationError::Zero),
+            x => Ok(PositiveNonzeroInteger(x as u64)),
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_parse_error() {
+        // We can't construct a ParseIntError, so we have to pattern match.
+        assert!(matches!(
+            PositiveNonzeroInteger::from_str("not a number"),
+            Err(ParsePosNonzeroError::ParseInt(_))
+        ));
+    }
+
+    #[test]
+    fn test_negative() {
+        assert_eq!(
+            PositiveNonzeroInteger::from_str("-555"),
+            Err(ParsePosNonzeroError::Creation(CreationError::Negative))
+        );
+    }
+
+    #[test]
+    fn test_zero() {
+        assert_eq!(
+            PositiveNonzeroInteger::from_str("0"),
+            Err(ParsePosNonzeroError::Creation(CreationError::Zero))
+        );
+    }
+
+    #[test]
+    fn test_positive() {
+        let x = PositiveNonzeroInteger::new(42);
+        assert!(x.is_ok());
+        assert_eq!(PositiveNonzeroInteger::from_str("42"), Ok(x.unwrap()));
+    }
+}
diff --git a/exercises/advanced_errors/advanced_errs2.rs b/exercises/advanced_errors/advanced_errs2.rs
new file mode 100644
index 0000000..54e669f
--- /dev/null
+++ b/exercises/advanced_errors/advanced_errs2.rs
@@ -0,0 +1,202 @@
+// advanced_errs2.rs
+
+// This exercise demonstrates a few traits that are useful for custom error
+// types to implement, especially so that other code can consume the custom
+// error type more usefully.
+
+// Make this compile, and make the tests pass!
+// Execute `rustlings hint advanced_errs2` for hints.
+
+// Steps:
+// 1. Implement a missing trait so that `main()` will compile.
+// 2. Complete the partial implementation of `From` for
+//    `ParseClimateError`.
+// 3. Handle the missing error cases in the `FromStr` implementation for
+//    `Climate`.
+// 4. Complete the partial implementation of `Display` for
+//    `ParseClimateError`.
+
+// I AM NOT DONE
+
+use std::error::Error;
+use std::fmt::{self, Display, Formatter};
+use std::num::{ParseFloatError, ParseIntError};
+use std::str::FromStr;
+
+// This is the custom error type that we will be using for the parser for
+// `Climate`.
+#[derive(Debug, PartialEq)]
+enum ParseClimateError {
+    Empty,
+    BadLen,
+    NoCity,
+    ParseInt(ParseIntError),
+    ParseFloat(ParseFloatError),
+}
+
+// This `From` implementation allows the `?` operator to work on
+// `ParseIntError` values.
+impl From<ParseIntError> for ParseClimateError {
+    fn from(e: ParseIntError) -> Self {
+        Self::ParseInt(e)
+    }
+}
+
+// This `From` implementation allows the `?` operator to work on
+// `ParseFloatError` values.
+impl From<ParseFloatError> for ParseClimateError {
+    fn from(e: ParseFloatError) -> Self {
+        // TODO: Complete this function
+    }
+}
+
+// TODO: Implement a missing trait so that `main()` below will compile. It
+// is not necessary to implement any methods inside the missing trait.
+
+// The `Display` trait allows for other code to obtain the error formatted
+// as a user-visible string.
+impl Display for ParseClimateError {
+    // TODO: Complete this function so that it produces the correct strings
+    // for each error variant.
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        // Imports the variants to make the following code more compact.
+        use ParseClimateError::*;
+        match self {
+            NoCity => write!(f, "no city name"),
+            ParseFloat(e) => write!(f, "error parsing temperature: {}", e),
+        }
+    }
+}
+
+#[derive(Debug, PartialEq)]
+struct Climate {
+    city: String,
+    year: u32,
+    temp: f32,
+}
+
+// Parser for `Climate`.
+// 1. Split the input string into 3 fields: city, year, temp.
+// 2. Return an error if the string is empty or has the wrong number of
+//    fields.
+// 3. Return an error if the city name is empty.
+// 4. Parse the year as a `u32` and return an error if that fails.
+// 5. Parse the temp as a `f32` and return an error if that fails.
+// 6. Return an `Ok` value containing the completed `Climate` value.
+impl FromStr for Climate {
+    type Err = ParseClimateError;
+    // TODO: Complete this function by making it handle the missing error
+    // cases.
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let v: Vec<_> = s.split(',').collect();
+        let (city, year, temp) = match &v[..] {
+            [city, year, temp] => (city.to_string(), year, temp),
+            _ => return Err(ParseClimateError::BadLen),
+        };
+        let year: u32 = year.parse()?;
+        let temp: f32 = temp.parse()?;
+        Ok(Climate { city, year, temp })
+    }
+}
+
+// Don't change anything below this line (other than to enable ignored
+// tests).
+
+fn main() -> Result<(), Box<dyn Error>> {
+    println!("{:?}", "Hong Kong,1999,25.7".parse::<Climate>()?);
+    println!("{:?}", "".parse::<Climate>()?);
+    Ok(())
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    #[test]
+    fn test_empty() {
+        let res = "".parse::<Climate>();
+        assert_eq!(res, Err(ParseClimateError::Empty));
+        assert_eq!(res.unwrap_err().to_string(), "empty input");
+    }
+    #[test]
+    fn test_short() {
+        let res = "Boston,1991".parse::<Climate>();
+        assert_eq!(res, Err(ParseClimateError::BadLen));
+        assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
+    }
+    #[test]
+    fn test_long() {
+        let res = "Paris,1920,17.2,extra".parse::<Climate>();
+        assert_eq!(res, Err(ParseClimateError::BadLen));
+        assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
+    }
+    #[test]
+    fn test_no_city() {
+        let res = ",1997,20.5".parse::<Climate>();
+        assert_eq!(res, Err(ParseClimateError::NoCity));
+        assert_eq!(res.unwrap_err().to_string(), "no city name");
+    }
+    #[test]
+    fn test_parse_int_neg() {
+        let res = "Barcelona,-25,22.3".parse::<Climate>();
+        assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
+        let err = res.unwrap_err();
+        if let ParseClimateError::ParseInt(ref inner) = err {
+            assert_eq!(
+                err.to_string(),
+                format!("error parsing year: {}", inner.to_string())
+            );
+        } else {
+            unreachable!();
+        };
+    }
+    #[test]
+    fn test_parse_int_bad() {
+        let res = "Beijing,foo,15.0".parse::<Climate>();
+        assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
+        let err = res.unwrap_err();
+        if let ParseClimateError::ParseInt(ref inner) = err {
+            assert_eq!(
+                err.to_string(),
+                format!("error parsing year: {}", inner.to_string())
+            );
+        } else {
+            unreachable!();
+        };
+    }
+    #[test]
+    fn test_parse_float() {
+        let res = "Manila,2001,bar".parse::<Climate>();
+        assert!(matches!(res, Err(ParseClimateError::ParseFloat(_))));
+        let err = res.unwrap_err();
+        if let ParseClimateError::ParseFloat(ref inner) = err {
+            assert_eq!(
+                err.to_string(),
+                format!("error parsing temperature: {}", inner.to_string())
+            );
+        } else {
+            unreachable!();
+        };
+    }
+    #[test]
+    fn test_parse_good() {
+        let res = "Munich,2015,23.1".parse::<Climate>();
+        assert_eq!(
+            res,
+            Ok(Climate {
+                city: "Munich".to_string(),
+                year: 2015,
+                temp: 23.1,
+            })
+        );
+    }
+    #[test]
+    #[ignore]
+    fn test_downcast() {
+        let res = "SΓ£o Paulo,-21,28.5".parse::<Climate>();
+        assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
+        let err = res.unwrap_err();
+        let inner: Option<&(dyn Error + 'static)> = err.source();
+        assert!(inner.is_some());
+        assert!(inner.unwrap().is::<ParseIntError>());
+    }
+}
diff --git a/exercises/clippy/clippy1.rs b/exercises/clippy/clippy1.rs
index bdb5dd2..c5f84a9 100644
--- a/exercises/clippy/clippy1.rs
+++ b/exercises/clippy/clippy1.rs
@@ -8,10 +8,16 @@
 
 // I AM NOT DONE
 
+use std::f32;
+
 fn main() {
-    let x = 1.2331f64;
-    let y = 1.2332f64;
-    if y != x {
-        println!("Success!");
-    }
+    let pi = 3.14f32;
+    let radius = 5.00f32;
+
+    let area = pi * f32::powi(radius, 2);
+
+    println!(
+        "The area of a circle with radius {:.2} is {:.5}!",
+        radius, area
+    )
 }
diff --git a/exercises/collections/README.md b/exercises/collections/README.md
index 0291bc8..b6d62ac 100644
--- a/exercises/collections/README.md
+++ b/exercises/collections/README.md
@@ -20,3 +20,4 @@ structures that are used very often in Rust programs:
 ## Further information
 
 - [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
+- [Storing Keys with Associated Values in Hash Maps](https://doc.rust-lang.org/book/ch08-03-hash-maps.html)
diff --git a/exercises/conversions/from_str.rs b/exercises/conversions/from_str.rs
index 4beebac..ece0b3c 100644
--- a/exercises/conversions/from_str.rs
+++ b/exercises/conversions/from_str.rs
@@ -1,16 +1,31 @@
-// This does practically the same thing that TryFrom<&str> does.
+// from_str.rs
+// This is similar to from_into.rs, but this time we'll implement `FromStr`
+// and return errors instead of falling back to a default value.
 // Additionally, upon implementing FromStr, you can use the `parse` method
 // on strings to generate an object of the implementor type.
 // You can read more about it at https://doc.rust-lang.org/std/str/trait.FromStr.html
-use std::error;
+use std::num::ParseIntError;
 use std::str::FromStr;
 
-#[derive(Debug)]
+#[derive(Debug, PartialEq)]
 struct Person {
     name: String,
     age: usize,
 }
 
+// We will use this error type for the `FromStr` implementation.
+#[derive(Debug, PartialEq)]
+enum ParsePersonError {
+    // Empty input string
+    Empty,
+    // Incorrect number of fields
+    BadLen,
+    // Empty name field
+    NoName,
+    // Wrapped error from parse::<usize>()
+    ParseInt(ParseIntError),
+}
+
 // I AM NOT DONE
 
 // Steps:
@@ -20,11 +35,11 @@ struct Person {
 // 4. Extract the first element from the split operation and use it as the name
 // 5. Extract the other element from the split operation and parse it into a `usize` as the age
 //    with something like `"4".parse::<usize>()`
-// 5. If while extracting the name and the age something goes wrong, an error should be returned
+// 6. If while extracting the name and the age something goes wrong, an error should be returned
 // If everything goes well, then return a Result of a Person object
 
 impl FromStr for Person {
-    type Err = Box<dyn error::Error>;
+    type Err = ParsePersonError;
     fn from_str(s: &str) -> Result<Person, Self::Err> {
     }
 }
@@ -40,7 +55,7 @@ mod tests {
 
     #[test]
     fn empty_input() {
-        assert!("".parse::<Person>().is_err());
+        assert_eq!("".parse::<Person>(), Err(ParsePersonError::Empty));
     }
     #[test]
     fn good_input() {
@@ -52,41 +67,56 @@ mod tests {
     }
     #[test]
     fn missing_age() {
-        assert!("John,".parse::<Person>().is_err());
+        assert!(matches!(
+            "John,".parse::<Person>(),
+            Err(ParsePersonError::ParseInt(_))
+        ));
     }
 
     #[test]
     fn invalid_age() {
-        assert!("John,twenty".parse::<Person>().is_err());
+        assert!(matches!(
+            "John,twenty".parse::<Person>(),
+            Err(ParsePersonError::ParseInt(_))
+        ));
     }
 
     #[test]
     fn missing_comma_and_age() {
-        assert!("John".parse::<Person>().is_err());
+        assert_eq!("John".parse::<Person>(), Err(ParsePersonError::BadLen));
     }
 
     #[test]
     fn missing_name() {
-        assert!(",1".parse::<Person>().is_err());
+        assert_eq!(",1".parse::<Person>(), Err(ParsePersonError::NoName));
     }
 
     #[test]
     fn missing_name_and_age() {
-        assert!(",".parse::<Person>().is_err());
+        assert!(matches!(
+            ",".parse::<Person>(),
+            Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_))
+        ));
     }
 
     #[test]
     fn missing_name_and_invalid_age() {
-        assert!(",one".parse::<Person>().is_err());
+        assert!(matches!(
+            ",one".parse::<Person>(),
+            Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_))
+        ));
     }
 
     #[test]
     fn trailing_comma() {
-        assert!("John,32,".parse::<Person>().is_err());
+        assert_eq!("John,32,".parse::<Person>(), Err(ParsePersonError::BadLen));
     }
 
     #[test]
     fn trailing_comma_and_some_string() {
-        assert!("John,32,man".parse::<Person>().is_err());
+        assert_eq!(
+            "John,32,man".parse::<Person>(),
+            Err(ParsePersonError::BadLen)
+        );
     }
 }
diff --git a/exercises/conversions/try_from_into.rs b/exercises/conversions/try_from_into.rs
index c0b5d98..b8ec445 100644
--- a/exercises/conversions/try_from_into.rs
+++ b/exercises/conversions/try_from_into.rs
@@ -1,9 +1,9 @@
+// try_from_into.rs
 // TryFrom is a simple and safe type conversion that may fail in a controlled way under some circumstances.
 // Basically, this is the same as From. The main difference is that this should return a Result type
 // instead of the target type itself.
 // You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
 use std::convert::{TryFrom, TryInto};
-use std::error;
 
 #[derive(Debug, PartialEq)]
 struct Color {
@@ -12,12 +12,21 @@ struct Color {
     blue: u8,
 }
 
+// We will use this error type for these `TryFrom` conversions.
+#[derive(Debug, PartialEq)]
+enum IntoColorError {
+    // Incorrect length of slice
+    BadLen,
+    // Integer conversion error
+    IntConversion,
+}
+
 // I AM NOT DONE
 
 // Your task is to complete this implementation
 // and return an Ok result of inner type Color.
 // You need to create an implementation for a tuple of three integers,
-// an array of three integers and a slice of integers.
+// an array of three integers, and a slice of integers.
 //
 // Note that the implementation for tuple and array will be checked at compile time,
 // but the slice implementation needs to check the slice length!
@@ -25,20 +34,23 @@ struct Color {
 
 // Tuple implementation
 impl TryFrom<(i16, i16, i16)> for Color {
-    type Error = Box<dyn error::Error>;
-    fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {}
+    type Error = IntoColorError;
+    fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
+    }
 }
 
 // Array implementation
 impl TryFrom<[i16; 3]> for Color {
-    type Error = Box<dyn error::Error>;
-    fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {}
+    type Error = IntoColorError;
+    fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
+    }
 }
 
 // Slice implementation
 impl TryFrom<&[i16]> for Color {
-    type Error = Box<dyn error::Error>;
-    fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {}
+    type Error = IntoColorError;
+    fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
+    }
 }
 
 fn main() {
@@ -46,15 +58,15 @@ fn main() {
     let c1 = Color::try_from((183, 65, 14));
     println!("{:?}", c1);
 
-    // Since From is implemented for Color, we should be able to use Into
+    // Since TryFrom is implemented for Color, we should be able to use TryInto
     let c2: Result<Color, _> = [183, 65, 14].try_into();
     println!("{:?}", c2);
 
     let v = vec![183, 65, 14];
-    // With slice we should use `from` function
+    // With slice we should use `try_from` function
     let c3 = Color::try_from(&v[..]);
     println!("{:?}", c3);
-    // or take slice within round brackets and use Into
+    // or take slice within round brackets and use TryInto
     let c4: Result<Color, _> = (&v[..]).try_into();
     println!("{:?}", c4);
 }
@@ -65,15 +77,24 @@ mod tests {
 
     #[test]
     fn test_tuple_out_of_range_positive() {
-        assert!(Color::try_from((256, 1000, 10000)).is_err());
+        assert_eq!(
+            Color::try_from((256, 1000, 10000)),
+            Err(IntoColorError::IntConversion)
+        );
     }
     #[test]
     fn test_tuple_out_of_range_negative() {
-        assert!(Color::try_from((-1, -10, -256)).is_err());
+        assert_eq!(
+            Color::try_from((-1, -10, -256)),
+            Err(IntoColorError::IntConversion)
+        );
     }
     #[test]
     fn test_tuple_sum() {
-        assert!(Color::try_from((-1, 255, 255)).is_err());
+        assert_eq!(
+            Color::try_from((-1, 255, 255)),
+            Err(IntoColorError::IntConversion)
+        );
     }
     #[test]
     fn test_tuple_correct() {
@@ -91,17 +112,17 @@ mod tests {
     #[test]
     fn test_array_out_of_range_positive() {
         let c: Result<Color, _> = [1000, 10000, 256].try_into();
-        assert!(c.is_err());
+        assert_eq!(c, Err(IntoColorError::IntConversion));
     }
     #[test]
     fn test_array_out_of_range_negative() {
         let c: Result<Color, _> = [-10, -256, -1].try_into();
-        assert!(c.is_err());
+        assert_eq!(c, Err(IntoColorError::IntConversion));
     }
     #[test]
     fn test_array_sum() {
         let c: Result<Color, _> = [-1, 255, 255].try_into();
-        assert!(c.is_err());
+        assert_eq!(c, Err(IntoColorError::IntConversion));
     }
     #[test]
     fn test_array_correct() {
@@ -119,17 +140,26 @@ mod tests {
     #[test]
     fn test_slice_out_of_range_positive() {
         let arr = [10000, 256, 1000];
-        assert!(Color::try_from(&arr[..]).is_err());
+        assert_eq!(
+            Color::try_from(&arr[..]),
+            Err(IntoColorError::IntConversion)
+        );
     }
     #[test]
     fn test_slice_out_of_range_negative() {
         let arr = [-256, -1, -10];
-        assert!(Color::try_from(&arr[..]).is_err());
+        assert_eq!(
+            Color::try_from(&arr[..]),
+            Err(IntoColorError::IntConversion)
+        );
     }
     #[test]
     fn test_slice_sum() {
         let arr = [-1, 255, 255];
-        assert!(Color::try_from(&arr[..]).is_err());
+        assert_eq!(
+            Color::try_from(&arr[..]),
+            Err(IntoColorError::IntConversion)
+        );
     }
     #[test]
     fn test_slice_correct() {
@@ -148,11 +178,11 @@ mod tests {
     #[test]
     fn test_slice_excess_length() {
         let v = vec![0, 0, 0, 0];
-        assert!(Color::try_from(&v[..]).is_err());
+        assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen));
     }
     #[test]
     fn test_slice_insufficient_length() {
         let v = vec![0, 0];
-        assert!(Color::try_from(&v[..]).is_err());
+        assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen));
     }
 }
diff --git a/exercises/error_handling/errors1.rs b/exercises/error_handling/errors1.rs
index 9c24d85..5844a49 100644
--- a/exercises/error_handling/errors1.rs
+++ b/exercises/error_handling/errors1.rs
@@ -36,6 +36,7 @@ mod tests {
     fn explains_why_generating_nametag_text_fails() {
         assert_eq!(
             generate_nametag_text("".into()),
+            // Don't change this line
             Err("`name` was empty; it must be nonempty.".into())
         );
     }
diff --git a/exercises/error_handling/result1.rs b/exercises/error_handling/errors4.rs
similarity index 88%
rename from exercises/error_handling/result1.rs
rename to exercises/error_handling/errors4.rs
index b978001..0685c37 100644
--- a/exercises/error_handling/result1.rs
+++ b/exercises/error_handling/errors4.rs
@@ -1,5 +1,5 @@
-// result1.rs
-// Make this test pass! Execute `rustlings hint result1` for hints :)
+// errors4.rs
+// Make this test pass! Execute `rustlings hint errors4` for hints :)
 
 // I AM NOT DONE
 
diff --git a/exercises/error_handling/errors5.rs b/exercises/error_handling/errors5.rs
new file mode 100644
index 0000000..365a869
--- /dev/null
+++ b/exercises/error_handling/errors5.rs
@@ -0,0 +1,53 @@
+// errors5.rs
+
+// This program uses a completed version of the code from errors4.
+// It won't compile right now! Why?
+// Execute `rustlings hint errors5` for hints!
+
+// I AM NOT DONE
+
+use std::error;
+use std::fmt;
+use std::num::ParseIntError;
+
+// TODO: update the return type of `main()` to make this compile.
+fn main() -> Result<(), ParseIntError> {
+    let pretend_user_input = "42";
+    let x: i64 = pretend_user_input.parse()?;
+    println!("output={:?}", PositiveNonzeroInteger::new(x)?);
+    Ok(())
+}
+
+// Don't change anything below this line.
+
+#[derive(PartialEq, Debug)]
+struct PositiveNonzeroInteger(u64);
+
+#[derive(PartialEq, Debug)]
+enum CreationError {
+    Negative,
+    Zero,
+}
+
+impl PositiveNonzeroInteger {
+    fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
+        match value {
+            x if x < 0 => Err(CreationError::Negative),
+            x if x == 0 => Err(CreationError::Zero),
+            x => Ok(PositiveNonzeroInteger(x as u64))
+        }
+    }
+}
+
+// This is required so that `CreationError` can implement `error::Error`.
+impl fmt::Display for CreationError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let description = match *self {
+            CreationError::Negative => "number is negative",
+            CreationError::Zero => "number is zero",
+        };
+        f.write_str(description)
+    }
+}
+
+impl error::Error for CreationError {}
diff --git a/exercises/error_handling/errors6.rs b/exercises/error_handling/errors6.rs
new file mode 100644
index 0000000..0f6b27a
--- /dev/null
+++ b/exercises/error_handling/errors6.rs
@@ -0,0 +1,95 @@
+// errors6.rs
+
+// Using catch-all error types like `Box<dyn error::Error>` isn't recommended
+// for library code, where callers might want to make decisions based on the
+// error content, instead of printing it out or propagating it further. Here,
+// we define a custom error type to make it possible for callers to decide
+// what to do next when our function returns an error.
+
+// Make these tests pass! Execute `rustlings hint errors6` for hints :)
+
+// I AM NOT DONE
+
+use std::num::ParseIntError;
+
+// This is a custom error type that we will be using in `parse_pos_nonzero()`.
+#[derive(PartialEq, Debug)]
+enum ParsePosNonzeroError {
+    Creation(CreationError),
+    ParseInt(ParseIntError)
+}
+
+impl ParsePosNonzeroError {
+    fn from_creation(err: CreationError) -> ParsePosNonzeroError {
+        ParsePosNonzeroError::Creation(err)
+    }
+    // TODO: add another error conversion function here.
+}
+
+fn parse_pos_nonzero(s: &str)
+    -> Result<PositiveNonzeroInteger, ParsePosNonzeroError>
+{
+    // TODO: change this to return an appropriate error instead of panicking
+    // when `parse()` returns an error.
+    let x: i64 = s.parse().unwrap();
+    PositiveNonzeroInteger::new(x)
+        .map_err(ParsePosNonzeroError::from_creation)
+}
+
+// Don't change anything below this line.
+
+#[derive(PartialEq, Debug)]
+struct PositiveNonzeroInteger(u64);
+
+#[derive(PartialEq, Debug)]
+enum CreationError {
+    Negative,
+    Zero,
+}
+
+impl PositiveNonzeroInteger {
+    fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
+        match value {
+            x if x < 0 => Err(CreationError::Negative),
+            x if x == 0 => Err(CreationError::Zero),
+            x => Ok(PositiveNonzeroInteger(x as u64))
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_parse_error() {
+        // We can't construct a ParseIntError, so we have to pattern match.
+        assert!(matches!(
+            parse_pos_nonzero("not a number"),
+            Err(ParsePosNonzeroError::ParseInt(_))
+        ));
+    }
+
+    #[test]
+    fn test_negative() {
+        assert_eq!(
+            parse_pos_nonzero("-555"),
+            Err(ParsePosNonzeroError::Creation(CreationError::Negative))
+        );
+    }
+
+    #[test]
+    fn test_zero() {
+        assert_eq!(
+            parse_pos_nonzero("0"),
+            Err(ParsePosNonzeroError::Creation(CreationError::Zero))
+        );
+    }
+
+    #[test]
+    fn test_positive() {
+        let x = PositiveNonzeroInteger::new(42);
+        assert!(x.is_ok());
+        assert_eq!(parse_pos_nonzero("42"), Ok(x.unwrap()));
+    }
+}
diff --git a/exercises/error_handling/errorsn.rs b/exercises/error_handling/errorsn.rs
deleted file mode 100644
index 5fe212b..0000000
--- a/exercises/error_handling/errorsn.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-// errorsn.rs
-// This is a bigger error exercise than the previous ones!
-// You can do it! :)
-//
-// Edit the `read_and_validate` function ONLY. Don't create any Errors
-// that do not already exist.
-//
-// So many things could go wrong!
-//
-// - Reading from stdin could produce an io::Error
-// - Parsing the input could produce a num::ParseIntError
-// - Validating the input could produce a CreationError (defined below)
-//
-// How can we lump these errors into one general error? That is, what
-// type goes where the question marks are, and how do we return
-// that type from the body of read_and_validate?
-//
-// Execute `rustlings hint errorsn` for hints :)
-
-// I AM NOT DONE
-
-use std::error;
-use std::fmt;
-use std::io;
-
-// PositiveNonzeroInteger is a struct defined below the tests.
-fn read_and_validate(b: &mut dyn io::BufRead) -> Result<PositiveNonzeroInteger, ???> {
-    let mut line = String::new();
-    b.read_line(&mut line);
-    let num: i64 = line.trim().parse();
-    let answer = PositiveNonzeroInteger::new(num);
-    answer
-}
-
-//
-// Nothing below this needs to be modified
-//
-
-// This is a test helper function that turns a &str into a BufReader.
-fn test_with_str(s: &str) -> Result<PositiveNonzeroInteger, Box<dyn error::Error>> {
-    let mut b = io::BufReader::new(s.as_bytes());
-    read_and_validate(&mut b)
-}
-
-#[test]
-fn test_success() {
-    let x = test_with_str("42\n");
-    assert_eq!(PositiveNonzeroInteger(42), x.unwrap());
-}
-
-#[test]
-fn test_not_num() {
-    let x = test_with_str("eleven billion\n");
-    assert!(x.is_err());
-}
-
-#[test]
-fn test_non_positive() {
-    let x = test_with_str("-40\n");
-    assert!(x.is_err());
-}
-
-#[test]
-fn test_ioerror() {
-    struct Broken;
-    impl io::Read for Broken {
-        fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
-            Err(io::Error::new(io::ErrorKind::BrokenPipe, "uh-oh!"))
-        }
-    }
-    let mut b = io::BufReader::new(Broken);
-    assert!(read_and_validate(&mut b).is_err());
-    assert_eq!("uh-oh!", read_and_validate(&mut b).unwrap_err().to_string());
-}
-
-#[derive(PartialEq, Debug)]
-struct PositiveNonzeroInteger(u64);
-
-impl PositiveNonzeroInteger {
-    fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
-        if value == 0 {
-            Err(CreationError::Zero)
-        } else if value < 0 {
-            Err(CreationError::Negative)
-        } else {
-            Ok(PositiveNonzeroInteger(value as u64))
-        }
-    }
-}
-
-#[test]
-fn test_positive_nonzero_integer_creation() {
-    assert!(PositiveNonzeroInteger::new(10).is_ok());
-    assert_eq!(
-        Err(CreationError::Negative),
-        PositiveNonzeroInteger::new(-10)
-    );
-    assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
-}
-
-#[derive(PartialEq, Debug)]
-enum CreationError {
-    Negative,
-    Zero,
-}
-
-impl fmt::Display for CreationError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let description = match *self {
-            CreationError::Negative => "Number is negative",
-            CreationError::Zero => "Number is zero",
-        };
-        f.write_str(description)
-    }
-}
-
-impl error::Error for CreationError {}
diff --git a/exercises/generics/generics1.rs b/exercises/generics/generics1.rs
index 967287e..f93e64a 100644
--- a/exercises/generics/generics1.rs
+++ b/exercises/generics/generics1.rs
@@ -1,6 +1,8 @@
 // This shopping list program isn't compiling!
 // Use your knowledge of generics to fix it.
 
+// Execute `rustlings hint generics1` for hints!
+
 // I AM NOT DONE
 
 fn main() {
diff --git a/exercises/generics/generics2.rs b/exercises/generics/generics2.rs
index 0cb59ad..1501529 100644
--- a/exercises/generics/generics2.rs
+++ b/exercises/generics/generics2.rs
@@ -1,6 +1,8 @@
 // This powerful wrapper provides the ability to store a positive integer value.
 // Rewrite it using generics so that it supports wrapping ANY type.
 
+// Execute `rustlings hint generics2` for hints!
+
 // I AM NOT DONE
 
 struct Wrapper {
diff --git a/exercises/intro/README.md b/exercises/intro/README.md
new file mode 100644
index 0000000..d32e4a8
--- /dev/null
+++ b/exercises/intro/README.md
@@ -0,0 +1,8 @@
+# Intro
+
+Rust uses the `print!` and `println!` macros to print text to the console.
+
+## Further information
+
+- [Hello World](https://doc.rust-lang.org/rust-by-example/hello.html)
+- [Formatted print](https://doc.rust-lang.org/rust-by-example/hello/print.html)
diff --git a/exercises/intro/intro1.rs b/exercises/intro/intro1.rs
new file mode 100644
index 0000000..1c4582d
--- /dev/null
+++ b/exercises/intro/intro1.rs
@@ -0,0 +1,23 @@
+// intro1.rs
+// About this `I AM NOT DONE` thing:
+// We sometimes encourage you to keep trying things on a given exercise, even
+// after you already figured it out. If you got everything working and feel
+// ready for the next exercise, remove the `I AM NOT DONE` comment below.
+// Execute the command `rustlings hint intro1` for a hint.
+
+// I AM NOT DONE
+
+fn main() {
+    println!("Hello and");
+    println!(r#"       welcome to...                      "#);
+    println!(r#"                 _   _ _                  "#);
+    println!(r#"  _ __ _   _ ___| |_| (_)_ __   __ _ ___  "#);
+    println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
+    println!(r#" | |  | |_| \__ \ |_| | | | | | (_| \__ \ "#);
+    println!(r#" |_|   \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
+    println!(r#"                               |___/      "#);
+    println!();
+    println!("This exercise compiles successfully. The remaining exercises contain a compiler");
+    println!("or logic error. The central concept behind Rustlings is to fix these errors and");
+    println!("solve the exercises. Good luck!");
+}
diff --git a/exercises/intro/intro2.rs b/exercises/intro/intro2.rs
new file mode 100644
index 0000000..97a073f
--- /dev/null
+++ b/exercises/intro/intro2.rs
@@ -0,0 +1,9 @@
+// intro2.rs
+// Make the code print a greeting to the world.
+// Execute `rustlings hint intro2` for a hint.
+
+// I AM NOT DONE
+
+fn main() {
+    println!("Hello {}!");
+}
diff --git a/exercises/modules/README.md b/exercises/modules/README.md
index 6582b00..3dc8a48 100644
--- a/exercises/modules/README.md
+++ b/exercises/modules/README.md
@@ -4,4 +4,4 @@ In this section we'll give you an introduction to Rust's module system.
 
 ## Further information
 
-- [The Module System](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html)
+- [The Module System](https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html)
diff --git a/exercises/modules/modules1.rs b/exercises/modules/modules1.rs
index 812dfee..1a2bd0d 100644
--- a/exercises/modules/modules1.rs
+++ b/exercises/modules/modules1.rs
@@ -4,7 +4,13 @@
 // I AM NOT DONE
 
 mod sausage_factory {
+    // Don't let anybody outside of this module see this!
+    fn get_secret_recipe() -> String {
+        String::from("Ginger")
+    }
+
     fn make_sausage() {
+        get_secret_recipe();
         println!("sausage!");
     }
 }
diff --git a/exercises/modules/modules2.rs b/exercises/modules/modules2.rs
index fde439d..87f0c45 100644
--- a/exercises/modules/modules2.rs
+++ b/exercises/modules/modules2.rs
@@ -1,11 +1,15 @@
 // modules2.rs
+// You can bring module paths into scopes and provide new names for them with the
+// 'use' and 'as' keywords. Fix these 'use' statements to make the code compile.
 // Make me compile! Execute `rustlings hint modules2` for hints :)
 
 // I AM NOT DONE
 
 mod delicious_snacks {
-    use self::fruits::PEAR as fruit;
-    use self::veggies::CUCUMBER as veggie;
+
+    // TODO: Fix these use statements
+    use self::fruits::PEAR as ???
+    use self::veggies::CUCUMBER as ???
 
     mod fruits {
         pub const PEAR: &'static str = "Pear";
diff --git a/exercises/modules/modules3.rs b/exercises/modules/modules3.rs
new file mode 100644
index 0000000..8eed77d
--- /dev/null
+++ b/exercises/modules/modules3.rs
@@ -0,0 +1,18 @@
+// modules3.rs
+// You can use the 'use' keyword to bring module paths from modules from anywhere
+// and especially from the Rust standard library into your scope.
+// Bring SystemTime and UNIX_EPOCH
+// from the std::time module. Bonus style points if you can do it with one line!
+// Make me compile! Execute `rustlings hint modules3` for hints :)
+
+// I AM NOT DONE
+
+// TODO: Complete this use statement
+use ???
+
+fn main() {
+    match SystemTime::now().duration_since(UNIX_EPOCH) {
+        Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
+        Err(_) => panic!("SystemTime before UNIX EPOCH!"),
+    }
+}
diff --git a/exercises/move_semantics/move_semantics5.rs b/exercises/move_semantics/move_semantics5.rs
new file mode 100644
index 0000000..c4704f9
--- /dev/null
+++ b/exercises/move_semantics/move_semantics5.rs
@@ -0,0 +1,15 @@
+// move_semantics5.rs
+// Make me compile only by reordering the lines in `main()`, but without
+// adding, changing or removing any of them.
+// Execute `rustlings hint move_semantics5` for hints :)
+
+// I AM NOT DONE
+
+fn main() {
+    let mut x = 100;
+    let y = &mut x;
+    let z = &mut x;
+    *y += 100;
+    *z += 1000;
+    assert_eq!(x, 1200);
+}
diff --git a/exercises/option/README.md b/exercises/option/README.md
index a304bb4..89c0028 100644
--- a/exercises/option/README.md
+++ b/exercises/option/README.md
@@ -16,3 +16,5 @@ Option types are very common in Rust code, as they have a number of uses:
 - [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions)
 - [Option Module Documentation](https://doc.rust-lang.org/std/option/)
 - [Option Enum Documentation](https://doc.rust-lang.org/std/option/enum.Option.html)
+- [if let](https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html)
+- [while let](https://doc.rust-lang.org/rust-by-example/flow_control/while_let.html)
diff --git a/exercises/option/option1.rs b/exercises/option/option1.rs
index 602ff1a..17cf4f6 100644
--- a/exercises/option/option1.rs
+++ b/exercises/option/option1.rs
@@ -3,7 +3,7 @@
 
 // I AM NOT DONE
 
-// you can modify anything EXCEPT for this function's sig
+// you can modify anything EXCEPT for this function's signature
 fn print_number(maybe_number: Option<u16>) {
     println!("printing: {}", maybe_number.unwrap());
 }
diff --git a/exercises/option/option3.rs b/exercises/option/option3.rs
new file mode 100644
index 0000000..045d2ac
--- /dev/null
+++ b/exercises/option/option3.rs
@@ -0,0 +1,19 @@
+// option3.rs
+// Make me compile! Execute `rustlings hint option3` for hints
+
+// I AM NOT DONE
+
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+fn main() {
+    let y: Option<Point> = Some(Point { x: 100, y: 200 });
+
+    match y {
+        Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y),
+        _ => println!("no match"),
+    }
+    y; // Fix without deleting this line.
+}
diff --git a/exercises/quiz1.rs b/exercises/quiz1.rs
index 2bb2c24..7bd3f58 100644
--- a/exercises/quiz1.rs
+++ b/exercises/quiz1.rs
@@ -2,15 +2,16 @@
 // This is a quiz for the following sections:
 // - Variables
 // - Functions
+// - If
 
 // Mary is buying apples. One apple usually costs 2 Rustbucks, but if you buy
 // more than 40 at once, each apple only costs 1! Write a function that calculates
-// the price of an order of apples given the order amount. No hints this time!
+// the price of an order of apples given the quantity bought. No hints this time!
 
 // I AM NOT DONE
 
 // Put your function here!
-// fn ..... {
+// fn calculate_apple_price {
 
 // Don't modify this function!
 #[test]
diff --git a/exercises/standard_library_types/iterators1.rs b/exercises/standard_library_types/iterators1.rs
index 3fd519d..4606ad3 100644
--- a/exercises/standard_library_types/iterators1.rs
+++ b/exercises/standard_library_types/iterators1.rs
@@ -1,11 +1,11 @@
 // iterators1.rs
-// 
+//
 //  Make me compile by filling in the `???`s
 //
 // When performing operations on elements within a collection, iterators are essential.
-// This module helps you get familiar with the structure of using an iterator and 
+// This module helps you get familiar with the structure of using an iterator and
 // how to go through elements within an iterable collection.
-// 
+//
 // Execute `rustlings hint iterators1` for hints :D
 
 // I AM NOT DONE
diff --git a/exercises/standard_library_types/iterators5.rs b/exercises/standard_library_types/iterators5.rs
index 2d97bd4..93f3ae1 100644
--- a/exercises/standard_library_types/iterators5.rs
+++ b/exercises/standard_library_types/iterators5.rs
@@ -1,5 +1,4 @@
 // iterators5.rs
-
 // Let's define a simple model to track Rustlings exercise progress. Progress
 // will be modelled using a hash map. The name of the exercise is the key and
 // the progress is the value. Two counting functions were created to count the
@@ -7,8 +6,7 @@
 // imperative style for loops. Recreate this counting functionality using
 // iterators. Only the two iterator methods (count_iterator and
 // count_collection_iterator) need to be modified.
-// Execute `rustlings hint
-// iterators5` for hints.
+// Execute `rustlings hint iterators5` for hints.
 //
 // Make the code compile and the tests pass.
 
@@ -16,7 +14,7 @@
 
 use std::collections::HashMap;
 
-#[derive(PartialEq, Eq)]
+#[derive(Clone, Copy, PartialEq, Eq)]
 enum Progress {
     None,
     Some,
diff --git a/exercises/structs/structs3.rs b/exercises/structs/structs3.rs
index 8d8b471..e84f2eb 100644
--- a/exercises/structs/structs3.rs
+++ b/exercises/structs/structs3.rs
@@ -16,13 +16,13 @@ struct Package {
 impl Package {
     fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package {
         if weight_in_grams <= 0 {
-            // Something goes here...
+            // panic statement goes here...
         } else {
-            return Package {
+            Package {
                 sender_country,
                 recipient_country,
                 weight_in_grams,
-            };
+            }
         }
     }
 
@@ -31,7 +31,7 @@ impl Package {
     }
 
     fn get_fees(&self, cents_per_gram: i32) -> ??? {
-        // Something goes here... 
+        // Something goes here...
     }
 }
 
@@ -73,7 +73,7 @@ mod tests {
         let sender_country = String::from("Spain");
         let recipient_country = String::from("Spain");
 
-        let cents_per_gram = ???;
+        let cents_per_gram = 3;
 
         let package = Package::new(sender_country, recipient_country, 1500);
 
diff --git a/exercises/traits/traits1.rs b/exercises/traits/traits1.rs
index 2ef9e11..15e08f2 100644
--- a/exercises/traits/traits1.rs
+++ b/exercises/traits/traits1.rs
@@ -29,12 +29,12 @@ mod tests {
     use super::*;
 
     #[test]
-    fn is_FooBar() {
+    fn is_foo_bar() {
         assert_eq!(String::from("Foo").append_bar(), String::from("FooBar"));
     }
 
     #[test]
-    fn is_BarBar() {
+    fn is_bar_bar() {
         assert_eq!(
             String::from("").append_bar().append_bar(),
             String::from("BarBar")
diff --git a/exercises/variables/variables1.rs b/exercises/variables/variables1.rs
index 4a3af73..d1af831 100644
--- a/exercises/variables/variables1.rs
+++ b/exercises/variables/variables1.rs
@@ -1,10 +1,6 @@
 // variables1.rs
-// Make me compile! Execute the command `rustlings hint variables1` if you want a hint :)
-
-// About this `I AM NOT DONE` thing:
-// We sometimes encourage you to keep trying things on a given exercise,
-// even after you already figured it out. If you got everything working and
-// feel ready for the next exercise, remove the `I AM NOT DONE` comment below.
+// Make me compile!
+// Execute the command `rustlings hint variables1` if you want a hint :)
 
 // I AM NOT DONE
 
diff --git a/exercises/variables/variables5.rs b/exercises/variables/variables5.rs
index da37ae9..175eebb 100644
--- a/exercises/variables/variables5.rs
+++ b/exercises/variables/variables5.rs
@@ -4,7 +4,7 @@
 // I AM NOT DONE
 
 fn main() {
-    let number = "T-H-R-E-E";
+    let number = "T-H-R-E-E"; // don't change this line
     println!("Spell a Number : {}", number);
     number = 3;
     println!("Number plus two is : {}", number + 2);
diff --git a/info.toml b/info.toml
index 82e1195..fbe0d53 100644
--- a/info.toml
+++ b/info.toml
@@ -1,3 +1,19 @@
+# INTRO
+
+[[exercises]]
+name = "intro1"
+path = "exercises/intro/intro1.rs"
+mode = "compile"
+hint = """
+Remove the I AM NOT DONE comment to move on to the next exercise."""
+
+[[exercises]]
+name = "intro2"
+path = "exercises/intro/intro2.rs"
+mode = "compile"
+hint = """
+Add an argument after the format string."""
+
 # VARIABLES
 
 [[exercises]]
@@ -114,8 +130,7 @@ path = "exercises/functions/functions5.rs"
 mode = "compile"
 hint = """
 This is a really common error that can be fixed by removing one character.
-It happens because Rust distinguishes between expressions and statements: expressions return
-a value based on its operand, and statements simply return a () type which behaves just like `void` in C/C++ language.
+It happens because Rust distinguishes between expressions and statements: expressions return a value based on their operand(s), and statements simply return a () type which behaves just like `void` in C/C++ language.
 We want to return a value of `i32` type from the `square` function, but it is returning a `()` type...
 They are not the same. There are two solutions:
 1. Add a `return` ahead of `num * num;`
@@ -210,6 +225,18 @@ So the end goal is to:
    - since we're not creating a new vec in `main` anymore, we need to create
      a new vec in `fill_vec`, similarly to the way we did in `main`"""
 
+[[exercises]]
+name = "move_semantics5"
+path = "exercises/move_semantics/move_semantics5.rs"
+mode = "compile"
+hint = """
+Carefully reason about the range in which each mutable reference is in
+vogue. Does it help to update the value of referent (x) immediately after
+the mutable reference is taken? Read more about 'Mutable References'
+in the book's section References and Borrowing':
+https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references.
+"""
+
 # PRIMITIVE TYPES
 
 [[exercises]]
@@ -350,11 +377,19 @@ name = "modules2"
 path = "exercises/modules/modules2.rs"
 mode = "compile"
 hint = """
-The delicious_snacks module is trying to present an external
-interface (the `fruit` and `veggie` constants) that is different than
-its internal structure (the `fruits` and `veggies` modules and
-associated constants). It's almost there except for one keyword missing for
-each constant."""
+The delicious_snacks module is trying to present an external interface that is 
+different than its internal structure (the `fruits` and `veggies` modules and
+associated constants). Complete the `use` statements to fit the uses in main and
+find the one keyword missing for both constants."""
+
+[[exercises]]
+name = "modules3"
+path = "exercises/modules/modules3.rs"
+mode = "compile"
+hint = """
+UNIX_EPOCH and SystemTime are declared in the std::time module. Add a use statement
+for these two to bring them into scope. You can use nested paths or the glob
+operator to bring these two in using only one line."""
 
 # COLLECTIONS
 
@@ -475,42 +510,61 @@ hint = """
 If other functions can return a `Result`, why shouldn't `main`?"""
 
 [[exercises]]
-name = "errorsn"
-path = "exercises/error_handling/errorsn.rs"
+name = "errors4"
+path = "exercises/error_handling/errors4.rs"
 mode = "test"
 hint = """
-First hint: To figure out what type should go where the ??? is, take a look
-at the test helper function `test_with_str`, since it returns whatever
-`read_and_validate` returns and `test_with_str` has its signature fully
-specified.
-
-
-Next hint: There are three places in `read_and_validate` that we call a
-function that returns a `Result` (that is, the functions might fail).
-Apply the `?` operator on those calls so that we return immediately from
-`read_and_validate` if those function calls fail.
+`PositiveNonzeroInteger::new` is always creating a new instance and returning an `Ok` result.
+It should be doing some checking, returning an `Err` result if those checks fail, and only
+returning an `Ok` result if those checks determine that everything is... okay :)"""
 
+[[exercises]]
+name = "errors5"
+path = "exercises/error_handling/errors5.rs"
+mode = "compile"
+hint = """
+Hint: There are two different possible `Result` types produced within
+`main()`, which are propagated using `?` operators. How do we declare a
+return type from `main()` that allows both?
 
 Another hint: under the hood, the `?` operator calls `From::from`
-on the error value to convert it to a boxed trait object, a Box<dyn error::Error>,
-which is polymorphic-- that means that lots of different kinds of errors
-can be returned from the same function because all errors act the same
-since they all implement the `error::Error` trait.
+on the error value to convert it to a boxed trait object, a
+`Box<dyn error::Error>`, which is polymorphic-- that means that lots of
+different kinds of errors can be returned from the same function because
+all errors act the same since they all implement the `error::Error` trait.
 Check out this section of the book:
 https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
 
+This exercise uses some concepts that we won't get to until later in the
+course, like `Box` and the `From` trait. It's not important to understand
+them in detail right now, but you can read ahead if you like.
 
-Another another hint: Note that because the `?` operator returns
-the *unwrapped* value in the `Ok` case, if we want to return a `Result` from
-`read_and_validate` for *its* success case, we'll have to rewrap a value
-that we got from the return value of a `?`ed call in an `Ok`-- this will
-look like `Ok(something)`.
+Read more about boxing errors:
+https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html
 
+Read more about using the `?` operator with boxed errors:
+https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html
+"""
 
-Another another another hint: `Result`s must be "used", that is, you'll
-get a warning if you don't handle a `Result` that you get in your
-function. Read more about that in the `std::result` module docs:
-https://doc.rust-lang.org/std/result/#results-must-be-used"""
+[[exercises]]
+name = "errors6"
+path = "exercises/error_handling/errors6.rs"
+mode = "test"
+hint = """
+This exercise uses a completed version of `PositiveNonzeroInteger` from
+errors4.
+
+Below the line that TODO asks you to change, there is an example of using
+the `map_err()` method on a `Result` to transform one type of error into
+another. Try using something similar on the `Result` from `parse()`. You
+might use the `?` operator to return early from the function, or you might
+use a `match` expression, or maybe there's another way!
+
+You can create another function inside `impl ParsePosNonzeroError` to use
+with `map_err()`.
+
+Read more about `map_err()` in the `std::result` documentation:
+https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err"""
 
 # Generics
 
@@ -546,7 +600,7 @@ ReportCard struct generic, but also the correct property - you will need to chan
 of the struct slightly too...you can do it!
 """
 
-# OPTIONS / RESULTS
+# OPTIONS
 
 [[exercises]]
 name = "option1"
@@ -579,13 +633,14 @@ Also see Option::flatten
 """
 
 [[exercises]]
-name = "result1"
-path = "exercises/error_handling/result1.rs"
-mode = "test"
+name = "option3"
+path = "exercises/option/option3.rs"
+mode = "compile"
 hint = """
-`PositiveNonzeroInteger::new` is always creating a new instance and returning an `Ok` result.
-It should be doing some checking, returning an `Err` result if those checks fail, and only
-returning an `Ok` result if those checks determine that everything is... okay :)"""
+The compiler says a partial move happened in the `match`
+statement. How can this be avoided? The compiler shows the correction
+needed. After making the correction as suggested by the compiler, do
+read: https://doc.rust-lang.org/std/keyword.ref.html"""
 
 # TRAITS
 
@@ -737,7 +792,10 @@ The division_results variable needs to be collected into a collection type.
 The result_with_list function needs to return a single Result where the success
 case is a vector of integers and the failure case is a DivisionError.
 
-The list_of_results function needs to return a vector of results."""
+The list_of_results function needs to return a vector of results.
+
+See https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect for how 
+the `FromIterator` trait is used in `collect()`."""
 
 [[exercises]]
 name = "iterators4"
@@ -763,7 +821,10 @@ test count_iterator.
 The collection variable in count_collection_iterator is a slice of HashMaps. It
 needs to be converted into an iterator in order to use the iterator methods.
 
-The fold method can be useful in the count_collection_iterator function."""
+The fold method can be useful in the count_collection_iterator function.
+
+For a further challenge, consult the documentation for Iterator to find
+a different method that could make your code more compact than using fold."""
 
 # THREADS
 
@@ -861,7 +922,15 @@ name = "clippy1"
 path = "exercises/clippy/clippy1.rs"
 mode = "clippy"
 hint = """
-Floating point calculations are usually imprecise, so asking if two values are exactly equal is asking for trouble"""
+Rust stores the highest precision version of any long or inifinite precision
+mathematical constants in the rust standard library.
+https://doc.rust-lang.org/stable/std/f32/consts/index.html
+
+We may be tempted to use our own approximations for certain mathematical constants,
+but clippy recognizes those imprecise mathematical constants as a source of 
+potential error.
+See the suggestions of the clippy warning in compile output and use the
+appropriate replacement constant from std::f32::consts..."""
 
 [[exercises]]
 name = "clippy2"
@@ -887,13 +956,48 @@ mode = "test"
 hint = """
 Follow the steps provided right before the `From` implementation"""
 
+[[exercises]]
+name = "from_str"
+path = "exercises/conversions/from_str.rs"
+mode = "test"
+hint = """
+The implementation of FromStr should return an Ok with a Person object,
+or an Err with an error if the string is not valid.
+
+This is almost like the `from_into` exercise, but returning errors instead
+of falling back to a default value.
+
+Hint: Look at the test cases to see which error variants to return.
+
+Another hint: You can use the `map_err` method of `Result` with a function
+or a closure to wrap the error from `parse::<usize>`.
+
+Yet another hint: If you would like to propagate errors by using the `?`
+operator in your solution, you might want to look at
+https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html
+"""
+
 [[exercises]]
 name = "try_from_into"
 path = "exercises/conversions/try_from_into.rs"
 mode = "test"
 hint = """
 Follow the steps provided right before the `TryFrom` implementation.
-You can also use the example at https://doc.rust-lang.org/std/convert/trait.TryFrom.html"""
+You can also use the example at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
+
+Hint: Is there an implementation of `TryFrom` in the standard library that
+can both do the required integer conversion and check the range of the input?
+
+Another hint: Look at the test cases to see which error variants to return.
+
+Yet another hint: You can use the `map_err` or `or` methods of `Result` to
+convert errors.
+
+Yet another hint: If you would like to propagate errors by using the `?`
+operator in your solution, you might want to look at
+https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html
+
+Challenge: Can you make the `TryFrom` implementations generic over many integer types?"""
 
 [[exercises]]
 name = "as_ref_mut"
@@ -902,11 +1006,54 @@ mode = "test"
 hint = """
 Add AsRef<str> as a trait bound to the functions."""
 
+# ADVANCED ERRORS
+
 [[exercises]]
-name = "from_str"
-path = "exercises/conversions/from_str.rs"
+name = "advanced_errs1"
+path = "exercises/advanced_errors/advanced_errs1.rs"
 mode = "test"
 hint = """
-The implementation of FromStr should return an Ok with a Person object,
-or an Err with an error if the string is not valid.
-This is almost like the `try_from_into` exercise."""
+This exercise uses an updated version of the code in errors6. The parsing
+code is now in an implementation of the `FromStr` trait. Note that the
+parsing code uses `?` directly, without any calls to `map_err()`. There is
+one partial implementation of the `From` trait example that you should
+complete.
+
+Details: The `?` operator calls `From::from()` on the error type to convert
+it to the error type of the return type of the surrounding function.
+
+Hint: You will need to write another implementation of `From` that has a
+different input type.
+"""
+
+[[exercises]]
+name = "advanced_errs2"
+path = "exercises/advanced_errors/advanced_errs2.rs"
+mode = "test"
+hint = """
+This exercise demonstrates a few traits that are useful for custom error
+types to implement. These traits make it easier for other code to consume
+the custom error type.
+
+Follow the steps in the comment near the top of the file. You will have to
+supply a missing trait implementation, and complete a few incomplete ones.
+
+You may find these pages to be helpful references:
+https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/define_error_type.html
+https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html
+https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/wrap_error.html
+
+Hint: What trait must our error type have for `main()` to return the return
+type that it returns?
+
+Another hint: It's not necessary to implement any methods inside the missing
+trait. (Some methods have default implementations that are supplied by the
+trait.)
+
+Another hint: Consult the tests to determine which error variants (and which
+error message text) to produce for certain error conditions.
+
+Challenge: There is one test that is marked `#[ignore]`. Can you supply the
+missing code that will make it pass? You may want to consult the standard
+library documentation for a certain trait for more hints.
+"""
diff --git a/install.sh b/install.sh
index e986e74..68b8da3 100755
--- a/install.sh
+++ b/install.sh
@@ -12,6 +12,18 @@ else
     exit 1
 fi
 
+if [ -x "$(command -v cc)" ]
+then
+    echo "SUCCESS: cc is installed"
+else
+    echo "ERROR: cc does not seem to be installed."
+    echo "Please download (g)cc using your package manager."
+    echo "OSX: xcode-select --install"
+    echo "Deb: sudo apt install gcc"
+    echo "Yum: sudo yum -y install gcc"
+    exit 1
+fi
+
 if [ -x "$(command -v rustc)" ]
 then
     echo "SUCCESS: Rust is installed"
diff --git a/src/exercise.rs b/src/exercise.rs
index d934cfd..6e49a9a 100644
--- a/src/exercise.rs
+++ b/src/exercise.rs
@@ -133,7 +133,7 @@ path = "{}.rs""#,
                     "Failed to write πŸ“Ž Clippy πŸ“Ž Cargo.toml file."
                 };
                 fs::write(CLIPPY_CARGO_TOML_PATH, cargo_toml).expect(cargo_toml_error_msg);
-                // To support the ability to run the clipy exercises, build
+                // To support the ability to run the clippy exercises, build
                 // an executable, in addition to running clippy. With a
                 // compilation failure, this would silently fail. But we expect
                 // clippy to reflect the same failure while compiling later.
@@ -154,7 +154,7 @@ path = "{}.rs""#,
                 Command::new("cargo")
                     .args(&["clippy", "--manifest-path", CLIPPY_CARGO_TOML_PATH])
                     .args(RUSTC_COLOR_ARGS)
-                    .args(&["--", "-D", "warnings"])
+                    .args(&["--", "-D", "warnings","-D","clippy::float_cmp"])
                     .output()
             }
         }
@@ -162,7 +162,7 @@ path = "{}.rs""#,
 
         if cmd.status.success() {
             Ok(CompiledExercise {
-                exercise: &self,
+                exercise: self,
                 _handle: FileHandle,
             })
         } else {
@@ -217,8 +217,7 @@ path = "{}.rs""#,
         let matched_line_index = source
             .lines()
             .enumerate()
-            .filter_map(|(i, line)| if re.is_match(line) { Some(i) } else { None })
-            .next()
+            .find_map(|(i, line)| if re.is_match(line) { Some(i) } else { None })
             .expect("This should not happen at all");
 
         let min_line = ((matched_line_index as i32) - (CONTEXT as i32)).max(0) as usize;
diff --git a/src/main.rs b/src/main.rs
index 64161e5..453b8c0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -10,7 +10,8 @@ use std::fs;
 use std::io::{self, prelude::*};
 use std::path::Path;
 use std::process::{Command, Stdio};
-use std::sync::mpsc::channel;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::mpsc::{channel, RecvTimeoutError};
 use std::sync::{Arc, Mutex};
 use std::thread;
 use std::time::Duration;
@@ -23,7 +24,7 @@ mod run;
 mod verify;
 
 // In sync with crate version
-const VERSION: &str = "4.4.0";
+const VERSION: &str = "4.6.0";
 
 #[derive(FromArgs, PartialEq, Debug)]
 /// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
@@ -154,9 +155,7 @@ fn main() {
                     "Pending"
                 };
                 let solve_cond = {
-                    (e.looks_done() && subargs.solved)
-                        || (!e.looks_done() && subargs.unsolved)
-                        || (!subargs.solved && !subargs.unsolved)
+                    (e.looks_done() && subargs.solved) || (!e.looks_done() && subargs.unsolved) || (!subargs.solved && !subargs.unsolved)
                 };
                 if solve_cond && (filter_cond || subargs.filter.is_none()) {
                     let line = if subargs.paths {
@@ -194,7 +193,7 @@ fn main() {
         Subcommands::Run(subargs) => {
             let exercise = find_exercise(&subargs.name, &exercises);
 
-            run(&exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
+            run(exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
         }
 
         Subcommands::Hint(subargs) => {
@@ -207,38 +206,50 @@ fn main() {
             verify(&exercises, verbose).unwrap_or_else(|_| std::process::exit(1));
         }
 
-        Subcommands::Watch(_subargs) => {
-            if let Err(e) = watch(&exercises, verbose) {
-                println!(
-                    "Error: Could not watch your progress. Error message was {:?}.",
-                    e
-                );
+        Subcommands::Watch(_subargs) => match watch(&exercises, verbose) {
+            Err(e) => {
+                println!("Error: Could not watch your progress. Error message was {:?}.", e);
                 println!("Most likely you've run out of disk space or your 'inotify limit' has been reached.");
                 std::process::exit(1);
             }
-            println!(
-                "{emoji} All exercises completed! {emoji}",
-                emoji = Emoji("πŸŽ‰", "β˜…")
-            );
-            println!("\n{}\n", FENISH_LINE);
-        }
+            Ok(WatchStatus::Finished) => {
+                println!("{emoji} All exercises completed! {emoji}", emoji = Emoji("πŸŽ‰", "β˜…"));
+                println!("\n{}\n", FENISH_LINE);
+            }
+            Ok(WatchStatus::Unfinished) => {
+                println!("We hope you're enjoying learning about Rust!");
+                println!("If you want to continue working on the exercises at a later point, you can simply run `rustlings watch` again");
+            }
+        },
     }
 }
 
-fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>) {
+fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>, should_quit: Arc<AtomicBool>) {
     let failed_exercise_hint = Arc::clone(failed_exercise_hint);
-    println!("Type 'hint' or open the corresponding README.md file to get help or type 'clear' to clear the screen.");
+    println!("Welcome to watch mode! You can type 'help' to get an overview of the commands you can use here.");
     thread::spawn(move || loop {
         let mut input = String::new();
         match io::stdin().read_line(&mut input) {
             Ok(_) => {
                 let input = input.trim();
-                if input.eq("hint") {
+                if input == "hint" {
                     if let Some(hint) = &*failed_exercise_hint.lock().unwrap() {
                         println!("{}", hint);
                     }
-                } else if input.eq("clear") {
+                } else if input == "clear" {
                     println!("\x1B[2J\x1B[1;1H");
+                } else if input.eq("quit") {
+                    should_quit.store(true, Ordering::SeqCst);
+                    println!("Bye!");
+                } else if input.eq("help") {
+                    println!("Commands available to you in watch mode:");
+                    println!("  hint  - prints the current exercise's hint");
+                    println!("  clear - clears the screen");
+                    println!("  quit  - quits watch mode");
+                    println!("  help  - displays this help message");
+                    println!();
+                    println!("Watch mode automatically re-evaluates the current exercise");
+                    println!("when you edit a file's contents.")
                 } else {
                     println!("unknown command: {}", input);
                 }
@@ -249,16 +260,26 @@ fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>) {
 }
 
 fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise {
-    exercises
-        .iter()
-        .find(|e| e.name == name)
-        .unwrap_or_else(|| {
+    if name.eq("next") {
+        exercises.iter().find(|e| !e.looks_done()).unwrap_or_else(|| {
+            println!("πŸŽ‰ Congratulations! You have done all the exercises!");
+            println!("πŸ”š There are no more exercises to do next!");
+            std::process::exit(1)
+        })
+    } else {
+        exercises.iter().find(|e| e.name == name).unwrap_or_else(|| {
             println!("No exercise found for '{}'!", name);
             std::process::exit(1)
         })
+    }
 }
 
-fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
+enum WatchStatus {
+    Finished,
+    Unfinished,
+}
+
+fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
     /* Clears the terminal with an ANSI escape code.
     Works in UNIX and newer Windows terminals. */
     fn clear_screen() {
@@ -266,6 +287,7 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
     }
 
     let (tx, rx) = channel();
+    let should_quit = Arc::new(AtomicBool::new(false));
 
     let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
     watcher.watch(Path::new("./exercises"), RecursiveMode::Recursive)?;
@@ -274,12 +296,12 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
 
     let to_owned_hint = |t: &Exercise| t.hint.to_owned();
     let failed_exercise_hint = match verify(exercises.iter(), verbose) {
-        Ok(_) => return Ok(()),
+        Ok(_) => return Ok(WatchStatus::Finished),
         Err(exercise) => Arc::new(Mutex::new(Some(to_owned_hint(exercise)))),
     };
-    spawn_watch_shell(&failed_exercise_hint);
+    spawn_watch_shell(&failed_exercise_hint, Arc::clone(&should_quit));
     loop {
-        match rx.recv() {
+        match rx.recv_timeout(Duration::from_secs(1)) {
             Ok(event) => match event {
                 DebouncedEvent::Create(b) | DebouncedEvent::Chmod(b) | DebouncedEvent::Write(b) => {
                     if b.extension() == Some(OsStr::new("rs")) && b.exists() {
@@ -288,14 +310,10 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
                             .iter()
                             .skip_while(|e| !filepath.ends_with(&e.path))
                             // .filter(|e| filepath.ends_with(&e.path))
-                            .chain(
-                                exercises
-                                    .iter()
-                                    .filter(|e| !e.looks_done() && !filepath.ends_with(&e.path)),
-                            );
+                            .chain(exercises.iter().filter(|e| !e.looks_done() && !filepath.ends_with(&e.path)));
                         clear_screen();
                         match verify(pending_exercises, verbose) {
-                            Ok(_) => return Ok(()),
+                            Ok(_) => return Ok(WatchStatus::Finished),
                             Err(exercise) => {
                                 let mut failed_exercise_hint = failed_exercise_hint.lock().unwrap();
                                 *failed_exercise_hint = Some(to_owned_hint(exercise));
@@ -305,8 +323,15 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
                 }
                 _ => {}
             },
+            Err(RecvTimeoutError::Timeout) => {
+                // the timeout expired, just check the `should_quit` variable below then loop again
+            }
             Err(e) => println!("watch error: {:?}", e),
         }
+        // Check if we need to exit
+        if should_quit.load(Ordering::SeqCst) {
+            return Ok(WatchStatus::Unfinished);
+        }
     }
 }
 
diff --git a/src/verify.rs b/src/verify.rs
index b98598a..fd59fa5 100644
--- a/src/verify.rs
+++ b/src/verify.rs
@@ -14,9 +14,9 @@ pub fn verify<'a>(
 ) -> Result<(), &'a Exercise> {
     for exercise in start_at {
         let compile_result = match exercise.mode {
-            Mode::Test => compile_and_test(&exercise, RunMode::Interactive, verbose),
-            Mode::Compile => compile_and_run_interactively(&exercise),
-            Mode::Clippy => compile_only(&exercise),
+            Mode::Test => compile_and_test(exercise, RunMode::Interactive, verbose),
+            Mode::Compile => compile_and_run_interactively(exercise),
+            Mode::Clippy => compile_only(exercise),
         };
         if !compile_result.unwrap_or(false) {
             return Err(exercise);
@@ -42,11 +42,11 @@ fn compile_only(exercise: &Exercise) -> Result<bool, ()> {
     progress_bar.set_message(format!("Compiling {}...", exercise).as_str());
     progress_bar.enable_steady_tick(100);
 
-    let _ = compile(&exercise, &progress_bar)?;
+    let _ = compile(exercise, &progress_bar)?;
     progress_bar.finish_and_clear();
 
     success!("Successfully compiled {}!", exercise);
-    Ok(prompt_for_completion(&exercise, None))
+    Ok(prompt_for_completion(exercise, None))
 }
 
 // Compile the given Exercise and run the resulting binary in an interactive mode
@@ -55,7 +55,7 @@ fn compile_and_run_interactively(exercise: &Exercise) -> Result<bool, ()> {
     progress_bar.set_message(format!("Compiling {}...", exercise).as_str());
     progress_bar.enable_steady_tick(100);
 
-    let compilation = compile(&exercise, &progress_bar)?;
+    let compilation = compile(exercise, &progress_bar)?;
 
     progress_bar.set_message(format!("Running {}...", exercise).as_str());
     let result = compilation.run();
@@ -73,7 +73,7 @@ fn compile_and_run_interactively(exercise: &Exercise) -> Result<bool, ()> {
 
     success!("Successfully ran {}!", exercise);
 
-    Ok(prompt_for_completion(&exercise, Some(output.stdout)))
+    Ok(prompt_for_completion(exercise, Some(output.stdout)))
 }
 
 // Compile the given Exercise as a test harness and display
@@ -94,7 +94,7 @@ fn compile_and_test(exercise: &Exercise, run_mode: RunMode, verbose: bool) -> Re
             }
             success!("Successfully tested {}", &exercise);
             if let RunMode::Interactive = run_mode {
-                Ok(prompt_for_completion(&exercise, None))
+                Ok(prompt_for_completion(exercise, None))
             } else {
                 Ok(true)
             }