diff --git a/mk/docs.mk b/mk/docs.mk index 8a0c17de27aa0..48758c783e302 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -202,6 +202,22 @@ endef $(foreach docname,$(DOCS),$(eval $(call DEF_DOC,$(docname)))) +# Error pages +doc/errors/: + @mkdir -p $@ + +ERROR_DOCS = $(basename $(notdir $(wildcard src/doc/errors/*.md))) + +define DEF_ERROR_DOC + +# HTML (rustdoc) +DOC_TARGETS += doc/errors/$(1).html +doc/errors/$(1).html: $$(D)/errors/$(1).md $$(HTML_DEPS) $$(RUSTDOC_DEPS_$(1)) | doc/errors + @$$(call E, rustdoc: $$@) + $$(Q)$$(RUSTDOC) $$(RUSTDOC_HTML_OPTS) $$(RUSTDOC_FLAGS_$(1)) -o doc/errors $$< +endef + +$(foreach docname,$(ERROR_DOCS),$(eval $(call DEF_ERROR_DOC,$(docname)))) # Localized documentation diff --git a/src/doc/errors/E0001.md b/src/doc/errors/E0001.md new file mode 100644 index 0000000000000..744a2dd40b75f --- /dev/null +++ b/src/doc/errors/E0001.md @@ -0,0 +1,88 @@ +% E0001: Unreachable Pattern + +# Summary + +This error occurs when it's impossible for a particular `match` arm to ever +match the given pattern, because one of the preceeding arms will match. + +This means that perhaps some of the preceeding patterns are too general, this +one is too specific or the ordering is incorrect. + +# Examples + +Here is a function that triggers an `E0001`: + +```{ignore} +fn f(x: u32) { + match x { + 1 .. 10 => (), + 7 => (), + _ => (), + } +} +``` + +The error: + +```{ignore,notrust} +4:10 error: unreachable pattern [E0001] (pass `--explain E0001` to see a detailed explanation) + 7 => (), + ^ +``` + +We get this error because the previous `match` arm, `1 .. 10`, is a range which +contains `7`, and so it will match before the second arm ever gets a chance to. + +Fixing this problem depends on the exact reason you wrote the extra arm. If in +this case, you wanted something special to happen on a `7` (how lucky!), but +the same thing happen for `1` through `10`, you can move the `7` arm to be first: + +``` +fn f(x: u32) { + match x { + 7 => (), + 1 .. 10 => (), + _ => (), + } +} +``` + +Now, the `7` arm matches first, and the second arm takes care of the rest. + +It's also possible that one of your previous arms is too general. This can happen when +matching enums that have values: + +```{ignore} +fn f(x: Option) { + match x { + Some(true) | Some(false) => (), + Some(x) => (), + None => (), + } +} +``` + +This will fail on the second arm: + +```{ignore,notrust} +4:28 error: unreachable pattern [E0001] (pass `--explain E0001` to see a detailed explanation) + Some(x) => (), + ^~~~~~~ +``` + +Our first arm matches both the `true` and `false` values of the `Option`, and +since those are the two possible values, the `Some(x)` arm is never evaluated. + +To fix this issue, we need to make our previous pattern less general: + +``` +fn f(x: Option) { + match x { + Some(true) => (), + Some(x) => (), + None => (), + } +} +``` + +Now, the second arm will match, and bind `x` to `false`. diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 0b26a641f8d50..9dacd21c309a0 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -298,8 +298,8 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level, match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) { Some(_) => { try!(write!(&mut dst.dst, - " (pass `--explain {}` to see a detailed explanation)", - code + " (pass `--explain {code}` to see more detail or visit http://doc.rust-lang.org/errors/{code}.html for extensive help with this error)", + code = code )); } None => ()